From dff0b5dce5565cc73c1b13c7907d1eac152a8c86 Mon Sep 17 00:00:00 2001 From: NIkita Fedrunov Date: Wed, 26 Jan 2022 16:07:56 +0100 Subject: [PATCH 001/302] Add all screens about Spaces in allScreensTest --- .../vector/app/ui/UiAllScreensSanityTest.kt | 18 ++ .../im/vector/app/ui/robot/ElementRobot.kt | 4 + .../java/im/vector/app/ui/robot/SpaceRobot.kt | 214 ++++++++++++++++++ 3 files changed, 236 insertions(+) create mode 100644 vector/src/androidTest/java/im/vector/app/ui/robot/SpaceRobot.kt diff --git a/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt b/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt index 042e9ef3ee..8d1f93bc1a 100644 --- a/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt +++ b/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt @@ -20,6 +20,7 @@ import androidx.test.espresso.IdlingPolicies import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest +import com.adevinta.android.barista.interaction.BaristaDrawerInteractions.openDrawer import im.vector.app.R import im.vector.app.espresso.tools.ScreenshotFailureRule import im.vector.app.features.MainActivity @@ -95,6 +96,23 @@ class UiAllScreensSanityTest { } } + elementRobot.space { + openDrawer() + createSpace() + openDrawer() + openSpaceMenu() + invitePeople() + openSpaceMenu() + spaceMembers() + spaceSettings() + exploreRooms() + addRoom() + openSpaceMenu() + addSpace() + openSpaceMenu() + leaveSpace() + } + elementRobot.withDeveloperMode { settings { advancedSettings { crawlDeveloperOptions() } diff --git a/vector/src/androidTest/java/im/vector/app/ui/robot/ElementRobot.kt b/vector/src/androidTest/java/im/vector/app/ui/robot/ElementRobot.kt index d7e99c63dd..4363f69fb9 100644 --- a/vector/src/androidTest/java/im/vector/app/ui/robot/ElementRobot.kt +++ b/vector/src/androidTest/java/im/vector/app/ui/robot/ElementRobot.kt @@ -147,6 +147,10 @@ class ElementRobot { waitUntilViewVisible(withId(R.id.bottomSheetFragmentContainer)) }.onFailure { Timber.w("Verification popup missing", it) } } + + fun space(block: SpaceRobot.() -> Unit) { + block(SpaceRobot()) + } } private fun Boolean.toWarningType() = if (this) "shown" else "skipped" diff --git a/vector/src/androidTest/java/im/vector/app/ui/robot/SpaceRobot.kt b/vector/src/androidTest/java/im/vector/app/ui/robot/SpaceRobot.kt new file mode 100644 index 0000000000..154582f2ad --- /dev/null +++ b/vector/src/androidTest/java/im/vector/app/ui/robot/SpaceRobot.kt @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2021 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.ui.robot + +import androidx.recyclerview.widget.RecyclerView +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.Espresso.pressBack +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.action.ViewActions.replaceText +import androidx.test.espresso.contrib.RecyclerViewActions +import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility +import androidx.test.espresso.matcher.ViewMatchers.withHint +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText +import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn +import com.adevinta.android.barista.internal.viewaction.ClickChildAction.clickChildWithId +import im.vector.app.EspressoHelper +import im.vector.app.R +import im.vector.app.espresso.tools.waitUntilActivityVisible +import im.vector.app.espresso.tools.waitUntilDialogVisible +import im.vector.app.espresso.tools.waitUntilViewVisible +import im.vector.app.features.home.HomeActivity +import im.vector.app.features.invite.InviteUsersToRoomActivity +import im.vector.app.features.roomprofile.RoomProfileActivity +import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleActivity +import im.vector.app.features.spaces.SpaceCreationActivity +import im.vector.app.features.spaces.SpaceExploreActivity +import im.vector.app.features.spaces.leave.SpaceLeaveAdvancedActivity +import im.vector.app.features.spaces.manage.SpaceManageActivity +import org.hamcrest.Matchers.allOf +import java.util.UUID + +class SpaceRobot { + + fun createSpace() { + clickOn(R.string.add_space) + waitUntilActivityVisible { + waitUntilViewVisible(withId(R.id.privateButton)) + } + crawlCreate() + + onView(withId(R.id.roomList)) + .perform( + RecyclerViewActions.actionOnItem( + ViewMatchers.hasDescendant(withText(R.string.room_displayname_empty_room)), + click() + ).atPosition(0) + ) + clickOn(R.id.spaceAddRoomSaveItem) + waitUntilActivityVisible { + waitUntilViewVisible(withId(R.id.roomListContainer)) + } + } + + private fun crawlCreate() { + //public + clickOn(R.id.publicButton) + waitUntilViewVisible(withId(R.id.recyclerView)) + onView(withHint(R.string.create_room_name_hint)).perform(replaceText(UUID.randomUUID().toString())) + clickOn(R.id.nextButton) + waitUntilViewVisible(withId(R.id.recyclerView)) + pressBack() + pressBack() + + //private + clickOn(R.id.privateButton) + waitUntilViewVisible(withId(R.id.recyclerView)) + clickOn(R.id.nextButton) + + waitUntilViewVisible(withId(R.id.teammatesButton)) + //me and teammates + clickOn(R.id.teammatesButton) + waitUntilViewVisible(withId(R.id.recyclerView)) + clickOn(R.id.nextButton) + pressBack() + pressBack() + + //just me + waitUntilViewVisible(withId(R.id.justMeButton)) + clickOn(R.id.justMeButton) + waitUntilActivityVisible { + waitUntilViewVisible(withId(R.id.roomList)) + } + } + + fun openSpaceMenu() { + waitUntilViewVisible(withId(R.id.groupListView)) + onView(withId(R.id.groupListView)) + .perform( + RecyclerViewActions.actionOnItem( + ViewMatchers.hasDescendant(allOf(withId(R.id.groupTmpLeave), withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))), + clickChildWithId(R.id.groupTmpLeave) + ).atPosition(0) + ) + waitUntilDialogVisible(withId(R.id.spaceNameView)) + } + + fun invitePeople() { + clickOn(R.id.invitePeople) + waitUntilDialogVisible(withId(R.id.inviteByMxidButton)) + clickOn(R.id.inviteByMxidButton) + waitUntilActivityVisible { + waitUntilViewVisible(withId(R.id.userListRecyclerView)) + } + EspressoHelper.getCurrentActivity()!!.finish() + //close invite dialog + pressBack() + } + + fun spaceMembers() { + clickOn(R.id.showMemberList) + waitUntilActivityVisible { + waitUntilViewVisible(withId(R.id.roomSettingsRecyclerView)) + } + pressBack() + } + + fun spaceSettings() { + clickOn(R.id.spaceSettings) + waitUntilActivityVisible() { + waitUntilViewVisible(withId(R.id.roomSettingsRecyclerView)) + } + crawlSettings() + } + + private fun crawlSettings() { + onView(withId(R.id.roomSettingsRecyclerView)) + .perform( + RecyclerViewActions.actionOnItem( + ViewMatchers.hasDescendant(withText(R.string.room_settings_space_access_title)), + click() + ) + ) + + waitUntilActivityVisible() { + waitUntilViewVisible(withId(R.id.genericRecyclerView)) + } + + pressBack() + + onView(withId(R.id.roomSettingsRecyclerView)) + .perform( + RecyclerViewActions.actionOnItem( + ViewMatchers.hasDescendant(withText(R.string.space_settings_manage_rooms)), + click() + ) + ) + + waitUntilViewVisible(withId(R.id.roomList)) + pressBack() + + onView(withId(R.id.roomSettingsRecyclerView)) + .perform( + RecyclerViewActions.actionOnItem( + ViewMatchers.hasDescendant(withText(R.string.space_settings_permissions_title)), + click() + ) + ) + + waitUntilViewVisible(withId(R.id.roomSettingsRecyclerView)) + pressBack() + pressBack() + } + + fun exploreRooms() { + clickOn(R.id.exploreRooms) + waitUntilActivityVisible { + waitUntilViewVisible(withId(R.id.spaceDirectoryList)) + } + pressBack() + } + + fun addRoom() { + clickOn(R.id.addRooms) + waitUntilActivityVisible { + waitUntilViewVisible(withId(R.id.roomList)) + } + pressBack() + } + + fun addSpace() { + clickOn(R.id.addSpaces) + waitUntilActivityVisible { + waitUntilViewVisible(withId(R.id.roomList)) + } + pressBack() + } + + fun leaveSpace() { + clickOn(R.id.leaveSpace) + waitUntilDialogVisible(withId(R.id.leaveButton)) + clickOn(R.id.leave_selected) + waitUntilActivityVisible { + waitUntilViewVisible(withId(R.id.roomList)) + } + clickOn(R.id.spaceLeaveButton) + waitUntilViewVisible(withId(R.id.groupListView)) + } +} From 90c502b16a7c933e16a16f371741d6c16d4c5bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timu=C3=A7in=20Boldt?= Date: Mon, 31 Jan 2022 09:12:10 +0100 Subject: [PATCH 002/302] Make Space creation screens more consistent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Timuçin Boldt --- changelog.d/5099.misc | 1 + ...ragment_space_create_choose_private_model.xml | 15 +++++++++++++-- .../layout/fragment_space_create_choose_type.xml | 16 ++-------------- 3 files changed, 16 insertions(+), 16 deletions(-) create mode 100644 changelog.d/5099.misc diff --git a/changelog.d/5099.misc b/changelog.d/5099.misc new file mode 100644 index 0000000000..37294b5163 --- /dev/null +++ b/changelog.d/5099.misc @@ -0,0 +1 @@ +Make Space creation screens more consistent \ No newline at end of file diff --git a/vector/src/main/res/layout/fragment_space_create_choose_private_model.xml b/vector/src/main/res/layout/fragment_space_create_choose_private_model.xml index e1e555eace..e3e5fe7e45 100644 --- a/vector/src/main/res/layout/fragment_space_create_choose_private_model.xml +++ b/vector/src/main/res/layout/fragment_space_create_choose_private_model.xml @@ -13,7 +13,7 @@ + + \ No newline at end of file diff --git a/vector/src/main/res/layout/fragment_space_create_choose_type.xml b/vector/src/main/res/layout/fragment_space_create_choose_type.xml index b675ec9b30..dd448bc967 100644 --- a/vector/src/main/res/layout/fragment_space_create_choose_type.xml +++ b/vector/src/main/res/layout/fragment_space_create_choose_type.xml @@ -12,26 +12,14 @@ - - + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toBottomOf="@id/headerText" /> Date: Mon, 31 Jan 2022 14:07:07 +0100 Subject: [PATCH 003/302] adapt changelog to pr# --- changelog.d/5099.misc | 1 - changelog.d/5104.misc | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 changelog.d/5099.misc create mode 100644 changelog.d/5104.misc diff --git a/changelog.d/5099.misc b/changelog.d/5099.misc deleted file mode 100644 index 37294b5163..0000000000 --- a/changelog.d/5099.misc +++ /dev/null @@ -1 +0,0 @@ -Make Space creation screens more consistent \ No newline at end of file diff --git a/changelog.d/5104.misc b/changelog.d/5104.misc new file mode 100644 index 0000000000..673614955b --- /dev/null +++ b/changelog.d/5104.misc @@ -0,0 +1 @@ +Make Space creation screens more consistent From 5fe270fc9c363f7e517eea744987bd917d70ef4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timu=C3=A7in=20Boldt?= Date: Tue, 1 Feb 2022 12:07:53 +0100 Subject: [PATCH 004/302] adapt strings for space creation --- vector/src/main/res/values/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 22c890eb01..7adace95ec 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -3480,12 +3480,13 @@ Add Space Your public space Your private space + Spaces are a new way to group rooms and people What type of space do you want to create? You can change this later To join an existing space, you need an invite. Who are you working with? - Make sure the right people have access to %s. You can change this later. + Make sure the right people have access to %s. Just me A private space to organise your rooms Me and teammates From 28ea600e0d6e7e805e6fb9636165cdd6a91be37b Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 3 Feb 2022 14:18:16 +0100 Subject: [PATCH 005/302] Updating PR template description --- .github/PULL_REQUEST_TEMPLATE.md | 42 ++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index eb30c18fcf..7096e6bdb5 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,9 +1,41 @@ -### Pull Request Checklist + + +## Type of change - +- [ ] Feature +- [ ] Bugfix +- [ ] Technical +- [ ] Other : + +## Content + + + +## Motivation and context + + + +## Screenshots / GIFs + + + +## Tests + + + +- Step 1 +- Step 2 +- Step ... + +## Tested devices + +- [ ] Physical +- [ ] Emulator +- OS version(s): + +## 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 From 8a4ecf616acc73f21be1792a1d0e8b3f3c397630 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 3 Feb 2022 21:05:30 +0100 Subject: [PATCH 006/302] Split the classes RealmMigration into smaller classes --- .../internal/auth/db/AuthRealmMigration.kt | 93 +-- .../auth/db/migration/MigrateAuthTo001.kt | 41 ++ .../auth/db/migration/MigrateAuthTo002.kt | 33 + .../auth/db/migration/MigrateAuthTo003.kt | 47 ++ .../auth/db/migration/MigrateAuthTo004.kt | 57 ++ .../store/db/RealmCryptoStoreMigration.kt | 569 +----------------- .../db/migration/MigrateCryptoTo001Legacy.kt | 35 ++ .../db/migration/MigrateCryptoTo002Legacy.kt | 86 +++ .../db/migration/MigrateCryptoTo003RiotX.kt | 83 +++ .../store/db/migration/MigrateCryptoTo004.kt | 139 +++++ .../store/db/migration/MigrateCryptoTo005.kt | 66 ++ .../store/db/migration/MigrateCryptoTo006.kt | 32 + .../store/db/migration/MigrateCryptoTo007.kt | 65 ++ .../store/db/migration/MigrateCryptoTo008.kt | 46 ++ .../store/db/migration/MigrateCryptoTo009.kt | 44 ++ .../store/db/migration/MigrateCryptoTo010.kt | 50 ++ .../store/db/migration/MigrateCryptoTo011.kt | 30 + .../store/db/migration/MigrateCryptoTo012.kt | 36 ++ .../store/db/migration/MigrateCryptoTo013.kt | 78 +++ .../store/db/migration/MigrateCryptoTo014.kt | 41 ++ .../database/RealmSessionStoreMigration.kt | 496 ++------------- .../database/migration/MigrateSessionTo001.kt | 33 + .../database/migration/MigrateSessionTo002.kt | 31 + .../database/migration/MigrateSessionTo003.kt | 33 + .../database/migration/MigrateSessionTo004.kt | 36 ++ .../database/migration/MigrateSessionTo005.kt | 29 + .../database/migration/MigrateSessionTo006.kt | 37 ++ .../database/migration/MigrateSessionTo007.kt | 38 ++ .../database/migration/MigrateSessionTo008.kt | 47 ++ .../database/migration/MigrateSessionTo009.kt | 65 ++ .../database/migration/MigrateSessionTo010.kt | 70 +++ .../database/migration/MigrateSessionTo011.kt | 29 + .../database/migration/MigrateSessionTo012.kt | 53 ++ .../database/migration/MigrateSessionTo013.kt | 32 + .../database/migration/MigrateSessionTo014.kt | 46 ++ .../database/migration/MigrateSessionTo015.kt | 38 ++ .../database/migration/MigrateSessionTo016.kt | 33 + .../database/migration/MigrateSessionTo017.kt | 29 + .../database/migration/MigrateSessionTo018.kt | 48 ++ .../database/migration/MigrateSessionTo019.kt | 37 ++ .../database/migration/MigrateSessionTo020.kt | 45 ++ .../database/migration/MigrateSessionTo021.kt | 55 ++ .../database/migration/MigrateSessionTo022.kt | 42 ++ .../database/migration/MigrateSessionTo023.kt | 40 ++ .../database/migration/MigrateSessionTo024.kt | 32 + .../sdk/internal/raw/GlobalRealmMigration.kt | 13 +- .../raw/migration/MigrateGlobalTo001.kt | 31 + .../db/RealmIdentityStoreMigration.kt | 11 +- .../db/migration/MigrateIdentityTo001.kt | 31 + .../internal/util/database/RealmMigrator.kt | 52 ++ 50 files changed, 2190 insertions(+), 1093 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo001.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo002.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo003.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo004.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo001Legacy.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo002Legacy.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo003RiotX.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo004.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo005.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo006.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo007.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo008.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo009.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo010.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo011.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo012.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo013.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo014.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo001.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo002.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo003.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo004.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo005.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo006.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo007.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo008.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo009.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo010.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo011.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo012.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo013.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo014.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo015.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo016.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo017.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo018.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo019.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo020.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo021.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo022.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo023.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo024.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/migration/MigrateGlobalTo001.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/migration/MigrateIdentityTo001.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/database/RealmMigrator.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/AuthRealmMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/AuthRealmMigration.kt index c2104690b3..484273eef5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/AuthRealmMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/AuthRealmMigration.kt @@ -16,13 +16,12 @@ package org.matrix.android.sdk.internal.auth.db -import android.net.Uri import io.realm.DynamicRealm import io.realm.RealmMigration -import org.matrix.android.sdk.api.auth.data.Credentials -import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig -import org.matrix.android.sdk.api.auth.data.sessionId -import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.auth.db.migration.MigrateAuthTo001 +import org.matrix.android.sdk.internal.auth.db.migration.MigrateAuthTo002 +import org.matrix.android.sdk.internal.auth.db.migration.MigrateAuthTo003 +import org.matrix.android.sdk.internal.auth.db.migration.MigrateAuthTo004 import timber.log.Timber internal object AuthRealmMigration : RealmMigration { @@ -33,85 +32,9 @@ internal object AuthRealmMigration : RealmMigration { override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { Timber.d("Migrating Auth Realm from $oldVersion to $newVersion") - if (oldVersion <= 0) migrateTo1(realm) - if (oldVersion <= 1) migrateTo2(realm) - if (oldVersion <= 2) migrateTo3(realm) - if (oldVersion <= 3) migrateTo4(realm) - } - - private fun migrateTo1(realm: DynamicRealm) { - Timber.d("Step 0 -> 1") - Timber.d("Create PendingSessionEntity") - - realm.schema.create("PendingSessionEntity") - .addField(PendingSessionEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON, String::class.java) - .setRequired(PendingSessionEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON, true) - .addField(PendingSessionEntityFields.CLIENT_SECRET, String::class.java) - .setRequired(PendingSessionEntityFields.CLIENT_SECRET, true) - .addField(PendingSessionEntityFields.SEND_ATTEMPT, Integer::class.java) - .setRequired(PendingSessionEntityFields.SEND_ATTEMPT, true) - .addField(PendingSessionEntityFields.RESET_PASSWORD_DATA_JSON, String::class.java) - .addField(PendingSessionEntityFields.CURRENT_SESSION, String::class.java) - .addField(PendingSessionEntityFields.IS_REGISTRATION_STARTED, Boolean::class.java) - .addField(PendingSessionEntityFields.CURRENT_THREE_PID_DATA_JSON, String::class.java) - } - - private fun migrateTo2(realm: DynamicRealm) { - Timber.d("Step 1 -> 2") - Timber.d("Add boolean isTokenValid in SessionParamsEntity, with value true") - - realm.schema.get("SessionParamsEntity") - ?.addField(SessionParamsEntityFields.IS_TOKEN_VALID, Boolean::class.java) - ?.transform { it.set(SessionParamsEntityFields.IS_TOKEN_VALID, true) } - } - - private fun migrateTo3(realm: DynamicRealm) { - Timber.d("Step 2 -> 3") - Timber.d("Update SessionParamsEntity primary key, to allow several sessions with the same userId") - - realm.schema.get("SessionParamsEntity") - ?.removePrimaryKey() - ?.addField(SessionParamsEntityFields.SESSION_ID, String::class.java) - ?.setRequired(SessionParamsEntityFields.SESSION_ID, true) - ?.transform { - val credentialsJson = it.getString(SessionParamsEntityFields.CREDENTIALS_JSON) - - val credentials = MoshiProvider.providesMoshi() - .adapter(Credentials::class.java) - .fromJson(credentialsJson) - - it.set(SessionParamsEntityFields.SESSION_ID, credentials!!.sessionId()) - } - ?.addPrimaryKey(SessionParamsEntityFields.SESSION_ID) - } - - private fun migrateTo4(realm: DynamicRealm) { - Timber.d("Step 3 -> 4") - Timber.d("Update SessionParamsEntity to add HomeServerConnectionConfig.homeServerUriBase value") - - val adapter = MoshiProvider.providesMoshi() - .adapter(HomeServerConnectionConfig::class.java) - - realm.schema.get("SessionParamsEntity") - ?.transform { - val homeserverConnectionConfigJson = it.getString(SessionParamsEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON) - - val homeserverConnectionConfig = adapter - .fromJson(homeserverConnectionConfigJson) - - val homeserverUrl = homeserverConnectionConfig?.homeServerUri?.toString() - // Special case for matrix.org. Old session may use "https://matrix.org", newer one may use - // "https://matrix-client.matrix.org". So fix that here - val alteredHomeserverConnectionConfig = - if (homeserverUrl == "https://matrix.org" || homeserverUrl == "https://matrix-client.matrix.org") { - homeserverConnectionConfig.copy( - homeServerUri = Uri.parse("https://matrix.org"), - homeServerUriBase = Uri.parse("https://matrix-client.matrix.org") - ) - } else { - homeserverConnectionConfig - } - it.set(SessionParamsEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON, adapter.toJson(alteredHomeserverConnectionConfig)) - } + if (oldVersion < 1) MigrateAuthTo001(realm).perform() + if (oldVersion < 2) MigrateAuthTo002(realm).perform() + if (oldVersion < 3) MigrateAuthTo003(realm).perform() + if (oldVersion < 4) MigrateAuthTo004(realm).perform() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo001.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo001.kt new file mode 100644 index 0000000000..627f4e16bc --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo001.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 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.internal.auth.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.auth.db.PendingSessionEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import timber.log.Timber + +class MigrateAuthTo001(realm: DynamicRealm) : RealmMigrator(realm, 1) { + + override fun doMigrate(realm: DynamicRealm) { + Timber.d("Create PendingSessionEntity") + + realm.schema.create("PendingSessionEntity") + .addField(PendingSessionEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON, String::class.java) + .setRequired(PendingSessionEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON, true) + .addField(PendingSessionEntityFields.CLIENT_SECRET, String::class.java) + .setRequired(PendingSessionEntityFields.CLIENT_SECRET, true) + .addField(PendingSessionEntityFields.SEND_ATTEMPT, Integer::class.java) + .setRequired(PendingSessionEntityFields.SEND_ATTEMPT, true) + .addField(PendingSessionEntityFields.RESET_PASSWORD_DATA_JSON, String::class.java) + .addField(PendingSessionEntityFields.CURRENT_SESSION, String::class.java) + .addField(PendingSessionEntityFields.IS_REGISTRATION_STARTED, Boolean::class.java) + .addField(PendingSessionEntityFields.CURRENT_THREE_PID_DATA_JSON, String::class.java) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo002.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo002.kt new file mode 100644 index 0000000000..6b133f8580 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo002.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 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.internal.auth.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.auth.db.SessionParamsEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import timber.log.Timber + +class MigrateAuthTo002(realm: DynamicRealm) : RealmMigrator(realm, 2) { + + override fun doMigrate(realm: DynamicRealm) { + Timber.d("Add boolean isTokenValid in SessionParamsEntity, with value true") + + realm.schema.get("SessionParamsEntity") + ?.addField(SessionParamsEntityFields.IS_TOKEN_VALID, Boolean::class.java) + ?.transform { it.set(SessionParamsEntityFields.IS_TOKEN_VALID, true) } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo003.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo003.kt new file mode 100644 index 0000000000..9319ec9987 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo003.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022 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.internal.auth.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.api.auth.data.Credentials +import org.matrix.android.sdk.api.auth.data.sessionId +import org.matrix.android.sdk.internal.auth.db.SessionParamsEntityFields +import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import timber.log.Timber + +class MigrateAuthTo003(realm: DynamicRealm) : RealmMigrator(realm, 3) { + + override fun doMigrate(realm: DynamicRealm) { + Timber.d("Update SessionParamsEntity primary key, to allow several sessions with the same userId") + + realm.schema.get("SessionParamsEntity") + ?.removePrimaryKey() + ?.addField(SessionParamsEntityFields.SESSION_ID, String::class.java) + ?.setRequired(SessionParamsEntityFields.SESSION_ID, true) + ?.transform { + val credentialsJson = it.getString(SessionParamsEntityFields.CREDENTIALS_JSON) + + val credentials = MoshiProvider.providesMoshi() + .adapter(Credentials::class.java) + .fromJson(credentialsJson) + + it.set(SessionParamsEntityFields.SESSION_ID, credentials!!.sessionId()) + } + ?.addPrimaryKey(SessionParamsEntityFields.SESSION_ID) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo004.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo004.kt new file mode 100644 index 0000000000..4a9b9022d5 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo004.kt @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 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.internal.auth.db.migration + +import android.net.Uri +import io.realm.DynamicRealm +import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig +import org.matrix.android.sdk.internal.auth.db.SessionParamsEntityFields +import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import timber.log.Timber + +class MigrateAuthTo004(realm: DynamicRealm) : RealmMigrator(realm, 4) { + + override fun doMigrate(realm: DynamicRealm) { + Timber.d("Update SessionParamsEntity to add HomeServerConnectionConfig.homeServerUriBase value") + + val adapter = MoshiProvider.providesMoshi() + .adapter(HomeServerConnectionConfig::class.java) + + realm.schema.get("SessionParamsEntity") + ?.transform { + val homeserverConnectionConfigJson = it.getString(SessionParamsEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON) + + val homeserverConnectionConfig = adapter + .fromJson(homeserverConnectionConfigJson) + + val homeserverUrl = homeserverConnectionConfig?.homeServerUri?.toString() + // Special case for matrix.org. Old session may use "https://matrix.org", newer one may use + // "https://matrix-client.matrix.org". So fix that here + val alteredHomeserverConnectionConfig = + if (homeserverUrl == "https://matrix.org" || homeserverUrl == "https://matrix-client.matrix.org") { + homeserverConnectionConfig.copy( + homeServerUri = Uri.parse("https://matrix.org"), + homeServerUriBase = Uri.parse("https://matrix-client.matrix.org") + ) + } else { + homeserverConnectionConfig + } + it.set(SessionParamsEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON, adapter.toJson(alteredHomeserverConnectionConfig)) + } + } +} 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 f73cbaf480..acee400cea 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 @@ -16,39 +16,23 @@ package org.matrix.android.sdk.internal.crypto.store.db -import com.squareup.moshi.Moshi -import com.squareup.moshi.Types import io.realm.DynamicRealm import io.realm.RealmMigration -import io.realm.RealmObjectSchema -import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.crypto.model.MXDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper -import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper2 -import org.matrix.android.sdk.internal.crypto.store.db.mapper.CrossSigningKeysMapper -import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.GossipingEventEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.IncomingGossipingRequestEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.KeyInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.OutboundGroupSessionInfoEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingGossipingRequestEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.TrustLevelEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields -import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntityFields -import org.matrix.android.sdk.internal.di.MoshiProvider -import org.matrix.android.sdk.internal.di.SerializeNulls -import org.matrix.androidsdk.crypto.data.MXOlmInboundGroupSession2 +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo001Legacy +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo002Legacy +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo003RiotX +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo004 +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo005 +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo006 +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo007 +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo008 +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo009 +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo010 +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo011 +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo012 +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo013 +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo014 import timber.log.Timber -import org.matrix.androidsdk.crypto.data.MXDeviceInfo as LegacyMXDeviceInfo internal object RealmCryptoStoreMigration : RealmMigration { @@ -57,519 +41,22 @@ internal object RealmCryptoStoreMigration : RealmMigration { // 4, 5, 6, 7, 8, 9: migrations from RiotX (which was previously 1, 2, 3, 4, 5, 6) const val CRYPTO_STORE_SCHEMA_VERSION = 14L - private fun RealmObjectSchema.addFieldIfNotExists(fieldName: String, fieldType: Class<*>): RealmObjectSchema { - if (!hasField(fieldName)) { - addField(fieldName, fieldType) - } - return this - } - - private fun RealmObjectSchema.removeFieldIfExists(fieldName: String): RealmObjectSchema { - if (hasField(fieldName)) { - removeField(fieldName) - } - return this - } - - private fun RealmObjectSchema.setRequiredIfNotAlready(fieldName: String, isRequired: Boolean): RealmObjectSchema { - if (isRequired != isRequired(fieldName)) { - setRequired(fieldName, isRequired) - } - return this - } - override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { Timber.v("Migrating Realm Crypto from $oldVersion to $newVersion") - if (oldVersion <= 0) migrateTo1Legacy(realm) - if (oldVersion <= 1) migrateTo2Legacy(realm) - if (oldVersion <= 2) migrateTo3RiotX(realm) - if (oldVersion <= 3) migrateTo4(realm) - if (oldVersion <= 4) migrateTo5(realm) - if (oldVersion <= 5) migrateTo6(realm) - if (oldVersion <= 6) migrateTo7(realm) - if (oldVersion <= 7) migrateTo8(realm) - if (oldVersion <= 8) migrateTo9(realm) - if (oldVersion <= 9) migrateTo10(realm) - 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) { - Timber.d("Step 0 -> 1") - Timber.d("Add field lastReceivedMessageTs (Long) and set the value to 0") - - realm.schema.get("OlmSessionEntity") - ?.addField(OlmSessionEntityFields.LAST_RECEIVED_MESSAGE_TS, Long::class.java) - ?.transform { - it.setLong(OlmSessionEntityFields.LAST_RECEIVED_MESSAGE_TS, 0) - } - } - - private fun migrateTo2Legacy(realm: DynamicRealm) { - Timber.d("Step 1 -> 2") - Timber.d("Update IncomingRoomKeyRequestEntity format: requestBodyString field is exploded into several fields") - - realm.schema.get("IncomingRoomKeyRequestEntity") - ?.addFieldIfNotExists("requestBodyAlgorithm", String::class.java) - ?.addFieldIfNotExists("requestBodyRoomId", String::class.java) - ?.addFieldIfNotExists("requestBodySenderKey", String::class.java) - ?.addFieldIfNotExists("requestBodySessionId", String::class.java) - ?.transform { dynamicObject -> - try { - val requestBodyString = dynamicObject.getString("requestBodyString") - // It was a map before - val map: Map? = deserializeFromRealm(requestBodyString) - - map?.let { - dynamicObject.setString("requestBodyAlgorithm", it["algorithm"]) - dynamicObject.setString("requestBodyRoomId", it["room_id"]) - dynamicObject.setString("requestBodySenderKey", it["sender_key"]) - dynamicObject.setString("requestBodySessionId", it["session_id"]) - } - } catch (e: Exception) { - Timber.e(e, "Error") - } - } - ?.removeFieldIfExists("requestBodyString") - - Timber.d("Update IncomingRoomKeyRequestEntity format: requestBodyString field is exploded into several fields") - - realm.schema.get("OutgoingRoomKeyRequestEntity") - ?.addFieldIfNotExists("requestBodyAlgorithm", String::class.java) - ?.addFieldIfNotExists("requestBodyRoomId", String::class.java) - ?.addFieldIfNotExists("requestBodySenderKey", String::class.java) - ?.addFieldIfNotExists("requestBodySessionId", String::class.java) - ?.transform { dynamicObject -> - try { - val requestBodyString = dynamicObject.getString("requestBodyString") - // It was a map before - val map: Map? = deserializeFromRealm(requestBodyString) - - map?.let { - dynamicObject.setString("requestBodyAlgorithm", it["algorithm"]) - dynamicObject.setString("requestBodyRoomId", it["room_id"]) - dynamicObject.setString("requestBodySenderKey", it["sender_key"]) - dynamicObject.setString("requestBodySessionId", it["session_id"]) - } - } catch (e: Exception) { - Timber.e(e, "Error") - } - } - ?.removeFieldIfExists("requestBodyString") - - Timber.d("Create KeysBackupDataEntity") - - if (!realm.schema.contains("KeysBackupDataEntity")) { - realm.schema.create("KeysBackupDataEntity") - .addField(KeysBackupDataEntityFields.PRIMARY_KEY, Integer::class.java) - .addPrimaryKey(KeysBackupDataEntityFields.PRIMARY_KEY) - .setRequired(KeysBackupDataEntityFields.PRIMARY_KEY, true) - .addField(KeysBackupDataEntityFields.BACKUP_LAST_SERVER_HASH, String::class.java) - .addField(KeysBackupDataEntityFields.BACKUP_LAST_SERVER_NUMBER_OF_KEYS, Integer::class.java) - } - } - - private fun migrateTo3RiotX(realm: DynamicRealm) { - Timber.d("Step 2 -> 3") - Timber.d("Migrate to RiotX model") - - realm.schema.get("CryptoRoomEntity") - ?.addFieldIfNotExists(CryptoRoomEntityFields.SHOULD_ENCRYPT_FOR_INVITED_MEMBERS, Boolean::class.java) - ?.setRequiredIfNotAlready(CryptoRoomEntityFields.SHOULD_ENCRYPT_FOR_INVITED_MEMBERS, false) - - // Convert format of MXDeviceInfo, package has to be the same. - realm.schema.get("DeviceInfoEntity") - ?.transform { obj -> - try { - val oldSerializedData = obj.getString("deviceInfoData") - deserializeFromRealm(oldSerializedData)?.let { legacyMxDeviceInfo -> - val newMxDeviceInfo = MXDeviceInfo( - deviceId = legacyMxDeviceInfo.deviceId, - userId = legacyMxDeviceInfo.userId, - algorithms = legacyMxDeviceInfo.algorithms, - keys = legacyMxDeviceInfo.keys, - signatures = legacyMxDeviceInfo.signatures, - unsigned = legacyMxDeviceInfo.unsigned, - verified = legacyMxDeviceInfo.mVerified - ) - - obj.setString("deviceInfoData", serializeForRealm(newMxDeviceInfo)) - } - } catch (e: Exception) { - Timber.e(e, "Error") - } - } - - // Convert MXOlmInboundGroupSession2 to OlmInboundGroupSessionWrapper - realm.schema.get("OlmInboundGroupSessionEntity") - ?.transform { obj -> - try { - val oldSerializedData = obj.getString("olmInboundGroupSessionData") - deserializeFromRealm(oldSerializedData)?.let { mxOlmInboundGroupSession2 -> - val sessionKey = mxOlmInboundGroupSession2.mSession.sessionIdentifier() - val newOlmInboundGroupSessionWrapper = OlmInboundGroupSessionWrapper(sessionKey, false) - .apply { - olmInboundGroupSession = mxOlmInboundGroupSession2.mSession - roomId = mxOlmInboundGroupSession2.mRoomId - senderKey = mxOlmInboundGroupSession2.mSenderKey - keysClaimed = mxOlmInboundGroupSession2.mKeysClaimed - forwardingCurve25519KeyChain = mxOlmInboundGroupSession2.mForwardingCurve25519KeyChain - } - - obj.setString("olmInboundGroupSessionData", serializeForRealm(newOlmInboundGroupSessionWrapper)) - } - } catch (e: Exception) { - Timber.e(e, "Error") - } - } - } - - // Version 4L added Cross Signing info persistence - private fun migrateTo4(realm: DynamicRealm) { - Timber.d("Step 3 -> 4") - - if (realm.schema.contains("TrustLevelEntity")) { - Timber.d("Skipping Step 3 -> 4 because entities already exist") - return - } - - Timber.d("Create KeyInfoEntity") - val trustLevelEntityEntitySchema = realm.schema.create("TrustLevelEntity") - .addField(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, Boolean::class.java) - .setNullable(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, true) - .addField(TrustLevelEntityFields.LOCALLY_VERIFIED, Boolean::class.java) - .setNullable(TrustLevelEntityFields.LOCALLY_VERIFIED, true) - - val keyInfoEntitySchema = realm.schema.create("KeyInfoEntity") - .addField(KeyInfoEntityFields.PUBLIC_KEY_BASE64, String::class.java) - .addField(KeyInfoEntityFields.SIGNATURES, String::class.java) - .addRealmListField(KeyInfoEntityFields.USAGES.`$`, String::class.java) - .addRealmObjectField(KeyInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevelEntityEntitySchema) - - Timber.d("Create CrossSigningInfoEntity") - - val crossSigningInfoSchema = realm.schema.create("CrossSigningInfoEntity") - .addField(CrossSigningInfoEntityFields.USER_ID, String::class.java) - .addPrimaryKey(CrossSigningInfoEntityFields.USER_ID) - .addRealmListField(CrossSigningInfoEntityFields.CROSS_SIGNING_KEYS.`$`, keyInfoEntitySchema) - - Timber.d("Updating UserEntity table") - realm.schema.get("UserEntity") - ?.addRealmObjectField(UserEntityFields.CROSS_SIGNING_INFO_ENTITY.`$`, crossSigningInfoSchema) - - Timber.d("Updating CryptoMetadataEntity table") - realm.schema.get("CryptoMetadataEntity") - ?.addField(CryptoMetadataEntityFields.X_SIGN_MASTER_PRIVATE_KEY, String::class.java) - ?.addField(CryptoMetadataEntityFields.X_SIGN_USER_PRIVATE_KEY, String::class.java) - ?.addField(CryptoMetadataEntityFields.X_SIGN_SELF_SIGNED_PRIVATE_KEY, String::class.java) - - val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build() - val listMigrationAdapter = moshi.adapter>(Types.newParameterizedType( - List::class.java, - String::class.java, - Any::class.java - )) - val mapMigrationAdapter = moshi.adapter(Types.newParameterizedType( - Map::class.java, - String::class.java, - Any::class.java - )) - - realm.schema.get("DeviceInfoEntity") - ?.addField(DeviceInfoEntityFields.USER_ID, String::class.java) - ?.addField(DeviceInfoEntityFields.ALGORITHM_LIST_JSON, String::class.java) - ?.addField(DeviceInfoEntityFields.KEYS_MAP_JSON, String::class.java) - ?.addField(DeviceInfoEntityFields.SIGNATURE_MAP_JSON, String::class.java) - ?.addField(DeviceInfoEntityFields.UNSIGNED_MAP_JSON, String::class.java) - ?.addField(DeviceInfoEntityFields.IS_BLOCKED, Boolean::class.java) - ?.setNullable(DeviceInfoEntityFields.IS_BLOCKED, true) - ?.addRealmObjectField(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevelEntityEntitySchema) - ?.transform { obj -> - - try { - val oldSerializedData = obj.getString("deviceInfoData") - deserializeFromRealm(oldSerializedData)?.let { oldDevice -> - - val trustLevel = realm.createObject("TrustLevelEntity") - when (oldDevice.verified) { - MXDeviceInfo.DEVICE_VERIFICATION_UNKNOWN -> { - obj.setNull(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`) - } - MXDeviceInfo.DEVICE_VERIFICATION_BLOCKED -> { - trustLevel.setNull(TrustLevelEntityFields.LOCALLY_VERIFIED) - trustLevel.setNull(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED) - obj.setBoolean(DeviceInfoEntityFields.IS_BLOCKED, oldDevice.isBlocked) - obj.setObject(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevel) - } - MXDeviceInfo.DEVICE_VERIFICATION_UNVERIFIED -> { - trustLevel.setBoolean(TrustLevelEntityFields.LOCALLY_VERIFIED, false) - trustLevel.setBoolean(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, false) - obj.setObject(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevel) - } - MXDeviceInfo.DEVICE_VERIFICATION_VERIFIED -> { - trustLevel.setBoolean(TrustLevelEntityFields.LOCALLY_VERIFIED, true) - trustLevel.setBoolean(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, false) - obj.setObject(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevel) - } - } - - obj.setString(DeviceInfoEntityFields.USER_ID, oldDevice.userId) - obj.setString(DeviceInfoEntityFields.IDENTITY_KEY, oldDevice.identityKey()) - obj.setString(DeviceInfoEntityFields.ALGORITHM_LIST_JSON, listMigrationAdapter.toJson(oldDevice.algorithms)) - obj.setString(DeviceInfoEntityFields.KEYS_MAP_JSON, mapMigrationAdapter.toJson(oldDevice.keys)) - obj.setString(DeviceInfoEntityFields.SIGNATURE_MAP_JSON, mapMigrationAdapter.toJson(oldDevice.signatures)) - obj.setString(DeviceInfoEntityFields.UNSIGNED_MAP_JSON, mapMigrationAdapter.toJson(oldDevice.unsigned)) - } - } catch (failure: Throwable) { - Timber.w(failure, "Crypto Data base migration error") - // an unfortunate refactor did modify that class, making deserialization failing - // so we just skip and ignore.. - } - } - ?.removeField("deviceInfoData") - } - - private fun migrateTo5(realm: DynamicRealm) { - Timber.d("Step 4 -> 5") - realm.schema.remove("OutgoingRoomKeyRequestEntity") - realm.schema.remove("IncomingRoomKeyRequestEntity") - - // Not need to migrate existing request, just start fresh? - - realm.schema.create("GossipingEventEntity") - .addField(GossipingEventEntityFields.TYPE, String::class.java) - .addIndex(GossipingEventEntityFields.TYPE) - .addField(GossipingEventEntityFields.CONTENT, String::class.java) - .addField(GossipingEventEntityFields.SENDER, String::class.java) - .addIndex(GossipingEventEntityFields.SENDER) - .addField(GossipingEventEntityFields.DECRYPTION_RESULT_JSON, String::class.java) - .addField(GossipingEventEntityFields.DECRYPTION_ERROR_CODE, String::class.java) - .addField(GossipingEventEntityFields.AGE_LOCAL_TS, Long::class.java) - .setNullable(GossipingEventEntityFields.AGE_LOCAL_TS, true) - .addField(GossipingEventEntityFields.SEND_STATE_STR, String::class.java) - - realm.schema.create("IncomingGossipingRequestEntity") - .addField(IncomingGossipingRequestEntityFields.REQUEST_ID, String::class.java) - .addIndex(IncomingGossipingRequestEntityFields.REQUEST_ID) - .addField(IncomingGossipingRequestEntityFields.TYPE_STR, String::class.java) - .addIndex(IncomingGossipingRequestEntityFields.TYPE_STR) - .addField(IncomingGossipingRequestEntityFields.OTHER_USER_ID, String::class.java) - .addField(IncomingGossipingRequestEntityFields.REQUESTED_INFO_STR, String::class.java) - .addField(IncomingGossipingRequestEntityFields.OTHER_DEVICE_ID, String::class.java) - .addField(IncomingGossipingRequestEntityFields.REQUEST_STATE_STR, String::class.java) - .addField(IncomingGossipingRequestEntityFields.LOCAL_CREATION_TIMESTAMP, Long::class.java) - .setNullable(IncomingGossipingRequestEntityFields.LOCAL_CREATION_TIMESTAMP, true) - - realm.schema.create("OutgoingGossipingRequestEntity") - .addField(OutgoingGossipingRequestEntityFields.REQUEST_ID, String::class.java) - .addIndex(OutgoingGossipingRequestEntityFields.REQUEST_ID) - .addField(OutgoingGossipingRequestEntityFields.RECIPIENTS_DATA, String::class.java) - .addField(OutgoingGossipingRequestEntityFields.REQUESTED_INFO_STR, String::class.java) - .addField(OutgoingGossipingRequestEntityFields.TYPE_STR, String::class.java) - .addIndex(OutgoingGossipingRequestEntityFields.TYPE_STR) - .addField(OutgoingGossipingRequestEntityFields.REQUEST_STATE_STR, String::class.java) - } - - private fun migrateTo6(realm: DynamicRealm) { - Timber.d("Step 5 -> 6") - Timber.d("Updating CryptoMetadataEntity table") - realm.schema.get("CryptoMetadataEntity") - ?.addField(CryptoMetadataEntityFields.KEY_BACKUP_RECOVERY_KEY, String::class.java) - ?.addField(CryptoMetadataEntityFields.KEY_BACKUP_RECOVERY_KEY_VERSION, String::class.java) - } - - private fun migrateTo7(realm: DynamicRealm) { - Timber.d("Step 6 -> 7") - Timber.d("Updating KeyInfoEntity table") - val crossSigningKeysMapper = CrossSigningKeysMapper(MoshiProvider.providesMoshi()) - - val keyInfoEntities = realm.where("KeyInfoEntity").findAll() - try { - keyInfoEntities.forEach { - val stringSignatures = it.getString(KeyInfoEntityFields.SIGNATURES) - val objectSignatures: Map>? = deserializeFromRealm(stringSignatures) - val jsonSignatures = crossSigningKeysMapper.serializeSignatures(objectSignatures) - it.setString(KeyInfoEntityFields.SIGNATURES, jsonSignatures) - } - } catch (failure: Throwable) { - } - - // Migrate frozen classes - val inboundGroupSessions = realm.where("OlmInboundGroupSessionEntity").findAll() - inboundGroupSessions.forEach { dynamicObject -> - dynamicObject.getString(OlmInboundGroupSessionEntityFields.OLM_INBOUND_GROUP_SESSION_DATA)?.let { serializedObject -> - try { - deserializeFromRealm(serializedObject)?.let { oldFormat -> - val newFormat = oldFormat.exportKeys()?.let { - OlmInboundGroupSessionWrapper2(it) - } - dynamicObject.setString(OlmInboundGroupSessionEntityFields.OLM_INBOUND_GROUP_SESSION_DATA, serializeForRealm(newFormat)) - } - } catch (failure: Throwable) { - Timber.e(failure, "## OlmInboundGroupSessionEntity migration failed") - } - } - } - } - - private fun migrateTo8(realm: DynamicRealm) { - Timber.d("Step 7 -> 8") - realm.schema.create("MyDeviceLastSeenInfoEntity") - .addField(MyDeviceLastSeenInfoEntityFields.DEVICE_ID, String::class.java) - .addPrimaryKey(MyDeviceLastSeenInfoEntityFields.DEVICE_ID) - .addField(MyDeviceLastSeenInfoEntityFields.DISPLAY_NAME, String::class.java) - .addField(MyDeviceLastSeenInfoEntityFields.LAST_SEEN_IP, String::class.java) - .addField(MyDeviceLastSeenInfoEntityFields.LAST_SEEN_TS, Long::class.java) - .setNullable(MyDeviceLastSeenInfoEntityFields.LAST_SEEN_TS, true) - - val now = System.currentTimeMillis() - realm.schema.get("DeviceInfoEntity") - ?.addField(DeviceInfoEntityFields.FIRST_TIME_SEEN_LOCAL_TS, Long::class.java) - ?.setNullable(DeviceInfoEntityFields.FIRST_TIME_SEEN_LOCAL_TS, true) - ?.transform { deviceInfoEntity -> - tryOrNull { - deviceInfoEntity.setLong(DeviceInfoEntityFields.FIRST_TIME_SEEN_LOCAL_TS, now) - } - } - } - - // Fixes duplicate devices in UserEntity#devices - private fun migrateTo9(realm: DynamicRealm) { - Timber.d("Step 8 -> 9") - val userEntities = realm.where("UserEntity").findAll() - userEntities.forEach { - try { - val deviceList = it.getList(UserEntityFields.DEVICES.`$`) - ?: return@forEach - val distinct = deviceList.distinctBy { it.getString(DeviceInfoEntityFields.DEVICE_ID) } - if (distinct.size != deviceList.size) { - deviceList.clear() - deviceList.addAll(distinct) - } - } catch (failure: Throwable) { - Timber.w(failure, "Crypto Data base migration error for migrateTo9") - } - } - } - - // Version 10L added WithHeld Keys Info (MSC2399) - private fun migrateTo10(realm: DynamicRealm) { - Timber.d("Step 9 -> 10") - realm.schema.create("WithHeldSessionEntity") - .addField(WithHeldSessionEntityFields.ROOM_ID, String::class.java) - .addField(WithHeldSessionEntityFields.ALGORITHM, String::class.java) - .addField(WithHeldSessionEntityFields.SESSION_ID, String::class.java) - .addIndex(WithHeldSessionEntityFields.SESSION_ID) - .addField(WithHeldSessionEntityFields.SENDER_KEY, String::class.java) - .addIndex(WithHeldSessionEntityFields.SENDER_KEY) - .addField(WithHeldSessionEntityFields.CODE_STRING, String::class.java) - .addField(WithHeldSessionEntityFields.REASON, String::class.java) - - realm.schema.create("SharedSessionEntity") - .addField(SharedSessionEntityFields.ROOM_ID, String::class.java) - .addField(SharedSessionEntityFields.ALGORITHM, String::class.java) - .addField(SharedSessionEntityFields.SESSION_ID, String::class.java) - .addIndex(SharedSessionEntityFields.SESSION_ID) - .addField(SharedSessionEntityFields.USER_ID, String::class.java) - .addIndex(SharedSessionEntityFields.USER_ID) - .addField(SharedSessionEntityFields.DEVICE_ID, String::class.java) - .addIndex(SharedSessionEntityFields.DEVICE_ID) - .addField(SharedSessionEntityFields.CHAIN_INDEX, Long::class.java) - .setNullable(SharedSessionEntityFields.CHAIN_INDEX, true) - } - - // Version 11L added deviceKeysSentToServer boolean to CryptoMetadataEntity - private fun migrateTo11(realm: DynamicRealm) { - Timber.d("Step 10 -> 11") - realm.schema.get("CryptoMetadataEntity") - ?.addField(CryptoMetadataEntityFields.DEVICE_KEYS_SENT_TO_SERVER, Boolean::class.java) - } - - // Version 12L added outbound group session persistence - private fun migrateTo12(realm: DynamicRealm) { - Timber.d("Step 11 -> 12") - val outboundEntitySchema = realm.schema.create("OutboundGroupSessionInfoEntity") - .addField(OutboundGroupSessionInfoEntityFields.SERIALIZED_OUTBOUND_SESSION_DATA, String::class.java) - .addField(OutboundGroupSessionInfoEntityFields.CREATION_TIME, Long::class.java) - .setNullable(OutboundGroupSessionInfoEntityFields.CREATION_TIME, true) - - realm.schema.get("CryptoRoomEntity") - ?.addRealmObjectField(CryptoRoomEntityFields.OUTBOUND_SESSION_INFO.`$`, outboundEntitySchema) - } - - // Version 13L delete unreferenced TrustLevelEntity - private fun migrateTo13(realm: DynamicRealm) { - Timber.d("Step 12 -> 13") - - // Use a trick to do that... Ref: https://stackoverflow.com/questions/55221366 - val trustLevelEntitySchema = realm.schema.get("TrustLevelEntity") - - /* - Creating a new temp field called isLinked which is set to true for those which are - references by other objects. Rest of them are set to false. Then removing all - those which are false and hence duplicate and unnecessary. Then removing the temp field - isLinked - */ - var mainCounter = 0 - var deviceInfoCounter = 0 - var keyInfoCounter = 0 - val deleteCounter: Int - - trustLevelEntitySchema - ?.addField("isLinked", Boolean::class.java) - ?.transform { obj -> - // Setting to false for all by default - obj.set("isLinked", false) - mainCounter++ - } - - realm.schema.get("DeviceInfoEntity")?.transform { obj -> - // Setting to true for those which are referenced in DeviceInfoEntity - deviceInfoCounter++ - obj.getObject("trustLevelEntity")?.set("isLinked", true) - } - - realm.schema.get("KeyInfoEntity")?.transform { obj -> - // Setting to true for those which are referenced in KeyInfoEntity - keyInfoCounter++ - obj.getObject("trustLevelEntity")?.set("isLinked", true) - } - - // Removing all those which are set as false - realm.where("TrustLevelEntity") - .equalTo("isLinked", false) - .findAll() - .also { deleteCounter = it.size } - .deleteAllFromRealm() - - trustLevelEntitySchema?.removeField("isLinked") - - Timber.w("TrustLevelEntity cleanup: $mainCounter entities") - Timber.w("TrustLevelEntity cleanup: $deviceInfoCounter entities referenced in DeviceInfoEntities") - Timber.w("TrustLevelEntity cleanup: $keyInfoCounter entities referenced in KeyInfoEntity") - Timber.w("TrustLevelEntity cleanup: $deleteCounter entities deleted!") - if (mainCounter != deviceInfoCounter + keyInfoCounter + deleteCounter) { - 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)) - } + if (oldVersion < 1) MigrateCryptoTo001Legacy(realm).perform() + if (oldVersion < 2) MigrateCryptoTo002Legacy(realm).perform() + if (oldVersion < 3) MigrateCryptoTo003RiotX(realm).perform() + if (oldVersion < 4) MigrateCryptoTo004(realm).perform() + if (oldVersion < 5) MigrateCryptoTo005(realm).perform() + if (oldVersion < 6) MigrateCryptoTo006(realm).perform() + if (oldVersion < 7) MigrateCryptoTo007(realm).perform() + if (oldVersion < 8) MigrateCryptoTo008(realm).perform() + if (oldVersion < 9) MigrateCryptoTo009(realm).perform() + if (oldVersion < 10) MigrateCryptoTo010(realm).perform() + if (oldVersion < 11) MigrateCryptoTo011(realm).perform() + if (oldVersion < 12) MigrateCryptoTo012(realm).perform() + if (oldVersion < 13) MigrateCryptoTo013(realm).perform() + if (oldVersion < 14) MigrateCryptoTo014(realm).perform() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo001Legacy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo001Legacy.kt new file mode 100644 index 0000000000..0e44689428 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo001Legacy.kt @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import timber.log.Timber + +class MigrateCryptoTo001Legacy(realm: DynamicRealm) : RealmMigrator(realm, 1) { + + override fun doMigrate(realm: DynamicRealm) { + Timber.d("Add field lastReceivedMessageTs (Long) and set the value to 0") + + realm.schema.get("OlmSessionEntity") + ?.addField(OlmSessionEntityFields.LAST_RECEIVED_MESSAGE_TS, Long::class.java) + ?.transform { + it.setLong(OlmSessionEntityFields.LAST_RECEIVED_MESSAGE_TS, 0) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo002Legacy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo002Legacy.kt new file mode 100644 index 0000000000..84e627a688 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo002Legacy.kt @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm +import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import timber.log.Timber + +class MigrateCryptoTo002Legacy(realm: DynamicRealm) : RealmMigrator(realm, 2) { + + override fun doMigrate(realm: DynamicRealm) { + Timber.d("Update IncomingRoomKeyRequestEntity format: requestBodyString field is exploded into several fields") + realm.schema.get("IncomingRoomKeyRequestEntity") + ?.addFieldIfNotExists("requestBodyAlgorithm", String::class.java) + ?.addFieldIfNotExists("requestBodyRoomId", String::class.java) + ?.addFieldIfNotExists("requestBodySenderKey", String::class.java) + ?.addFieldIfNotExists("requestBodySessionId", String::class.java) + ?.transform { dynamicObject -> + try { + val requestBodyString = dynamicObject.getString("requestBodyString") + // It was a map before + val map: Map? = deserializeFromRealm(requestBodyString) + + map?.let { + dynamicObject.setString("requestBodyAlgorithm", it["algorithm"]) + dynamicObject.setString("requestBodyRoomId", it["room_id"]) + dynamicObject.setString("requestBodySenderKey", it["sender_key"]) + dynamicObject.setString("requestBodySessionId", it["session_id"]) + } + } catch (e: Exception) { + Timber.e(e, "Error") + } + } + ?.removeFieldIfExists("requestBodyString") + + Timber.d("Update IncomingRoomKeyRequestEntity format: requestBodyString field is exploded into several fields") + realm.schema.get("OutgoingRoomKeyRequestEntity") + ?.addFieldIfNotExists("requestBodyAlgorithm", String::class.java) + ?.addFieldIfNotExists("requestBodyRoomId", String::class.java) + ?.addFieldIfNotExists("requestBodySenderKey", String::class.java) + ?.addFieldIfNotExists("requestBodySessionId", String::class.java) + ?.transform { dynamicObject -> + try { + val requestBodyString = dynamicObject.getString("requestBodyString") + // It was a map before + val map: Map? = deserializeFromRealm(requestBodyString) + + map?.let { + dynamicObject.setString("requestBodyAlgorithm", it["algorithm"]) + dynamicObject.setString("requestBodyRoomId", it["room_id"]) + dynamicObject.setString("requestBodySenderKey", it["sender_key"]) + dynamicObject.setString("requestBodySessionId", it["session_id"]) + } + } catch (e: Exception) { + Timber.e(e, "Error") + } + } + ?.removeFieldIfExists("requestBodyString") + + Timber.d("Create KeysBackupDataEntity") + if (!realm.schema.contains("KeysBackupDataEntity")) { + realm.schema.create("KeysBackupDataEntity") + .addField(KeysBackupDataEntityFields.PRIMARY_KEY, Integer::class.java) + .addPrimaryKey(KeysBackupDataEntityFields.PRIMARY_KEY) + .setRequired(KeysBackupDataEntityFields.PRIMARY_KEY, true) + .addField(KeysBackupDataEntityFields.BACKUP_LAST_SERVER_HASH, String::class.java) + .addField(KeysBackupDataEntityFields.BACKUP_LAST_SERVER_NUMBER_OF_KEYS, Integer::class.java) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo003RiotX.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo003RiotX.kt new file mode 100644 index 0000000000..b468a56af6 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo003RiotX.kt @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper +import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm +import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import org.matrix.androidsdk.crypto.data.MXDeviceInfo +import org.matrix.androidsdk.crypto.data.MXOlmInboundGroupSession2 +import timber.log.Timber + +class MigrateCryptoTo003RiotX(realm: DynamicRealm) : RealmMigrator(realm, 3) { + + override fun doMigrate(realm: DynamicRealm) { + Timber.d("Migrate to RiotX model") + realm.schema.get("CryptoRoomEntity") + ?.addFieldIfNotExists(CryptoRoomEntityFields.SHOULD_ENCRYPT_FOR_INVITED_MEMBERS, Boolean::class.java) + ?.setRequiredIfNotAlready(CryptoRoomEntityFields.SHOULD_ENCRYPT_FOR_INVITED_MEMBERS, false) + + // Convert format of MXDeviceInfo, package has to be the same. + realm.schema.get("DeviceInfoEntity") + ?.transform { obj -> + try { + val oldSerializedData = obj.getString("deviceInfoData") + deserializeFromRealm(oldSerializedData)?.let { legacyMxDeviceInfo -> + val newMxDeviceInfo = org.matrix.android.sdk.internal.crypto.model.MXDeviceInfo( + deviceId = legacyMxDeviceInfo.deviceId, + userId = legacyMxDeviceInfo.userId, + algorithms = legacyMxDeviceInfo.algorithms, + keys = legacyMxDeviceInfo.keys, + signatures = legacyMxDeviceInfo.signatures, + unsigned = legacyMxDeviceInfo.unsigned, + verified = legacyMxDeviceInfo.mVerified + ) + + obj.setString("deviceInfoData", serializeForRealm(newMxDeviceInfo)) + } + } catch (e: Exception) { + Timber.e(e, "Error") + } + } + + // Convert MXOlmInboundGroupSession2 to OlmInboundGroupSessionWrapper + realm.schema.get("OlmInboundGroupSessionEntity") + ?.transform { obj -> + try { + val oldSerializedData = obj.getString("olmInboundGroupSessionData") + deserializeFromRealm(oldSerializedData)?.let { mxOlmInboundGroupSession2 -> + val sessionKey = mxOlmInboundGroupSession2.mSession.sessionIdentifier() + val newOlmInboundGroupSessionWrapper = OlmInboundGroupSessionWrapper(sessionKey, false) + .apply { + olmInboundGroupSession = mxOlmInboundGroupSession2.mSession + roomId = mxOlmInboundGroupSession2.mRoomId + senderKey = mxOlmInboundGroupSession2.mSenderKey + keysClaimed = mxOlmInboundGroupSession2.mKeysClaimed + forwardingCurve25519KeyChain = mxOlmInboundGroupSession2.mForwardingCurve25519KeyChain + } + + obj.setString("olmInboundGroupSessionData", serializeForRealm(newOlmInboundGroupSessionWrapper)) + } + } catch (e: Exception) { + Timber.e(e, "Error") + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo004.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo004.kt new file mode 100644 index 0000000000..20a4814b8d --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo004.kt @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types +import io.realm.DynamicRealm +import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.internal.crypto.model.MXDeviceInfo +import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm +import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.KeyInfoEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.TrustLevelEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields +import org.matrix.android.sdk.internal.di.SerializeNulls +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import timber.log.Timber + +// Version 4L added Cross Signing info persistence +class MigrateCryptoTo004(realm: DynamicRealm) : RealmMigrator(realm, 4) { + + override fun doMigrate(realm: DynamicRealm) { + if (realm.schema.contains("TrustLevelEntity")) { + Timber.d("Skipping Step 3 -> 4 because entities already exist") + return + } + + Timber.d("Create KeyInfoEntity") + val trustLevelEntityEntitySchema = realm.schema.create("TrustLevelEntity") + .addField(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, Boolean::class.java) + .setNullable(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, true) + .addField(TrustLevelEntityFields.LOCALLY_VERIFIED, Boolean::class.java) + .setNullable(TrustLevelEntityFields.LOCALLY_VERIFIED, true) + + val keyInfoEntitySchema = realm.schema.create("KeyInfoEntity") + .addField(KeyInfoEntityFields.PUBLIC_KEY_BASE64, String::class.java) + .addField(KeyInfoEntityFields.SIGNATURES, String::class.java) + .addRealmListField(KeyInfoEntityFields.USAGES.`$`, String::class.java) + .addRealmObjectField(KeyInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevelEntityEntitySchema) + + Timber.d("Create CrossSigningInfoEntity") + + val crossSigningInfoSchema = realm.schema.create("CrossSigningInfoEntity") + .addField(CrossSigningInfoEntityFields.USER_ID, String::class.java) + .addPrimaryKey(CrossSigningInfoEntityFields.USER_ID) + .addRealmListField(CrossSigningInfoEntityFields.CROSS_SIGNING_KEYS.`$`, keyInfoEntitySchema) + + Timber.d("Updating UserEntity table") + realm.schema.get("UserEntity") + ?.addRealmObjectField(UserEntityFields.CROSS_SIGNING_INFO_ENTITY.`$`, crossSigningInfoSchema) + + Timber.d("Updating CryptoMetadataEntity table") + realm.schema.get("CryptoMetadataEntity") + ?.addField(CryptoMetadataEntityFields.X_SIGN_MASTER_PRIVATE_KEY, String::class.java) + ?.addField(CryptoMetadataEntityFields.X_SIGN_USER_PRIVATE_KEY, String::class.java) + ?.addField(CryptoMetadataEntityFields.X_SIGN_SELF_SIGNED_PRIVATE_KEY, String::class.java) + + val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build() + val listMigrationAdapter = moshi.adapter>(Types.newParameterizedType( + List::class.java, + String::class.java, + Any::class.java + )) + val mapMigrationAdapter = moshi.adapter(Types.newParameterizedType( + Map::class.java, + String::class.java, + Any::class.java + )) + + realm.schema.get("DeviceInfoEntity") + ?.addField(DeviceInfoEntityFields.USER_ID, String::class.java) + ?.addField(DeviceInfoEntityFields.ALGORITHM_LIST_JSON, String::class.java) + ?.addField(DeviceInfoEntityFields.KEYS_MAP_JSON, String::class.java) + ?.addField(DeviceInfoEntityFields.SIGNATURE_MAP_JSON, String::class.java) + ?.addField(DeviceInfoEntityFields.UNSIGNED_MAP_JSON, String::class.java) + ?.addField(DeviceInfoEntityFields.IS_BLOCKED, Boolean::class.java) + ?.setNullable(DeviceInfoEntityFields.IS_BLOCKED, true) + ?.addRealmObjectField(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevelEntityEntitySchema) + ?.transform { obj -> + + try { + val oldSerializedData = obj.getString("deviceInfoData") + deserializeFromRealm(oldSerializedData)?.let { oldDevice -> + + val trustLevel = realm.createObject("TrustLevelEntity") + when (oldDevice.verified) { + MXDeviceInfo.DEVICE_VERIFICATION_UNKNOWN -> { + obj.setNull(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`) + } + MXDeviceInfo.DEVICE_VERIFICATION_BLOCKED -> { + trustLevel.setNull(TrustLevelEntityFields.LOCALLY_VERIFIED) + trustLevel.setNull(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED) + obj.setBoolean(DeviceInfoEntityFields.IS_BLOCKED, oldDevice.isBlocked) + obj.setObject(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevel) + } + MXDeviceInfo.DEVICE_VERIFICATION_UNVERIFIED -> { + trustLevel.setBoolean(TrustLevelEntityFields.LOCALLY_VERIFIED, false) + trustLevel.setBoolean(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, false) + obj.setObject(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevel) + } + MXDeviceInfo.DEVICE_VERIFICATION_VERIFIED -> { + trustLevel.setBoolean(TrustLevelEntityFields.LOCALLY_VERIFIED, true) + trustLevel.setBoolean(TrustLevelEntityFields.CROSS_SIGNED_VERIFIED, false) + obj.setObject(DeviceInfoEntityFields.TRUST_LEVEL_ENTITY.`$`, trustLevel) + } + } + + obj.setString(DeviceInfoEntityFields.USER_ID, oldDevice.userId) + obj.setString(DeviceInfoEntityFields.IDENTITY_KEY, oldDevice.identityKey()) + obj.setString(DeviceInfoEntityFields.ALGORITHM_LIST_JSON, listMigrationAdapter.toJson(oldDevice.algorithms)) + obj.setString(DeviceInfoEntityFields.KEYS_MAP_JSON, mapMigrationAdapter.toJson(oldDevice.keys)) + obj.setString(DeviceInfoEntityFields.SIGNATURE_MAP_JSON, mapMigrationAdapter.toJson(oldDevice.signatures)) + obj.setString(DeviceInfoEntityFields.UNSIGNED_MAP_JSON, mapMigrationAdapter.toJson(oldDevice.unsigned)) + } + } catch (failure: Throwable) { + Timber.w(failure, "Crypto Data base migration error") + // an unfortunate refactor did modify that class, making deserialization failing + // so we just skip and ignore.. + } + } + ?.removeField("deviceInfoData") + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo005.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo005.kt new file mode 100644 index 0000000000..8365d34464 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo005.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.crypto.store.db.model.GossipingEventEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.IncomingGossipingRequestEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingGossipingRequestEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateCryptoTo005(realm: DynamicRealm) : RealmMigrator(realm, 5) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.remove("OutgoingRoomKeyRequestEntity") + realm.schema.remove("IncomingRoomKeyRequestEntity") + + // Not need to migrate existing request, just start fresh? + + realm.schema.create("GossipingEventEntity") + .addField(GossipingEventEntityFields.TYPE, String::class.java) + .addIndex(GossipingEventEntityFields.TYPE) + .addField(GossipingEventEntityFields.CONTENT, String::class.java) + .addField(GossipingEventEntityFields.SENDER, String::class.java) + .addIndex(GossipingEventEntityFields.SENDER) + .addField(GossipingEventEntityFields.DECRYPTION_RESULT_JSON, String::class.java) + .addField(GossipingEventEntityFields.DECRYPTION_ERROR_CODE, String::class.java) + .addField(GossipingEventEntityFields.AGE_LOCAL_TS, Long::class.java) + .setNullable(GossipingEventEntityFields.AGE_LOCAL_TS, true) + .addField(GossipingEventEntityFields.SEND_STATE_STR, String::class.java) + + realm.schema.create("IncomingGossipingRequestEntity") + .addField(IncomingGossipingRequestEntityFields.REQUEST_ID, String::class.java) + .addIndex(IncomingGossipingRequestEntityFields.REQUEST_ID) + .addField(IncomingGossipingRequestEntityFields.TYPE_STR, String::class.java) + .addIndex(IncomingGossipingRequestEntityFields.TYPE_STR) + .addField(IncomingGossipingRequestEntityFields.OTHER_USER_ID, String::class.java) + .addField(IncomingGossipingRequestEntityFields.REQUESTED_INFO_STR, String::class.java) + .addField(IncomingGossipingRequestEntityFields.OTHER_DEVICE_ID, String::class.java) + .addField(IncomingGossipingRequestEntityFields.REQUEST_STATE_STR, String::class.java) + .addField(IncomingGossipingRequestEntityFields.LOCAL_CREATION_TIMESTAMP, Long::class.java) + .setNullable(IncomingGossipingRequestEntityFields.LOCAL_CREATION_TIMESTAMP, true) + + realm.schema.create("OutgoingGossipingRequestEntity") + .addField(OutgoingGossipingRequestEntityFields.REQUEST_ID, String::class.java) + .addIndex(OutgoingGossipingRequestEntityFields.REQUEST_ID) + .addField(OutgoingGossipingRequestEntityFields.RECIPIENTS_DATA, String::class.java) + .addField(OutgoingGossipingRequestEntityFields.REQUESTED_INFO_STR, String::class.java) + .addField(OutgoingGossipingRequestEntityFields.TYPE_STR, String::class.java) + .addIndex(OutgoingGossipingRequestEntityFields.TYPE_STR) + .addField(OutgoingGossipingRequestEntityFields.REQUEST_STATE_STR, String::class.java) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo006.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo006.kt new file mode 100644 index 0000000000..a29a791826 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo006.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import timber.log.Timber + +class MigrateCryptoTo006(realm: DynamicRealm) : RealmMigrator(realm, 6) { + + override fun doMigrate(realm: DynamicRealm) { + Timber.d("Updating CryptoMetadataEntity table") + realm.schema.get("CryptoMetadataEntity") + ?.addField(CryptoMetadataEntityFields.KEY_BACKUP_RECOVERY_KEY, String::class.java) + ?.addField(CryptoMetadataEntityFields.KEY_BACKUP_RECOVERY_KEY_VERSION, String::class.java) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo007.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo007.kt new file mode 100644 index 0000000000..7ae58e7fc0 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo007.kt @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper +import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper2 +import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm +import org.matrix.android.sdk.internal.crypto.store.db.mapper.CrossSigningKeysMapper +import org.matrix.android.sdk.internal.crypto.store.db.model.KeyInfoEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm +import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import timber.log.Timber + +class MigrateCryptoTo007(realm: DynamicRealm) : RealmMigrator(realm, 7) { + + override fun doMigrate(realm: DynamicRealm) { + Timber.d("Updating KeyInfoEntity table") + val crossSigningKeysMapper = CrossSigningKeysMapper(MoshiProvider.providesMoshi()) + + val keyInfoEntities = realm.where("KeyInfoEntity").findAll() + try { + keyInfoEntities.forEach { + val stringSignatures = it.getString(KeyInfoEntityFields.SIGNATURES) + val objectSignatures: Map>? = deserializeFromRealm(stringSignatures) + val jsonSignatures = crossSigningKeysMapper.serializeSignatures(objectSignatures) + it.setString(KeyInfoEntityFields.SIGNATURES, jsonSignatures) + } + } catch (failure: Throwable) { + } + + // Migrate frozen classes + val inboundGroupSessions = realm.where("OlmInboundGroupSessionEntity").findAll() + inboundGroupSessions.forEach { dynamicObject -> + dynamicObject.getString(OlmInboundGroupSessionEntityFields.OLM_INBOUND_GROUP_SESSION_DATA)?.let { serializedObject -> + try { + deserializeFromRealm(serializedObject)?.let { oldFormat -> + val newFormat = oldFormat.exportKeys()?.let { + OlmInboundGroupSessionWrapper2(it) + } + dynamicObject.setString(OlmInboundGroupSessionEntityFields.OLM_INBOUND_GROUP_SESSION_DATA, serializeForRealm(newFormat)) + } + } catch (failure: Throwable) { + Timber.e(failure, "## OlmInboundGroupSessionEntity migration failed") + } + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo008.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo008.kt new file mode 100644 index 0000000000..e3bd3f035a --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo008.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateCryptoTo008(realm: DynamicRealm) : RealmMigrator(realm, 8) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.create("MyDeviceLastSeenInfoEntity") + .addField(MyDeviceLastSeenInfoEntityFields.DEVICE_ID, String::class.java) + .addPrimaryKey(MyDeviceLastSeenInfoEntityFields.DEVICE_ID) + .addField(MyDeviceLastSeenInfoEntityFields.DISPLAY_NAME, String::class.java) + .addField(MyDeviceLastSeenInfoEntityFields.LAST_SEEN_IP, String::class.java) + .addField(MyDeviceLastSeenInfoEntityFields.LAST_SEEN_TS, Long::class.java) + .setNullable(MyDeviceLastSeenInfoEntityFields.LAST_SEEN_TS, true) + + val now = System.currentTimeMillis() + realm.schema.get("DeviceInfoEntity") + ?.addField(DeviceInfoEntityFields.FIRST_TIME_SEEN_LOCAL_TS, Long::class.java) + ?.setNullable(DeviceInfoEntityFields.FIRST_TIME_SEEN_LOCAL_TS, true) + ?.transform { deviceInfoEntity -> + tryOrNull { + deviceInfoEntity.setLong(DeviceInfoEntityFields.FIRST_TIME_SEEN_LOCAL_TS, now) + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo009.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo009.kt new file mode 100644 index 0000000000..ed705318f9 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo009.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import timber.log.Timber + +// Fixes duplicate devices in UserEntity#devices +class MigrateCryptoTo009(realm: DynamicRealm) : RealmMigrator(realm, 9) { + + override fun doMigrate(realm: DynamicRealm) { + val userEntities = realm.where("UserEntity").findAll() + userEntities.forEach { + try { + val deviceList = it.getList(UserEntityFields.DEVICES.`$`) + ?: return@forEach + val distinct = deviceList.distinctBy { it.getString(DeviceInfoEntityFields.DEVICE_ID) } + if (distinct.size != deviceList.size) { + deviceList.clear() + deviceList.addAll(distinct) + } + } catch (failure: Throwable) { + Timber.w(failure, "Crypto Data base migration error for migrateTo9") + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo010.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo010.kt new file mode 100644 index 0000000000..8d69ee5558 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo010.kt @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +// Version 10L added WithHeld Keys Info (MSC2399) +class MigrateCryptoTo010(realm: DynamicRealm) : RealmMigrator(realm, 10) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.create("WithHeldSessionEntity") + .addField(WithHeldSessionEntityFields.ROOM_ID, String::class.java) + .addField(WithHeldSessionEntityFields.ALGORITHM, String::class.java) + .addField(WithHeldSessionEntityFields.SESSION_ID, String::class.java) + .addIndex(WithHeldSessionEntityFields.SESSION_ID) + .addField(WithHeldSessionEntityFields.SENDER_KEY, String::class.java) + .addIndex(WithHeldSessionEntityFields.SENDER_KEY) + .addField(WithHeldSessionEntityFields.CODE_STRING, String::class.java) + .addField(WithHeldSessionEntityFields.REASON, String::class.java) + + realm.schema.create("SharedSessionEntity") + .addField(SharedSessionEntityFields.ROOM_ID, String::class.java) + .addField(SharedSessionEntityFields.ALGORITHM, String::class.java) + .addField(SharedSessionEntityFields.SESSION_ID, String::class.java) + .addIndex(SharedSessionEntityFields.SESSION_ID) + .addField(SharedSessionEntityFields.USER_ID, String::class.java) + .addIndex(SharedSessionEntityFields.USER_ID) + .addField(SharedSessionEntityFields.DEVICE_ID, String::class.java) + .addIndex(SharedSessionEntityFields.DEVICE_ID) + .addField(SharedSessionEntityFields.CHAIN_INDEX, Long::class.java) + .setNullable(SharedSessionEntityFields.CHAIN_INDEX, true) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo011.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo011.kt new file mode 100644 index 0000000000..c9825a7f3d --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo011.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +// Version 11L added deviceKeysSentToServer boolean to CryptoMetadataEntity +class MigrateCryptoTo011(realm: DynamicRealm) : RealmMigrator(realm, 11) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("CryptoMetadataEntity") + ?.addField(CryptoMetadataEntityFields.DEVICE_KEYS_SENT_TO_SERVER, Boolean::class.java) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo012.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo012.kt new file mode 100644 index 0000000000..6b1460d9d6 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo012.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.OutboundGroupSessionInfoEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +// Version 12L added outbound group session persistence +class MigrateCryptoTo012(realm: DynamicRealm) : RealmMigrator(realm, 12) { + + override fun doMigrate(realm: DynamicRealm) { + val outboundEntitySchema = realm.schema.create("OutboundGroupSessionInfoEntity") + .addField(OutboundGroupSessionInfoEntityFields.SERIALIZED_OUTBOUND_SESSION_DATA, String::class.java) + .addField(OutboundGroupSessionInfoEntityFields.CREATION_TIME, Long::class.java) + .setNullable(OutboundGroupSessionInfoEntityFields.CREATION_TIME, true) + + realm.schema.get("CryptoRoomEntity") + ?.addRealmObjectField(CryptoRoomEntityFields.OUTBOUND_SESSION_INFO.`$`, outboundEntitySchema) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo013.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo013.kt new file mode 100644 index 0000000000..dc22c5f133 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo013.kt @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import timber.log.Timber + +// Version 13L delete unreferenced TrustLevelEntity +class MigrateCryptoTo013(realm: DynamicRealm) : RealmMigrator(realm, 13) { + + override fun doMigrate(realm: DynamicRealm) { + // Use a trick to do that... Ref: https://stackoverflow.com/questions/55221366 + val trustLevelEntitySchema = realm.schema.get("TrustLevelEntity") + + /* + Creating a new temp field called isLinked which is set to true for those which are + references by other objects. Rest of them are set to false. Then removing all + those which are false and hence duplicate and unnecessary. Then removing the temp field + isLinked + */ + var mainCounter = 0 + var deviceInfoCounter = 0 + var keyInfoCounter = 0 + val deleteCounter: Int + + trustLevelEntitySchema + ?.addField("isLinked", Boolean::class.java) + ?.transform { obj -> + // Setting to false for all by default + obj.set("isLinked", false) + mainCounter++ + } + + realm.schema.get("DeviceInfoEntity")?.transform { obj -> + // Setting to true for those which are referenced in DeviceInfoEntity + deviceInfoCounter++ + obj.getObject("trustLevelEntity")?.set("isLinked", true) + } + + realm.schema.get("KeyInfoEntity")?.transform { obj -> + // Setting to true for those which are referenced in KeyInfoEntity + keyInfoCounter++ + obj.getObject("trustLevelEntity")?.set("isLinked", true) + } + + // Removing all those which are set as false + realm.where("TrustLevelEntity") + .equalTo("isLinked", false) + .findAll() + .also { deleteCounter = it.size } + .deleteAllFromRealm() + + trustLevelEntitySchema?.removeField("isLinked") + + Timber.w("TrustLevelEntity cleanup: $mainCounter entities") + Timber.w("TrustLevelEntity cleanup: $deviceInfoCounter entities referenced in DeviceInfoEntities") + Timber.w("TrustLevelEntity cleanup: $keyInfoCounter entities referenced in KeyInfoEntity") + Timber.w("TrustLevelEntity cleanup: $deleteCounter entities deleted!") + if (mainCounter != deviceInfoCounter + keyInfoCounter + deleteCounter) { + Timber.e("TrustLevelEntity cleanup: Something is not correct...") + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo014.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo014.kt new file mode 100644 index 0000000000..f0089e3427 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo014.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFields +import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +// Version 14L Update the way we remember key sharing +class MigrateCryptoTo014(realm: DynamicRealm) : RealmMigrator(realm, 14) { + + override fun doMigrate(realm: DynamicRealm) { + 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/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt index dfb0915566..f6f93d3c41 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt @@ -17,37 +17,31 @@ package org.matrix.android.sdk.internal.database import io.realm.DynamicRealm -import io.realm.FieldAttribute import io.realm.RealmMigration -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent -import org.matrix.android.sdk.api.session.room.model.VersioningState -import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent -import org.matrix.android.sdk.api.session.room.model.tag.RoomTag -import org.matrix.android.sdk.api.session.threads.ThreadNotificationState -import org.matrix.android.sdk.internal.crypto.model.event.EncryptionEventContent -import org.matrix.android.sdk.internal.database.model.ChunkEntityFields -import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields -import org.matrix.android.sdk.internal.database.model.EditAggregatedSummaryEntityFields -import org.matrix.android.sdk.internal.database.model.EditionOfEventFields -import org.matrix.android.sdk.internal.database.model.EventEntityFields -import org.matrix.android.sdk.internal.database.model.EventInsertEntityFields -import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields -import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields -import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields -import org.matrix.android.sdk.internal.database.model.RoomAccountDataEntityFields -import org.matrix.android.sdk.internal.database.model.RoomEntityFields -import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields -import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType -import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields -import org.matrix.android.sdk.internal.database.model.RoomTagEntityFields -import org.matrix.android.sdk.internal.database.model.SpaceChildSummaryEntityFields -import org.matrix.android.sdk.internal.database.model.SpaceParentSummaryEntityFields -import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields -import org.matrix.android.sdk.internal.database.model.presence.UserPresenceEntityFields -import org.matrix.android.sdk.internal.di.MoshiProvider -import org.matrix.android.sdk.internal.query.process +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo001 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo002 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo003 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo004 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo005 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo006 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo007 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo008 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo009 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo010 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo011 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo012 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo013 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo014 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo015 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo016 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo017 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo018 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo019 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo020 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo021 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo022 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo023 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo024 import org.matrix.android.sdk.internal.util.Normalizer import timber.log.Timber import javax.inject.Inject @@ -70,423 +64,29 @@ internal class RealmSessionStoreMigration @Inject constructor( override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { Timber.v("Migrating Realm Session from $oldVersion to $newVersion") - if (oldVersion <= 0) migrateTo1(realm) - if (oldVersion <= 1) migrateTo2(realm) - if (oldVersion <= 2) migrateTo3(realm) - if (oldVersion <= 3) migrateTo4(realm) - if (oldVersion <= 4) migrateTo5(realm) - if (oldVersion <= 5) migrateTo6(realm) - if (oldVersion <= 6) migrateTo7(realm) - if (oldVersion <= 7) migrateTo8(realm) - if (oldVersion <= 8) migrateTo9(realm) - if (oldVersion <= 9) migrateTo10(realm) - if (oldVersion <= 10) migrateTo11(realm) - if (oldVersion <= 11) migrateTo12(realm) - if (oldVersion <= 12) migrateTo13(realm) - if (oldVersion <= 13) migrateTo14(realm) - if (oldVersion <= 14) migrateTo15(realm) - if (oldVersion <= 15) migrateTo16(realm) - if (oldVersion <= 16) migrateTo17(realm) - if (oldVersion <= 17) migrateTo18(realm) - if (oldVersion <= 18) migrateTo19(realm) - if (oldVersion <= 19) migrateTo20(realm) - if (oldVersion <= 20) migrateTo21(realm) - if (oldVersion <= 21) migrateTo22(realm) - if (oldVersion <= 22) migrateTo23(realm) - if (oldVersion <= 23) migrateTo24(realm) - } - - private fun migrateTo1(realm: DynamicRealm) { - Timber.d("Step 0 -> 1") - // Add hasFailedSending in RoomSummary and a small warning icon on room list - - realm.schema.get("RoomSummaryEntity") - ?.addField(RoomSummaryEntityFields.HAS_FAILED_SENDING, Boolean::class.java) - ?.transform { obj -> - obj.setBoolean(RoomSummaryEntityFields.HAS_FAILED_SENDING, false) - } - } - - private fun migrateTo2(realm: DynamicRealm) { - Timber.d("Step 1 -> 2") - realm.schema.get("HomeServerCapabilitiesEntity") - ?.addField("adminE2EByDefault", Boolean::class.java) - ?.transform { obj -> - obj.setBoolean("adminE2EByDefault", true) - } - } - - private fun migrateTo3(realm: DynamicRealm) { - Timber.d("Step 2 -> 3") - realm.schema.get("HomeServerCapabilitiesEntity") - ?.addField("preferredJitsiDomain", String::class.java) - ?.transform { obj -> - // Schedule a refresh of the capabilities - obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0) - } - } - - private fun migrateTo4(realm: DynamicRealm) { - Timber.d("Step 3 -> 4") - realm.schema.create("PendingThreePidEntity") - .addField(PendingThreePidEntityFields.CLIENT_SECRET, String::class.java) - .setRequired(PendingThreePidEntityFields.CLIENT_SECRET, true) - .addField(PendingThreePidEntityFields.EMAIL, String::class.java) - .addField(PendingThreePidEntityFields.MSISDN, String::class.java) - .addField(PendingThreePidEntityFields.SEND_ATTEMPT, Int::class.java) - .addField(PendingThreePidEntityFields.SID, String::class.java) - .setRequired(PendingThreePidEntityFields.SID, true) - .addField(PendingThreePidEntityFields.SUBMIT_URL, String::class.java) - } - - private fun migrateTo5(realm: DynamicRealm) { - Timber.d("Step 4 -> 5") - realm.schema.get("HomeServerCapabilitiesEntity") - ?.removeField("adminE2EByDefault") - ?.removeField("preferredJitsiDomain") - } - - private fun migrateTo6(realm: DynamicRealm) { - Timber.d("Step 5 -> 6") - realm.schema.create("PreviewUrlCacheEntity") - .addField(PreviewUrlCacheEntityFields.URL, String::class.java) - .setRequired(PreviewUrlCacheEntityFields.URL, true) - .addPrimaryKey(PreviewUrlCacheEntityFields.URL) - .addField(PreviewUrlCacheEntityFields.URL_FROM_SERVER, String::class.java) - .addField(PreviewUrlCacheEntityFields.SITE_NAME, String::class.java) - .addField(PreviewUrlCacheEntityFields.TITLE, String::class.java) - .addField(PreviewUrlCacheEntityFields.DESCRIPTION, String::class.java) - .addField(PreviewUrlCacheEntityFields.MXC_URL, String::class.java) - .addField(PreviewUrlCacheEntityFields.LAST_UPDATED_TIMESTAMP, Long::class.java) - } - - private fun migrateTo7(realm: DynamicRealm) { - Timber.d("Step 6 -> 7") - realm.schema.get("RoomEntity") - ?.addField(RoomEntityFields.MEMBERS_LOAD_STATUS_STR, String::class.java) - ?.transform { obj -> - if (obj.getBoolean("areAllMembersLoaded")) { - obj.setString("membersLoadStatusStr", RoomMembersLoadStatusType.LOADED.name) - } else { - obj.setString("membersLoadStatusStr", RoomMembersLoadStatusType.NONE.name) - } - } - ?.removeField("areAllMembersLoaded") - } - - private fun migrateTo8(realm: DynamicRealm) { - Timber.d("Step 7 -> 8") - - val editionOfEventSchema = realm.schema.create("EditionOfEvent") - .addField(EditionOfEventFields.CONTENT, String::class.java) - .addField(EditionOfEventFields.EVENT_ID, String::class.java) - .setRequired(EditionOfEventFields.EVENT_ID, true) - .addField(EditionOfEventFields.SENDER_ID, String::class.java) - .setRequired(EditionOfEventFields.SENDER_ID, true) - .addField(EditionOfEventFields.TIMESTAMP, Long::class.java) - .addField(EditionOfEventFields.IS_LOCAL_ECHO, Boolean::class.java) - - realm.schema.get("EditAggregatedSummaryEntity") - ?.removeField("aggregatedContent") - ?.removeField("sourceEvents") - ?.removeField("lastEditTs") - ?.removeField("sourceLocalEchoEvents") - ?.addRealmListField(EditAggregatedSummaryEntityFields.EDITIONS.`$`, editionOfEventSchema) - - // This has to be done once a parent use the model as a child - // See https://github.com/realm/realm-java/issues/7402 - editionOfEventSchema.isEmbedded = true - } - - private fun migrateTo9(realm: DynamicRealm) { - Timber.d("Step 8 -> 9") - - realm.schema.get("RoomSummaryEntity") - ?.addField(RoomSummaryEntityFields.LAST_ACTIVITY_TIME, Long::class.java, FieldAttribute.INDEXED) - ?.setNullable(RoomSummaryEntityFields.LAST_ACTIVITY_TIME, true) - ?.addIndex(RoomSummaryEntityFields.MEMBERSHIP_STR) - ?.addIndex(RoomSummaryEntityFields.IS_DIRECT) - ?.addIndex(RoomSummaryEntityFields.VERSIONING_STATE_STR) - - ?.addField(RoomSummaryEntityFields.IS_FAVOURITE, Boolean::class.java) - ?.addIndex(RoomSummaryEntityFields.IS_FAVOURITE) - ?.addField(RoomSummaryEntityFields.IS_LOW_PRIORITY, Boolean::class.java) - ?.addIndex(RoomSummaryEntityFields.IS_LOW_PRIORITY) - ?.addField(RoomSummaryEntityFields.IS_SERVER_NOTICE, Boolean::class.java) - ?.addIndex(RoomSummaryEntityFields.IS_SERVER_NOTICE) - - ?.transform { obj -> - val isFavorite = obj.getList(RoomSummaryEntityFields.TAGS.`$`).any { - it.getString(RoomTagEntityFields.TAG_NAME) == RoomTag.ROOM_TAG_FAVOURITE - } - obj.setBoolean(RoomSummaryEntityFields.IS_FAVOURITE, isFavorite) - - val isLowPriority = obj.getList(RoomSummaryEntityFields.TAGS.`$`).any { - it.getString(RoomTagEntityFields.TAG_NAME) == RoomTag.ROOM_TAG_LOW_PRIORITY - } - - obj.setBoolean(RoomSummaryEntityFields.IS_LOW_PRIORITY, isLowPriority) - -// XXX migrate last message origin server ts - obj.getObject(RoomSummaryEntityFields.LATEST_PREVIEWABLE_EVENT.`$`) - ?.getObject(TimelineEventEntityFields.ROOT.`$`) - ?.getLong(EventEntityFields.ORIGIN_SERVER_TS)?.let { - obj.setLong(RoomSummaryEntityFields.LAST_ACTIVITY_TIME, it) - } - } - } - - private fun migrateTo10(realm: DynamicRealm) { - Timber.d("Step 9 -> 10") - realm.schema.create("SpaceChildSummaryEntity") - ?.addField(SpaceChildSummaryEntityFields.ORDER, String::class.java) - ?.addField(SpaceChildSummaryEntityFields.CHILD_ROOM_ID, String::class.java) - ?.addField(SpaceChildSummaryEntityFields.AUTO_JOIN, Boolean::class.java) - ?.setNullable(SpaceChildSummaryEntityFields.AUTO_JOIN, true) - ?.addRealmObjectField(SpaceChildSummaryEntityFields.CHILD_SUMMARY_ENTITY.`$`, realm.schema.get("RoomSummaryEntity")!!) - ?.addRealmListField(SpaceChildSummaryEntityFields.VIA_SERVERS.`$`, String::class.java) - - realm.schema.create("SpaceParentSummaryEntity") - ?.addField(SpaceParentSummaryEntityFields.PARENT_ROOM_ID, String::class.java) - ?.addField(SpaceParentSummaryEntityFields.CANONICAL, Boolean::class.java) - ?.setNullable(SpaceParentSummaryEntityFields.CANONICAL, true) - ?.addRealmObjectField(SpaceParentSummaryEntityFields.PARENT_SUMMARY_ENTITY.`$`, realm.schema.get("RoomSummaryEntity")!!) - ?.addRealmListField(SpaceParentSummaryEntityFields.VIA_SERVERS.`$`, String::class.java) - - val creationContentAdapter = MoshiProvider.providesMoshi().adapter(RoomCreateContent::class.java) - realm.schema.get("RoomSummaryEntity") - ?.addField(RoomSummaryEntityFields.ROOM_TYPE, String::class.java) - ?.addField(RoomSummaryEntityFields.FLATTEN_PARENT_IDS, String::class.java) - ?.addField(RoomSummaryEntityFields.GROUP_IDS, String::class.java) - ?.transform { obj -> - - val creationEvent = realm.where("CurrentStateEventEntity") - .equalTo(CurrentStateEventEntityFields.ROOM_ID, obj.getString(RoomSummaryEntityFields.ROOM_ID)) - .equalTo(CurrentStateEventEntityFields.TYPE, EventType.STATE_ROOM_CREATE) - .findFirst() - - val roomType = creationEvent?.getObject(CurrentStateEventEntityFields.ROOT.`$`) - ?.getString(EventEntityFields.CONTENT)?.let { - creationContentAdapter.fromJson(it)?.type - } - - obj.setString(RoomSummaryEntityFields.ROOM_TYPE, roomType) - } - ?.addRealmListField(RoomSummaryEntityFields.PARENTS.`$`, realm.schema.get("SpaceParentSummaryEntity")!!) - ?.addRealmListField(RoomSummaryEntityFields.CHILDREN.`$`, realm.schema.get("SpaceChildSummaryEntity")!!) - } - - private fun migrateTo11(realm: DynamicRealm) { - Timber.d("Step 10 -> 11") - realm.schema.get("EventEntity") - ?.addField(EventEntityFields.SEND_STATE_DETAILS, String::class.java) - } - - private fun migrateTo12(realm: DynamicRealm) { - Timber.d("Step 11 -> 12") - - val joinRulesContentAdapter = MoshiProvider.providesMoshi().adapter(RoomJoinRulesContent::class.java) - realm.schema.get("RoomSummaryEntity") - ?.addField(RoomSummaryEntityFields.JOIN_RULES_STR, String::class.java) - ?.transform { obj -> - val joinRulesEvent = realm.where("CurrentStateEventEntity") - .equalTo(CurrentStateEventEntityFields.ROOM_ID, obj.getString(RoomSummaryEntityFields.ROOM_ID)) - .equalTo(CurrentStateEventEntityFields.TYPE, EventType.STATE_ROOM_JOIN_RULES) - .findFirst() - - val roomJoinRules = joinRulesEvent?.getObject(CurrentStateEventEntityFields.ROOT.`$`) - ?.getString(EventEntityFields.CONTENT)?.let { - joinRulesContentAdapter.fromJson(it)?.joinRules - } - - obj.setString(RoomSummaryEntityFields.JOIN_RULES_STR, roomJoinRules?.name) - } - - realm.schema.get("SpaceChildSummaryEntity") - ?.addField(SpaceChildSummaryEntityFields.SUGGESTED, Boolean::class.java) - ?.setNullable(SpaceChildSummaryEntityFields.SUGGESTED, true) - } - - private fun migrateTo13(realm: DynamicRealm) { - Timber.d("Step 12 -> 13") - // Fix issue with the nightly build. Eventually play again the migration which has been included in migrateTo12() - realm.schema.get("SpaceChildSummaryEntity") - ?.takeIf { !it.hasField(SpaceChildSummaryEntityFields.SUGGESTED) } - ?.addField(SpaceChildSummaryEntityFields.SUGGESTED, Boolean::class.java) - ?.setNullable(SpaceChildSummaryEntityFields.SUGGESTED, true) - } - - private fun migrateTo14(realm: DynamicRealm) { - Timber.d("Step 13 -> 14") - val roomAccountDataSchema = realm.schema.create("RoomAccountDataEntity") - .addField(RoomAccountDataEntityFields.CONTENT_STR, String::class.java) - .addField(RoomAccountDataEntityFields.TYPE, String::class.java, FieldAttribute.INDEXED) - - realm.schema.get("RoomEntity") - ?.addRealmListField(RoomEntityFields.ACCOUNT_DATA.`$`, roomAccountDataSchema) - - realm.schema.get("RoomSummaryEntity") - ?.addField(RoomSummaryEntityFields.IS_HIDDEN_FROM_USER, Boolean::class.java, FieldAttribute.INDEXED) - ?.transform { - val isHiddenFromUser = it.getString(RoomSummaryEntityFields.VERSIONING_STATE_STR) == VersioningState.UPGRADED_ROOM_JOINED.name - it.setBoolean(RoomSummaryEntityFields.IS_HIDDEN_FROM_USER, isHiddenFromUser) - } - - roomAccountDataSchema.isEmbedded = true - } - - private fun migrateTo15(realm: DynamicRealm) { - Timber.d("Step 14 -> 15") - // fix issue with flattenParentIds on DM that kept growing with duplicate - // so we reset it, will be updated next sync - realm.where("RoomSummaryEntity") - .process(RoomSummaryEntityFields.MEMBERSHIP_STR, Membership.activeMemberships()) - .equalTo(RoomSummaryEntityFields.IS_DIRECT, true) - .findAll() - .onEach { - it.setString(RoomSummaryEntityFields.FLATTEN_PARENT_IDS, null) - } - } - - private fun migrateTo16(realm: DynamicRealm) { - Timber.d("Step 15 -> 16") - realm.schema.get("HomeServerCapabilitiesEntity") - ?.addField(HomeServerCapabilitiesEntityFields.ROOM_VERSIONS_JSON, String::class.java) - ?.transform { obj -> - // Schedule a refresh of the capabilities - obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0) - } - } - - private fun migrateTo17(realm: DynamicRealm) { - Timber.d("Step 16 -> 17") - realm.schema.get("EventInsertEntity") - ?.addField(EventInsertEntityFields.CAN_BE_PROCESSED, Boolean::class.java) - } - - private fun migrateTo18(realm: DynamicRealm) { - Timber.d("Step 17 -> 18") - realm.schema.create("UserPresenceEntity") - ?.addField(UserPresenceEntityFields.USER_ID, String::class.java) - ?.addPrimaryKey(UserPresenceEntityFields.USER_ID) - ?.setRequired(UserPresenceEntityFields.USER_ID, true) - ?.addField(UserPresenceEntityFields.PRESENCE_STR, String::class.java) - ?.addField(UserPresenceEntityFields.LAST_ACTIVE_AGO, Long::class.java) - ?.setNullable(UserPresenceEntityFields.LAST_ACTIVE_AGO, true) - ?.addField(UserPresenceEntityFields.STATUS_MESSAGE, String::class.java) - ?.addField(UserPresenceEntityFields.IS_CURRENTLY_ACTIVE, Boolean::class.java) - ?.setNullable(UserPresenceEntityFields.IS_CURRENTLY_ACTIVE, true) - ?.addField(UserPresenceEntityFields.AVATAR_URL, String::class.java) - ?.addField(UserPresenceEntityFields.DISPLAY_NAME, String::class.java) - - val userPresenceEntity = realm.schema.get("UserPresenceEntity") ?: return - realm.schema.get("RoomSummaryEntity") - ?.addRealmObjectField(RoomSummaryEntityFields.DIRECT_USER_PRESENCE.`$`, userPresenceEntity) - - realm.schema.get("RoomMemberSummaryEntity") - ?.addRealmObjectField(RoomMemberSummaryEntityFields.USER_PRESENCE_ENTITY.`$`, userPresenceEntity) - } - - private fun migrateTo19(realm: DynamicRealm) { - Timber.d("Step 18 -> 19") - realm.schema.get("RoomSummaryEntity") - ?.addField(RoomSummaryEntityFields.NORMALIZED_DISPLAY_NAME, String::class.java) - ?.transform { - it.getString(RoomSummaryEntityFields.DISPLAY_NAME)?.let { displayName -> - val normalised = normalizer.normalize(displayName) - it.set(RoomSummaryEntityFields.NORMALIZED_DISPLAY_NAME, normalised) - } - } - } - - private fun migrateTo20(realm: DynamicRealm) { - Timber.d("Step 19 -> 20") - - realm.schema.get("ChunkEntity")?.apply { - if (hasField("numberOfTimelineEvents")) { - removeField("numberOfTimelineEvents") - } - var cleanOldChunks = false - if (!hasField(ChunkEntityFields.NEXT_CHUNK.`$`)) { - cleanOldChunks = true - addRealmObjectField(ChunkEntityFields.NEXT_CHUNK.`$`, this) - } - if (!hasField(ChunkEntityFields.PREV_CHUNK.`$`)) { - cleanOldChunks = true - addRealmObjectField(ChunkEntityFields.PREV_CHUNK.`$`, this) - } - if (cleanOldChunks) { - val chunkEntities = realm.where("ChunkEntity").equalTo(ChunkEntityFields.IS_LAST_FORWARD, false).findAll() - chunkEntities.deleteAllFromRealm() - } - } - } - - private fun migrateTo21(realm: DynamicRealm) { - Timber.d("Step 20 -> 21") - - realm.schema.get("RoomSummaryEntity") - ?.addField(RoomSummaryEntityFields.E2E_ALGORITHM, String::class.java) - ?.transform { obj -> - - val encryptionContentAdapter = MoshiProvider.providesMoshi().adapter(EncryptionEventContent::class.java) - - val encryptionEvent = realm.where("CurrentStateEventEntity") - .equalTo(CurrentStateEventEntityFields.ROOM_ID, obj.getString(RoomSummaryEntityFields.ROOM_ID)) - .equalTo(CurrentStateEventEntityFields.TYPE, EventType.STATE_ROOM_ENCRYPTION) - .findFirst() - - val encryptionEventRoot = encryptionEvent?.getObject(CurrentStateEventEntityFields.ROOT.`$`) - val algorithm = encryptionEventRoot - ?.getString(EventEntityFields.CONTENT)?.let { - encryptionContentAdapter.fromJson(it)?.algorithm - } - - obj.setString(RoomSummaryEntityFields.E2E_ALGORITHM, algorithm) - obj.setBoolean(RoomSummaryEntityFields.IS_ENCRYPTED, encryptionEvent != null) - encryptionEventRoot?.getLong(EventEntityFields.ORIGIN_SERVER_TS)?.let { - obj.setLong(RoomSummaryEntityFields.ENCRYPTION_EVENT_TS, it) - } - } - } - - private fun migrateTo22(realm: DynamicRealm) { - Timber.d("Step 21 -> 22") - val listJoinedRoomIds = realm.where("RoomEntity") - .equalTo(RoomEntityFields.MEMBERSHIP_STR, Membership.JOIN.name).findAll() - .map { it.getString(RoomEntityFields.ROOM_ID) } - - val hasMissingStateEvent = realm.where("CurrentStateEventEntity") - .`in`(CurrentStateEventEntityFields.ROOM_ID, listJoinedRoomIds.toTypedArray()) - .isNull(CurrentStateEventEntityFields.ROOT.`$`).findFirst() != null - - if (hasMissingStateEvent) { - Timber.v("Has some missing state event, clear session cache") - realm.deleteAll() - } - } - - private fun migrateTo23(realm: DynamicRealm) { - Timber.d("Step 22 -> 23") - val eventEntity = realm.schema.get("TimelineEventEntity") ?: return - - realm.schema.get("EventEntity") - ?.addField(EventEntityFields.IS_ROOT_THREAD, Boolean::class.java, FieldAttribute.INDEXED) - ?.addField(EventEntityFields.ROOT_THREAD_EVENT_ID, String::class.java, FieldAttribute.INDEXED) - ?.addField(EventEntityFields.NUMBER_OF_THREADS, Int::class.java) - ?.addField(EventEntityFields.THREAD_NOTIFICATION_STATE_STR, String::class.java) - ?.transform { - it.setString(EventEntityFields.THREAD_NOTIFICATION_STATE_STR, ThreadNotificationState.NO_NEW_MESSAGE.name) - } - ?.addRealmObjectField(EventEntityFields.THREAD_SUMMARY_LATEST_MESSAGE.`$`, eventEntity) - } - - private fun migrateTo24(realm: DynamicRealm) { - Timber.d("Step 23 -> 24") - realm.schema.get("PreviewUrlCacheEntity") - ?.addField(PreviewUrlCacheEntityFields.IMAGE_WIDTH, Int::class.java) - ?.setNullable(PreviewUrlCacheEntityFields.IMAGE_WIDTH, true) - ?.addField(PreviewUrlCacheEntityFields.IMAGE_HEIGHT, Int::class.java) - ?.setNullable(PreviewUrlCacheEntityFields.IMAGE_HEIGHT, true) + if (oldVersion < 1) MigrateSessionTo001(realm).perform() + if (oldVersion < 2) MigrateSessionTo002(realm).perform() + if (oldVersion < 3) MigrateSessionTo003(realm).perform() + if (oldVersion < 4) MigrateSessionTo004(realm).perform() + if (oldVersion < 5) MigrateSessionTo005(realm).perform() + if (oldVersion < 6) MigrateSessionTo006(realm).perform() + if (oldVersion < 7) MigrateSessionTo007(realm).perform() + if (oldVersion < 8) MigrateSessionTo008(realm).perform() + if (oldVersion < 9) MigrateSessionTo009(realm).perform() + if (oldVersion < 10) MigrateSessionTo010(realm).perform() + if (oldVersion < 11) MigrateSessionTo011(realm).perform() + if (oldVersion < 12) MigrateSessionTo012(realm).perform() + if (oldVersion < 13) MigrateSessionTo013(realm).perform() + if (oldVersion < 14) MigrateSessionTo014(realm).perform() + if (oldVersion < 15) MigrateSessionTo015(realm).perform() + if (oldVersion < 16) MigrateSessionTo016(realm).perform() + if (oldVersion < 17) MigrateSessionTo017(realm).perform() + if (oldVersion < 18) MigrateSessionTo018(realm).perform() + if (oldVersion < 19) MigrateSessionTo019(realm, normalizer).perform() + if (oldVersion < 20) MigrateSessionTo020(realm).perform() + if (oldVersion < 21) MigrateSessionTo021(realm).perform() + if (oldVersion < 22) MigrateSessionTo022(realm).perform() + if (oldVersion < 23) MigrateSessionTo023(realm).perform() + if (oldVersion < 24) MigrateSessionTo024(realm).perform() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo001.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo001.kt new file mode 100644 index 0000000000..831c6280ad --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo001.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo001(realm: DynamicRealm) : RealmMigrator(realm, 1) { + + override fun doMigrate(realm: DynamicRealm) { + // Add hasFailedSending in RoomSummary and a small warning icon on room list + realm.schema.get("RoomSummaryEntity") + ?.addField(RoomSummaryEntityFields.HAS_FAILED_SENDING, Boolean::class.java) + ?.transform { obj -> + obj.setBoolean(RoomSummaryEntityFields.HAS_FAILED_SENDING, false) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo002.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo002.kt new file mode 100644 index 0000000000..215e558e2a --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo002.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo002(realm: DynamicRealm) : RealmMigrator(realm, 2) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("HomeServerCapabilitiesEntity") + ?.addField("adminE2EByDefault", Boolean::class.java) + ?.transform { obj -> + obj.setBoolean("adminE2EByDefault", true) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo003.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo003.kt new file mode 100644 index 0000000000..ab848d129a --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo003.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo003(realm: DynamicRealm) : RealmMigrator(realm, 3) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("HomeServerCapabilitiesEntity") + ?.addField("preferredJitsiDomain", String::class.java) + ?.transform { obj -> + // Schedule a refresh of the capabilities + obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo004.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo004.kt new file mode 100644 index 0000000000..be13ae2c2f --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo004.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo004(realm: DynamicRealm) : RealmMigrator(realm, 4) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.create("PendingThreePidEntity") + .addField(PendingThreePidEntityFields.CLIENT_SECRET, String::class.java) + .setRequired(PendingThreePidEntityFields.CLIENT_SECRET, true) + .addField(PendingThreePidEntityFields.EMAIL, String::class.java) + .addField(PendingThreePidEntityFields.MSISDN, String::class.java) + .addField(PendingThreePidEntityFields.SEND_ATTEMPT, Int::class.java) + .addField(PendingThreePidEntityFields.SID, String::class.java) + .setRequired(PendingThreePidEntityFields.SID, true) + .addField(PendingThreePidEntityFields.SUBMIT_URL, String::class.java) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo005.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo005.kt new file mode 100644 index 0000000000..b4826b23a4 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo005.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo005(realm: DynamicRealm) : RealmMigrator(realm, 5) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("HomeServerCapabilitiesEntity") + ?.removeField("adminE2EByDefault") + ?.removeField("preferredJitsiDomain") + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo006.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo006.kt new file mode 100644 index 0000000000..3d7f26ccee --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo006.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo006(realm: DynamicRealm) : RealmMigrator(realm, 6) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.create("PreviewUrlCacheEntity") + .addField(PreviewUrlCacheEntityFields.URL, String::class.java) + .setRequired(PreviewUrlCacheEntityFields.URL, true) + .addPrimaryKey(PreviewUrlCacheEntityFields.URL) + .addField(PreviewUrlCacheEntityFields.URL_FROM_SERVER, String::class.java) + .addField(PreviewUrlCacheEntityFields.SITE_NAME, String::class.java) + .addField(PreviewUrlCacheEntityFields.TITLE, String::class.java) + .addField(PreviewUrlCacheEntityFields.DESCRIPTION, String::class.java) + .addField(PreviewUrlCacheEntityFields.MXC_URL, String::class.java) + .addField(PreviewUrlCacheEntityFields.LAST_UPDATED_TIMESTAMP, Long::class.java) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo007.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo007.kt new file mode 100644 index 0000000000..be8c8ce9c6 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo007.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.RoomEntityFields +import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo007(realm: DynamicRealm) : RealmMigrator(realm, 7) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("RoomEntity") + ?.addField(RoomEntityFields.MEMBERS_LOAD_STATUS_STR, String::class.java) + ?.transform { obj -> + if (obj.getBoolean("areAllMembersLoaded")) { + obj.setString("membersLoadStatusStr", RoomMembersLoadStatusType.LOADED.name) + } else { + obj.setString("membersLoadStatusStr", RoomMembersLoadStatusType.NONE.name) + } + } + ?.removeField("areAllMembersLoaded") + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo008.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo008.kt new file mode 100644 index 0000000000..d46730ef70 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo008.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.EditAggregatedSummaryEntityFields +import org.matrix.android.sdk.internal.database.model.EditionOfEventFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo008(realm: DynamicRealm) : RealmMigrator(realm, 8) { + + override fun doMigrate(realm: DynamicRealm) { + val editionOfEventSchema = realm.schema.create("EditionOfEvent") + .addField(EditionOfEventFields.CONTENT, String::class.java) + .addField(EditionOfEventFields.EVENT_ID, String::class.java) + .setRequired(EditionOfEventFields.EVENT_ID, true) + .addField(EditionOfEventFields.SENDER_ID, String::class.java) + .setRequired(EditionOfEventFields.SENDER_ID, true) + .addField(EditionOfEventFields.TIMESTAMP, Long::class.java) + .addField(EditionOfEventFields.IS_LOCAL_ECHO, Boolean::class.java) + + realm.schema.get("EditAggregatedSummaryEntity") + ?.removeField("aggregatedContent") + ?.removeField("sourceEvents") + ?.removeField("lastEditTs") + ?.removeField("sourceLocalEchoEvents") + ?.addRealmListField(EditAggregatedSummaryEntityFields.EDITIONS.`$`, editionOfEventSchema) + + // This has to be done once a parent use the model as a child + // See https://github.com/realm/realm-java/issues/7402 + editionOfEventSchema.isEmbedded = true + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo009.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo009.kt new file mode 100644 index 0000000000..370430b9e3 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo009.kt @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import io.realm.FieldAttribute +import org.matrix.android.sdk.api.session.room.model.tag.RoomTag +import org.matrix.android.sdk.internal.database.model.EventEntityFields +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields +import org.matrix.android.sdk.internal.database.model.RoomTagEntityFields +import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo009(realm: DynamicRealm) : RealmMigrator(realm, 9) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("RoomSummaryEntity") + ?.addField(RoomSummaryEntityFields.LAST_ACTIVITY_TIME, Long::class.java, FieldAttribute.INDEXED) + ?.setNullable(RoomSummaryEntityFields.LAST_ACTIVITY_TIME, true) + ?.addIndex(RoomSummaryEntityFields.MEMBERSHIP_STR) + ?.addIndex(RoomSummaryEntityFields.IS_DIRECT) + ?.addIndex(RoomSummaryEntityFields.VERSIONING_STATE_STR) + + ?.addField(RoomSummaryEntityFields.IS_FAVOURITE, Boolean::class.java) + ?.addIndex(RoomSummaryEntityFields.IS_FAVOURITE) + ?.addField(RoomSummaryEntityFields.IS_LOW_PRIORITY, Boolean::class.java) + ?.addIndex(RoomSummaryEntityFields.IS_LOW_PRIORITY) + ?.addField(RoomSummaryEntityFields.IS_SERVER_NOTICE, Boolean::class.java) + ?.addIndex(RoomSummaryEntityFields.IS_SERVER_NOTICE) + + ?.transform { obj -> + val isFavorite = obj.getList(RoomSummaryEntityFields.TAGS.`$`).any { + it.getString(RoomTagEntityFields.TAG_NAME) == RoomTag.ROOM_TAG_FAVOURITE + } + obj.setBoolean(RoomSummaryEntityFields.IS_FAVOURITE, isFavorite) + + val isLowPriority = obj.getList(RoomSummaryEntityFields.TAGS.`$`).any { + it.getString(RoomTagEntityFields.TAG_NAME) == RoomTag.ROOM_TAG_LOW_PRIORITY + } + + obj.setBoolean(RoomSummaryEntityFields.IS_LOW_PRIORITY, isLowPriority) + +// XXX migrate last message origin server ts + obj.getObject(RoomSummaryEntityFields.LATEST_PREVIEWABLE_EVENT.`$`) + ?.getObject(TimelineEventEntityFields.ROOT.`$`) + ?.getLong(EventEntityFields.ORIGIN_SERVER_TS)?.let { + obj.setLong(RoomSummaryEntityFields.LAST_ACTIVITY_TIME, it) + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo010.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo010.kt new file mode 100644 index 0000000000..b968862d10 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo010.kt @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent +import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields +import org.matrix.android.sdk.internal.database.model.EventEntityFields +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields +import org.matrix.android.sdk.internal.database.model.SpaceChildSummaryEntityFields +import org.matrix.android.sdk.internal.database.model.SpaceParentSummaryEntityFields +import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo010(realm: DynamicRealm) : RealmMigrator(realm, 10) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.create("SpaceChildSummaryEntity") + ?.addField(SpaceChildSummaryEntityFields.ORDER, String::class.java) + ?.addField(SpaceChildSummaryEntityFields.CHILD_ROOM_ID, String::class.java) + ?.addField(SpaceChildSummaryEntityFields.AUTO_JOIN, Boolean::class.java) + ?.setNullable(SpaceChildSummaryEntityFields.AUTO_JOIN, true) + ?.addRealmObjectField(SpaceChildSummaryEntityFields.CHILD_SUMMARY_ENTITY.`$`, realm.schema.get("RoomSummaryEntity")!!) + ?.addRealmListField(SpaceChildSummaryEntityFields.VIA_SERVERS.`$`, String::class.java) + + realm.schema.create("SpaceParentSummaryEntity") + ?.addField(SpaceParentSummaryEntityFields.PARENT_ROOM_ID, String::class.java) + ?.addField(SpaceParentSummaryEntityFields.CANONICAL, Boolean::class.java) + ?.setNullable(SpaceParentSummaryEntityFields.CANONICAL, true) + ?.addRealmObjectField(SpaceParentSummaryEntityFields.PARENT_SUMMARY_ENTITY.`$`, realm.schema.get("RoomSummaryEntity")!!) + ?.addRealmListField(SpaceParentSummaryEntityFields.VIA_SERVERS.`$`, String::class.java) + + val creationContentAdapter = MoshiProvider.providesMoshi().adapter(RoomCreateContent::class.java) + realm.schema.get("RoomSummaryEntity") + ?.addField(RoomSummaryEntityFields.ROOM_TYPE, String::class.java) + ?.addField(RoomSummaryEntityFields.FLATTEN_PARENT_IDS, String::class.java) + ?.addField(RoomSummaryEntityFields.GROUP_IDS, String::class.java) + ?.transform { obj -> + + val creationEvent = realm.where("CurrentStateEventEntity") + .equalTo(CurrentStateEventEntityFields.ROOM_ID, obj.getString(RoomSummaryEntityFields.ROOM_ID)) + .equalTo(CurrentStateEventEntityFields.TYPE, EventType.STATE_ROOM_CREATE) + .findFirst() + + val roomType = creationEvent?.getObject(CurrentStateEventEntityFields.ROOT.`$`) + ?.getString(EventEntityFields.CONTENT)?.let { + creationContentAdapter.fromJson(it)?.type + } + + obj.setString(RoomSummaryEntityFields.ROOM_TYPE, roomType) + } + ?.addRealmListField(RoomSummaryEntityFields.PARENTS.`$`, realm.schema.get("SpaceParentSummaryEntity")!!) + ?.addRealmListField(RoomSummaryEntityFields.CHILDREN.`$`, realm.schema.get("SpaceChildSummaryEntity")!!) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo011.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo011.kt new file mode 100644 index 0000000000..92ee26df42 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo011.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.EventEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo011(realm: DynamicRealm) : RealmMigrator(realm, 11) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("EventEntity") + ?.addField(EventEntityFields.SEND_STATE_DETAILS, String::class.java) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo012.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo012.kt new file mode 100644 index 0000000000..a914cadd80 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo012.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent +import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields +import org.matrix.android.sdk.internal.database.model.EventEntityFields +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields +import org.matrix.android.sdk.internal.database.model.SpaceChildSummaryEntityFields +import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo012(realm: DynamicRealm) : RealmMigrator(realm, 12) { + + override fun doMigrate(realm: DynamicRealm) { + val joinRulesContentAdapter = MoshiProvider.providesMoshi().adapter(RoomJoinRulesContent::class.java) + realm.schema.get("RoomSummaryEntity") + ?.addField(RoomSummaryEntityFields.JOIN_RULES_STR, String::class.java) + ?.transform { obj -> + val joinRulesEvent = realm.where("CurrentStateEventEntity") + .equalTo(CurrentStateEventEntityFields.ROOM_ID, obj.getString(RoomSummaryEntityFields.ROOM_ID)) + .equalTo(CurrentStateEventEntityFields.TYPE, EventType.STATE_ROOM_JOIN_RULES) + .findFirst() + + val roomJoinRules = joinRulesEvent?.getObject(CurrentStateEventEntityFields.ROOT.`$`) + ?.getString(EventEntityFields.CONTENT)?.let { + joinRulesContentAdapter.fromJson(it)?.joinRules + } + + obj.setString(RoomSummaryEntityFields.JOIN_RULES_STR, roomJoinRules?.name) + } + + realm.schema.get("SpaceChildSummaryEntity") + ?.addField(SpaceChildSummaryEntityFields.SUGGESTED, Boolean::class.java) + ?.setNullable(SpaceChildSummaryEntityFields.SUGGESTED, true) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo013.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo013.kt new file mode 100644 index 0000000000..2ea0303802 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo013.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.SpaceChildSummaryEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo013(realm: DynamicRealm) : RealmMigrator(realm, 13) { + + override fun doMigrate(realm: DynamicRealm) { + // Fix issue with the nightly build. Eventually play again the migration which has been included in migrateTo12() + realm.schema.get("SpaceChildSummaryEntity") + ?.takeIf { !it.hasField(SpaceChildSummaryEntityFields.SUGGESTED) } + ?.addField(SpaceChildSummaryEntityFields.SUGGESTED, Boolean::class.java) + ?.setNullable(SpaceChildSummaryEntityFields.SUGGESTED, true) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo014.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo014.kt new file mode 100644 index 0000000000..c524b6f284 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo014.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import io.realm.FieldAttribute +import org.matrix.android.sdk.api.session.room.model.VersioningState +import org.matrix.android.sdk.internal.database.model.RoomAccountDataEntityFields +import org.matrix.android.sdk.internal.database.model.RoomEntityFields +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo014(realm: DynamicRealm) : RealmMigrator(realm, 14) { + + override fun doMigrate(realm: DynamicRealm) { + val roomAccountDataSchema = realm.schema.create("RoomAccountDataEntity") + .addField(RoomAccountDataEntityFields.CONTENT_STR, String::class.java) + .addField(RoomAccountDataEntityFields.TYPE, String::class.java, FieldAttribute.INDEXED) + + realm.schema.get("RoomEntity") + ?.addRealmListField(RoomEntityFields.ACCOUNT_DATA.`$`, roomAccountDataSchema) + + realm.schema.get("RoomSummaryEntity") + ?.addField(RoomSummaryEntityFields.IS_HIDDEN_FROM_USER, Boolean::class.java, FieldAttribute.INDEXED) + ?.transform { + val isHiddenFromUser = it.getString(RoomSummaryEntityFields.VERSIONING_STATE_STR) == VersioningState.UPGRADED_ROOM_JOINED.name + it.setBoolean(RoomSummaryEntityFields.IS_HIDDEN_FROM_USER, isHiddenFromUser) + } + + roomAccountDataSchema.isEmbedded = true + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo015.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo015.kt new file mode 100644 index 0000000000..329964a9a4 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo015.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.api.session.room.model.Membership +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields +import org.matrix.android.sdk.internal.query.process +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo015(realm: DynamicRealm) : RealmMigrator(realm, 15) { + + override fun doMigrate(realm: DynamicRealm) { + // fix issue with flattenParentIds on DM that kept growing with duplicate + // so we reset it, will be updated next sync + realm.where("RoomSummaryEntity") + .process(RoomSummaryEntityFields.MEMBERSHIP_STR, Membership.activeMemberships()) + .equalTo(RoomSummaryEntityFields.IS_DIRECT, true) + .findAll() + .onEach { + it.setString(RoomSummaryEntityFields.FLATTEN_PARENT_IDS, null) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo016.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo016.kt new file mode 100644 index 0000000000..e6b3d4a463 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo016.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo016(realm: DynamicRealm) : RealmMigrator(realm, 16) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("HomeServerCapabilitiesEntity") + ?.addField(HomeServerCapabilitiesEntityFields.ROOM_VERSIONS_JSON, String::class.java) + ?.transform { obj -> + // Schedule a refresh of the capabilities + obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo017.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo017.kt new file mode 100644 index 0000000000..95d67b9ad8 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo017.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.EventInsertEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo017(realm: DynamicRealm) : RealmMigrator(realm, 17) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("EventInsertEntity") + ?.addField(EventInsertEntityFields.CAN_BE_PROCESSED, Boolean::class.java) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo018.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo018.kt new file mode 100644 index 0000000000..b415c51d4b --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo018.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields +import org.matrix.android.sdk.internal.database.model.presence.UserPresenceEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo018(realm: DynamicRealm) : RealmMigrator(realm, 18) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.create("UserPresenceEntity") + ?.addField(UserPresenceEntityFields.USER_ID, String::class.java) + ?.addPrimaryKey(UserPresenceEntityFields.USER_ID) + ?.setRequired(UserPresenceEntityFields.USER_ID, true) + ?.addField(UserPresenceEntityFields.PRESENCE_STR, String::class.java) + ?.addField(UserPresenceEntityFields.LAST_ACTIVE_AGO, Long::class.java) + ?.setNullable(UserPresenceEntityFields.LAST_ACTIVE_AGO, true) + ?.addField(UserPresenceEntityFields.STATUS_MESSAGE, String::class.java) + ?.addField(UserPresenceEntityFields.IS_CURRENTLY_ACTIVE, Boolean::class.java) + ?.setNullable(UserPresenceEntityFields.IS_CURRENTLY_ACTIVE, true) + ?.addField(UserPresenceEntityFields.AVATAR_URL, String::class.java) + ?.addField(UserPresenceEntityFields.DISPLAY_NAME, String::class.java) + + val userPresenceEntity = realm.schema.get("UserPresenceEntity") ?: return + realm.schema.get("RoomSummaryEntity") + ?.addRealmObjectField(RoomSummaryEntityFields.DIRECT_USER_PRESENCE.`$`, userPresenceEntity) + + realm.schema.get("RoomMemberSummaryEntity") + ?.addRealmObjectField(RoomMemberSummaryEntityFields.USER_PRESENCE_ENTITY.`$`, userPresenceEntity) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo019.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo019.kt new file mode 100644 index 0000000000..d0b368be46 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo019.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields +import org.matrix.android.sdk.internal.util.Normalizer +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo019(realm: DynamicRealm, + private val normalizer: Normalizer) : RealmMigrator(realm, 19) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("RoomSummaryEntity") + ?.addField(RoomSummaryEntityFields.NORMALIZED_DISPLAY_NAME, String::class.java) + ?.transform { + it.getString(RoomSummaryEntityFields.DISPLAY_NAME)?.let { displayName -> + val normalised = normalizer.normalize(displayName) + it.set(RoomSummaryEntityFields.NORMALIZED_DISPLAY_NAME, normalised) + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo020.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo020.kt new file mode 100644 index 0000000000..c7f6e3ceed --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo020.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.ChunkEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo020(realm: DynamicRealm) : RealmMigrator(realm, 20) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("ChunkEntity")?.apply { + if (hasField("numberOfTimelineEvents")) { + removeField("numberOfTimelineEvents") + } + var cleanOldChunks = false + if (!hasField(ChunkEntityFields.NEXT_CHUNK.`$`)) { + cleanOldChunks = true + addRealmObjectField(ChunkEntityFields.NEXT_CHUNK.`$`, this) + } + if (!hasField(ChunkEntityFields.PREV_CHUNK.`$`)) { + cleanOldChunks = true + addRealmObjectField(ChunkEntityFields.PREV_CHUNK.`$`, this) + } + if (cleanOldChunks) { + val chunkEntities = realm.where("ChunkEntity").equalTo(ChunkEntityFields.IS_LAST_FORWARD, false).findAll() + chunkEntities.deleteAllFromRealm() + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo021.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo021.kt new file mode 100644 index 0000000000..6b6952e697 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo021.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.internal.crypto.model.event.EncryptionEventContent +import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields +import org.matrix.android.sdk.internal.database.model.EventEntityFields +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields +import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo021(realm: DynamicRealm) : RealmMigrator(realm, 21) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("RoomSummaryEntity") + ?.addField(RoomSummaryEntityFields.E2E_ALGORITHM, String::class.java) + ?.transform { obj -> + + val encryptionContentAdapter = MoshiProvider.providesMoshi().adapter(EncryptionEventContent::class.java) + + val encryptionEvent = realm.where("CurrentStateEventEntity") + .equalTo(CurrentStateEventEntityFields.ROOM_ID, obj.getString(RoomSummaryEntityFields.ROOM_ID)) + .equalTo(CurrentStateEventEntityFields.TYPE, EventType.STATE_ROOM_ENCRYPTION) + .findFirst() + + val encryptionEventRoot = encryptionEvent?.getObject(CurrentStateEventEntityFields.ROOT.`$`) + val algorithm = encryptionEventRoot + ?.getString(EventEntityFields.CONTENT)?.let { + encryptionContentAdapter.fromJson(it)?.algorithm + } + + obj.setString(RoomSummaryEntityFields.E2E_ALGORITHM, algorithm) + obj.setBoolean(RoomSummaryEntityFields.IS_ENCRYPTED, encryptionEvent != null) + encryptionEventRoot?.getLong(EventEntityFields.ORIGIN_SERVER_TS)?.let { + obj.setLong(RoomSummaryEntityFields.ENCRYPTION_EVENT_TS, it) + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo022.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo022.kt new file mode 100644 index 0000000000..e78a9d05da --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo022.kt @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.api.session.room.model.Membership +import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields +import org.matrix.android.sdk.internal.database.model.RoomEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import timber.log.Timber + +class MigrateSessionTo022(realm: DynamicRealm) : RealmMigrator(realm, 22) { + + override fun doMigrate(realm: DynamicRealm) { + val listJoinedRoomIds = realm.where("RoomEntity") + .equalTo(RoomEntityFields.MEMBERSHIP_STR, Membership.JOIN.name).findAll() + .map { it.getString(RoomEntityFields.ROOM_ID) } + + val hasMissingStateEvent = realm.where("CurrentStateEventEntity") + .`in`(CurrentStateEventEntityFields.ROOM_ID, listJoinedRoomIds.toTypedArray()) + .isNull(CurrentStateEventEntityFields.ROOT.`$`).findFirst() != null + + if (hasMissingStateEvent) { + Timber.v("Has some missing state event, clear session cache") + realm.deleteAll() + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo023.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo023.kt new file mode 100644 index 0000000000..0bb8ceeaa5 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo023.kt @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import io.realm.FieldAttribute +import org.matrix.android.sdk.api.session.threads.ThreadNotificationState +import org.matrix.android.sdk.internal.database.model.EventEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo023(realm: DynamicRealm) : RealmMigrator(realm, 23) { + + override fun doMigrate(realm: DynamicRealm) { + val eventEntity = realm.schema.get("TimelineEventEntity") ?: return + + realm.schema.get("EventEntity") + ?.addField(EventEntityFields.IS_ROOT_THREAD, Boolean::class.java, FieldAttribute.INDEXED) + ?.addField(EventEntityFields.ROOT_THREAD_EVENT_ID, String::class.java, FieldAttribute.INDEXED) + ?.addField(EventEntityFields.NUMBER_OF_THREADS, Int::class.java) + ?.addField(EventEntityFields.THREAD_NOTIFICATION_STATE_STR, String::class.java) + ?.transform { + it.setString(EventEntityFields.THREAD_NOTIFICATION_STATE_STR, ThreadNotificationState.NO_NEW_MESSAGE.name) + } + ?.addRealmObjectField(EventEntityFields.THREAD_SUMMARY_LATEST_MESSAGE.`$`, eventEntity) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo024.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo024.kt new file mode 100644 index 0000000000..ff88972566 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo024.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo024(realm: DynamicRealm) : RealmMigrator(realm, 24) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("PreviewUrlCacheEntity") + ?.addField(PreviewUrlCacheEntityFields.IMAGE_WIDTH, Int::class.java) + ?.setNullable(PreviewUrlCacheEntityFields.IMAGE_WIDTH, true) + ?.addField(PreviewUrlCacheEntityFields.IMAGE_HEIGHT, Int::class.java) + ?.setNullable(PreviewUrlCacheEntityFields.IMAGE_HEIGHT, true) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/GlobalRealmMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/GlobalRealmMigration.kt index 49bcc72181..7a37ce2838 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/GlobalRealmMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/GlobalRealmMigration.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.internal.raw import io.realm.DynamicRealm import io.realm.RealmMigration -import org.matrix.android.sdk.internal.database.model.KnownServerUrlEntityFields +import org.matrix.android.sdk.internal.raw.migration.MigrateGlobalTo001 import timber.log.Timber internal object GlobalRealmMigration : RealmMigration { @@ -27,15 +27,8 @@ internal object GlobalRealmMigration : RealmMigration { const val SCHEMA_VERSION = 1L override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { - Timber.d("Migrating Auth Realm from $oldVersion to $newVersion") + Timber.d("Migrating Global Realm from $oldVersion to $newVersion") - if (oldVersion <= 0) migrateTo1(realm) - } - - private fun migrateTo1(realm: DynamicRealm) { - realm.schema.create("KnownServerUrlEntity") - .addField(KnownServerUrlEntityFields.URL, String::class.java) - .addPrimaryKey(KnownServerUrlEntityFields.URL) - .setRequired(KnownServerUrlEntityFields.URL, true) + if (oldVersion < 1) MigrateGlobalTo001(realm).perform() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/migration/MigrateGlobalTo001.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/migration/MigrateGlobalTo001.kt new file mode 100644 index 0000000000..cff2f7b8e8 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/migration/MigrateGlobalTo001.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 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.internal.raw.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.KnownServerUrlEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateGlobalTo001(realm: DynamicRealm) : RealmMigrator(realm, 1) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.create("KnownServerUrlEntity") + .addField(KnownServerUrlEntityFields.URL, String::class.java) + .addPrimaryKey(KnownServerUrlEntityFields.URL) + .setRequired(KnownServerUrlEntityFields.URL, true) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStoreMigration.kt index 21c0f8eb9e..cda85312ad 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStoreMigration.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.identity.db import io.realm.DynamicRealm import io.realm.RealmMigration +import org.matrix.android.sdk.internal.session.identity.db.migration.MigrateIdentityTo001 import timber.log.Timber internal object RealmIdentityStoreMigration : RealmMigration { @@ -27,14 +28,6 @@ internal object RealmIdentityStoreMigration : RealmMigration { override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { Timber.v("Migrating Realm Identity from $oldVersion to $newVersion") - if (oldVersion <= 0) migrateTo1(realm) - } - - private fun migrateTo1(realm: DynamicRealm) { - Timber.d("Step 0 -> 1") - Timber.d("Add field userConsent (Boolean) and set the value to false") - - realm.schema.get("IdentityDataEntity") - ?.addField(IdentityDataEntityFields.USER_CONSENT, Boolean::class.java) + if (oldVersion < 1) MigrateIdentityTo001(realm).perform() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/migration/MigrateIdentityTo001.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/migration/MigrateIdentityTo001.kt new file mode 100644 index 0000000000..002601470d --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/migration/MigrateIdentityTo001.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 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.internal.session.identity.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.session.identity.db.IdentityDataEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator +import timber.log.Timber + +class MigrateIdentityTo001(realm: DynamicRealm) : RealmMigrator(realm, 1) { + + override fun doMigrate(realm: DynamicRealm) { + Timber.d("Add field userConsent (Boolean) and set the value to false") + realm.schema.get("IdentityDataEntity") + ?.addField(IdentityDataEntityFields.USER_CONSENT, Boolean::class.java) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/database/RealmMigrator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/database/RealmMigrator.kt new file mode 100644 index 0000000000..15e82f3cc0 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/database/RealmMigrator.kt @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 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.internal.util.database + +import io.realm.DynamicRealm +import io.realm.RealmObjectSchema +import timber.log.Timber + +abstract class RealmMigrator(private val realm: DynamicRealm, + private val targetSchemaVersion: Int) { + fun perform() { + Timber.d("Migrate ${realm.configuration.realmFileName} to $targetSchemaVersion") + doMigrate(realm) + } + + abstract fun doMigrate(realm: DynamicRealm) + + protected fun RealmObjectSchema.addFieldIfNotExists(fieldName: String, fieldType: Class<*>): RealmObjectSchema { + if (!hasField(fieldName)) { + addField(fieldName, fieldType) + } + return this + } + + protected fun RealmObjectSchema.removeFieldIfExists(fieldName: String): RealmObjectSchema { + if (hasField(fieldName)) { + removeField(fieldName) + } + return this + } + + protected fun RealmObjectSchema.setRequiredIfNotAlready(fieldName: String, isRequired: Boolean): RealmObjectSchema { + if (isRequired != isRequired(fieldName)) { + setRequired(fieldName, isRequired) + } + return this + } +} From eed4bf175fd34dc3dee2fe1340db0450af2b811a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 2 Feb 2022 17:52:26 +0100 Subject: [PATCH 007/302] Realm migrations are not objects anymore SchemaVersion is now a val --- .../matrix/android/sdk/internal/auth/AuthModule.kt | 8 +++++--- .../sdk/internal/auth/db/AuthRealmMigration.kt | 12 +++++++++--- .../android/sdk/internal/crypto/CryptoModule.kt | 7 ++++--- .../crypto/store/db/RealmCryptoStoreMigration.kt | 13 ++++++++++--- .../internal/database/RealmSessionStoreMigration.kt | 9 +++------ .../database/SessionRealmConfigurationFactory.kt | 2 +- .../internal/legacy/DefaultLegacySessionImporter.kt | 7 ++++--- .../sdk/internal/raw/GlobalRealmMigration.kt | 12 +++++++++--- .../matrix/android/sdk/internal/raw/RawModule.kt | 7 ++++--- .../sdk/internal/session/identity/IdentityModule.kt | 5 +++-- .../identity/db/RealmIdentityStoreMigration.kt | 13 ++++++++++--- 11 files changed, 62 insertions(+), 33 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthModule.kt index bb62dbbfe9..298e116199 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthModule.kt @@ -46,7 +46,9 @@ internal abstract class AuthModule { @JvmStatic @Provides @AuthDatabase - fun providesRealmConfiguration(context: Context, realmKeysUtils: RealmKeysUtils): RealmConfiguration { + fun providesRealmConfiguration(context: Context, + realmKeysUtils: RealmKeysUtils, + authRealmMigration: AuthRealmMigration): RealmConfiguration { val old = File(context.filesDir, "matrix-sdk-auth") if (old.exists()) { old.renameTo(File(context.filesDir, "matrix-sdk-auth.realm")) @@ -58,8 +60,8 @@ internal abstract class AuthModule { } .name("matrix-sdk-auth.realm") .modules(AuthRealmModule()) - .schemaVersion(AuthRealmMigration.SCHEMA_VERSION) - .migration(AuthRealmMigration) + .schemaVersion(authRealmMigration.schemaVersion) + .migration(authRealmMigration) .build() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/AuthRealmMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/AuthRealmMigration.kt index 484273eef5..59b6471a05 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/AuthRealmMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/AuthRealmMigration.kt @@ -23,11 +23,17 @@ import org.matrix.android.sdk.internal.auth.db.migration.MigrateAuthTo002 import org.matrix.android.sdk.internal.auth.db.migration.MigrateAuthTo003 import org.matrix.android.sdk.internal.auth.db.migration.MigrateAuthTo004 import timber.log.Timber +import javax.inject.Inject -internal object AuthRealmMigration : RealmMigration { +internal class AuthRealmMigration @Inject constructor() : RealmMigration { + /** + * Forces all AuthRealmMigration instances to be equal + * Avoids Realm throwing when multiple instances of the migration are set + */ + override fun equals(other: Any?) = other is AuthRealmMigration + override fun hashCode() = 4000 - // Current schema version - const val SCHEMA_VERSION = 4L + val schemaVersion = 4L override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { Timber.d("Migrating Auth Realm from $oldVersion to $newVersion") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt index fe388b44e2..3130a6382f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt @@ -112,7 +112,8 @@ internal abstract class CryptoModule { @SessionScope fun providesRealmConfiguration(@SessionFilesDirectory directory: File, @UserMd5 userMd5: String, - realmKeysUtils: RealmKeysUtils): RealmConfiguration { + realmKeysUtils: RealmKeysUtils, + realmCryptoStoreMigration: RealmCryptoStoreMigration): RealmConfiguration { return RealmConfiguration.Builder() .directory(directory) .apply { @@ -121,8 +122,8 @@ internal abstract class CryptoModule { .name("crypto_store.realm") .modules(RealmCryptoStoreModule()) .allowWritesOnUiThread(true) - .schemaVersion(RealmCryptoStoreMigration.CRYPTO_STORE_SCHEMA_VERSION) - .migration(RealmCryptoStoreMigration) + .schemaVersion(realmCryptoStoreMigration.schemaVersion) + .migration(realmCryptoStoreMigration) .build() } 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 acee400cea..685b2d2967 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 @@ -33,16 +33,23 @@ import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo013 import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo014 import timber.log.Timber +import javax.inject.Inject -internal object RealmCryptoStoreMigration : RealmMigration { +internal class RealmCryptoStoreMigration @Inject constructor() : RealmMigration { + /** + * Forces all RealmCryptoStoreMigration instances to be equal + * Avoids Realm throwing when multiple instances of the migration are set + */ + override fun equals(other: Any?) = other is RealmCryptoStoreMigration + override fun hashCode() = 5000 // 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 = 14L + val schemaVersion = 14L override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { - Timber.v("Migrating Realm Crypto from $oldVersion to $newVersion") + Timber.d("Migrating Realm Crypto from $oldVersion to $newVersion") if (oldVersion < 1) MigrateCryptoTo001Legacy(realm).perform() if (oldVersion < 2) MigrateCryptoTo002Legacy(realm).perform() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt index f6f93d3c41..f4a8ae2c67 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt @@ -49,11 +49,6 @@ import javax.inject.Inject internal class RealmSessionStoreMigration @Inject constructor( private val normalizer: Normalizer ) : RealmMigration { - - companion object { - const val SESSION_STORE_SCHEMA_VERSION = 24L - } - /** * Forces all RealmSessionStoreMigration instances to be equal * Avoids Realm throwing when multiple instances of the migration are set @@ -61,8 +56,10 @@ internal class RealmSessionStoreMigration @Inject constructor( override fun equals(other: Any?) = other is RealmSessionStoreMigration override fun hashCode() = 1000 + val schemaVersion = 24L + override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { - Timber.v("Migrating Realm Session from $oldVersion to $newVersion") + Timber.d("Migrating Realm Session from $oldVersion to $newVersion") if (oldVersion < 1) MigrateSessionTo001(realm).perform() if (oldVersion < 2) MigrateSessionTo002(realm).perform() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt index 04ca26a943..08d55b5647 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt @@ -71,7 +71,7 @@ internal class SessionRealmConfigurationFactory @Inject constructor( } .allowWritesOnUiThread(true) .modules(SessionRealmModule()) - .schemaVersion(RealmSessionStoreMigration.SESSION_STORE_SCHEMA_VERSION) + .schemaVersion(realmSessionStoreMigration.schemaVersion) .migration(realmSessionStoreMigration) .build() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt index 445b6be8e8..22085e30fc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt @@ -42,7 +42,8 @@ import org.matrix.android.sdk.internal.legacy.riot.HomeServerConnectionConfig as internal class DefaultLegacySessionImporter @Inject constructor( private val context: Context, private val sessionParamsStore: SessionParamsStore, - private val realmKeysUtils: RealmKeysUtils + private val realmKeysUtils: RealmKeysUtils, + private val realmCryptoStoreMigration: RealmCryptoStoreMigration ) : LegacySessionImporter { private val loginStorage = LoginStorage(context) @@ -170,8 +171,8 @@ internal class DefaultLegacySessionImporter @Inject constructor( .directory(File(context.filesDir, userMd5)) .name("crypto_store.realm") .modules(RealmCryptoStoreModule()) - .schemaVersion(RealmCryptoStoreMigration.CRYPTO_STORE_SCHEMA_VERSION) - .migration(RealmCryptoStoreMigration) + .schemaVersion(realmCryptoStoreMigration.schemaVersion) + .migration(realmCryptoStoreMigration) .build() Timber.d("Migration: copy DB to encrypted DB") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/GlobalRealmMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/GlobalRealmMigration.kt index 7a37ce2838..8dffac5fa0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/GlobalRealmMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/GlobalRealmMigration.kt @@ -20,11 +20,17 @@ import io.realm.DynamicRealm import io.realm.RealmMigration import org.matrix.android.sdk.internal.raw.migration.MigrateGlobalTo001 import timber.log.Timber +import javax.inject.Inject -internal object GlobalRealmMigration : RealmMigration { +internal class GlobalRealmMigration @Inject constructor() : RealmMigration { + /** + * Forces all GlobalRealmMigration instances to be equal + * Avoids Realm throwing when multiple instances of the migration are set + */ + override fun equals(other: Any?) = other is GlobalRealmMigration + override fun hashCode() = 2000 - // Current schema version - const val SCHEMA_VERSION = 1L + val schemaVersion = 1L override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { Timber.d("Migrating Global Realm from $oldVersion to $newVersion") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/RawModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/RawModule.kt index 50721b809a..a830976671 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/RawModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/RawModule.kt @@ -51,14 +51,15 @@ internal abstract class RawModule { @Provides @GlobalDatabase @MatrixScope - fun providesRealmConfiguration(realmKeysUtils: RealmKeysUtils): RealmConfiguration { + fun providesRealmConfiguration(realmKeysUtils: RealmKeysUtils, + globalRealmMigration: GlobalRealmMigration): RealmConfiguration { return RealmConfiguration.Builder() .apply { realmKeysUtils.configureEncryption(this, DB_ALIAS) } .name("matrix-sdk-global.realm") - .schemaVersion(GlobalRealmMigration.SCHEMA_VERSION) - .migration(GlobalRealmMigration) + .schemaVersion(globalRealmMigration.schemaVersion) + .migration(globalRealmMigration) .allowWritesOnUiThread(true) .modules(GlobalRealmModule()) .build() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt index 65794e6b14..4e9d7dc7f7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt @@ -60,6 +60,7 @@ internal abstract class IdentityModule { @IdentityDatabase @SessionScope fun providesIdentityRealmConfiguration(realmKeysUtils: RealmKeysUtils, + realmIdentityStoreMigration: RealmIdentityStoreMigration, @SessionFilesDirectory directory: File, @UserMd5 userMd5: String): RealmConfiguration { return RealmConfiguration.Builder() @@ -68,8 +69,8 @@ internal abstract class IdentityModule { .apply { realmKeysUtils.configureEncryption(this, SessionModule.getKeyAlias(userMd5)) } - .schemaVersion(RealmIdentityStoreMigration.IDENTITY_STORE_SCHEMA_VERSION) - .migration(RealmIdentityStoreMigration) + .schemaVersion(realmIdentityStoreMigration.schemaVersion) + .migration(realmIdentityStoreMigration) .allowWritesOnUiThread(true) .modules(IdentityRealmModule()) .build() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStoreMigration.kt index cda85312ad..0c279d8a7e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/RealmIdentityStoreMigration.kt @@ -20,13 +20,20 @@ import io.realm.DynamicRealm import io.realm.RealmMigration import org.matrix.android.sdk.internal.session.identity.db.migration.MigrateIdentityTo001 import timber.log.Timber +import javax.inject.Inject -internal object RealmIdentityStoreMigration : RealmMigration { +internal class RealmIdentityStoreMigration @Inject constructor() : RealmMigration { + /** + * Forces all RealmIdentityStoreMigration instances to be equal + * Avoids Realm throwing when multiple instances of the migration are set + */ + override fun equals(other: Any?) = other is RealmIdentityStoreMigration + override fun hashCode() = 3000 - const val IDENTITY_STORE_SCHEMA_VERSION = 1L + val schemaVersion = 1L override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { - Timber.v("Migrating Realm Identity from $oldVersion to $newVersion") + Timber.d("Migrating Realm Identity from $oldVersion to $newVersion") if (oldVersion < 1) MigrateIdentityTo001(realm).perform() } From 1369d1fa2fd2eef30cecb44e3ac2e968ee7b57f7 Mon Sep 17 00:00:00 2001 From: bmarty Date: Mon, 7 Feb 2022 00:02:21 +0000 Subject: [PATCH 008/302] Sync analytics plan --- .../app/features/analytics/plan/Composer.kt | 53 +++++ .../features/analytics/plan/Interaction.kt | 172 ++++++++++++++++ .../app/features/analytics/plan/JoinedRoom.kt | 33 +++ .../analytics/plan/PerformanceTimer.kt | 6 +- .../app/features/analytics/plan/Screen.kt | 15 ++ .../plan/{Click.kt => SlashCommand.kt} | 22 +- .../plan/{Identity.kt => UserProperties.kt} | 21 +- .../app/features/analytics/plan/ViewRoom.kt | 190 ++++++++++++++++++ 8 files changed, 488 insertions(+), 24 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/analytics/plan/Composer.kt create mode 100644 vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt rename vector/src/main/java/im/vector/app/features/analytics/plan/{Click.kt => SlashCommand.kt} (70%) rename vector/src/main/java/im/vector/app/features/analytics/plan/{Identity.kt => UserProperties.kt} (72%) create mode 100644 vector/src/main/java/im/vector/app/features/analytics/plan/ViewRoom.kt diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Composer.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Composer.kt new file mode 100644 index 0000000000..a3b847a1bd --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Composer.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 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.analytics.plan + +import im.vector.app.features.analytics.itf.VectorAnalyticsEvent + +// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT +// https://github.com/matrix-org/matrix-analytics-events/ + +/** + * Triggered when the user sends a message via the composer. + */ +data class Composer( + /** + * Whether the user was using the composer inside of a thread. + */ + val inThread: Boolean, + /** + * Whether the user's composer interaction was editing a previously sent + * event. + */ + val isEditing: Boolean, + /** + * Whether the user's composer interaction was a reply to a previously + * sent event. + */ + val isReply: Boolean, +) : VectorAnalyticsEvent { + + override fun getName() = "Composer" + + override fun getProperties(): Map? { + return mutableMapOf().apply { + put("inThread", inThread) + put("isEditing", isEditing) + put("isReply", isReply) + }.takeIf { it.isNotEmpty() } + } +} diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt new file mode 100644 index 0000000000..3d71b36c51 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2021 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.analytics.plan + +import im.vector.app.features.analytics.itf.VectorAnalyticsEvent + +// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT +// https://github.com/matrix-org/matrix-analytics-events/ + +/** + * Triggered when the user clicks/taps/activates a UI element. + */ +data class Interaction( + /** + * The index of the element, if its in a list of elements. + */ + val index: Int? = null, + /** + * The manner with which the user activated the UI element. + */ + val interactionType: InteractionType? = null, + /** + * The unique name of this element. + */ + val name: Name, +) : VectorAnalyticsEvent { + + enum class Name { + /** + * User tapped the already selected space from the space list. + */ + SpacePanelSelectedSpace, + + /** + * User tapped an unselected space from the space list -> space + * switching should occur. + */ + SpacePanelSwitchSpace, + + /** + * User accessed the room invite flow using the button at the top of the + * room member list in the right panel of Element Web/Desktop. + */ + WebRightPanelMemberListInviteButton, + + /** + * User accessed room member list using the 'People' button in the right + * panel room summary card of Element Web/Desktop. + */ + WebRightPanelRoomInfoPeopleButton, + + /** + * User accessed room settings using the 'Settings' button in the right + * panel room summary card of Element Web/Desktop. + */ + WebRightPanelRoomInfoSettingsButton, + + /** + * User accessed room member list using the back button in the right + * panel user info card of Element Web/Desktop. + */ + WebRightPanelRoomUserInfoBackButton, + + /** + * User invited someone to room by clicking invite on the right panel + * user info card in Element Web/Desktop. + */ + WebRightPanelRoomUserInfoInviteButton, + + /** + * User adjusted their favourites using the context menu on the header + * of a room in Element Web/Desktop. + */ + WebRoomHeaderContextMenuFavouriteToggle, + + /** + * User accessed the room invite flow using the context menu on the + * header of a room in Element Web/Desktop. + */ + WebRoomHeaderContextMenuInviteItem, + + /** + * User interacted with leave action in the context menu on the header + * of a room in Element Web/Desktop. + */ + WebRoomHeaderContextMenuLeaveItem, + + /** + * User accessed their room notification settings via the context menu + * on the header of a room in Element Web/Desktop. + */ + WebRoomHeaderContextMenuNotificationsItem, + + /** + * User accessed room member list using the context menu on the header + * of a room in Element Web/Desktop. + */ + WebRoomHeaderContextMenuPeopleItem, + + /** + * User accessed room settings using the context menu on the header of a + * room in Element Web/Desktop. + */ + WebRoomHeaderContextMenuSettingsItem, + + /** + * User adjusted their favourites using the context menu on a room tile + * in the room list in Element Web/Desktop. + */ + WebRoomListRoomTileContextMenuFavouriteToggle, + + /** + * User accessed the room invite flow using the context menu on a room + * tile in the room list in Element Web/Desktop. + */ + WebRoomListRoomTileContextMenuInviteItem, + + /** + * User interacted with leave action in the context menu on a room tile + * in the room list in Element Web/Desktop. + */ + WebRoomListRoomTileContextMenuLeaveItem, + + /** + * User accessed room settings using the context menu on a room tile in + * the room list in Element Web/Desktop. + */ + WebRoomListRoomTileContextMenuSettingsItem, + + /** + * User accessed their room notification settings via the context menu + * on a room tile in the room list in Element Web/Desktop. + */ + WebRoomListRoomTileNotificationsMenu, + + /** + * User interacted with leave action in the general tab of the room + * settings dialog in Element Web/Desktop. + */ + WebRoomSettingsLeaveButton, + } + + enum class InteractionType { + Keyboard, + Pointer, + Touch, + } + + override fun getName() = "Interaction" + + override fun getProperties(): Map? { + return mutableMapOf().apply { + index?.let { put("index", it) } + interactionType?.let { put("interactionType", it.name) } + put("name", name.name) + }.takeIf { it.isNotEmpty() } + } +} diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/JoinedRoom.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/JoinedRoom.kt index 97ac19ec93..d2fb6832ba 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/JoinedRoom.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/JoinedRoom.kt @@ -29,15 +29,46 @@ data class JoinedRoom( * Whether the room is a DM. */ val isDM: Boolean, + /** + * Whether the room is a Space. + */ + val isSpace: Boolean, /** * The size of the room. */ val roomSize: RoomSize, + /** + * The trigger for a room being joined if known. + */ + val trigger: Trigger? = null, ) : VectorAnalyticsEvent { + enum class Trigger { + /** + * Room joined via a push/desktop notification. + */ + Notification, + + /** + * Room joined via the public rooms directory. + */ + RoomDirectory, + + /** + * Room joined via the space hierarchy view. + */ + SpaceHierarchy, + + /** + * Room joined via a timeline pill or link in another room. + */ + Timeline, + } + enum class RoomSize { ElevenToOneHundred, MoreThanAThousand, + One, OneHundredAndOneToAThousand, ThreeToTen, Two, @@ -48,7 +79,9 @@ data class JoinedRoom( override fun getProperties(): Map? { return mutableMapOf().apply { put("isDM", isDM) + put("isSpace", isSpace) put("roomSize", roomSize.name) + trigger?.let { put("trigger", it.name) } }.takeIf { it.isNotEmpty() } } } diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/PerformanceTimer.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/PerformanceTimer.kt index 59dd997f92..2770d668e5 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/PerformanceTimer.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/PerformanceTimer.kt @@ -83,13 +83,15 @@ data class PerformanceTimer( StartupLaunchScreen, /** - * The time to preload data in the MXStore on iOS. + * The time to preload data in the MXStore on iOS. In this case, + * `itemCount` should contain the number of rooms in the store. */ StartupStorePreload, /** * The time to load all data from the store (including - * StartupStorePreload time). + * StartupStorePreload time). In this case, `itemCount` should contain + * the number of rooms loaded into the session */ StartupStoreReady, } diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt index db4dcd0fac..476c72fa30 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt @@ -121,6 +121,16 @@ data class Screen( */ MobileSidebar, + /** + * Screen that displays the list of memebrs of a space + */ + MobileSpaceMembers, + + /** + * The bottom sheet that list all space options + */ + MobileSpaceMenu, + /** * The screen shown to select which room directory you'd like to use. */ @@ -206,6 +216,11 @@ data class Screen( */ SettingsSecurity, + /** + * Screen that displays the list of rooms and spaces of a space + */ + SpaceExploreRooms, + /** * The screen shown to create a new direct room. */ diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Click.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt similarity index 70% rename from vector/src/main/java/im/vector/app/features/analytics/plan/Click.kt rename to vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt index fbc847165d..69c34bbc15 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Click.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt @@ -22,29 +22,25 @@ import im.vector.app.features.analytics.itf.VectorAnalyticsEvent // https://github.com/matrix-org/matrix-analytics-events/ /** - * Triggered when the user clicks/taps on a UI element. + * Triggered when the user runs a slash command in their composer. */ -data class Click( +data class SlashCommand( /** - * The index of the element, if its in a list of elements. + * The name of this command. */ - val index: Int? = null, - /** - * The unique name of this element. - */ - val name: Name, + val command: Command, ) : VectorAnalyticsEvent { - enum class Name { - SendMessageButton, + enum class Command { + invite, + part, } - override fun getName() = "Click" + override fun getName() = "SlashCommand" override fun getProperties(): Map? { return mutableMapOf().apply { - index?.let { put("index", it) } - put("name", name.name) + put("command", command.name) }.takeIf { it.isNotEmpty() } } } diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Identity.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt similarity index 72% rename from vector/src/main/java/im/vector/app/features/analytics/plan/Identity.kt rename to vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt index 99f1fadfc4..453cd0ec9d 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Identity.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt @@ -16,20 +16,23 @@ package im.vector.app.features.analytics.plan -import im.vector.app.features.analytics.itf.VectorAnalyticsEvent - // GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT // https://github.com/matrix-org/matrix-analytics-events/ /** - * The user properties to apply when identifying + * The user properties to apply when identifying. This is not an event + * definition. These properties must all be device independent. */ -data class Identity( +data class UserProperties( /** * The selected messaging use case during the onboarding flow. */ val ftueUseCaseSelection: FtueUseCaseSelection? = null, -) : VectorAnalyticsEvent { + /** + * Number of spaces (and sub-spaces) the user is joined to + */ + val numSpaces: Int? = null, +) { enum class FtueUseCaseSelection { /** @@ -53,11 +56,11 @@ data class Identity( WorkMessaging, } - override fun getName() = "Identity" - override fun getProperties(): Map? { - return mutableMapOf().apply { - put("ftueUseCaseSelection", null) + fun getProperties(): Map? { + return mutableMapOf().apply { + ftueUseCaseSelection?.let { put("ftueUseCaseSelection", it.name) } + numSpaces?.let { put("numSpaces", it) } }.takeIf { it.isNotEmpty() } } } diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/ViewRoom.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/ViewRoom.kt new file mode 100644 index 0000000000..50c74a64c1 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/ViewRoom.kt @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2021 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.analytics.plan + +import im.vector.app.features.analytics.itf.VectorAnalyticsEvent + +// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT +// https://github.com/matrix-org/matrix-analytics-events/ + +/** + * Triggered when the user changes rooms. + */ +data class ViewRoom( + /** + * The reason for the room change if known. + */ + val trigger: Trigger? = null, + /** + * Whether the interaction was performed via the keyboard input. + */ + val viaKeyboard: Boolean? = null, +) : VectorAnalyticsEvent { + + enum class Trigger { + /** + * Room accessed due to being just created. + */ + Created, + + /** + * Room switched due to user interacting with a message search result. + */ + MessageSearch, + + /** + * Room switched due to user selecting a user to go to a DM with. + */ + MessageUser, + + /** + * Room accessed via a push/desktop notification. + */ + Notification, + + /** + * Room accessed via the predecessor link at the top of the upgraded + * room. + */ + Predecessor, + + /** + * Room accessed via the public rooms directory. + */ + RoomDirectory, + + /** + * Room accessed via the room list. + */ + RoomList, + + /** + * Room accessed via a slash command in Element Web/Desktop like /goto. + */ + SlashCommand, + + /** + * Room accessed via the space hierarchy view. + */ + SpaceHierarchy, + + /** + * Room accessed via a timeline pill or link in another room. + */ + Timeline, + + /** + * Room accessed via a tombstone at the bottom of a predecessor room. + */ + Tombstone, + + /** + * Room switched due to user interacting with incoming verification + * request. + */ + VerificationRequest, + + /** + * Room switched due to accepting a call in a different room in Element + * Web/Desktop. + */ + WebAcceptCall, + + /** + * Room switched due to making a call via the dial pad in Element + * Web/Desktop. + */ + WebDialPad, + + /** + * Room accessed via interacting with the floating call or Jitsi PIP in + * Element Web/Desktop. + */ + WebFloatingCallWindow, + + /** + * Room accessed via the shortcut in Element Web/Desktop's forward + * modal. + */ + WebForwardShortcut, + + /** + * Room accessed via the Element Web/Desktop horizontal breadcrumbs at + * the top of the room list. + */ + WebHorizontalBreadcrumbs, + + /** + * Room accessed via an Element Web/Desktop keyboard shortcut like go to + * next room with unread messages. + */ + WebKeyboardShortcut, + + /** + * Room accessed via Element Web/Desktop's notification panel. + */ + WebNotificationPanel, + + /** + * Room accessed via the predecessor link in Settings > Advanced in + * Element Web/Desktop. + */ + WebPredecessorSettings, + + /** + * Room accessed via clicking on a notifications badge on a room list + * sublist in Element Web/Desktop. + */ + WebRoomListNotificationBadge, + + /** + * Room switched due to the user changing space in Element Web/Desktop. + */ + WebSpaceContextSwitch, + + /** + * Room accessed via clicking on the notifications badge on the + * currently selected space in Element Web/Desktop. + */ + WebSpacePanelNotificationBadge, + + /** + * Room accessed via Element Web/Desktop's Unified Search modal. + */ + WebUnifiedSearch, + + /** + * Room accessed via the Element Web/Desktop vertical breadcrumb hover + * menu. + */ + WebVerticalBreadcrumbs, + + /** + * Room switched due to widget interaction. + */ + Widget, + } + + override fun getName() = "ViewRoom" + + override fun getProperties(): Map? { + return mutableMapOf().apply { + trigger?.let { put("trigger", it.name) } + viaKeyboard?.let { put("viaKeyboard", it) } + }.takeIf { it.isNotEmpty() } + } +} From 7e182ed6625783b9fe060425d929d1ff19dda1fd Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 7 Feb 2022 17:35:26 +0300 Subject: [PATCH 009/302] Remove redundant highlight on add poll option button. --- changelog.d/5178.bugfix | 1 + .../java/im/vector/app/core/ui/list/GenericButtonItem.kt | 8 ++++++++ .../app/features/poll/create/CreatePollController.kt | 1 + 3 files changed, 10 insertions(+) create mode 100644 changelog.d/5178.bugfix diff --git a/changelog.d/5178.bugfix b/changelog.d/5178.bugfix new file mode 100644 index 0000000000..73021a0485 --- /dev/null +++ b/changelog.d/5178.bugfix @@ -0,0 +1 @@ +Remove redundant highlight on add poll option button \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt b/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt index fe59c82ce9..bea65ecd64 100644 --- a/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt +++ b/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt @@ -15,10 +15,12 @@ */ package im.vector.app.core.ui.list +import android.content.res.ColorStateList import android.graphics.Typeface import android.view.Gravity import androidx.annotation.ColorInt import androidx.annotation.DrawableRes +import androidx.core.content.ContextCompat import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import com.google.android.material.button.MaterialButton @@ -55,6 +57,9 @@ abstract class GenericButtonItem : VectorEpoxyModel() @EpoxyAttribute var bold: Boolean = false + @EpoxyAttribute + var highlight: Boolean = true + override fun bind(holder: Holder) { super.bind(holder) holder.button.text = text @@ -70,6 +75,9 @@ abstract class GenericButtonItem : VectorEpoxyModel() val textStyle = if (bold) Typeface.BOLD else Typeface.NORMAL holder.button.setTypeface(null, textStyle) + holder.button.rippleColor = if (highlight) ColorStateList.valueOf(ThemeUtils.getColor(holder.view.context, R.attr.colorSecondary)) else + ContextCompat.getColorStateList(holder.view.context, android.R.color.transparent) + holder.button.onClick(buttonClickAction) } diff --git a/vector/src/main/java/im/vector/app/features/poll/create/CreatePollController.kt b/vector/src/main/java/im/vector/app/features/poll/create/CreatePollController.kt index d938b98eed..6ccf7fc6aa 100644 --- a/vector/src/main/java/im/vector/app/features/poll/create/CreatePollController.kt +++ b/vector/src/main/java/im/vector/app/features/poll/create/CreatePollController.kt @@ -121,6 +121,7 @@ class CreatePollController @Inject constructor( textColor(host.colorProvider.getColor(R.color.palette_element_green)) gravity(Gravity.START) bold(true) + highlight(false) buttonClickAction { host.callback?.onAddOption() } From 457a6a2dd0bd4b0672f8223e72d2b3e053bcea7e Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 7 Feb 2022 17:44:27 +0300 Subject: [PATCH 010/302] Lint fix. --- .../java/im/vector/app/core/ui/list/GenericButtonItem.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt b/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt index bea65ecd64..215f999755 100644 --- a/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt +++ b/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt @@ -75,8 +75,11 @@ abstract class GenericButtonItem : VectorEpoxyModel() val textStyle = if (bold) Typeface.BOLD else Typeface.NORMAL holder.button.setTypeface(null, textStyle) - holder.button.rippleColor = if (highlight) ColorStateList.valueOf(ThemeUtils.getColor(holder.view.context, R.attr.colorSecondary)) else + holder.button.rippleColor = if (highlight) { + ColorStateList.valueOf(ThemeUtils.getColor(holder.view.context, R.attr.colorSecondary)) + } else { ContextCompat.getColorStateList(holder.view.context, android.R.color.transparent) + } holder.button.onClick(buttonClickAction) } From 2d80c6bc4ebd39dbb9f7acf60968b74625bfa9f4 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 8 Feb 2022 14:02:39 +0000 Subject: [PATCH 011/302] avoiding using the matrix getInstance internally within the sdk to allow us to inject a consistent instance --- .../android/sdk/internal/session/sync/job/SyncService.kt | 4 +++- .../java/im/vector/app/core/services/VectorSyncService.kt | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncService.kt index 0ecf91f6fa..97ae9b3a68 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncService.kt @@ -192,12 +192,14 @@ abstract class SyncService : Service() { } } + abstract fun provideMatrix(): Matrix + private fun initialize(intent: Intent?): Boolean { if (intent == null) { Timber.d("## Sync: initialize intent is null") return false } - val matrix = Matrix.getInstance(applicationContext) + val matrix = provideMatrix() val safeSessionId = intent.getStringExtra(EXTRA_SESSION_ID) ?: return false syncTimeoutSeconds = intent.getIntExtra(EXTRA_TIMEOUT_SECONDS, getDefaultSyncTimeoutSeconds()) syncDelaySeconds = intent.getIntExtra(EXTRA_DELAY_SECONDS, getDefaultSyncDelaySeconds()) diff --git a/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt b/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt index a6f6d8d82f..8621c28d57 100644 --- a/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt +++ b/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt @@ -35,6 +35,7 @@ import im.vector.app.R import im.vector.app.core.platform.PendingIntentCompat import im.vector.app.features.notifications.NotificationUtils import im.vector.app.features.settings.BackgroundSyncMode +import org.matrix.android.sdk.api.Matrix import org.matrix.android.sdk.internal.session.sync.job.SyncService import timber.log.Timber import javax.inject.Inject @@ -75,6 +76,9 @@ class VectorSyncService : SyncService() { } @Inject lateinit var notificationUtils: NotificationUtils + @Inject lateinit var matrix: Matrix + + override fun provideMatrix() = matrix override fun getDefaultSyncDelaySeconds() = BackgroundSyncMode.DEFAULT_SYNC_DELAY_SECONDS From c160f5dff1959216f318728ed2c3e4d70578003f Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 8 Feb 2022 15:09:38 +0000 Subject: [PATCH 012/302] always providing matrix via the singleton module - allows the matrix configuration to also contain dependencies --- .../main/java/im/vector/app/VectorApplication.kt | 13 ++----------- .../java/im/vector/app/core/di/SingletonModule.kt | 14 +++++++++++++- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/vector/src/main/java/im/vector/app/VectorApplication.kt b/vector/src/main/java/im/vector/app/VectorApplication.kt index e64188765e..a3f4ffcfcd 100644 --- a/vector/src/main/java/im/vector/app/VectorApplication.kt +++ b/vector/src/main/java/im/vector/app/VectorApplication.kt @@ -55,7 +55,6 @@ import im.vector.app.features.pin.PinLocker import im.vector.app.features.popup.PopupAlertManager import im.vector.app.features.rageshake.VectorFileLogger import im.vector.app.features.rageshake.VectorUncaughtExceptionHandler -import im.vector.app.features.room.VectorRoomDisplayNameFallbackProvider import im.vector.app.features.settings.VectorLocale import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.themes.ThemeUtils @@ -63,7 +62,6 @@ import im.vector.app.features.version.VersionProvider import im.vector.app.push.fcm.FcmHelper import org.jitsi.meet.sdk.log.JitsiMeetDefaultLogHandler import org.matrix.android.sdk.api.Matrix -import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.auth.AuthenticationService import org.matrix.android.sdk.api.legacy.LegacySessionImporter import timber.log.Timber @@ -77,7 +75,6 @@ import androidx.work.Configuration as WorkConfiguration @HiltAndroidApp class VectorApplication : Application(), - MatrixConfiguration.Provider, WorkConfiguration.Provider { lateinit var appContext: Context @@ -100,6 +97,7 @@ class VectorApplication : @Inject lateinit var autoRageShaker: AutoRageShaker @Inject lateinit var vectorFileLogger: VectorFileLogger @Inject lateinit var vectorAnalytics: VectorAnalytics + @Inject lateinit var matrix: Matrix // font thread handler private var fontThreadHandler: Handler? = null @@ -220,16 +218,9 @@ class VectorApplication : } } - override fun providesMatrixConfiguration(): MatrixConfiguration { - return MatrixConfiguration( - applicationFlavor = BuildConfig.FLAVOR_DESCRIPTION, - roomDisplayNameFallbackProvider = VectorRoomDisplayNameFallbackProvider(this) - ) - } - override fun getWorkManagerConfiguration(): WorkConfiguration { return WorkConfiguration.Builder() - .setWorkerFactory(Matrix.getInstance(this.appContext).workerFactory()) + .setWorkerFactory(matrix.workerFactory()) .setExecutor(Executors.newCachedThreadPool()) .build() } diff --git a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt index 0e19cd4388..84061daf0f 100644 --- a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt @@ -26,6 +26,7 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent +import im.vector.app.BuildConfig import im.vector.app.EmojiCompatWrapper import im.vector.app.EmojiSpanify import im.vector.app.core.dispatchers.CoroutineDispatchers @@ -42,12 +43,14 @@ import im.vector.app.features.navigation.DefaultNavigator import im.vector.app.features.navigation.Navigator import im.vector.app.features.pin.PinCodeStore import im.vector.app.features.pin.SharedPrefPinCodeStore +import im.vector.app.features.room.VectorRoomDisplayNameFallbackProvider import im.vector.app.features.ui.SharedPreferencesUiStateRepository import im.vector.app.features.ui.UiStateRepository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import org.matrix.android.sdk.api.Matrix +import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.auth.AuthenticationService import org.matrix.android.sdk.api.auth.HomeServerHistoryService import org.matrix.android.sdk.api.legacy.LegacySessionImporter @@ -107,7 +110,16 @@ object VectorStaticModule { } @Provides - fun providesMatrix(context: Context): Matrix { + fun providesMatrixConfiguration(context: Context): MatrixConfiguration { + return MatrixConfiguration( + applicationFlavor = BuildConfig.FLAVOR_DESCRIPTION, + roomDisplayNameFallbackProvider = VectorRoomDisplayNameFallbackProvider(context) + ) + } + + @Provides + fun providesMatrix(context: Context, configuration: MatrixConfiguration): Matrix { + Matrix.initialize(context, configuration) return Matrix.getInstance(context) } From a63e79bad5501ceba80163b5194cb033c73858ee Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 8 Feb 2022 15:36:23 +0000 Subject: [PATCH 013/302] initialising a new matrix instance for android tests, ideally this would also be backed back the test module instead of the singleton state --- .../im/vector/app/SecurityBootstrapTest.kt | 6 ++-- .../app/VerifySessionInteractiveTest.kt | 6 ++-- .../vector/app/VerifySessionPassphraseTest.kt | 6 ++-- .../vector/app/core/utils/TestMatrixHelper.kt | 32 +++++++++++++++++++ 4 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 vector/src/androidTest/java/im/vector/app/core/utils/TestMatrixHelper.kt diff --git a/vector/src/androidTest/java/im/vector/app/SecurityBootstrapTest.kt b/vector/src/androidTest/java/im/vector/app/SecurityBootstrapTest.kt index fb7b9dcb41..69fe63fb7b 100644 --- a/vector/src/androidTest/java/im/vector/app/SecurityBootstrapTest.kt +++ b/vector/src/androidTest/java/im/vector/app/SecurityBootstrapTest.kt @@ -38,7 +38,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest -import androidx.test.platform.app.InstrumentationRegistry +import im.vector.app.core.utils.getMatrixInstance import im.vector.app.features.MainActivity import im.vector.app.features.crypto.recover.SetupMode import im.vector.app.features.home.HomeActivity @@ -47,7 +47,6 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.matrix.android.sdk.api.Matrix import org.matrix.android.sdk.api.session.Session @RunWith(AndroidJUnit4::class) @@ -61,8 +60,7 @@ class SecurityBootstrapTest : VerificationTestBase() { @Before fun createSessionWithCrossSigning() { - val context = InstrumentationRegistry.getInstrumentation().targetContext - val matrix = Matrix.getInstance(context) + val matrix = getMatrixInstance() val userName = "foobar_${System.currentTimeMillis()}" existingSession = createAccountAndSync(matrix, userName, password, true) stubAllExternalIntents() diff --git a/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt b/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt index 982a421425..c82b543a08 100644 --- a/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt +++ b/vector/src/androidTest/java/im/vector/app/VerifySessionInteractiveTest.kt @@ -33,7 +33,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest -import androidx.test.platform.app.InstrumentationRegistry +import im.vector.app.core.utils.getMatrixInstance import im.vector.app.features.MainActivity import im.vector.app.features.home.HomeActivity import org.hamcrest.CoreMatchers.not @@ -41,7 +41,6 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.matrix.android.sdk.api.Matrix import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.auth.UserPasswordAuth @@ -66,8 +65,7 @@ class VerifySessionInteractiveTest : VerificationTestBase() { @Before fun createSessionWithCrossSigning() { - val context = InstrumentationRegistry.getInstrumentation().targetContext - val matrix = Matrix.getInstance(context) + val matrix = getMatrixInstance() val userName = "foobar_${System.currentTimeMillis()}" existingSession = createAccountAndSync(matrix, userName, password, true) doSync { diff --git a/vector/src/androidTest/java/im/vector/app/VerifySessionPassphraseTest.kt b/vector/src/androidTest/java/im/vector/app/VerifySessionPassphraseTest.kt index c51ff29669..80d8315a0e 100644 --- a/vector/src/androidTest/java/im/vector/app/VerifySessionPassphraseTest.kt +++ b/vector/src/androidTest/java/im/vector/app/VerifySessionPassphraseTest.kt @@ -34,6 +34,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest import androidx.test.platform.app.InstrumentationRegistry import im.vector.app.core.resources.StringProvider +import im.vector.app.core.utils.getMatrixInstance import im.vector.app.features.MainActivity import im.vector.app.features.crypto.quads.SharedSecureStorageActivity import im.vector.app.features.crypto.recover.BootstrapCrossSigningTask @@ -45,7 +46,6 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.matrix.android.sdk.api.Matrix import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.auth.UserPasswordAuth @@ -67,7 +67,7 @@ class VerifySessionPassphraseTest : VerificationTestBase() { @Before fun createSessionWithCrossSigningAnd4S() { val context = InstrumentationRegistry.getInstrumentation().targetContext - val matrix = Matrix.getInstance(context) + val matrix = getMatrixInstance() val userName = "foobar_${System.currentTimeMillis()}" existingSession = createAccountAndSync(matrix, userName, password, true) doSync { @@ -90,7 +90,7 @@ class VerifySessionPassphraseTest : VerificationTestBase() { runBlocking { task.execute(Params( - userInteractiveAuthInterceptor = object : UserInteractiveAuthInterceptor { + userInteractiveAuthInterceptor = object : UserInteractiveAuthInterceptor { override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation) { promise.resume( UserPasswordAuth( diff --git a/vector/src/androidTest/java/im/vector/app/core/utils/TestMatrixHelper.kt b/vector/src/androidTest/java/im/vector/app/core/utils/TestMatrixHelper.kt new file mode 100644 index 0000000000..f7b6c6308a --- /dev/null +++ b/vector/src/androidTest/java/im/vector/app/core/utils/TestMatrixHelper.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 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.core.utils + +import androidx.test.platform.app.InstrumentationRegistry +import im.vector.app.features.room.VectorRoomDisplayNameFallbackProvider +import org.matrix.android.sdk.BuildConfig +import org.matrix.android.sdk.api.Matrix +import org.matrix.android.sdk.api.MatrixConfiguration + +fun getMatrixInstance(): Matrix { + val context = InstrumentationRegistry.getInstrumentation().targetContext + val configuration = MatrixConfiguration( + roomDisplayNameFallbackProvider = VectorRoomDisplayNameFallbackProvider(context) + ) + Matrix.initialize(context, configuration) + return Matrix.getInstance(context) +} From 8dc8c209d327e4642c15c464190c72b3e5863fac Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 8 Feb 2022 15:38:04 +0000 Subject: [PATCH 014/302] using injected matrix instance for the bug reporting to avoid directly calling getInstance --- .../java/im/vector/app/features/rageshake/BugReporter.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt index 2c554716d2..b6454b89e4 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt @@ -73,7 +73,8 @@ class BugReporter @Inject constructor( private val versionProvider: VersionProvider, private val vectorPreferences: VectorPreferences, private val vectorFileLogger: VectorFileLogger, - private val systemLocaleProvider: SystemLocaleProvider + private val systemLocaleProvider: SystemLocaleProvider, + private val matrix: Matrix ) { var inMultiWindowMode = false @@ -265,7 +266,7 @@ class BugReporter @Inject constructor( val builder = BugReporterMultipartBody.Builder() .addFormDataPart("text", text) .addFormDataPart("app", rageShakeAppNameForReport(reportType)) - .addFormDataPart("user_agent", Matrix.getInstance(context).getUserAgent()) + .addFormDataPart("user_agent", matrix.getUserAgent()) .addFormDataPart("user_id", userId) .addFormDataPart("can_contact", canContact.toString()) .addFormDataPart("device_id", deviceId) From 0390994e1414827ffeb81d1c9760ad27351d2a3c Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 8 Feb 2022 15:51:30 +0000 Subject: [PATCH 015/302] removing unused import --- .../java/im/vector/app/core/utils/TestMatrixHelper.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/vector/src/androidTest/java/im/vector/app/core/utils/TestMatrixHelper.kt b/vector/src/androidTest/java/im/vector/app/core/utils/TestMatrixHelper.kt index f7b6c6308a..fab41a68bb 100644 --- a/vector/src/androidTest/java/im/vector/app/core/utils/TestMatrixHelper.kt +++ b/vector/src/androidTest/java/im/vector/app/core/utils/TestMatrixHelper.kt @@ -18,7 +18,6 @@ package im.vector.app.core.utils import androidx.test.platform.app.InstrumentationRegistry import im.vector.app.features.room.VectorRoomDisplayNameFallbackProvider -import org.matrix.android.sdk.BuildConfig import org.matrix.android.sdk.api.Matrix import org.matrix.android.sdk.api.MatrixConfiguration From 5ff420f4f0be742699ea86bef59305785cbf6de5 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 8 Feb 2022 15:56:07 +0000 Subject: [PATCH 016/302] marking the matrix provision as a singleton to avoid reinitialising --- vector/src/main/java/im/vector/app/core/di/SingletonModule.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt index 84061daf0f..2629d2056b 100644 --- a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt @@ -118,6 +118,7 @@ object VectorStaticModule { } @Provides + @Singleton fun providesMatrix(context: Context, configuration: MatrixConfiguration): Matrix { Matrix.initialize(context, configuration) return Matrix.getInstance(context) From c62b9949f2e3386fc19063faaa71c95f7761b57b Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 8 Feb 2022 16:00:38 +0000 Subject: [PATCH 017/302] adding changelog entry --- changelog.d/5185.sdk | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5185.sdk diff --git a/changelog.d/5185.sdk b/changelog.d/5185.sdk new file mode 100644 index 0000000000..14071c2961 --- /dev/null +++ b/changelog.d/5185.sdk @@ -0,0 +1 @@ +Avoids using Matrix.getInstance() within the SyncService and instead relies on the SDK client to provide the matrix instance \ No newline at end of file From 99f2052ad867873d33ac11ac83b88d365e9549b2 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 8 Feb 2022 15:54:17 +0000 Subject: [PATCH 018/302] Translated using Weblate (Ukrainian) Currently translated at 100.0% (49 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/ --- fastlane/metadata/android/uk/changelogs/40103170.txt | 2 ++ fastlane/metadata/android/uk/changelogs/40103180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/uk/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/uk/changelogs/40103180.txt diff --git a/fastlane/metadata/android/uk/changelogs/40103170.txt b/fastlane/metadata/android/uk/changelogs/40103170.txt new file mode 100644 index 0000000000..708af771ac --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Основні зміни цієї версії: надсилання свого розташування у будь-яку кімнату. Редагування опитувань. +Повний перелік змін: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/uk/changelogs/40103180.txt b/fastlane/metadata/android/uk/changelogs/40103180.txt new file mode 100644 index 0000000000..6ffbe45571 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Основні зміни цієї версії: надсилання свого розташування у будь-яку кімнату. Редагування опитувань. +Повний перелік змін: https://github.com/vector-im/element-android/releases/tag/v1.3.18 From de082420ce61056e48b92801c7f460423008f549 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Tue, 8 Feb 2022 15:03:41 +0000 Subject: [PATCH 019/302] Translated using Weblate (Persian) Currently translated at 100.0% (49 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/ --- fastlane/metadata/android/fa/changelogs/40103170.txt | 2 ++ fastlane/metadata/android/fa/changelogs/40103180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/fa/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/fa/changelogs/40103180.txt diff --git a/fastlane/metadata/android/fa/changelogs/40103170.txt b/fastlane/metadata/android/fa/changelogs/40103170.txt new file mode 100644 index 0000000000..55769b8a12 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40103170.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: فرستادن مکانتان به هر اتاقی. ویرایش نظرسنجی. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/fa/changelogs/40103180.txt b/fastlane/metadata/android/fa/changelogs/40103180.txt new file mode 100644 index 0000000000..529da3f5a4 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40103180.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: فرستادن مکانتان به هر اتاقی. ویرایش نظرسنجی. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.3.18 From 279262c1037338f273fc49eb5ed2f1daeead43ab Mon Sep 17 00:00:00 2001 From: Linerly Date: Tue, 8 Feb 2022 16:58:12 +0000 Subject: [PATCH 020/302] Translated using Weblate (Indonesian) Currently translated at 100.0% (49 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/id/ --- fastlane/metadata/android/id/changelogs/40103170.txt | 2 ++ fastlane/metadata/android/id/changelogs/40103180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/id/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/id/changelogs/40103180.txt diff --git a/fastlane/metadata/android/id/changelogs/40103170.txt b/fastlane/metadata/android/id/changelogs/40103170.txt new file mode 100644 index 0000000000..04197b674d --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: kirim lokasi Anda ke ruangan apa saja. Edit poll. +Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/id/changelogs/40103180.txt b/fastlane/metadata/android/id/changelogs/40103180.txt new file mode 100644 index 0000000000..655fbd562a --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: kirim lokasi Anda ke ruangan apa saja. Edit poll. +Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.18 From 5b1d610dd3bea47b52a1813ac7f142cda87b74de Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Tue, 8 Feb 2022 15:39:39 +0000 Subject: [PATCH 021/302] Translated using Weblate (Albanian) Currently translated at 100.0% (49 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sq/ --- fastlane/metadata/android/sq/changelogs/40103130.txt | 2 ++ fastlane/metadata/android/sq/changelogs/40103170.txt | 2 ++ fastlane/metadata/android/sq/changelogs/40103180.txt | 2 ++ 3 files changed, 6 insertions(+) create mode 100644 fastlane/metadata/android/sq/changelogs/40103130.txt create mode 100644 fastlane/metadata/android/sq/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/sq/changelogs/40103180.txt diff --git a/fastlane/metadata/android/sq/changelogs/40103130.txt b/fastlane/metadata/android/sq/changelogs/40103130.txt new file mode 100644 index 0000000000..abae5b8206 --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40103130.txt @@ -0,0 +1,2 @@ +Ndryshimet kryesore në këtë version: Ndryshimi i parë te skena e mirëseardhjeve, përfshi zgjedhje për pjesëmarrje në Analizime. Mbulim për Akte dhe Formula Matematikore të shtuara te laboratorë. +Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.3.13 diff --git a/fastlane/metadata/android/sq/changelogs/40103170.txt b/fastlane/metadata/android/sq/changelogs/40103170.txt new file mode 100644 index 0000000000..405743bcb6 --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Ndryshimet kryesore në këtë version: dërgojeni vendndodhjen tuaj në çfarëdo dhome. Përpunoni pyetësorë. +Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/sq/changelogs/40103180.txt b/fastlane/metadata/android/sq/changelogs/40103180.txt new file mode 100644 index 0000000000..5ec41f7db3 --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Ndryshimet kryesore në këtë version: dërgojeni vendndodhjen tuaj në çfarëdo dhome. Përpunoni pyetësorë. +Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.3.18 From f6a24e964e1b7c8c3f959b5e00e2cab4a37eff0e Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Tue, 8 Feb 2022 23:23:03 +0300 Subject: [PATCH 022/302] Code review fix. --- .../java/im/vector/app/core/ui/list/GenericButtonItem.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt b/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt index 215f999755..d4838289a6 100644 --- a/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt +++ b/vector/src/main/java/im/vector/app/core/ui/list/GenericButtonItem.kt @@ -15,7 +15,6 @@ */ package im.vector.app.core.ui.list -import android.content.res.ColorStateList import android.graphics.Typeface import android.view.Gravity import androidx.annotation.ColorInt @@ -76,9 +75,9 @@ abstract class GenericButtonItem : VectorEpoxyModel() holder.button.setTypeface(null, textStyle) holder.button.rippleColor = if (highlight) { - ColorStateList.valueOf(ThemeUtils.getColor(holder.view.context, R.attr.colorSecondary)) + ContextCompat.getColorStateList(holder.view.context, R.color.mtrl_btn_text_btn_ripple_color) } else { - ContextCompat.getColorStateList(holder.view.context, android.R.color.transparent) + null } holder.button.onClick(buttonClickAction) From f2fd9a0469198c0ac1dd4ce0db46c6644756b006 Mon Sep 17 00:00:00 2001 From: gradle-update-robot Date: Wed, 9 Feb 2022 00:18:52 +0000 Subject: [PATCH 023/302] Update Gradle Wrapper from 7.3.3 to 7.4. Signed-off-by: gradle-update-robot --- gradle/wrapper/gradle-wrapper.jar | Bin 59536 -> 59821 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180f2ae8848c63b8b4dea2cb829da983f2fa..41d9927a4d4fb3f96a785543079b8df6723c946b 100644 GIT binary patch delta 8958 zcmY+KWl$VIlZIh&f(Hri?gR<$?iyT!TL`X;1^2~W7YVSq1qtqM!JWlDxLm%}UESUM zndj}Uny%^UnjhVhFb!8V3s(a#fIy>`VW15{5nuy;_V&a5O#0S&!a4dSkUMz_VHu3S zGA@p9Q$T|Sj}tYGWdjH;Mpp8m&yu&YURcrt{K;R|kM~(*{v%QwrBJIUF+K1kX5ZmF zty3i{d`y0;DgE+de>vN@yYqFPe1Ud{!&G*Q?iUc^V=|H%4~2|N zW+DM)W!`b&V2mQ0Y4u_)uB=P@-2`v|Wm{>CxER1P^ z>c}ZPZ)xxdOCDu59{X^~2id7+6l6x)U}C4Em?H~F`uOxS1?}xMxTV|5@}PlN%Cg$( zwY6c}r60=z5ZA1L zTMe;84rLtYvcm?M(H~ZqU;6F7Evo{P7!LGcdwO|qf1w+)MsnvK5^c@Uzj<{ zUoej1>95tuSvDJ|5K6k%&UF*uE6kBn47QJw^yE&#G;u^Z9oYWrK(+oL97hBsUMc_^ z;-lmxebwlB`Er_kXp2$`&o+rPJAN<`WX3ws2K{q@qUp}XTfV{t%KrsZ5vM!Q#4{V& zq>iO$MCiLq#%wXj%`W$_%FRg_WR*quv65TdHhdpV&jlq<=K^K`&!Kl5mA6p4n~p3u zWE{20^hYpn1M}}VmSHBXl1*-)2MP=0_k)EPr#>EoZukiXFDz?Di1I>2@Z^P$pvaF+ zN+qUy63jek2m59;YG)`r^F3-O)0RDIXPhf)XOOdkmu`3SMMSW(g+`Ajt{=h1dt~ks ztrhhP|L4G%5x79N#kwAHh5N){@{fzE7n&%dnisCm65Za<8r_hKvfx4Bg*`%-*-Mvn zFvn~)VP@}1sAyD+B{{8l{EjD10Av&Mz9^Xff*t`lU=q=S#(|>ls520;n3<}X#pyh& z*{CJf7$*&~!9jMnw_D~ikUKJ2+UnXmN6qak{xx%W;BKuXt7@ky!LPI1qk?gDwG@@o zkY+BkIie>{{q==5)kXw(*t#I?__Kwi>`=+s?Gq6X+vtSsaAO&Tf+Bl$vKnzc&%BHM z=loWOQq~n}>l=EL(5&6((ESsQC3^@4jlO5Od{qN#sWV)vqXw}aA>*uvwZopNN(|-T zRTF%5Y_k1R$;(d-)n;hWex{;7b6KgdAVE@&0pd(*qDzBO#YZV%kh%pYt1`hnQ(Fa& zYiDrOTDqk5M7hzp9kI2h!PxNnuJ&xl*zF8sx6!67bA49R1bmUF5bpK&&{eI0U~cH}PM z3aW1$lRb|ItkG5~_eBNu$|I|vYIdAA9a!pVq<+UTx*M}fG`23zxXp&E=FfnY- zEzKj;Cu_s4v>leO7M2-mE(UzKHL4c$c`3dS*19OpLV^4NI*hWWnJQ9lvzP4c;c?do zqrcsKT*i~eIHl0D3r4N{)+RsB6XhrC^;sp2cf_Eq#6*CV;t8v=V!ISe>>9kPgh}NI z=1UZutslxcT$Ad;_P^;Oouoa(cs!Ctpvi>%aQ+Zp=1d|h{W9Wmf7JWxa(~<#tSZ?C%wu4_5F!fc!<@PIBeJ)Nr^$bB6!_Gic_7}c3J{QI~Gg5g5jTp9}V6KYgrgaX>pJt}7$!wOht&KO|+z{Iw@YL|@~D zMww}+lG}rm2^peNx>58ME||ZQxFQeVSX8iogHLq_vXb`>RnoEKaTWBF-$JD#Q4BMv zt2(2Qb*x-?ur1Y(NsW8AdtX0#rDB?O(Vs4_xA(u-o!-tBG03OI!pQD+2UytbL5>lG z*(F)KacHqMa4?dxa(Vcrw>IIAeB$3cx#;;5r2X;HE8|}eYdAgCw#tpXNy7C3w1q`9 zGxZ6;@1G%8shz9e+!K2MO*{_RjO}Jo6eL3{TSZ>nY7)Qs`Dhi5><@oh0r)gT7H-?3 zLDsd^@m%JvrS8sta5`QiZNs^*GT}Hiy^zjK2^Ni%`Z|ma)D2 zuyumbvw$M8$haCTI~6M%d4+P)uX%u{Sfg4Al+F7c6;O-*)DKI7E8izSOKB#FcV{M+ zEvY0FBkq!$J0EW$Cxl}3{JwV^ki-T?q6C30Y5e&p@8Rd?$ST-Ghn*-`tB{k54W<>F z5I)TFpUC!E9298=sk>m#FI4sUDy_!8?51FqqW!9LN1(zuDnB3$!pEUjL>N>RNgAG~-9Xm|1lqHseW(%v&6K(DZ3Pano(1-Qe?3%J&>0`~w^Q-p&@ zg@HjvhJk?*hpF7$9P|gkzz`zBz_5Z!C4_-%fCcAgiSilzFQef!@amHDrW!YZS@?7C zs2Y9~>yqO+rkih?kXztzvnB^6W=f52*iyuZPv$c42$WK7>PHb z6%MYIr5D32KPdwL1hJf{_#jn?`k(taW?mwmZVvrr=y~fNcV$`}v(8};o9AjOJumS4 z`889O91^pkF+|@$d9wVoZ3;^j;^sUs&Ubo_qD&MTL%O z&*SE0ujG~zm;?x)8TLC&ft))nyI zcg44@*Q{cYT+qGrA=In_X{NNCD+B0w#;@g)jvBU;_8od6U>;7HIo@F*=g8CQUo(u^ z3r4FJ7#<@)MXO&5+DgKE&^>^`r!loe7CWE*1k0*0wLFzSOV8jvlX~WOQ?$1v zk$Or}!;ix0g78^6W;+<=J>z@CBs!<<)HvF(Ls-&`matpesJ5kkjC)6nGB@b{ii6-Uoho$BT%iJgugTOeZ$5Xo4D7Pd< zC*LJh5V@2#5%aBZCgzlQi3@<_!VfiL07ywc)ZbwKPfcR|ElQoS(8x|a7#IR}7#Io= zwg4$8S{egr-NffD)Fg&X9bJSoM25pF&%hf>(T&9bI}=#dPQyNYz;ZZ7EZ=u1n701SWKkZ9n(-qU ztN`sdWL1uxQ1mKS@x11;O|@^AD9!NeoPx}?EKIr!2>1Qq4gjfGU)tr6?Z5l7JAS3j zZeq{vG{rb%DFE4%$szK}d2UzB{4>L?Tv+NAlE*&Nq6g+XauaSI+N2Y8PJLw+aNg1p zbxr|hI8wcMP&&+(Cu|%+Jq|r>+BHk@{AvfBXKiVldN)@}TBS0LdIpnANCVE26WL-} zV}HJ^?m&$Rkq;Zf*i-hoasnpJVyTH__dbGWrB_R55d*>pTyl6(?$EO@>RCmTX1Hzr zT2)rOng?D4FfZ_C49hjMV*UonG2DlG$^+k=Y%|?Dqae4}JOU=8=fgY4Uh!pa9eEqf zFX&WLPu!jArN*^(>|H>dj~g`ONZhaaD%h_HHrHkk%d~TR_RrX{&eM#P@3x=S^%_6h zh=A)A{id16$zEFq@-D7La;kTuE!oopx^9{uA3y<}9 z^bQ@U<&pJV6kq7LRF47&!UAvgkBx=)KS_X!NY28^gQr27P=gKh0+E>$aCx&^vj2uc}ycsfSEP zedhTgUwPx%?;+dESs!g1z}5q9EC+fol}tAH9#fhZQ?q1GjyIaR@}lGCSpM-014T~l zEwriqt~ftwz=@2tn$xP&-rJt?nn5sy8sJ5Roy;pavj@O+tm}d_qmAlvhG(&k>(arz z;e|SiTr+0<&6(-An0*4{7akwUk~Yf4M!!YKj^swp9WOa%al`%R>V7mi z+5+UodFAaPdi4(8_FO&O!Ymb#@yxkuVMrog(7gkj$G@FLA#ENMxG)4f<}S%Fn?Up$+C%{02AgMKa^ z4SFGWp6U>{Q6VRJV}yjxXT*e`1XaX}(dW1F&RNhpTzvCtzuu;LMhMfJ2LBEy?{^GHG!OF!! zDvs64TG)?MX&9NCE#H3(M0K>O>`ca0WT2YR>PTe&tn?~0FV!MRtdb@v?MAUG&Ef7v zW%7>H(;Mm)RJkt18GXv!&np z?RUxOrCfs;m{fBz5MVlq59idhov21di5>WXWD-594L-X5;|@kyWi@N+(jLuh=o+5l zGGTi~)nflP_G}Yg5Pi%pl88U4+^*ihDoMP&zA*^xJE_X*Ah!jODrijCqQ^{=&hD7& z^)qv3;cu?olaT3pc{)Kcy9jA2E8I)#Kn8qO>70SQ5P8YSCN=_+_&)qg)OYBg|-k^d3*@jRAeB?;yd-O1A0wJ z?K*RDm|wE<(PBz~+C%2CTtzCTUohxP2*1kE8Of~{KRAvMrO_}NN&@P7SUO{;zx0iK z@or9R8ydYOFZf(cHASCAatL%;62IL27~SmASr(7F&NMr+#gNw@z1VM z_ALFwo3)SoANEwRerBdRV`>y`t72#aF2ConmWQp(Xy|msN9$yxhZ1jAQ67lq{vbC5 zujj|MlGo`6Bfn0TfKgi(k=gq0`K~W+X(@GzYlPI4g0M;owH3yG14rhK>lG8lS{`!K z+Nc@glT-DGz?Ym?v#Hq|_mEdPAlHH5jZuh*6glq!+>Lk$S%ED2@+ea6CE@&1-9a?s znglt|fmIK}fg<9@XgHe4*q!aO<-;Xj$T?IzB-{&2`#eA6rdtCi80mpP&vw(Uytxu$#YzNI_cB>LS zmim>ys;ir;*Dzbr22ZDxO2s;671&J0U<9(n1yj)J zHFNz=ufPcQVEG+ePjB<5C;=H0{>Mi*xD>hQq8`Vi7TjJ$V04$`h3EZGL|}a07oQdR z?{cR(z+d>arn^AUug&voOzzi$ZqaS)blz-z3zr;10x;oP2)|Cyb^WtN2*wNn`YX!Y z+$Pji<7|!XyMCEw4so}xXLU)p)BA~2fl>y2Tt}o9*BPm?AXA8UE8a;>rOgyCwZBFa zyl42y`bc3}+hiZL_|L_LY29vVerM+BVE@YxK>TGm@dHi@Uw*7AIq?QA9?THL603J% zIBJ4y3n8OFzsOI;NH%DZ!MDwMl<#$)d9eVVeqVl(5ZX$PPbt*p_(_9VSXhaUPa9Qu z7)q4vqYKX7ieVSjOmVEbLj4VYtnDpe*0Y&+>0dS^bJ<8s*eHq3tjRAw^+Mu4W^-E= z4;&namG4G;3pVDyPkUw#0kWEO1;HI6M51(1<0|*pa(I!sj}F^)avrE`ShVMKBz}nE zzKgOPMSEp6M>hJzyTHHcjV%W*;Tdb}1xJjCP#=iQuBk_Eho6yCRVp&e!}4IBJ&?ksVc&u#g3+G$oNlJ?mWfADjeBS-Ph3`DKk-~Z70XugH8sq2eba@4 zIC1H_J$`9b$K`J)sGX3d!&>OmC@@rx1TL~NinQOYy72Q_+^&Mg>Ku(fTgaXdr$p_V z#gav1o{k~c>#)u3r@~6v^o)Lf=C{rAlL@!s457pq)pO;Cojx7U{urO4cvXP|E>+dV zmr2?!-5)tk-&*ap^D^2x7NG6nOop2zNFQ9v8-EZ{WCz-h36C)<^|f{V#R_WE^@(T0+d-at5hXX{U?zak*ac-XnyINo+yBD~~3O1I=a z99|CI>502&s-Qi5bv>^2#cQ%ut<4d7KgQ^kE|=%6#VlGiY8$rdJUH{sra;P~cyb_i zeX(kS%w0C?mjhJl9TZp8RS;N~y3(EXEz13oPhOSE4WaTljGkVXWd~|#)vsG6_76I)Kb z8ro?;{j^lxNsaxE-cfP;g(e;mhh3)&ba}li?woV2#7ByioiD>s%L_D;?#;C#z;a(N z-_WY<=SH42m9bFQ>Nb z@4K$@4l8pD7AKxCR>t0%`Qoy9=hA?<<^Vcj8;-E+oBe3ReW1`el8np8E$k{LgFQ}2 z2t8a`wOXFdJ9!5$&mEfD1CnJ)TB+RJih88-Zos9@HZ# zL#{qfbF0ARTXkR@G{lwlOH~nnL)1jcyu!qv2`57S&%oKz0}r{~l9U_UHaJ5!8#nrs z?2FrL`mxnzu&{bweD&62)ilz*?pYIvt`T!XFVVA78})p1YEy7 z8fK#s?b~Yo$n7&_a?EBdXH-_W)Z44?!;DFx6pZ?~RArtBI*Qm4~6nX6Z_T*i$bQPE;Qz?DAPstpGSqr-AJ zo%m9cA`oDDm?&dTaoh_>@F>a?!y4qt_;NGN9Z<%SS;fX-cSu|>+Pba22`CRb#|HZa z;{)yHE>M-pc1C0mrnT~80!u&dvVTYFV8xTQ#g;6{c<9d!FDqU%TK5T6h*w*p980D~ zUyCb`y3{-?(mJFP)0*-Nt;mI$-gc4VQumh|rs&j_^R{sgTPF`1Xja2YWstsKFuQ(d zmZMxV$p$|qQUXchu&8%J(9|)B?`~rIx&)LqDS>ob5%gTeTP#Sbny#y*rnJ&?(l=!( zoV~}LJ1DPLnF8oyM(2ScrQ0{Q4m4-BWnS4wilgCW-~~;}pw=&<+HggRD_3c@3RQIr z9+-%!%}u_{`YS=&>h%kPO3ce}>y!d-zqiniNR-b5r97u;+K6HA2tS>Z#cV{+eFI`* zd8RMGAUtX1KWfPV;q<-5JAykS+2sY$2~UX+4461a(%{P#{rwFPu0xpIuYlbgD{C7C z=U{FUarVTYX6ZUq3wE@G^QT4H2Re;n$Fz9cJ>hABl)9T8pozqbA1)H-%1=WKm^QMu zjnUZ&Pu>q+X&6Co*y#@pxc-4waKMInEPGmE_>3@Ym3S*dedSradmc5mlJn`i0vMW6 zhBnGQD^Z;&S0lnS0curqDO@({J7kTtRE+Ra?nl^HP9<)W&C>~`!258f$XDbyQOQXG zP8hhySnarOpgu8xv8@WlXnm(Uk~)_3$Sg0vTbU3 z{W!5B(L3{Yy3K5PN<@jEarAtja`}@KYva&zFRF*s+_%jIXh$T(S=an8?=Ry3H*NRqWgsM`&!#|@kf1>=4q%bFw7^Rhz!z5I zyI^zU8_R1WN9`88Z=n>pIZQ`Ixr~_9G%Q}@A7rd#*%y7G zXl^Id=^ZL?Rx}}gWXCqzj9C6;x(~mAH|$JteXa1MH<6UQig@!Hf~t}B%tP0I|H&;y zO6N0}svOa1a^PyP9N5?4W6VF%=Bj{qHUgc8@siw4bafT=UPFSoQqKgyUX>sXTBZ=x zOh^Ad!{kOM9v{%5y}`-8u*T&C7Vq6mD%GR}UeU(*epO&qgC-CkD;%=l)ZuinSzHM` z{@`j&_vC6dDe{Yb9k@1zeV_K6!l(@=6ucoI=R^cH=6{i71%4W3$J-?<8Qn#$-DMtA z6Qqi)t?4ifrt%3jSA#6ji#{f(($KBL-iQh-xrC||3U3lq`9>r)>X%oLvtimuHW-)} zy}>9~|M>w4eES`g7;iBM%Se5-OP%1U6gNWp3AZqT8C6OlFFfQ$|7LL;tBV)(qlp4K zruar^K8FnJN3@_}B;G`a~H`t|3+6d>q3#`ctTkE-D^1#d9NalQ04lH*qUW2!V zhk7#z8OwHhSl8w14;KctfO8ubZJ4$dEdpXE78wABz=n5*=q9ex3S}`e7x~~V-jmHOhtX2*n+pBslo3uosdE7xABK=V#-t{1Hd~?i z{i~%Bw6NYF+F$aK$M`r#xe=NxhA5=p%i7!$);sd>Q}#`G?Q~fygrMXmZw?0#5#17W}6Tj+&kFexG{!mYl5FoA99}3G9l;3lVQ^ z48^~gsVppE*x91WheqI(A%F0Z#$#1UJP1R12Mj9r)y(A?a+iquX+d8WD4WAQJ_!oq z9rTISr7bPd(GTP57xm$}C}&kjMivi;zi^Y9g3&X0A;ovdJ?{%_wHgt%%9P&N4H z^XzV(uNA4 zAP`hgP6BEN5`YXh|DF~6Pud?~gWfhUKoPX4>z|}0aocC&K+AoV%|SX*N!wGq3|y< zg4lP(04XIPmt6}$N!dTk+pZv>u;MTB{L4hp9uXk7>aS!6jqM2lVr%{)H3$O127TSZ z0x9hi0k-P?nWFdQ0K`pykqUIT&jD~B0tHP{ffS(}fZ(aW$oBWTSfHO!A^><6vA?qar%tzN-5NQO zL&|F{nGiQyzNJ+bM$Y`n=Lx^3wTG^o2bGB@cwr1eb+6c-1tN=U+Db;bc~eJ!hwM{SbI=#g?$!PjDB+) zPgU_2EIxocr*EOJG52-~!gml&|D|C2OQ3Y(zAhL}iae4-Ut0F*!z!VEdfw8#`LAi# zhJ_EM*~;S|FMV6y%-SduHjPOI3cFM(GpH|HES<}*=vqY+64%dJYc|k?n6Br7)D#~# zEqO(xepfaf2F{>{E2`xb=AO%A<7RtUq6kU_Iu0m?@0K(+<}u3gVw5fy=Y4CC*{IE3 zLP3YBJ7x+U(os5=&NT%gKi23bbaZ`@;%ln)wp4GpDUT$J8NtFDHJzIe_-t}{!HAsh zJ4<^WovY};)9IKAskSebdQiXv$y5}THuJZ}ouoElIZRui=6lrupV|_Jz=9^&;@HwL;J#@23k?A;k`0Bgf;ioO>W`IQ+4? z7A)eKoY4%+g%=w;=Vm8}H>@U*=*AWNtPqgWRqib#5RTGA@Q=43FrQn3J`GkTUV5yp0U`EOTqjfp+-9;0F8!dMEwwcK%(6`8sDD^aR04 zd6O5vh|Xk?&3dy4f|1QK&Ulf{h6Iq;d-&*ti#Ck>wZFG;GHwc?b;X~eBITx49>2d8 z4HcK&1&DvEGT6kXdzAm4oO8%c}8OBt~8H956_;YP-ss*uMf==a+%w~F>Qkm7r)IAuxuoX}h92$gHqbFUun#8m zWHdy`Zrm#=Pa98x8cO0vd@Tgkr*lm0{dky+Gocr0P8y%HGEI#c3qLqIRc`Oq_C%*; zG+QTr(#Q|yHKv6R@!DmLlwJQ3FAB)Yor-I4zyDyqM4yp5n2TrQH>gRt*Zw0+WI-Sj`EgmYHh=t9! zF6lz^xpqGGpo6!5`sc0a^FVhy_Uxq|@~(1@IIzV)nTpY9sY`CV!?8e&bB8=M&sYEb z2i}fvKdhp9Hs68Y-!QJ<=wE(iQ5+49tqt;Rh|jhYrI5VW-mIz|UY{h8E=rC5sh#DU z?wGgk-Tn!I?+Zer7pHlF_Z^!Kd1qkS3&lv#%s6-<5Y%jQL${cge5=G5Ab?D&|9$Y~ zf%rJC2+=2vg;y0-SJb3<@3%}BO$T$C66q$L_H33a`VUbgW~N(4B=v5(<=My|#|J7q z*Ox4wL4kbJd_~EjLTABSu4U7Jk#`y(6O*U6(k6XxM}CtGZB(H@3~kh*zaGRXM}Iwp zQ%xFk2>@wiZrVCV_G4G~v;NebCQ%T7{SDyPpSv&dT@Cn)Mx@IK*IdNrj{*4pkV4wv z)y0J538h>cpB7iPSzA~x24T`{dzNkpvGIqvt1Dvdq@o-`B=$hkczX8$yFMhsWNK-X zxr$kR$tMD0@W)Vxe1^t9qVmsg&K^F@u84)(n2dttIEAZFN6VD$&tskpG%SI7whGL3 z)DeRiwe&?8m7U{G`oW8!SCi*dM>oYL%UKQnKxV_0RXAEBQg1kStExGEUVwLJ0orGGwb7uv+kPDl7_E2*iD|J*=8A@;XCvwq0aw5oJYN*Yh&o=l} z2z8YKb-fIAH5spql4eXqp*)o2*b>#1@DSt?zZi{GPj0gH&Nm+EI<3^z0w%YTEV4xw zI6$+=Faa|Y4o5i0zm5lOg|&tmnJ806DBovU@Ll6XsA;NRrTK~t*AAJIAS=v-UZ%Pr z$oddI@NRir&erzCwq|)ciJemr-E061j{0Vc@Ys7K(mW|JYj*$+i1Q8XlIK8T?TYS(AXu$`2U zQ@fHxc=AVHl_}cRZQ)w0anMEoqRKKIvS^`<-aMf*FM`NsG&Uowneo+Ji$7DUDYc7*Hjg;-&aHM%3 zXO6cz$$G};Uqh+iY7Wpme>PHG4cu(q;xyskNLs$^uRRMfEg?8Cj~aE-ajM%CXkx0F z>C?g3tIA#9sBQOpe`J+04{q7^TqhFk^F1jFtk4JDRO*`d-fx`GYHb=&(JiaM1b?Y^ zO3Kj3sj76ieol|N$;>j@t#tKj=@*gP+mv}KwlTcPYgR$+)2(gk)2JNE=jSauPq!$< z<|?Sb%W)wS)b>b6i{8!x!^!xIdU3{CJFVnTcw0j{M%DUCF=_>eYYEUWnA-|B(+KYL z_W_`JI&&u^@t0})@DH^1LDuT0s3dMpCHIbYBgOT4Zh_4yHbSqRbtIKndeT4Q*Jg91 z@>rO!^t-G~*AIW;FQ$3J=b;oGg8?CTa~qNCb>&cgp@e;?0AqA&paz~(%PYO+QBo4( zp?}ZdSMWx0iJm7HVNk9A#^9Osa#GPJ!_pYEW}($8>&2}fbr@&ygZ?${A7_9?X$(&5 z#~-hxdPQwCNEpf=^+WH-3`2LxrrBMTa}~qJC9S;VzhG!On^JLyW6WkF{8aAE$sM+( zxr8xLW(KIjI`Rm(24r3OJBk<3GF=G!uSP0-G&AY32mLm8q=#Xom&Pqv=1C{d3>1^ zAjsmV@XZ%BKq^eUfBpa8KvO8ob|F3hAjJv*yo2Bhl0)KUus{qA9m8jf)KnOGGTa6~4>3@J_VzkL|vYPl*uL+Ot*Q7W!f5rJw5+AsjP_IfL+-S*2p| zB7!FhjvkUTxQkGWGSg{X;h~dK>gAJivW?88Nu!3o>ySDaABn$rAYt086#27fbjPQS zhq>55ASvm*60qRdVOY9=bU^+{Pi#!OaZwENN;zy5?EztOHK-Q5;rCuiFl}BSc1YaQ zC-S{=KsGDz@Ji9O5W;XxE0xI|@3o6(2~i4b8Ii9VT;^G$*dRw(V?=br)D&q^XkeBX z+gl~+R@rVD-Hwv@7RHV?Bip5KMI)aV^&snt?H<$Nt=OPx#VxF&BGi?2A2+lNOYywNUGMeGL;|(=UjGDtLG0sN&LpGx;|U;xa13s z;W_|SPk^G}!M9_^pO zA3bt3-tca%^42sHeDtfcC0S3w3H1ny!Bxpa=*k?XRPpx9Bb-gx1J9Yvx)4J(8cG+q z(iCPZ9dsf3#QVyZgD_MW#G#qgV)olu$59&3(PzQfw@%4uZ~<5J=ABvdY43(Qnp{;G zHg3>@T#>DbTuhFl3)fb3TFqdh)V2aq7!;&JOHseTWukvA7}(iGUq;v-{2J0iHSNHq z;+)h!p6Ok^+Sp8-jgL($n6Qu47xyE`cFO5SdZR6;R!FET`tm#0D37z339Suxjpv+s z*=%2-N$N?X&0?x_uut3erF@aBGj;9$k9?3FlbDO{RQa1_qtxrh4!4#fjp4x~akvdTp@ zos?^Q&XE;3N93s4rHQGPrV7+au1$$aB6$hLy*Yz_kN$~dweb9PcB!eYVQTGjFuJP> zZCEwBtb>TIgIO^qAzq@Bv-qud_ZD-2W<_at&ml-gv`tPt$@DF5`HlA zM>DmmMkpv&Zm-8)Y#0bLQf4MpD4_-7M8eu6rh(tL8dq8onHs#R9J~dGd2IaXXMC~h z91pKhnQa%Fsn29nAA1;x(%oC zhca~qQDJaMf?wFrl-Pj;e$bZMYmMF!Y3Lv&Sb?Sjn#!NVx&NDyc^$b4uYyo2OmERa zRz;yDGd@JTykzFLe|Wk-y7#3x`6$wt$zR8r48mdUvfbeL+4D|Z``~7$PrE@qc7rZe zVsIoIbCwzjLZ@_M1*bD{HaYn();Z1-q*-I{tEnTZ(}Zmk&%MXSNBX>o| z-u*RNkAyKC-Srp7c-=@5f)xMWg>o2WWl}j6j9=8+D8;T z>0*0q#;qw8%U8i;6s0fu#I*%(g*@@a2Er@@nyI}{=@W{Z-;`=wN4N~>6Xrh&z#g}l zN1g5}0-#(nHUTv_rl2{yUZ;h#t&Fd?tY!7L%ClY)>uH-Ny2ET$lW$S)IQiN79H)D^ zb&0AXYkupy0~w8)*>Sj_p9}4L?lGTq%VG|2p`nWGhnM^!g|j-|O{%9Q%swOq63|*W zw$(N_laI}`ilB+o!a-wl?er~;;3+)$_akSQ!8YO_&-e*SI7n^(QQ;X0ZE`{4f!gAl z5$d+9CKVNonM!NO_frREICIAxOv)wm>}-k?iRisM`R7;=lyo|E_YR~FpS&PS`Lg0f zl-ON<0S%Uix8J%#yZdkCz4YNhcec<|7*P(JsM#>-L>+tYg_71q9~70FAc^6KW5jql zw!crdgVLH1G_eET=|SEc977;)ezVC|{PJZfra|}@rD;0s&@61mTEBJtILllg{%{vN zfhb&lq0yChaLhnJ-Qb62MB7`>M;|_ceHKZAeeh@#8tbrK!ArP6oXIhMK;dhEJTY`@ z0Tq>MIe0`7tGv)N*F0IGYSJv0vN?Az8g+4K9S!pW2~9F4W(_U_T=jCZrzuZ3*|__T zONp_UWmyePv8C~rckc?Xji;Z5OEqg zC*Um)i;Wh4TEwqReQdVVbUKT^2>Tpi6z_^-uF*adUFug4i@JhzpWT^Sk&E>CyP2?H zWf6x}ehuTs6wvzCnTU&gYzT029Nz19(In1WC z`(1IGmi!O%2AR|BjQa4Q0~u)kM%}?xQyjWuQ16^Gp++;`vr7!k--UZWM*~7Zl|ceO@I3`OpaRhD;YoCuo5IC0uHx>9 z478hu@H|e0Zlo)Zj@01#;8BDs@991xe~^9uG2}UXLM(m7fa}AMwX*tjioBeV&Q8Gx zSq$6wZFkRBK`cMI>R(@W@+lo2t)L+4q-negWRLWZBz*|%=W4v62JrmzNuOtA*x)QE z5L%=OH#@KMdB%Jp^r?0tE}5-*6oP`-lO7Sf)0)n*e<{HA=&qhLR)oD8-+V}Z4=md) z+k9lKf64DB2hAT)UaCP~di?-V3~JBH7itYyk~L6hrnxM%?RKntqd`=!b|e7eFnAcu z3*V;g{xr7TSTm$}DY%~SMpl>m{Sj!We+WfxSEor?YeiAxYUy25pn(?T()E>ByP^c@ zipwvWrhIK((R((VU+;@LmOnDu)ZXB3YArzzin!Z^0;PyJWnlfflo|q8(QY;o1*5CO z##hnkO{uynTMdk`~DOC#1 zdiYxQoy}=@7(ke#A8$YZZVtk4wo$8x28&I;cY3Ro-|kW=*yiiHgCLZeAr)UtVx>Tu z|LvL0hq|1-jC0I4x#>&QZCfrVB=zT!nR|~Uz`9%~2 znl{uZ{VEszW`Fad^q_HB!K9*|U-stK%?~;g?&&+12A}Rq$z($Bzuk^2X(Y=hF?-dQ ztc3DsQKI;qhWIV`99Q#R3xnU0AvY!i*BECj-z9l74|%O=V@nlv|qqC^r^-~C?E zGW%c|uYgnfJ(gjsTm_cIqcv*mYM{+i+&@F@+69ZQOK&u#v4oxUSQJ=tvqQ3W=*m;| z>SkBi8LYb-qRY7Sthh*0%3XAC%$z1rhOJzuX=PkTOa=DlocZUpE#KxVNH5)_4n=T( zGi3YrH7e~sPNYVBd~Grcq#CF~rN{p9Zza-Ntnwfma@TB)=3g36*0lSZg#ixEjFe%+ zX=&LDZ5zqculZ`=RYc^ln(~;nN|Qh6gN=!6f9-N2h+3NWbIxYud&;4SX*tWf5slk4 z{q@@l71UAZgj~*6edXb57fBUxvAS7s(RI=X868JM0+^DCn2yC>;v%S;qPOjB>YVsz(Zx9a>>BK&M zIQK>7_n)4ud0X5YM}^i*keH{ehLsiy9@NvOpsFeQjdI6anLGvVbBw_*fU1TzdVS$i z*4j7z!I5RF#rSz|8ibi$;qE{4`aqWYik7QB5U&F5C*;TO_x+gtzPGpzNt!7~nsBT7)Ckc(K~%uv&{{6A`mmBJVAk-{s~52Vu|HbCH7_W1~ZCX^RflOakGg=jo2Z z<*s;5-J+2@^LRDZ-7EV&Pq+FTErw@pfFqvx^i%E7Fx#^n(E`m2(c>K-O5`M`Yek9el zzTGs5qD6*G;y#~xu3>qWuO?-amKYtvRA}I9z#UspEeM;wOERYeot_n_EUMJf$4_u?E!6X~?q)tPoZb^_;8Y_Ox2h1m<+Le-fsRd|T8db<8#$bqez zua^Z|>h%zdnuU^ww$#-dZ9NTM`FN+!IlLkz*FqWb!x^Z|C{KyGjZ+>G;;7Mb@LY|H zc+Gp`L((Dw7pnDlHNm&;SfHedhx*kad$I^uGz{`0BYelq0yEUHpNKSkvj$|dpvY3{7*YGyhXA^LP0&wOw9oNoC=QoVx1<2Dne8qqZL zm>nFh5DX(-RnQwvHCZQwn^#Z=E!SPVlaRJ78Bo@}!!9dRt^qZy?-*`Pt4WSmgucJv zV1yFkcjlEM^uz-;b#Q7ZCP@Lk)m}uPX={R4B=56k7WNh11BN~0T*vr@!!ow^B0hOR zQ)4)&(e%>bNNL%bm<&8H{*l_L7s0$2GUgX2Vd;=4d9Dm2v3TaL+;L>{K7h7 zV#k?xDPm(NDE31$ z<}|X)pEY6myjK+^gaIMk&Yj2~F0rSKemNqlsVm4c|N7mp_C*L01s;GNx#D-*&gk!qQr}^?_r@q!8fuXw!)fA7xkd} zb>vHvdx~H$5qqAWrow7}+8zBM65-JOt5z za=T6f7MK`XJuQog8kIEboPdhcaVJeHy)5z7EBLK5NRr()E|#K0L0N^JD@pUA^Czb` zbUZ_558y+vqAGeyHCbrvOvLD67Ph}06959VzQ_|>RrXQAqE+AQ(-AaKdxoWaF8hdt z{O3W@b^*o#-f1VuU>YMV03ELF7zkCN4Q&b#prz%3Nne0lSbRo@@ z^ihv%oIl~Qyl6Q;a#$*jOC%x0_;eis*)J7=f@Ct*)xF5 zo}u~@-I}2|$b%5L7>@+Z?4o+1r&v6ceIy+vroK&jCQ<4q&45HP2wCol4hVm3pZtjf zHz1D7oyaSKJ~T{Gx}7ONLA)D5k(%%`WswrDyzX*rn}i}}TB4^y#@mAwPzoC)`?rYv zHgx|trUN#mu*VzUV~8TnJM2Qh*ZM5B{x&y>5An`(M7=Z*Q>TdiH@j*2=moNuOtvpz z+G`@~-`%~+AgPKgke@XiRPgndh@bp*-HRsh;HTtz@-y_uhb%7ylVOTqG0#u?Vn5c5 zEp*XRo|8hcgG^$#{$O9CJ&NE;TrfRpSnLmes&MO{m=N%zc`}gb!eQ7odl$oy1%PI} z#AIxx%oRVy&{O~9xnK4$EY>(eQj}!HKIV$Fz*H=-=Kn)N0D6u`(;iO|VraI4fu_W` z;b5{7;Lyx4za}DU#+U7}=H0dAS#YJJ&g2!P@Htu-AL&w=-)*%P9h2{wR|@?Ff9~)b z^+e_3Hetq7W%ls{!?<6&Y$Z;NNB41pvrv)|MET6AZXFXJeFqbFW5@i5WGzl?bP+~? z*&_puH;wKv2)9T_d+P`bLvJFqX#j&xa*-;0nGBbQf0DC>o~=J_Wmtf*2SZQr?{i~X z9-IbRH8{iy?<0v9Ir1?$66+igy|yDQ5J~A9sFX@Pe<*kCY8+MwH?I z`P}zfQ6l^AO8ehZ=l^ZR;R%uu4;BK*=?W9t|0{+-at(MQZ(CtG=EJFNaFMlKCMXu30(gJUqj5+ z`GM|!keqcj;FKTa_qq;{*dHRXAq157hlB@kL#8%yAm2AgfU|*rDKX@FLlp=HL8ddv zAWLCHe@DcDeB2}fl7#=0+#<05c3=VqM*O3bkr@9X4nO|)q0hU;Gye{L8ZN*NH8Id@mP-u;Fmb8YuorjLrW&ndip8CN%_qp982r w1WEnz9^$&s1hkp_3#lPJQ~!HI7WYYjA7>z!`?f%npAh2%rB@vD|Lau$2O)#1n*aa+ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ee6ba9a3ac..dcf5e2cb7b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=c9490e938b221daf0094982288e4038deed954a3f12fb54cbf270ddf4e37d879 -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip +distributionSha256Sum=cd5c2958a107ee7f0722004a12d0f8559b4564c34daad7df06cffd4d12a426d0 +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From c28a20dce3c94460e84fe8a29602436a95268ce3 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 9 Feb 2022 12:55:33 +0100 Subject: [PATCH 024/302] Bump versions to 1.4.2 --- matrix-sdk-android/build.gradle | 2 +- vector/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index e1877d5f71..ead4d4f397 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -31,7 +31,7 @@ android { // that the app's state is completely cleared between tests. testInstrumentationRunnerArguments clearPackageData: 'true' - buildConfigField "String", "SDK_VERSION", "\"1.3.19\"" + buildConfigField "String", "SDK_VERSION", "\"1.4.2\"" buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\"" resValue "string", "git_sdk_revision", "\"${gitRevision()}\"" diff --git a/vector/build.gradle b/vector/build.gradle index feaa21d71a..63c749daeb 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -18,7 +18,7 @@ ext.versionMinor = 4 // Note: even values are reserved for regular release, odd values for hotfix release. // When creating a hotfix, you should decrease the value, since the current value // is the value for the next regular release. -ext.versionPatch = 0 +ext.versionPatch = 2 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' From f78446c1e7996b9de46c03345453fbb5404df4bf Mon Sep 17 00:00:00 2001 From: NIkita Fedrunov Date: Wed, 9 Feb 2022 14:23:45 +0100 Subject: [PATCH 025/302] Click replaced with Compose on message sent Identity replaced with UserProperty added missing param for JoinedRoom --- .../app/features/analytics/AnalyticsTracker.kt | 4 ++-- .../features/analytics/extensions/JoinedRoomExt.kt | 3 +++ .../{IdentityExt.kt => UserPropertiesExt.kt} | 12 ++++++------ .../analytics/impl/DefaultVectorAnalytics.kt | 6 +++--- .../features/home/room/detail/TimelineFragment.kt | 6 ++++-- .../app/features/onboarding/OnboardingViewModel.kt | 6 +++--- .../roompreview/RoomPreviewViewModel.kt | 1 + 7 files changed, 22 insertions(+), 16 deletions(-) rename vector/src/main/java/im/vector/app/features/analytics/extensions/{IdentityExt.kt => UserPropertiesExt.kt} (60%) diff --git a/vector/src/main/java/im/vector/app/features/analytics/AnalyticsTracker.kt b/vector/src/main/java/im/vector/app/features/analytics/AnalyticsTracker.kt index e85919a45f..2389fbd724 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/AnalyticsTracker.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/AnalyticsTracker.kt @@ -18,7 +18,7 @@ package im.vector.app.features.analytics import im.vector.app.features.analytics.itf.VectorAnalyticsEvent import im.vector.app.features.analytics.itf.VectorAnalyticsScreen -import im.vector.app.features.analytics.plan.Identity +import im.vector.app.features.analytics.plan.UserProperties interface AnalyticsTracker { /** @@ -34,5 +34,5 @@ interface AnalyticsTracker { /** * Update user specific properties */ - fun updateUserProperties(identity: Identity) + fun updateUserProperties(userProperties: UserProperties) } diff --git a/vector/src/main/java/im/vector/app/features/analytics/extensions/JoinedRoomExt.kt b/vector/src/main/java/im/vector/app/features/analytics/extensions/JoinedRoomExt.kt index ff23fd9a64..c13f8295f2 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/extensions/JoinedRoomExt.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/extensions/JoinedRoomExt.kt @@ -19,6 +19,7 @@ package im.vector.app.features.analytics.extensions import im.vector.app.features.analytics.plan.JoinedRoom import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.room.model.RoomSummary +import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom fun Int?.toAnalyticsRoomSize(): JoinedRoom.RoomSize { @@ -35,6 +36,7 @@ fun Int?.toAnalyticsRoomSize(): JoinedRoom.RoomSize { fun RoomSummary?.toAnalyticsJoinedRoom(): JoinedRoom { return JoinedRoom( isDM = this?.isDirect.orFalse(), + isSpace = this?.roomType == RoomType.SPACE, roomSize = this?.joinedMembersCount?.toAnalyticsRoomSize() ?: JoinedRoom.RoomSize.Two ) } @@ -42,6 +44,7 @@ fun RoomSummary?.toAnalyticsJoinedRoom(): JoinedRoom { fun PublicRoom.toAnalyticsJoinedRoom(): JoinedRoom { return JoinedRoom( isDM = false, + isSpace = false, roomSize = numJoinedMembers.toAnalyticsRoomSize() ) } diff --git a/vector/src/main/java/im/vector/app/features/analytics/extensions/IdentityExt.kt b/vector/src/main/java/im/vector/app/features/analytics/extensions/UserPropertiesExt.kt similarity index 60% rename from vector/src/main/java/im/vector/app/features/analytics/extensions/IdentityExt.kt rename to vector/src/main/java/im/vector/app/features/analytics/extensions/UserPropertiesExt.kt index d87769fd36..7fad43783b 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/extensions/IdentityExt.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/extensions/UserPropertiesExt.kt @@ -16,14 +16,14 @@ package im.vector.app.features.analytics.extensions -import im.vector.app.features.analytics.plan.Identity +import im.vector.app.features.analytics.plan.UserProperties import im.vector.app.features.onboarding.FtueUseCase -fun FtueUseCase.toTrackingValue(): Identity.FtueUseCaseSelection { +fun FtueUseCase.toTrackingValue(): UserProperties.FtueUseCaseSelection { return when (this) { - FtueUseCase.FRIENDS_FAMILY -> Identity.FtueUseCaseSelection.PersonalMessaging - FtueUseCase.TEAMS -> Identity.FtueUseCaseSelection.WorkMessaging - FtueUseCase.COMMUNITIES -> Identity.FtueUseCaseSelection.CommunityMessaging - FtueUseCase.SKIP -> Identity.FtueUseCaseSelection.Skip + FtueUseCase.FRIENDS_FAMILY -> UserProperties.FtueUseCaseSelection.PersonalMessaging + FtueUseCase.TEAMS -> UserProperties.FtueUseCaseSelection.WorkMessaging + FtueUseCase.COMMUNITIES -> UserProperties.FtueUseCaseSelection.CommunityMessaging + FtueUseCase.SKIP -> UserProperties.FtueUseCaseSelection.Skip } } diff --git a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt index 62d360f5f7..83e21ced03 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt @@ -26,7 +26,7 @@ import im.vector.app.features.analytics.VectorAnalytics import im.vector.app.features.analytics.itf.VectorAnalyticsEvent import im.vector.app.features.analytics.itf.VectorAnalyticsScreen import im.vector.app.features.analytics.log.analyticsTag -import im.vector.app.features.analytics.plan.Identity +import im.vector.app.features.analytics.plan.UserProperties import im.vector.app.features.analytics.store.AnalyticsStore import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.Flow @@ -175,8 +175,8 @@ class DefaultVectorAnalytics @Inject constructor( ?.screen(screen.getName(), screen.getProperties()?.toPostHogProperties()) } - override fun updateUserProperties(identity: Identity) { - posthog?.identify(REUSE_EXISTING_ID, identity.getProperties().toPostHogProperties(), IGNORED_OPTIONS) + override fun updateUserProperties(userProperties: UserProperties) { + posthog?.identify(REUSE_EXISTING_ID, userProperties.getProperties().toPostHogProperties(), IGNORED_OPTIONS) } private fun Map?.toPostHogProperties(): Properties? { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 2da69bbe6c..c757fd02ba 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -119,7 +119,7 @@ import im.vector.app.core.utils.startInstallFromSourceIntent import im.vector.app.core.utils.toast import im.vector.app.databinding.DialogReportContentBinding import im.vector.app.databinding.FragmentTimelineBinding -import im.vector.app.features.analytics.plan.Click +import im.vector.app.features.analytics.plan.Composer import im.vector.app.features.analytics.plan.Screen import im.vector.app.features.attachments.AttachmentTypeSelectorView import im.vector.app.features.attachments.AttachmentsHelper @@ -1499,7 +1499,9 @@ class TimelineFragment @Inject constructor( return } if (text.isNotBlank()) { - analyticsTracker.capture(Click(name = Click.Name.SendMessageButton)) + withState(messageComposerViewModel) { state -> + analyticsTracker.capture(Composer(isThreadTimeLine(), isEditing = state.sendMode is SendMode.Edit, isReply = state.sendMode is SendMode.Reply)) + } // We collapse ASAP, if not there will be a slight annoying delay views.composerLayout.collapse(true) lockSendButton = true diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 8097e90206..0d05a38dfa 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -39,7 +39,7 @@ import im.vector.app.core.utils.ensureTrailingSlash import im.vector.app.features.VectorFeatures import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.extensions.toTrackingValue -import im.vector.app.features.analytics.plan.Identity +import im.vector.app.features.analytics.plan.UserProperties import im.vector.app.features.login.HomeServerConnectionConfigFactory import im.vector.app.features.login.LoginConfig import im.vector.app.features.login.LoginMode @@ -465,13 +465,13 @@ class OnboardingViewModel @AssistedInject constructor( private fun handleUpdateUseCase(action: OnboardingAction.UpdateUseCase) { setState { copy(useCase = action.useCase) } - analyticsTracker.updateUserProperties(Identity(ftueUseCaseSelection = action.useCase.toTrackingValue())) + analyticsTracker.updateUserProperties(UserProperties(ftueUseCaseSelection = action.useCase.toTrackingValue())) _viewEvents.post(OnboardingViewEvents.OpenServerSelection) } private fun resetUseCase() { setState { copy(useCase = null) } - analyticsTracker.updateUserProperties(Identity(ftueUseCaseSelection = null)) + analyticsTracker.updateUserProperties(UserProperties(ftueUseCaseSelection = null)) } private fun handleUpdateServerType(action: OnboardingAction.UpdateServerType) { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt index b1fa0e974a..42bec8c8b3 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt @@ -251,6 +251,7 @@ class RoomPreviewViewModel @AssistedInject constructor( analyticsTracker.capture(JoinedRoom( // Always false in this case (?) isDM = false, + isSpace = false, roomSize = state.numJoinMembers.toAnalyticsRoomSize() )) // We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data. From e196b010388799f0948c5a5452c6d52f0dcf6c2d Mon Sep 17 00:00:00 2001 From: NIkita Fedrunov Date: Wed, 9 Feb 2022 15:55:22 +0100 Subject: [PATCH 026/302] synced with latest changes in analytics repo --- .../features/analytics/plan/Interaction.kt | 30 +++++ .../app/features/analytics/plan/Screen.kt | 120 ++++++++++++++---- .../features/analytics/plan/UserProperties.kt | 26 +++- 3 files changed, 148 insertions(+), 28 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt index 3d71b36c51..feffa6d5c6 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt @@ -51,6 +51,18 @@ data class Interaction( */ SpacePanelSwitchSpace, + /** + * User interacted with pin to sidebar checkboxes in the quick settings + * menu of Element Web/Desktop. + */ + WebQuickSettingsPinToSidebarCheckbox, + + /** + * User interacted with the theme dropdown in the quick settings menu of + * Element Web/Desktop. + */ + WebQuickSettingsThemeDropdown, + /** * User accessed the room invite flow using the button at the top of the * room member list in the right panel of Element Web/Desktop. @@ -152,6 +164,24 @@ data class Interaction( * settings dialog in Element Web/Desktop. */ WebRoomSettingsLeaveButton, + + /** + * User interacted with the theme radio selector in the Appearance tab + * of Settings in Element Web/Desktop. + */ + WebSettingsAppearanceTabThemeSelector, + + /** + * User interacted with the pre-built space checkboxes in the Sidebar + * tab of Settings in Element Web/Desktop. + */ + WebSettingsSidebarTabSpacesCheckbox, + + /** + * User clicked the theme toggle button in the user menu of Element + * Web/Desktop. + */ + WebUserMenuThemeToggleButton, } enum class InteractionType { diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt index 476c72fa30..710ae8f6f2 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt @@ -54,8 +54,8 @@ data class Screen( Group, /** - * The Home tab on iOS | possibly the same on Android? | The Home space - * on Web? + * The Home tab on iOS | possibly the same on Android? | Home page on + * Web */ Home, @@ -116,13 +116,33 @@ data class Screen( */ MobileSearchRooms, + /** + * The global settings screen shown in the app. + */ + MobileSettings, + + /** + * The settings screen to change the default notification options. + */ + MobileSettingsDefaultNotifications, + + /** + * The settings screen to manage notification mentions and keywords. + */ + MobileSettingsMentionsAndKeywords, + + /** + * The global security settings screen. + */ + MobileSettingsSecurity, + /** * The sidebar shown on mobile with spaces, settings etc. */ MobileSidebar, /** - * Screen that displays the list of memebrs of a space + * Screen that displays the list of members of a space */ MobileSpaceMembers, @@ -196,26 +216,6 @@ data class Screen( */ RoomUploads, - /** - * The global settings screen shown in the app. - */ - Settings, - - /** - * The settings screen to change the default notification options. - */ - SettingsDefaultNotifications, - - /** - * The settings screen to manage notification mentions and keywords. - */ - SettingsMentionsAndKeywords, - - /** - * The global security settings screen. - */ - SettingsSecurity, - /** * Screen that displays the list of rooms and spaces of a space */ @@ -232,25 +232,91 @@ data class Screen( User, /** - * ? + * Element Web showing flow to trust this new device with cross-signing. */ WebCompleteSecurity, /** - * ? + * Element Web showing flow to setup SSSS / cross-signing on this + * account. */ WebE2ESetup, /** - * ? + * Element Web loading spinner. */ WebLoading, /** - * ? + * Element Web device has been soft logged out by the server. */ WebSoftLogout, + /** + * Legacy: Element Web User Settings Flair Tab. + */ + WebUserSettingFlair, + + /** + * Element Web User Settings Mjolnir (labs) Tab. + */ + WebUserSettingMjolnir, + + /** + * Element Web User Settings Appearance Tab. + */ + WebUserSettingsAppearance, + + /** + * Element Web User Settings General Tab. + */ + WebUserSettingsGeneral, + + /** + * Element Web User Settings Help & About Tab. + */ + WebUserSettingsHelpAbout, + + /** + * Element Web User Settings Ignored Users Tab. + */ + WebUserSettingsIgnoredUsers, + + /** + * Element Web User Settings Keyboard Tab. + */ + WebUserSettingsKeyboard, + + /** + * Element Web User Settings Labs Tab. + */ + WebUserSettingsLabs, + + /** + * Element Web User Settings Notifications Tab. + */ + WebUserSettingsNotifications, + + /** + * Element Web User Settings Preferences Tab. + */ + WebUserSettingsPreferences, + + /** + * Element Web User Settings Security & Privacy Tab. + */ + WebUserSettingsSecurityPrivacy, + + /** + * Element Web User Settings Sidebar Tab. + */ + WebUserSettingsSidebar, + + /** + * Element Web User Settings Voice & Video Tab. + */ + WebUserSettingsVoiceVideo, + /** * The splash screen. */ diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt index 453cd0ec9d..bbe2c48fec 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt @@ -24,6 +24,26 @@ package im.vector.app.features.analytics.plan * definition. These properties must all be device independent. */ data class UserProperties( + /** + * Whether the user has the favourites space enabled + */ + val WebMetaSpaceFavouritesEnabled: Boolean? = null, + /** + * Whether the user has the home space set to all rooms + */ + val WebMetaSpaceHomeAllRooms: Boolean? = null, + /** + * Whether the user has the home space enabled + */ + val WebMetaSpaceHomeEnabled: Boolean? = null, + /** + * Whether the user has the other rooms space enabled + */ + val WebMetaSpaceOrphansEnabled: Boolean? = null, + /** + * Whether the user has the people space enabled + */ + val WebMetaSpacePeopleEnabled: Boolean? = null, /** * The selected messaging use case during the onboarding flow. */ @@ -56,9 +76,13 @@ data class UserProperties( WorkMessaging, } - fun getProperties(): Map? { return mutableMapOf().apply { + WebMetaSpaceFavouritesEnabled?.let { put("WebMetaSpaceFavouritesEnabled", it) } + WebMetaSpaceHomeAllRooms?.let { put("WebMetaSpaceHomeAllRooms", it) } + WebMetaSpaceHomeEnabled?.let { put("WebMetaSpaceHomeEnabled", it) } + WebMetaSpaceOrphansEnabled?.let { put("WebMetaSpaceOrphansEnabled", it) } + WebMetaSpacePeopleEnabled?.let { put("WebMetaSpacePeopleEnabled", it) } ftueUseCaseSelection?.let { put("ftueUseCaseSelection", it.name) } numSpaces?.let { put("numSpaces", it) } }.takeIf { it.isNotEmpty() } From cc4228ed266781477064559b1730a0c810e13db0 Mon Sep 17 00:00:00 2001 From: NIkita Fedrunov Date: Wed, 9 Feb 2022 16:07:47 +0100 Subject: [PATCH 027/302] use new screen name constants --- .../vector/app/features/settings/VectorSettingsRootFragment.kt | 2 +- .../features/settings/VectorSettingsSecurityPrivacyFragment.kt | 2 +- .../VectorSettingsDefaultNotificationPreferenceFragment.kt | 2 +- ...rSettingsKeywordAndMentionsNotificationPreferenceFragment.kt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt index fb5d83239b..cd76efac58 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt @@ -29,7 +29,7 @@ class VectorSettingsRootFragment @Inject constructor() : VectorSettingsBaseFragm override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.Settings + analyticsScreenName = Screen.ScreenName.MobileSettings } override fun bindPref() { diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index 31fce00f3c..e4e287e83a 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -94,7 +94,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.SettingsSecurity + analyticsScreenName = Screen.ScreenName.MobileSettingsSecurity } // cryptography diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt index b6f2098209..27007744c8 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt @@ -38,7 +38,7 @@ class VectorSettingsDefaultNotificationPreferenceFragment : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.SettingsDefaultNotifications + analyticsScreenName = Screen.ScreenName.MobileSettingsDefaultNotifications } override fun bindPref() { diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt index b7cf7f6bbe..dd3b899fcc 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt @@ -45,7 +45,7 @@ class VectorSettingsKeywordAndMentionsNotificationPreferenceFragment : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.SettingsMentionsAndKeywords + analyticsScreenName = Screen.ScreenName.MobileSettingsMentionsAndKeywords } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { From 911ee971220522d1d049e1c27b5c1ba8c71b85f2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 9 Feb 2022 21:29:03 +0100 Subject: [PATCH 028/302] Reactions: start handling show more, show less and add more actions in timeline. --- .../ui-styles/src/main/res/values/dimens.xml | 2 + .../home/room/detail/TimelineFragment.kt | 10 ++- .../timeline/TimelineEventController.kt | 10 ++- .../helper/MessageInformationDataFactory.kt | 10 +-- .../helper/ReactionsSummaryFactory.kt | 66 ++++++++++++++++ .../timeline/item/AbsBaseMessageItem.kt | 78 ++++++++++++++----- .../timeline/item/MessageInformationData.kt | 13 +++- .../reactions/widget/ReactionButton.kt | 2 +- .../res/drawable/ic_add_reaction_small.xml | 4 + vector/src/main/res/values/strings.xml | 3 + 10 files changed, 166 insertions(+), 32 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ReactionsSummaryFactory.kt create mode 100644 vector/src/main/res/drawable/ic_add_reaction_small.xml diff --git a/library/ui-styles/src/main/res/values/dimens.xml b/library/ui-styles/src/main/res/values/dimens.xml index be57f75dc8..9a3929094a 100644 --- a/library/ui-styles/src/main/res/values/dimens.xml +++ b/library/ui-styles/src/main/res/values/dimens.xml @@ -61,6 +61,8 @@ 300dp 12dp + 30dp + 0.05 0.95 diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 2da69bbe6c..0821574c96 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -1913,6 +1913,10 @@ class TimelineFragment @Inject constructor( timelineViewModel.handle(RoomDetailAction.LoadMoreTimelineEvents(direction)) } + override fun onAddMoreReaction(event: TimelineEvent) { + openEmojiReactionPicker(event.eventId) + } + override fun onEventCellClicked(informationData: MessageInformationData, messageContent: Any?, view: View, isRootThreadEvent: Boolean) { when (messageContent) { is MessageVerificationRequestContent -> { @@ -2117,7 +2121,7 @@ class TimelineFragment @Inject constructor( openRoomMemberProfile(action.userId) } is EventSharedAction.AddReaction -> { - emojiActivityResultLauncher.launch(EmojiReactionPickerActivity.intent(requireContext(), action.eventId)) + openEmojiReactionPicker(action.eventId) } is EventSharedAction.ViewReactions -> { ViewReactionsBottomSheet.newInstance(timelineArgs.roomId, action.messageInformationData) @@ -2239,6 +2243,10 @@ class TimelineFragment @Inject constructor( } } + private fun openEmojiReactionPicker(eventId: String) { + emojiActivityResultLauncher.launch(EmojiReactionPickerActivity.intent(requireContext(), eventId)) + } + private fun askConfirmationToEndPoll(eventId: String) { MaterialAlertDialogBuilder(requireContext(), R.style.ThemeOverlay_Vector_MaterialAlertDialog) .setTitle(R.string.end_poll_confirmation_title) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt index 2ac592797c..9875c41a80 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt @@ -43,6 +43,7 @@ import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadSt import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder import im.vector.app.features.home.room.detail.timeline.helper.TimelineControllerInterceptorHelper import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventDiffUtilCallback +import im.vector.app.features.home.room.detail.timeline.helper.ReactionsSummaryFactory import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventVisibilityHelper import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventVisibilityStateChangedListener import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventsGroups @@ -86,7 +87,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec @TimelineEventControllerHandler private val backgroundHandler: Handler, private val timelineEventVisibilityHelper: TimelineEventVisibilityHelper, - private val readReceiptsItemFactory: ReadReceiptsItemFactory + private val readReceiptsItemFactory: ReadReceiptsItemFactory, + private val reactionListFactory: ReactionsSummaryFactory ) : EpoxyController(backgroundHandler, backgroundHandler), Timeline.Listener, EpoxyController.Interceptor { /** @@ -138,6 +140,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec fun getPreviewUrlRetriever(): PreviewUrlRetriever fun onVoiceControlButtonClicked(eventId: String, messageAudioContent: MessageAudioContent) + + fun onAddMoreReaction(event: TimelineEvent) } interface ReactionPillCallback { @@ -283,6 +287,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec super.onAttachedToRecyclerView(recyclerView) timeline?.addListener(this) timelineMediaSizeProvider.recyclerView = recyclerView + reactionListFactory.onRequestBuild = { requestModelBuild() } } override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) { @@ -290,6 +295,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec contentUploadStateTrackerBinder.clear() contentDownloadStateTrackerBinder.clear() timeline?.removeListener(this) + reactionListFactory.onRequestBuild = null super.onDetachedFromRecyclerView(recyclerView) } @@ -383,7 +389,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec val event = currentSnapshot[position] val nextEvent = currentSnapshot.nextOrNull(position) // Should be build if not cached or if model should be refreshed - if (modelCache[position] == null || modelCache[position]?.isCacheable(partialState) == false) { + if (modelCache[position] == null || modelCache[position]?.isCacheable(partialState) == false || reactionListFactory.needsRebuild(event)) { val prevEvent = currentSnapshot.prevOrNull(position) val prevDisplayableEvent = currentSnapshot.subList(0, position).lastOrNull { timelineEventVisibilityHelper.shouldShowEvent( diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt index 276802e574..2bd2257cf7 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt @@ -24,7 +24,6 @@ import im.vector.app.features.home.room.detail.timeline.item.E2EDecoration import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData import im.vector.app.features.home.room.detail.timeline.item.PollResponseData import im.vector.app.features.home.room.detail.timeline.item.PollVoteSummaryData -import im.vector.app.features.home.room.detail.timeline.item.ReactionInfoData import im.vector.app.features.home.room.detail.timeline.item.ReferencesInfoData import im.vector.app.features.home.room.detail.timeline.item.SendStateDecoration import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayoutFactory @@ -50,7 +49,8 @@ import javax.inject.Inject */ class MessageInformationDataFactory @Inject constructor(private val session: Session, private val dateFormatter: VectorDateFormatter, - private val messageLayoutFactory: TimelineMessageLayoutFactory) { + private val messageLayoutFactory: TimelineMessageLayoutFactory, + private val reactionListFactory: ReactionsSummaryFactory) { fun create(params: TimelineItemFactoryParams): MessageInformationData { val event = params.event @@ -93,11 +93,7 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses avatarUrl = event.senderInfo.avatarUrl, memberName = event.senderInfo.disambiguatedDisplayName, messageLayout = messageLayout, - orderedReactionList = event.annotations?.reactionsSummary - // ?.filter { isSingleEmoji(it.key) } - ?.map { - ReactionInfoData(it.key, it.count, it.addedByMe, it.localEchoEvents.isEmpty()) - }, + reactionsSummary = reactionListFactory.create(event, params.callback), pollResponseAggregatedSummary = event.annotations?.pollResponseSummary?.let { PollResponseData( myVote = it.aggregatedContent?.myVote, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ReactionsSummaryFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ReactionsSummaryFactory.kt new file mode 100644 index 0000000000..e811d704d7 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ReactionsSummaryFactory.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 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.home.room.detail.timeline.helper + +import dagger.hilt.android.scopes.ActivityScoped +import im.vector.app.features.home.room.detail.RoomDetailAction +import im.vector.app.features.home.room.detail.timeline.TimelineEventController +import im.vector.app.features.home.room.detail.timeline.item.ReactionInfoData +import im.vector.app.features.home.room.detail.timeline.item.ReactionsSummaryData +import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent +import javax.inject.Inject + +@ActivityScoped +class ReactionsSummaryFactory @Inject constructor() { + + var onRequestBuild: (() -> Unit)? = null + private val showAllReactionsByEvent = HashSet() + private val eventsRequestingBuild = HashSet() + + fun needsRebuild(event: TimelineEvent): Boolean { + return eventsRequestingBuild.remove(event.eventId) + } + + fun create(event: TimelineEvent, callback: TimelineEventController.Callback?): ReactionsSummaryData { + val eventId = event.eventId + val showAllStates = showAllReactionsByEvent.contains(eventId) + val reactions = event.annotations?.reactionsSummary + ?.map { + ReactionInfoData(it.key, it.count, it.addedByMe, it.localEchoEvents.isEmpty()) + } + return ReactionsSummaryData( + reactions = reactions, + showAll = showAllStates, + onShowMoreClicked = { + showAllReactionsByEvent.add(eventId) + onRequestBuild(eventId) + }, + onShowLessClicked = { + showAllReactionsByEvent.remove(eventId) + onRequestBuild(eventId) + }, + onAddMoreClicked = { + callback?.onAddMoreReaction(event) + } + ) + } + + private fun onRequestBuild(eventId: String) { + eventsRequestingBuild.add(eventId) + onRequestBuild?.invoke() + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt index 9621b1c2f9..6d0714e929 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt @@ -16,11 +16,15 @@ package im.vector.app.features.home.room.detail.timeline.item +import android.annotation.SuppressLint +import android.content.Context +import android.view.Gravity import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.annotation.IdRes +import androidx.core.content.ContextCompat.getDrawable import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.core.epoxy.ClickListener @@ -65,27 +69,10 @@ abstract class AbsBaseMessageItem : BaseEventItem return listOf(baseAttributes.informationData.eventId) } + @SuppressLint("SetTextI18n") override fun bind(holder: H) { super.bind(holder) - val reactions = baseAttributes.informationData.orderedReactionList - if (!shouldShowReactionAtBottom() || reactions.isNullOrEmpty()) { - holder.reactionsContainer.isVisible = false - } else { - holder.reactionsContainer.isVisible = true - holder.reactionsContainer.removeAllViews() - reactions.take(8).forEach { reaction -> - val reactionButton = ReactionButton(holder.view.context) - reactionButton.reactedListener = reactionClickListener - reactionButton.setTag(R.id.reactionsContainer, reaction.key) - reactionButton.reactionString = reaction.key - reactionButton.reactionCount = reaction.count - reactionButton.setChecked(reaction.addedByMe) - reactionButton.isEnabled = reaction.synced - holder.reactionsContainer.addView(reactionButton) - } - holder.reactionsContainer.setOnLongClickListener(baseAttributes.itemLongClickListener) - } - + renderReactions(holder, baseAttributes.informationData.reactionsSummary) when (baseAttributes.informationData.e2eDecoration) { E2EDecoration.NONE -> { holder.e2EDecorationView.render(null) @@ -102,6 +89,59 @@ abstract class AbsBaseMessageItem : BaseEventItem (holder.view as? TimelineMessageLayoutRenderer)?.renderMessageLayout(baseAttributes.informationData.messageLayout) } + private fun renderReactions(holder: H, reactionsSummary: ReactionsSummaryData) { + val reactions = reactionsSummary.reactions + if (!shouldShowReactionAtBottom() || reactions.isNullOrEmpty()) { + holder.reactionsContainer.isVisible = false + } else { + holder.reactionsContainer.isVisible = true + holder.reactionsContainer.removeAllViews() + val reactionsToShow = if (reactionsSummary.showAll) { + reactions + } else { + reactions.take(8) + } + reactionsToShow.forEach { reaction -> + val reactionButton = ReactionButton(holder.view.context) + reactionButton.reactedListener = reactionClickListener + reactionButton.setTag(R.id.reactionsContainer, reaction.key) + reactionButton.reactionString = reaction.key + reactionButton.reactionCount = reaction.count + reactionButton.setChecked(reaction.addedByMe) + reactionButton.isEnabled = reaction.synced + holder.reactionsContainer.addView(reactionButton) + } + if (reactions.count() > 8) { + val showReactionsTextView = createReactionTextView(holder.view.context) + if (reactionsSummary.showAll) { + showReactionsTextView.setText(R.string.message_reaction_show_less) + showReactionsTextView.onClick { reactionsSummary.onShowLessClicked() } + } else { + val moreCount = reactions.count() - 8 + showReactionsTextView.text = holder.view.resources.getString(R.string.message_reaction_show_more, moreCount) + showReactionsTextView.onClick { reactionsSummary.onShowMoreClicked() } + } + holder.reactionsContainer.addView(showReactionsTextView) + } + val addMoreReactionsTextView = createReactionTextView(holder.view.context) + addMoreReactionsTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_add_reaction_small, 0, 0, 0) + addMoreReactionsTextView.onClick { reactionsSummary.onAddMoreClicked() } + holder.reactionsContainer.addView(addMoreReactionsTextView) + holder.reactionsContainer.setOnLongClickListener(baseAttributes.itemLongClickListener) + } + } + + private fun createReactionTextView(context: Context): TextView { + return TextView(context).apply { + textSize = 10f + gravity = Gravity.CENTER + minimumHeight = resources.getDimensionPixelSize(R.dimen.chat_reaction_min_height) + background = getDrawable(context, R.drawable.reaction_rounded_rect_shape_off) + val padding = resources.getDimensionPixelSize(R.dimen.layout_horizontal_margin) + setPadding(padding, 0, padding, 0) + } + } + override fun unbind(holder: H) { holder.reactionsContainer.setOnLongClickListener(null) super.unbind(holder) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageInformationData.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageInformationData.kt index 629d20e898..2b68742e7e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageInformationData.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageInformationData.kt @@ -33,8 +33,7 @@ data class MessageInformationData( val avatarUrl: String?, val memberName: CharSequence? = null, val messageLayout: TimelineMessageLayout, - /*List of reactions (emoji,count,isSelected)*/ - val orderedReactionList: List? = null, + val reactionsSummary: ReactionsSummaryData, val pollResponseAggregatedSummary: PollResponseData? = null, val hasBeenEdited: Boolean = false, val hasPendingEdits: Boolean = false, @@ -55,6 +54,16 @@ data class ReferencesInfoData( val verificationStatus: VerificationState ) : Parcelable +@Parcelize +data class ReactionsSummaryData( + /*List of reactions (emoji,count,isSelected)*/ + val reactions: List? = null, + val showAll: Boolean = false, + val onShowMoreClicked: () -> Unit, + val onShowLessClicked: () -> Unit, + val onAddMoreClicked: () -> Unit +) : Parcelable + @Parcelize data class ReactionInfoData( val key: String, diff --git a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt index cc41141607..d307e1fd16 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt @@ -68,7 +68,7 @@ class ReactionButton @JvmOverloads constructor(context: Context, init { inflate(context, R.layout.reaction_button, this) orientation = HORIZONTAL - minimumHeight = DimensionConverter(context.resources).dpToPx(30) + minimumHeight = resources.getDimensionPixelSize(R.dimen.chat_reaction_min_height) gravity = Gravity.CENTER layoutDirection = View.LAYOUT_DIRECTION_LOCALE views = ReactionButtonBinding.bind(this) diff --git a/vector/src/main/res/drawable/ic_add_reaction_small.xml b/vector/src/main/res/drawable/ic_add_reaction_small.xml new file mode 100644 index 0000000000..ddd4367ce0 --- /dev/null +++ b/vector/src/main/res/drawable/ic_add_reaction_small.xml @@ -0,0 +1,4 @@ + + + diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index ec9310cd36..c155b6bb75 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -3779,4 +3779,7 @@ Create poll Share location + Show less + "%1$d more" + From a4b50d2a7834cf8a89eb908b634ad1c97a93d9b0 Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Wed, 9 Feb 2022 16:48:02 -0600 Subject: [PATCH 029/302] Set PREFS_CRASH_KEY synchronously Sometimes the app dies before this preference gets written to disk, and then the crash dialog is not displayed to the user Signed-off-by: Alex Baker --- changelog.d/5195.bugfix | 1 + .../app/features/rageshake/VectorUncaughtExceptionHandler.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/5195.bugfix diff --git a/changelog.d/5195.bugfix b/changelog.d/5195.bugfix new file mode 100644 index 0000000000..50d47e089e --- /dev/null +++ b/changelog.d/5195.bugfix @@ -0,0 +1 @@ +Reliably display crash report prompt diff --git a/vector/src/main/java/im/vector/app/features/rageshake/VectorUncaughtExceptionHandler.kt b/vector/src/main/java/im/vector/app/features/rageshake/VectorUncaughtExceptionHandler.kt index 670b28f1e1..bd2f0b67bd 100644 --- a/vector/src/main/java/im/vector/app/features/rageshake/VectorUncaughtExceptionHandler.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/VectorUncaughtExceptionHandler.kt @@ -63,7 +63,7 @@ class VectorUncaughtExceptionHandler @Inject constructor( */ override fun uncaughtException(thread: Thread, throwable: Throwable) { Timber.v("Uncaught exception: $throwable") - preferences.edit { + preferences.edit(commit = true) { putBoolean(PREFS_CRASH_KEY, true) } val b = StringBuilder() From 002332496a941cac91a86e6744b72b0582e1a660 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Feb 2022 23:11:56 +0000 Subject: [PATCH 030/302] Bump libphonenumber from 8.12.42 to 8.12.43 Bumps [libphonenumber](https://github.com/google/libphonenumber) from 8.12.42 to 8.12.43. - [Release notes](https://github.com/google/libphonenumber/releases) - [Changelog](https://github.com/google/libphonenumber/blob/master/making-metadata-changes.md) - [Commits](https://github.com/google/libphonenumber/compare/v8.12.42...v8.12.43) --- updated-dependencies: - dependency-name: com.googlecode.libphonenumber:libphonenumber dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- matrix-sdk-android/build.gradle | 2 +- vector/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index ead4d4f397..083c198720 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -169,7 +169,7 @@ dependencies { implementation libs.apache.commonsImaging // Phone number https://github.com/google/libphonenumber - implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.42' + implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.43' testImplementation libs.tests.junit testImplementation 'org.robolectric:robolectric:4.7.3' diff --git a/vector/build.gradle b/vector/build.gradle index 63c749daeb..91a6319975 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -376,7 +376,7 @@ dependencies { implementation 'com.facebook.stetho:stetho:1.6.0' // Phone number https://github.com/google/libphonenumber - implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.42' + implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.43' // FlowBinding implementation libs.github.flowBinding From 06b5563ff638187546a7113cc5c09f71b6705a26 Mon Sep 17 00:00:00 2001 From: fedrunov <66663241+fedrunov@users.noreply.github.com> Date: Thu, 10 Feb 2022 10:05:03 +0100 Subject: [PATCH 031/302] =?UTF-8?q?join=20and=20leave=20methods=20moved=20?= =?UTF-8?q?from=20MembershipService=20to=20RoomService=20an=E2=80=A6=20(#5?= =?UTF-8?q?183)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog.d/5183.sdk | 1 + .../sdk/session/space/SpaceHierarchyTest.kt | 3 +-- .../android/sdk/api/session/room/RoomService.kt | 7 +++++++ .../api/session/room/members/MembershipService.kt | 10 ---------- .../matrix/android/sdk/api/session/space/Space.kt | 2 -- .../android/sdk/api/session/space/SpaceService.kt | 7 +++++++ .../internal/session/room/DefaultRoomService.kt | 8 +++++++- .../room/membership/DefaultMembershipService.kt | 14 -------------- .../sdk/internal/session/space/DefaultSpace.kt | 4 ---- .../internal/session/space/DefaultSpaceService.kt | 4 ++++ .../features/home/room/detail/TimelineViewModel.kt | 4 ++-- .../detail/composer/MessageComposerViewModel.kt | 6 ++++-- .../features/home/room/list/RoomListViewModel.kt | 9 +++------ .../vector/app/features/invite/InvitesAcceptor.kt | 9 ++++----- .../notifications/NotificationBroadcastReceiver.kt | 9 +++------ .../features/roomprofile/RoomProfileViewModel.kt | 2 +- .../app/features/spaces/SpaceListViewModel.kt | 2 +- .../app/features/spaces/SpaceMenuViewModel.kt | 6 +++--- .../invite/SpaceInviteBottomSheetViewModel.kt | 4 ++-- .../spaces/leave/SpaceLeaveAdvancedViewModel.kt | 4 ++-- 20 files changed, 52 insertions(+), 63 deletions(-) create mode 100644 changelog.d/5183.sdk diff --git a/changelog.d/5183.sdk b/changelog.d/5183.sdk new file mode 100644 index 0000000000..66d2c3793d --- /dev/null +++ b/changelog.d/5183.sdk @@ -0,0 +1 @@ +`join` and `leave` methods moved from MembershipService to RoomService and SpaceService to split logic for rooms and spaces \ No newline at end of file diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/space/SpaceHierarchyTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/space/SpaceHierarchyTest.kt index 5fbfaf99a0..20faa81bb6 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/space/SpaceHierarchyTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/space/SpaceHierarchyTest.kt @@ -344,7 +344,6 @@ class SpaceHierarchyTest : InstrumentedTest { // Test part one of the rooms val bRoomId = spaceBInfo.roomIds.first() - val bRoom = session.getRoom(bRoomId) commonTestHelper.waitWithLatch { latch -> val flatAChildren = session.getFlattenRoomSummaryChildrenOfLive(spaceAInfo.spaceId) @@ -360,7 +359,7 @@ class SpaceHierarchyTest : InstrumentedTest { } // part from b room - bRoom!!.leave(null) + session.leaveRoom(bRoomId) // The room should have disapear from flat children flatAChildren.observeForever(childObserver) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt index e4bd498990..bca432320d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt @@ -76,6 +76,13 @@ interface RoomService { thirdPartySigned: SignInvitationResult ) + /** + * Leave the room, or reject an invitation. + * @param roomId the roomId of the room to leave + * @param reason optional reason for leaving the room + */ + suspend fun leaveRoom(roomId: String, reason: String? = null) + /** * Get a room from a roomId * @param roomId the roomId to look for. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/MembershipService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/MembershipService.kt index d5bc65c142..6c8e2d310c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/MembershipService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/members/MembershipService.kt @@ -81,14 +81,4 @@ interface MembershipService { @Deprecated("Use remove instead", ReplaceWith("remove(userId, reason)")) suspend fun kick(userId: String, reason: String? = null) = remove(userId, reason) - - /** - * Join the room, or accept an invitation. - */ - suspend fun join(reason: String? = null, viaServers: List = emptyList()) - - /** - * Leave the room, or reject an invitation. - */ - suspend fun leave(reason: String? = null) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/Space.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/Space.kt index 207050be7d..f0ed9daac5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/Space.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/Space.kt @@ -26,8 +26,6 @@ interface Space { val spaceId: String - suspend fun leave(reason: String? = null) - /** * A current snapshot of [RoomSummary] associated with the space */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt index 357c0b941a..41c4e7eed1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt @@ -87,6 +87,13 @@ interface SpaceService { suspend fun rejectInvite(spaceId: String, reason: String?) + /** + * Leave the space, or reject an invitation. + * @param spaceId the spaceId of the space to leave + * @param reason optional reason for leaving the space + */ + suspend fun leaveSpace(spaceId: String, reason: String? = null) + // fun getSpaceParentsOfRoom(roomId: String) : List /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt index 7ca64aa66a..4a02c55db0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt @@ -46,6 +46,7 @@ import org.matrix.android.sdk.internal.session.room.create.CreateRoomTask import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper import org.matrix.android.sdk.internal.session.room.membership.joining.JoinRoomTask +import org.matrix.android.sdk.internal.session.room.membership.leaving.LeaveRoomTask import org.matrix.android.sdk.internal.session.room.peeking.PeekRoomTask import org.matrix.android.sdk.internal.session.room.peeking.ResolveRoomStateTask import org.matrix.android.sdk.internal.session.room.read.MarkAllRoomsReadTask @@ -66,7 +67,8 @@ internal class DefaultRoomService @Inject constructor( private val peekRoomTask: PeekRoomTask, private val roomGetter: RoomGetter, private val roomSummaryDataSource: RoomSummaryDataSource, - private val roomChangeMembershipStateDataSource: RoomChangeMembershipStateDataSource + private val roomChangeMembershipStateDataSource: RoomChangeMembershipStateDataSource, + private val leaveRoomTask: LeaveRoomTask, ) : RoomService { override suspend fun createRoom(createRoomParams: CreateRoomParams): String { @@ -133,6 +135,10 @@ internal class DefaultRoomService @Inject constructor( joinRoomTask.execute(JoinRoomTask.Params(roomId, reason, thirdPartySigned = thirdPartySigned)) } + override suspend fun leaveRoom(roomId: String, reason: String?) { + leaveRoomTask.execute(LeaveRoomTask.Params(roomId, reason)) + } + override suspend fun markAllAsRead(roomIds: List) { markAllRoomsReadTask.execute(MarkAllRoomsReadTask.Params(roomIds)) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt index 49b58aa765..005d7f26db 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt @@ -37,8 +37,6 @@ import org.matrix.android.sdk.internal.query.QueryStringValueProcessor import org.matrix.android.sdk.internal.query.process import org.matrix.android.sdk.internal.session.room.membership.admin.MembershipAdminTask import org.matrix.android.sdk.internal.session.room.membership.joining.InviteTask -import org.matrix.android.sdk.internal.session.room.membership.joining.JoinRoomTask -import org.matrix.android.sdk.internal.session.room.membership.leaving.LeaveRoomTask import org.matrix.android.sdk.internal.session.room.membership.threepid.InviteThreePidTask import org.matrix.android.sdk.internal.util.fetchCopied @@ -48,8 +46,6 @@ internal class DefaultMembershipService @AssistedInject constructor( private val loadRoomMembersTask: LoadRoomMembersTask, private val inviteTask: InviteTask, private val inviteThreePidTask: InviteThreePidTask, - private val joinTask: JoinRoomTask, - private val leaveRoomTask: LeaveRoomTask, private val membershipAdminTask: MembershipAdminTask, @UserId private val userId: String, @@ -139,14 +135,4 @@ internal class DefaultMembershipService @AssistedInject constructor( val params = InviteThreePidTask.Params(roomId, threePid) return inviteThreePidTask.execute(params) } - - override suspend fun join(reason: String?, viaServers: List) { - val params = JoinRoomTask.Params(roomId, reason, viaServers) - joinTask.execute(params) - } - - override suspend fun leave(reason: String?) { - val params = LeaveRoomTask.Params(roomId, reason) - leaveRoomTask.execute(params) - } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpace.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpace.kt index 8589db27b1..303eda49d8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpace.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpace.kt @@ -40,10 +40,6 @@ internal class DefaultSpace( override val spaceId = room.roomId - override suspend fun leave(reason: String?) { - return room.leave(reason) - } - override fun spaceSummary(): RoomSummary? { return spaceSummaryDataSource.getSpaceSummary(room.roomId) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt index ebd5f2578e..c18055e089 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt @@ -184,6 +184,10 @@ internal class DefaultSpaceService @Inject constructor( return joinSpaceTask.execute(JoinSpaceTask.Params(spaceIdOrAlias, reason, viaServers)) } + override suspend fun leaveSpace(spaceId: String, reason: String?) { + leaveRoomTask.execute(LeaveRoomTask.Params(spaceId, reason)) + } + override suspend fun rejectInvite(spaceId: String, reason: String?) { leaveRoomTask.execute(LeaveRoomTask.Params(spaceId, reason)) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt index 7d678520ec..a404f9136b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt @@ -801,14 +801,14 @@ class TimelineViewModel @AssistedInject constructor( private fun handleRejectInvite() { viewModelScope.launch { - tryOrNull { room.leave(null) } + tryOrNull { session.leaveRoom(room.roomId) } } } private fun handleAcceptInvite() { viewModelScope.launch { tryOrNull { - room.join() + session.joinRoom(room.roomId) analyticsTracker.capture(room.roomSummary().toAnalyticsJoinedRoom()) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt index 0d90227168..6adf248af9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt @@ -440,7 +440,7 @@ class MessageComposerViewModel @AssistedInject constructor( is ParsedCommand.LeaveRoom -> { viewModelScope.launch(Dispatchers.IO) { try { - session.getRoom(slashCommandResult.roomId)?.leave(null) + session.leaveRoom(slashCommandResult.roomId) popDraft() _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) } catch (failure: Throwable) { @@ -683,7 +683,9 @@ class MessageComposerViewModel @AssistedInject constructor( ?.roomId ?.let { session.getRoom(it) } } - ?.leave(reason = null) + ?.let { + session.leaveRoom(it.roomId) + } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt index 42c800ab9d..a5977501d2 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt @@ -222,10 +222,9 @@ class RoomListViewModel @AssistedInject constructor( ) } - val room = session.getRoom(roomId) ?: return@withState viewModelScope.launch { try { - room.join() + session.joinRoom(roomId) analyticsTracker.capture(action.roomSummary.toAnalyticsJoinedRoom()) // We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data. // Instead, we wait for the room to be joined @@ -245,10 +244,9 @@ class RoomListViewModel @AssistedInject constructor( return@withState } - val room = session.getRoom(roomId) ?: return@withState viewModelScope.launch { try { - room.leave(null) + session.leaveRoom(roomId) // We do not update the rejectingRoomsIds here, because, the room is not rejected yet regarding the sync data. // Instead, we wait for the room to be rejected // Known bug: if the user is invited again (after rejecting the first invitation), the loading will be displayed instead of the buttons. @@ -333,9 +331,8 @@ class RoomListViewModel @AssistedInject constructor( private fun handleLeaveRoom(action: RoomListAction.LeaveRoom) { _viewEvents.post(RoomListViewEvents.Loading(null)) - val room = session.getRoom(action.roomId) ?: return viewModelScope.launch { - val value = runCatching { room.leave(null) } + val value = runCatching { session.leaveRoom(action.roomId) } .fold({ RoomListViewEvents.Done }, { RoomListViewEvents.Failure(it) }) _viewEvents.post(value) } diff --git a/vector/src/main/java/im/vector/app/features/invite/InvitesAcceptor.kt b/vector/src/main/java/im/vector/app/features/invite/InvitesAcceptor.kt index 73876bf6e9..a482998f77 100644 --- a/vector/src/main/java/im/vector/app/features/invite/InvitesAcceptor.kt +++ b/vector/src/main/java/im/vector/app/features/invite/InvitesAcceptor.kt @@ -34,7 +34,6 @@ import kotlinx.coroutines.sync.withPermit import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams @@ -109,7 +108,7 @@ class InvitesAcceptor @Inject constructor( private suspend fun Session.joinRoomSafely(roomId: String) { if (shouldRejectRoomIds.contains(roomId)) { - getRoom(roomId)?.rejectInviteSafely() + rejectInviteSafely(roomId) return } val roomMembershipChanged = getChangeMemberships(roomId) @@ -126,16 +125,16 @@ class InvitesAcceptor @Inject constructor( // if the inviting user is on the same HS, there can only be one cause: they left, so we try to reject the invite. if (inviterId?.endsWith(sessionParams.credentials.homeServer.orEmpty()).orFalse()) { shouldRejectRoomIds.add(roomId) - room.rejectInviteSafely() + rejectInviteSafely(roomId) } } } } } - private suspend fun Room.rejectInviteSafely() { + private suspend fun Session.rejectInviteSafely(roomId: String) { try { - leave(null) + leaveRoom(roomId) shouldRejectRoomIds.remove(roomId) } catch (failure: Throwable) { Timber.v("Fail rejecting invite for room: $roomId") diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt index ac2ec06474..01c1117ab2 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt @@ -83,7 +83,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { if (room != null) { session.coroutineScope.launch { tryOrNull { - room.join() + session.joinRoom(room.roomId) analyticsTracker.capture(room.roomSummary().toAnalyticsJoinedRoom()) } } @@ -93,11 +93,8 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { private fun handleRejectRoom(roomId: String) { activeSessionHolder.getSafeActiveSession()?.let { session -> - val room = session.getRoom(roomId) - if (room != null) { - session.coroutineScope.launch { - tryOrNull { room.leave() } - } + session.coroutineScope.launch { + tryOrNull { session.leaveRoom(roomId) } } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt index 363cb1ea31..b7c7d24888 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt @@ -186,7 +186,7 @@ class RoomProfileViewModel @AssistedInject constructor( _viewEvents.post(RoomProfileViewEvents.Loading(stringProvider.getString(R.string.room_profile_leaving_room))) viewModelScope.launch { try { - room.leave(null) + session.leaveRoom(room.roomId) // Do nothing, we will be closing the room automatically when it will get back from sync } catch (failure: Throwable) { _viewEvents.post(RoomProfileViewEvents.Failure(failure)) diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt index 02771abc95..20af5b5827 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt @@ -256,7 +256,7 @@ class SpaceListViewModel @AssistedInject constructor(@Assisted initialState: Spa private fun handleLeaveSpace(action: SpaceListAction.LeaveSpace) { viewModelScope.launch { tryOrNull("Failed to leave space ${action.spaceSummary.roomId}") { - session.spaceService().getSpace(action.spaceSummary.roomId)?.leave(null) + session.spaceService().leaveSpace(action.spaceSummary.roomId) } } } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt index 2e9af2eacb..9b95b5328f 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt @@ -131,7 +131,7 @@ class SpaceMenuViewModel @AssistedInject constructor( session.coroutineScope.launch { try { if (state.leaveMode == SpaceMenuState.LeaveMode.LEAVE_NONE) { - session.getRoom(initialState.spaceId)?.leave(null) + session.spaceService().leaveSpace(initialState.spaceId) } else if (state.leaveMode == SpaceMenuState.LeaveMode.LEAVE_ALL) { // need to find all child rooms that i have joined @@ -143,13 +143,13 @@ class SpaceMenuViewModel @AssistedInject constructor( } ).forEach { try { - session.getRoom(it.roomId)?.leave(null) + session.spaceService().leaveSpace(it.roomId) } catch (failure: Throwable) { // silently ignore? Timber.e(failure, "Fail to leave sub rooms/spaces") } } - session.getRoom(initialState.spaceId)?.leave(null) + session.spaceService().leaveSpace(initialState.spaceId) } // We observe the membership and to dismiss when we have remote echo of leaving diff --git a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt index 79ad043813..9c6b092135 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt @@ -104,7 +104,7 @@ class SpaceInviteBottomSheetViewModel @AssistedInject constructor( setState { copy(joinActionState = Loading()) } session.coroutineScope.launch(Dispatchers.IO) { try { - session.getRoom(initialState.spaceId)?.join() + session.spaceService().joinSpace(initialState.spaceId) setState { copy(joinActionState = Success(Unit)) } } catch (failure: Throwable) { setState { copy(joinActionState = Fail(failure)) } @@ -116,7 +116,7 @@ class SpaceInviteBottomSheetViewModel @AssistedInject constructor( setState { copy(rejectActionState = Loading()) } session.coroutineScope.launch(Dispatchers.IO) { try { - session.getRoom(initialState.spaceId)?.leave() + session.spaceService().leaveSpace(initialState.spaceId) setState { copy(rejectActionState = Success(Unit)) } } catch (failure: Throwable) { setState { copy(rejectActionState = Fail(failure)) } diff --git a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt index e9b75836e9..fc241e711c 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt @@ -72,14 +72,14 @@ class SpaceLeaveAdvancedViewModel @AssistedInject constructor( try { state.selectedRooms.forEach { try { - session.getRoom(it)?.leave(null) + session.leaveRoom(it) } catch (failure: Throwable) { // silently ignore? Timber.e(failure, "Fail to leave sub rooms/spaces") } } - session.getRoom(initialState.spaceId)?.leave(null) + session.spaceService().leaveSpace(initialState.spaceId) // We observe the membership and to dismiss when we have remote echo of leaving } catch (failure: Throwable) { setState { copy(leaveState = Fail(failure)) } From eb90268cf5394937b6143d15272dab6551d7fae8 Mon Sep 17 00:00:00 2001 From: David Langley Date: Thu, 10 Feb 2022 10:30:47 +0000 Subject: [PATCH 032/302] Updates getAccountDataEvents function to match it's description. --- changelog.d/5198.buxfix | 1 + .../session/room/accountdata/RoomAccountDataDataSource.kt | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 changelog.d/5198.buxfix diff --git a/changelog.d/5198.buxfix b/changelog.d/5198.buxfix new file mode 100644 index 0000000000..3fce6906d5 --- /dev/null +++ b/changelog.d/5198.buxfix @@ -0,0 +1 @@ +Fix for rooms with virtual rooms not showing call status events in the timeline. \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/accountdata/RoomAccountDataDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/accountdata/RoomAccountDataDataSource.kt index d96beed3f1..d5a110dfc2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/accountdata/RoomAccountDataDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/accountdata/RoomAccountDataDataSource.kt @@ -54,8 +54,7 @@ internal class RoomAccountDataDataSource @Inject constructor(@SessionDatabase pr */ fun getAccountDataEvents(roomId: String?, types: Set): List { return realmSessionProvider.withRealm { realm -> - val roomEntity = buildRoomQuery(realm, roomId, types).findFirst() ?: return@withRealm emptyList() - roomEntity.accountDataEvents(types) + buildRoomQuery(realm, roomId, types).findAll().flatMap { it.accountDataEvents(types) } } } From ba5c7a530c283a0add6a542300eb90fcbf7b581f Mon Sep 17 00:00:00 2001 From: NIkita Fedrunov Date: Thu, 10 Feb 2022 13:22:00 +0100 Subject: [PATCH 033/302] another sync with analytics repo --- .../features/analytics/plan/Interaction.kt | 48 +++++++++++++++++++ .../features/analytics/plan/SlashCommand.kt | 4 +- .../features/analytics/plan/UserProperties.kt | 5 ++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt index feffa6d5c6..7bdc7740e1 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt @@ -51,6 +51,18 @@ data class Interaction( */ SpacePanelSwitchSpace, + /** + * User clicked the create room button in the + context menu of the room + * list header in Element Web/Desktop. + */ + WebAddExistingToSpaceDialogCreateRoomButton, + + /** + * User clicked the create room button in the home page of Element + * Web/Desktop. + */ + WebHomeCreateRoomButton, + /** * User interacted with pin to sidebar checkboxes in the quick settings * menu of Element Web/Desktop. @@ -93,6 +105,12 @@ data class Interaction( */ WebRightPanelRoomUserInfoInviteButton, + /** + * User clicked the create room button in the room directory of Element + * Web/Desktop. + */ + WebRoomDirectoryCreateRoomButton, + /** * User adjusted their favourites using the context menu on the header * of a room in Element Web/Desktop. @@ -129,6 +147,12 @@ data class Interaction( */ WebRoomHeaderContextMenuSettingsItem, + /** + * User clicked the create room button in the + context menu of the room + * list header in Element Web/Desktop. + */ + WebRoomListHeaderPlusMenuCreateRoomItem, + /** * User adjusted their favourites using the context menu on a room tile * in the room list in Element Web/Desktop. @@ -159,12 +183,24 @@ data class Interaction( */ WebRoomListRoomTileNotificationsMenu, + /** + * User clicked the create room button in the + context menu of the + * rooms sublist in Element Web/Desktop. + */ + WebRoomListRoomsSublistPlusMenuCreateRoomItem, + /** * User interacted with leave action in the general tab of the room * settings dialog in Element Web/Desktop. */ WebRoomSettingsLeaveButton, + /** + * User interacted with the prompt to create a new room when adjusting + * security settings in an existing room in Element Web/Desktop. + */ + WebRoomSettingsSecurityTabCreateNewRoomButton, + /** * User interacted with the theme radio selector in the Appearance tab * of Settings in Element Web/Desktop. @@ -177,6 +213,18 @@ data class Interaction( */ WebSettingsSidebarTabSpacesCheckbox, + /** + * User clicked the create room button in the + context menu of the room + * list header in Element Web/Desktop. + */ + WebSpaceContextMenuNewRoomItem, + + /** + * User clicked the create room button in the + context menu of the room + * list header in Element Web/Desktop. + */ + WebSpaceHomeCreateRoomButton, + /** * User clicked the theme toggle button in the user menu of Element * Web/Desktop. diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt index 69c34bbc15..33d3545487 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt @@ -32,8 +32,8 @@ data class SlashCommand( ) : VectorAnalyticsEvent { enum class Command { - invite, - part, + Invite, + Part, } override fun getName() = "SlashCommand" diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt index bbe2c48fec..dea499edde 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt @@ -48,6 +48,10 @@ data class UserProperties( * The selected messaging use case during the onboarding flow. */ val ftueUseCaseSelection: FtueUseCaseSelection? = null, + /** + * Number of joined rooms the user has favourited + */ + val numFavouriteRooms: Int? = null, /** * Number of spaces (and sub-spaces) the user is joined to */ @@ -84,6 +88,7 @@ data class UserProperties( WebMetaSpaceOrphansEnabled?.let { put("WebMetaSpaceOrphansEnabled", it) } WebMetaSpacePeopleEnabled?.let { put("WebMetaSpacePeopleEnabled", it) } ftueUseCaseSelection?.let { put("ftueUseCaseSelection", it.name) } + numFavouriteRooms?.let { put("numFavouriteRooms", it) } numSpaces?.let { put("numSpaces", it) } }.takeIf { it.isNotEmpty() } } From 0244fea222712b961fc84842b4c9954af6833918 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 10 Feb 2022 17:51:49 +0100 Subject: [PATCH 034/302] Reactions: more refinements --- .../ui-styles/src/main/res/values/dimens.xml | 3 ++- .../helper/MessageInformationDataFactory.kt | 4 +-- .../timeline/item/AbsBaseMessageItem.kt | 25 ++++++++++++------- .../reactions/widget/ReactionButton.kt | 1 + .../main/res/drawable/reaction_divider.xml | 4 +-- .../src/main/res/layout/reaction_button.xml | 9 +++---- 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/library/ui-styles/src/main/res/values/dimens.xml b/library/ui-styles/src/main/res/values/dimens.xml index 9a3929094a..c8f1ec5c86 100644 --- a/library/ui-styles/src/main/res/values/dimens.xml +++ b/library/ui-styles/src/main/res/values/dimens.xml @@ -61,7 +61,8 @@ 300dp 12dp - 30dp + 28dp + 40dp 0.05 diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt index 2bd2257cf7..59b39d17ef 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt @@ -50,7 +50,7 @@ import javax.inject.Inject class MessageInformationDataFactory @Inject constructor(private val session: Session, private val dateFormatter: VectorDateFormatter, private val messageLayoutFactory: TimelineMessageLayoutFactory, - private val reactionListFactory: ReactionsSummaryFactory) { + private val reactionsSummaryFactory: ReactionsSummaryFactory) { fun create(params: TimelineItemFactoryParams): MessageInformationData { val event = params.event @@ -93,7 +93,7 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses avatarUrl = event.senderInfo.avatarUrl, memberName = event.senderInfo.disambiguatedDisplayName, messageLayout = messageLayout, - reactionsSummary = reactionListFactory.create(event, params.callback), + reactionsSummary = reactionsSummaryFactory.create(event, params.callback), pollResponseAggregatedSummary = event.annotations?.pollResponseSummary?.let { PollResponseData( myVote = it.aggregatedContent?.myVote, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt index 6d0714e929..07fa4192c8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt @@ -17,7 +17,6 @@ package im.vector.app.features.home.room.detail.timeline.item import android.annotation.SuppressLint -import android.content.Context import android.view.Gravity import android.view.View import android.view.ViewGroup @@ -30,6 +29,7 @@ import im.vector.app.R import im.vector.app.core.epoxy.ClickListener import im.vector.app.core.epoxy.onClick import im.vector.app.core.ui.views.ShieldImageView +import im.vector.app.core.utils.DimensionConverter import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.TimelineEventController @@ -38,6 +38,9 @@ import im.vector.app.features.reactions.widget.ReactionButton import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.room.send.SendState + +private const val MAX_REACTIONS_TO_SHOW = 8 + /** * Base timeline item with reactions and read receipts. * Manages associated click listeners and send status. @@ -99,7 +102,7 @@ abstract class AbsBaseMessageItem : BaseEventItem val reactionsToShow = if (reactionsSummary.showAll) { reactions } else { - reactions.take(8) + reactions.take(MAX_REACTIONS_TO_SHOW) } reactionsToShow.forEach { reaction -> val reactionButton = ReactionButton(holder.view.context) @@ -111,19 +114,19 @@ abstract class AbsBaseMessageItem : BaseEventItem reactionButton.isEnabled = reaction.synced holder.reactionsContainer.addView(reactionButton) } - if (reactions.count() > 8) { - val showReactionsTextView = createReactionTextView(holder.view.context) + if (reactions.count() > MAX_REACTIONS_TO_SHOW) { + val showReactionsTextView = createReactionTextView(holder, 6) if (reactionsSummary.showAll) { showReactionsTextView.setText(R.string.message_reaction_show_less) showReactionsTextView.onClick { reactionsSummary.onShowLessClicked() } } else { - val moreCount = reactions.count() - 8 + val moreCount = reactions.count() - MAX_REACTIONS_TO_SHOW showReactionsTextView.text = holder.view.resources.getString(R.string.message_reaction_show_more, moreCount) showReactionsTextView.onClick { reactionsSummary.onShowMoreClicked() } } holder.reactionsContainer.addView(showReactionsTextView) } - val addMoreReactionsTextView = createReactionTextView(holder.view.context) + val addMoreReactionsTextView = createReactionTextView(holder, 14) addMoreReactionsTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_add_reaction_small, 0, 0, 0) addMoreReactionsTextView.onClick { reactionsSummary.onAddMoreClicked() } holder.reactionsContainer.addView(addMoreReactionsTextView) @@ -131,13 +134,14 @@ abstract class AbsBaseMessageItem : BaseEventItem } } - private fun createReactionTextView(context: Context): TextView { - return TextView(context).apply { + private fun createReactionTextView(holder: H, horizontalPaddingDp: Int): TextView { + return TextView(holder.view.context).apply { textSize = 10f gravity = Gravity.CENTER minimumHeight = resources.getDimensionPixelSize(R.dimen.chat_reaction_min_height) + minimumWidth = resources.getDimensionPixelSize(R.dimen.chat_reaction_min_width) background = getDrawable(context, R.drawable.reaction_rounded_rect_shape_off) - val padding = resources.getDimensionPixelSize(R.dimen.layout_horizontal_margin) + val padding = holder.dimensionConverter.dpToPx(horizontalPaddingDp) setPadding(padding, 0, padding, 0) } } @@ -155,6 +159,9 @@ abstract class AbsBaseMessageItem : BaseEventItem } abstract class Holder(@IdRes stubId: Int) : BaseEventItem.BaseHolder(stubId) { + val dimensionConverter by lazy { + DimensionConverter(view.resources) + } val reactionsContainer by bind(R.id.reactionsContainer) val e2EDecorationView by bind(R.id.messageE2EDecoration) } diff --git a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt index d307e1fd16..5553c1faab 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt @@ -69,6 +69,7 @@ class ReactionButton @JvmOverloads constructor(context: Context, inflate(context, R.layout.reaction_button, this) orientation = HORIZONTAL minimumHeight = resources.getDimensionPixelSize(R.dimen.chat_reaction_min_height) + minimumWidth = resources.getDimensionPixelSize(R.dimen.chat_reaction_min_width) gravity = Gravity.CENTER layoutDirection = View.LAYOUT_DIRECTION_LOCALE views = ReactionButtonBinding.bind(this) diff --git a/vector/src/main/res/drawable/reaction_divider.xml b/vector/src/main/res/drawable/reaction_divider.xml index d68b6a9094..1d7ee57084 100644 --- a/vector/src/main/res/drawable/reaction_divider.xml +++ b/vector/src/main/res/drawable/reaction_divider.xml @@ -2,7 +2,7 @@ + android:width="4dp" + android:height="4dp" /> \ No newline at end of file diff --git a/vector/src/main/res/layout/reaction_button.xml b/vector/src/main/res/layout/reaction_button.xml index a6d84407ce..f0a8011220 100644 --- a/vector/src/main/res/layout/reaction_button.xml +++ b/vector/src/main/res/layout/reaction_button.xml @@ -3,11 +3,11 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" - android:layout_height="26dp" + android:layout_height="@dimen/chat_reaction_min_height" android:background="@drawable/reaction_rounded_rect_shape" android:clipChildren="false" android:gravity="center" - android:minWidth="44dp" + android:minWidth="@dimen/chat_reaction_min_width" tools:parentTag="android.widget.LinearLayout"> @@ -20,12 +20,11 @@ android:id="@+id/reactionText" style="@style/Widget.Vector.TextView.Caption" android:layout_width="wrap_content" - android:layout_height="20dp" + android:layout_height="wrap_content" android:layout_marginStart="6dp" android:ellipsize="middle" android:gravity="center" android:maxEms="10" - android:minWidth="20dp" android:singleLine="true" android:textColor="@color/emoji_color" tools:text="* Party Parrot Again * 👀" /> @@ -36,7 +35,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="2dp" - android:layout_marginEnd="8dp" + android:layout_marginEnd="6dp" android:gravity="center" android:maxLines="1" android:textColor="?vctr_content_secondary" From 31fa43b5bd8e0ff6f880aded34effe3a0b9f2f4e Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 10 Feb 2022 17:52:10 +0100 Subject: [PATCH 035/302] Reactions: fix direction for outgoing bubble --- .../home/room/detail/timeline/view/MessageBubbleView.kt | 2 ++ vector/src/main/res/layout/view_message_bubble.xml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt index 422dfb0dbd..bf5bb8d302 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt @@ -31,6 +31,7 @@ import androidx.core.content.withStyledAttributes import androidx.core.graphics.drawable.DrawableCompat import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams +import com.google.android.flexbox.FlexDirection import com.google.android.material.shape.MaterialShapeDrawable import im.vector.app.R import im.vector.app.core.resources.LocaleProvider @@ -79,6 +80,7 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri views.messageThreadSummaryContainer.layoutDirection = layoutDirectionToSet views.bubbleWrapper.layoutDirection = layoutDirectionToSet views.bubbleView.layoutDirection = currentLayoutDirection + views.reactionsContainer.flexDirection = if (isIncoming) FlexDirection.ROW else FlexDirection.ROW_REVERSE bubbleDrawable = MaterialShapeDrawable() rippleMaskDrawable = MaterialShapeDrawable() diff --git a/vector/src/main/res/layout/view_message_bubble.xml b/vector/src/main/res/layout/view_message_bubble.xml index 7e4d3e8f7d..e6f24e43c5 100644 --- a/vector/src/main/res/layout/view_message_bubble.xml +++ b/vector/src/main/res/layout/view_message_bubble.xml @@ -177,7 +177,7 @@ Date: Thu, 10 Feb 2022 17:23:38 +0000 Subject: [PATCH 036/302] Intent information that is pass to attachViewRenderers is not present on intent then onNewIntent called. --- changelog.d/5201.bugfix | 1 + .../main/java/im/vector/app/features/call/VectorCallActivity.kt | 1 + 2 files changed, 2 insertions(+) create mode 100644 changelog.d/5201.bugfix diff --git a/changelog.d/5201.bugfix b/changelog.d/5201.bugfix new file mode 100644 index 0000000000..f77ddcce84 --- /dev/null +++ b/changelog.d/5201.bugfix @@ -0,0 +1 @@ +Fix for call transfer with consult failing to make outgoing consultation call. \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt index caab4c85e1..abba36f2a0 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt @@ -165,6 +165,7 @@ class VectorCallActivity : VectorBaseActivity(), CallContro ?.let { callViewModel.handle(VectorCallViewActions.SwitchCall(it)) } + this.intent = intent } override fun getMenuRes() = R.menu.vector_call From 9f44ec1d704a46d88dbf280610a26081e61ca337 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 10 Feb 2022 18:56:39 +0100 Subject: [PATCH 037/302] Reactions: fix ui echo ordering --- .../internal/session/room/timeline/UIEchoManager.kt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/UIEchoManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/UIEchoManager.kt index 16d36c0cd9..bb92623249 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/UIEchoManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/UIEchoManager.kt @@ -66,11 +66,11 @@ internal class UIEchoManager(private val listener: Listener) { return existingState != sendState } - fun onLocalEchoCreated(timelineEvent: TimelineEvent): Boolean { + fun onLocalEchoCreated(timelineEvent: TimelineEvent): Boolean { when (timelineEvent.root.getClearType()) { EventType.REDACTION -> { } - EventType.REACTION -> { + EventType.REACTION -> { val content: ReactionContent? = timelineEvent.root.content?.toModel() if (RelationType.ANNOTATION == content?.relatesTo?.type) { val reaction = content.relatesTo.key @@ -104,8 +104,8 @@ internal class UIEchoManager(private val listener: Listener) { val updateReactions = existingAnnotationSummary.reactionsSummary.toMutableList() contents.forEach { uiEchoReaction -> - val existing = updateReactions.firstOrNull { it.key == uiEchoReaction.reaction } - if (existing == null) { + val indexOfExistingReaction = updateReactions.indexOfFirst { it.key == uiEchoReaction.reaction } + if (indexOfExistingReaction == -1) { // just add the new key ReactionAggregatedSummary( key = uiEchoReaction.reaction, @@ -117,6 +117,7 @@ internal class UIEchoManager(private val listener: Listener) { ).let { updateReactions.add(it) } } else { // update Existing Key + val existing = updateReactions[indexOfExistingReaction] if (!existing.localEchoEvents.contains(uiEchoReaction.localEchoId)) { updateReactions.remove(existing) // only update if echo is not yet there @@ -128,7 +129,7 @@ internal class UIEchoManager(private val listener: Listener) { sourceEvents = existing.sourceEvents, localEchoEvents = existing.localEchoEvents + uiEchoReaction.localEchoId - ).let { updateReactions.add(it) } + ).let { updateReactions.add(indexOfExistingReaction, it) } } } } From c690bada0d4865200a4b5a2f50fc310b54b3cae2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 10 Feb 2022 19:13:35 +0100 Subject: [PATCH 038/302] Clean code and add changelog. --- changelog.d/5204.feature | 1 + .../home/room/detail/timeline/TimelineEventController.kt | 2 +- .../home/room/detail/timeline/helper/ReactionsSummaryFactory.kt | 1 - .../home/room/detail/timeline/item/AbsBaseMessageItem.kt | 1 - .../im/vector/app/features/reactions/widget/ReactionButton.kt | 1 - 5 files changed, 2 insertions(+), 4 deletions(-) create mode 100644 changelog.d/5204.feature diff --git a/changelog.d/5204.feature b/changelog.d/5204.feature new file mode 100644 index 0000000000..a107342de7 --- /dev/null +++ b/changelog.d/5204.feature @@ -0,0 +1 @@ +Improve UI of reactions in timeline, including quick add reaction. \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt index 9875c41a80..e3f162dfd4 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt @@ -41,9 +41,9 @@ import im.vector.app.features.home.room.detail.timeline.factory.TimelineItemFact import im.vector.app.features.home.room.detail.timeline.factory.TimelineItemFactoryParams import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadStateTrackerBinder import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder +import im.vector.app.features.home.room.detail.timeline.helper.ReactionsSummaryFactory import im.vector.app.features.home.room.detail.timeline.helper.TimelineControllerInterceptorHelper import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventDiffUtilCallback -import im.vector.app.features.home.room.detail.timeline.helper.ReactionsSummaryFactory import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventVisibilityHelper import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventVisibilityStateChangedListener import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventsGroups diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ReactionsSummaryFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ReactionsSummaryFactory.kt index e811d704d7..fcc98ff729 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ReactionsSummaryFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ReactionsSummaryFactory.kt @@ -17,7 +17,6 @@ package im.vector.app.features.home.room.detail.timeline.helper import dagger.hilt.android.scopes.ActivityScoped -import im.vector.app.features.home.room.detail.RoomDetailAction import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.item.ReactionInfoData import im.vector.app.features.home.room.detail.timeline.item.ReactionsSummaryData diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt index 07fa4192c8..21b58e0f4b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt @@ -38,7 +38,6 @@ import im.vector.app.features.reactions.widget.ReactionButton import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.room.send.SendState - private const val MAX_REACTIONS_TO_SHOW = 8 /** diff --git a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt index 5553c1faab..219ca166bb 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt @@ -26,7 +26,6 @@ import androidx.core.content.withStyledAttributes import dagger.hilt.android.AndroidEntryPoint import im.vector.app.EmojiSpanify import im.vector.app.R -import im.vector.app.core.utils.DimensionConverter import im.vector.app.core.utils.TextUtils import im.vector.app.databinding.ReactionButtonBinding import javax.inject.Inject From cb37bc56a650ffe46f4106976f799051a7bd1b25 Mon Sep 17 00:00:00 2001 From: David Langley Date: Thu, 10 Feb 2022 19:07:32 +0000 Subject: [PATCH 039/302] Move call transfer actions back to callViewModel via result from callTransferActivity --- .../app/features/call/VectorCallActivity.kt | 16 ++++- .../features/call/VectorCallViewActions.kt | 2 + .../app/features/call/VectorCallViewEvents.kt | 1 + .../app/features/call/VectorCallViewModel.kt | 58 ++++++++++++++++++- .../call/transfer/CallTransferActivity.kt | 23 +++++--- ...ransferAction.kt => CallTransferResult.kt} | 10 ++-- .../call/transfer/CallTransferViewEvents.kt | 2 - .../call/transfer/CallTransferViewModel.kt | 54 +---------------- 8 files changed, 97 insertions(+), 69 deletions(-) rename vector/src/main/java/im/vector/app/features/call/transfer/{CallTransferAction.kt => CallTransferResult.kt} (64%) diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt index abba36f2a0..e21aaf8880 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt @@ -54,6 +54,9 @@ import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.databinding.ActivityCallBinding import im.vector.app.features.call.dialpad.CallDialPadBottomSheet import im.vector.app.features.call.dialpad.DialPadFragment +import im.vector.app.features.call.transfer.CallTransferActivity +import im.vector.app.features.call.transfer.CallTransferResult +import im.vector.app.features.call.transfer.CallTransferViewEvents import im.vector.app.features.call.utils.EglUtils import im.vector.app.features.call.webrtc.WebRtcCall import im.vector.app.features.call.webrtc.WebRtcCallManager @@ -523,14 +526,23 @@ class VectorCallActivity : VectorBaseActivity(), CallContro val callId = withState(callViewModel) { it.callId } navigator.openCallTransfer(this, callTransferActivityResultLauncher, callId) } + is VectorCallViewEvents.FailToTransfer -> showSnackbar(getString(R.string.call_transfer_failure)) null -> { } } } private val callTransferActivityResultLauncher = registerStartForActivityResult { activityResult -> - if (activityResult.resultCode == Activity.RESULT_CANCELED) { - callViewModel.handle(VectorCallViewActions.CallTransferSelectionCancelled) + + when(activityResult.resultCode) { + Activity.RESULT_CANCELED -> { + callViewModel.handle(VectorCallViewActions.CallTransferSelectionCancelled) + } + Activity.RESULT_OK -> { + activityResult.data?.extras?.getParcelable(CallTransferActivity.EXTRA_TRANSFER_RESULT)?.also { + callViewModel.handle(VectorCallViewActions.CallTransferSelectionResult(it)) + } + } } } diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallViewActions.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallViewActions.kt index fb39660282..d1ed961814 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallViewActions.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallViewActions.kt @@ -18,6 +18,7 @@ package im.vector.app.features.call import im.vector.app.core.platform.VectorViewModelAction import im.vector.app.features.call.audio.CallAudioManager +import im.vector.app.features.call.transfer.CallTransferResult sealed class VectorCallViewActions : VectorViewModelAction { object EndCall : VectorCallViewActions() @@ -37,5 +38,6 @@ sealed class VectorCallViewActions : VectorViewModelAction { object ToggleHDSD : VectorCallViewActions() object InitiateCallTransfer : VectorCallViewActions() object CallTransferSelectionCancelled : VectorCallViewActions() + data class CallTransferSelectionResult(val callTransferResult: CallTransferResult) : VectorCallViewActions() object TransferCall : VectorCallViewActions() } diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallViewEvents.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallViewEvents.kt index 5a0a2f127c..7c29d7eea3 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallViewEvents.kt @@ -29,6 +29,7 @@ sealed class VectorCallViewEvents : VectorViewEvents { ) : VectorCallViewEvents() object ShowDialPad : VectorCallViewEvents() object ShowCallTransferScreen : VectorCallViewEvents() + object FailToTransfer : VectorCallViewEvents() // data class CallAnswered(val content: CallAnswerContent) : VectorCallViewEvents() // data class CallHangup(val content: CallHangupContent) : VectorCallViewEvents() // object CallAccepted : VectorCallViewEvents() 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 4aca0ea499..a26eec04f3 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 @@ -29,13 +29,17 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.call.audio.CallAudioManager +import im.vector.app.features.call.dialpad.DialPadLookup +import im.vector.app.features.call.transfer.CallTransferResult import im.vector.app.features.call.webrtc.WebRtcCall import im.vector.app.features.call.webrtc.WebRtcCallManager import im.vector.app.features.call.webrtc.getOpponentAsMatrixItem +import im.vector.app.features.createdirect.DirectRoomHelper import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.matrix.android.sdk.api.MatrixPatterns +import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.call.CallState import org.matrix.android.sdk.api.session.call.MxCall @@ -47,7 +51,9 @@ class VectorCallViewModel @AssistedInject constructor( @Assisted initialState: VectorCallViewState, val session: Session, val callManager: WebRtcCallManager, - val proximityManager: CallProximityManager + val proximityManager: CallProximityManager, + private val dialPadLookup: DialPadLookup, + private val directRoomHelper: DirectRoomHelper, ) : VectorViewModel(initialState) { private var call: WebRtcCall? = null @@ -327,6 +333,9 @@ class VectorCallViewModel @AssistedInject constructor( VectorCallViewActions.CallTransferSelectionCancelled -> { call?.updateRemoteOnHold(false) } + is VectorCallViewActions.CallTransferSelectionResult -> { + handleCallTransferSelectionResult(action.callTransferResult) + } VectorCallViewActions.TransferCall -> { handleCallTransfer() } @@ -345,6 +354,53 @@ class VectorCallViewModel @AssistedInject constructor( } } + private fun handleCallTransferSelectionResult(result: CallTransferResult) { + when (result) { + is CallTransferResult.ConnectWithUserId -> connectWithUserId(result) + is CallTransferResult.ConnectWithPhoneNumber -> connectWithPhoneNumber(result) + }.exhaustive + } + + private fun connectWithUserId(result: CallTransferResult.ConnectWithUserId) { + viewModelScope.launch { + try { + if (result.consultFirst) { + val dmRoomId = directRoomHelper.ensureDMExists(result.selectedUserId) + callManager.startOutgoingCall( + nativeRoomId = dmRoomId, + otherUserId = result.selectedUserId, + isVideoCall = call?.mxCall?.isVideoCall.orFalse(), + transferee = call + ) + } else { + call?.transferToUser(result.selectedUserId, null) + } + } catch (failure: Throwable) { + _viewEvents.post(VectorCallViewEvents.FailToTransfer) + } + } + } + + private fun connectWithPhoneNumber(action: CallTransferResult.ConnectWithPhoneNumber) { + viewModelScope.launch { + try { + val result = dialPadLookup.lookupPhoneNumber(action.phoneNumber) + if (action.consultFirst) { + callManager.startOutgoingCall( + nativeRoomId = result.roomId, + otherUserId = result.userId, + isVideoCall = call?.mxCall?.isVideoCall.orFalse(), + transferee = call + ) + } else { + call?.transferToUser(result.userId, result.roomId) + } + } catch (failure: Throwable) { + _viewEvents.post(VectorCallViewEvents.FailToTransfer) + } + } + } + @AssistedFactory interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: VectorCallViewState): VectorCallViewModel diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt index 0e63316bbe..4c0f092e3b 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt @@ -57,8 +57,6 @@ class CallTransferActivity : VectorBaseActivity() { callTransferViewModel.observeViewEvents { when (it) { is CallTransferViewEvents.Complete -> handleComplete() - CallTransferViewEvents.Loading -> showWaitingView() - is CallTransferViewEvents.FailToTransfer -> showSnackbar(getString(R.string.call_transfer_failure)) } } @@ -82,25 +80,32 @@ class CallTransferActivity : VectorBaseActivity() { when (views.callTransferTabLayout.selectedTabPosition) { CallTransferPagerAdapter.USER_LIST_INDEX -> { val selectedUser = sectionsPagerAdapter.userListFragment?.getCurrentState()?.getSelectedMatrixId()?.firstOrNull() ?: return@debouncedClicks - val action = CallTransferAction.ConnectWithUserId(views.callTransferConsultCheckBox.isChecked, selectedUser) - callTransferViewModel.handle(action) + val result = CallTransferResult.ConnectWithUserId(views.callTransferConsultCheckBox.isChecked, selectedUser) + handleComplete(result) } CallTransferPagerAdapter.DIAL_PAD_INDEX -> { val phoneNumber = sectionsPagerAdapter.dialPadFragment?.getRawInput() ?: return@debouncedClicks - val action = CallTransferAction.ConnectWithPhoneNumber(views.callTransferConsultCheckBox.isChecked, phoneNumber) - callTransferViewModel.handle(action) + val result = CallTransferResult.ConnectWithPhoneNumber(views.callTransferConsultCheckBox.isChecked, phoneNumber) + handleComplete(result) } } } } - private fun handleComplete() { - setResult(Activity.RESULT_OK) + private fun handleComplete(callTransferResult: CallTransferResult? = null) { + if (callTransferResult != null) { + val intent = Intent().apply { + putExtra(EXTRA_TRANSFER_RESULT, callTransferResult) + } + setResult(RESULT_OK, intent) + } else { + setResult(RESULT_OK) + } finish() } companion object { - + const val EXTRA_TRANSFER_RESULT = "EXTRA_TRANSFER_RESULT" fun newIntent(context: Context, callId: String): Intent { return Intent(context, CallTransferActivity::class.java).also { it.putExtra(Mavericks.KEY_ARG, CallTransferArgs(callId)) diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferAction.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferResult.kt similarity index 64% rename from vector/src/main/java/im/vector/app/features/call/transfer/CallTransferAction.kt rename to vector/src/main/java/im/vector/app/features/call/transfer/CallTransferResult.kt index bd694ad14e..238c916634 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferAction.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferResult.kt @@ -16,9 +16,11 @@ package im.vector.app.features.call.transfer -import im.vector.app.core.platform.VectorViewModelAction +import android.os.Parcelable +import kotlinx.parcelize.Parcelize -sealed class CallTransferAction : VectorViewModelAction { - data class ConnectWithUserId(val consultFirst: Boolean, val selectedUserId: String) : CallTransferAction() - data class ConnectWithPhoneNumber(val consultFirst: Boolean, val phoneNumber: String) : CallTransferAction() + +sealed class CallTransferResult : Parcelable{ + @Parcelize data class ConnectWithUserId(val consultFirst: Boolean, val selectedUserId: String) : CallTransferResult() + @Parcelize data class ConnectWithPhoneNumber(val consultFirst: Boolean, val phoneNumber: String) : CallTransferResult() } diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewEvents.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewEvents.kt index a8451e4fb5..4202506d23 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewEvents.kt @@ -20,6 +20,4 @@ import im.vector.app.core.platform.VectorViewEvents sealed class CallTransferViewEvents : VectorViewEvents { object Complete : CallTransferViewEvents() - object Loading : CallTransferViewEvents() - object FailToTransfer : CallTransferViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt index de6a5de539..64140eacf0 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt @@ -23,6 +23,7 @@ import dagger.assisted.AssistedInject import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive +import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.call.dialpad.DialPadLookup import im.vector.app.features.call.webrtc.WebRtcCall @@ -34,10 +35,8 @@ import org.matrix.android.sdk.api.session.call.CallState import org.matrix.android.sdk.api.session.call.MxCall class CallTransferViewModel @AssistedInject constructor(@Assisted initialState: CallTransferViewState, - private val dialPadLookup: DialPadLookup, - private val directRoomHelper: DirectRoomHelper, private val callManager: WebRtcCallManager) : - VectorViewModel(initialState) { + VectorViewModel(initialState) { @AssistedFactory interface Factory : MavericksAssistedViewModelFactory { @@ -68,53 +67,6 @@ class CallTransferViewModel @AssistedInject constructor(@Assisted initialState: call?.removeListener(callListener) } - override fun handle(action: CallTransferAction) { - when (action) { - is CallTransferAction.ConnectWithUserId -> connectWithUserId(action) - is CallTransferAction.ConnectWithPhoneNumber -> connectWithPhoneNumber(action) - }.exhaustive - } + override fun handle(action: EmptyAction) { } - private fun connectWithUserId(action: CallTransferAction.ConnectWithUserId) { - viewModelScope.launch { - try { - if (action.consultFirst) { - val dmRoomId = directRoomHelper.ensureDMExists(action.selectedUserId) - callManager.startOutgoingCall( - nativeRoomId = dmRoomId, - otherUserId = action.selectedUserId, - isVideoCall = call?.mxCall?.isVideoCall.orFalse(), - transferee = call - ) - } else { - call?.transferToUser(action.selectedUserId, null) - } - _viewEvents.post(CallTransferViewEvents.Complete) - } catch (failure: Throwable) { - _viewEvents.post(CallTransferViewEvents.FailToTransfer) - } - } - } - - private fun connectWithPhoneNumber(action: CallTransferAction.ConnectWithPhoneNumber) { - viewModelScope.launch { - try { - _viewEvents.post(CallTransferViewEvents.Loading) - val result = dialPadLookup.lookupPhoneNumber(action.phoneNumber) - if (action.consultFirst) { - callManager.startOutgoingCall( - nativeRoomId = result.roomId, - otherUserId = result.userId, - isVideoCall = call?.mxCall?.isVideoCall.orFalse(), - transferee = call - ) - } else { - call?.transferToUser(result.userId, result.roomId) - } - _viewEvents.post(CallTransferViewEvents.Complete) - } catch (failure: Throwable) { - _viewEvents.post(CallTransferViewEvents.FailToTransfer) - } - } - } } From 8e492cf98d4e315c2b641135fc6da8bc3203f8ce Mon Sep 17 00:00:00 2001 From: David Langley Date: Thu, 10 Feb 2022 19:20:40 +0000 Subject: [PATCH 040/302] lint --- .../java/im/vector/app/features/call/VectorCallActivity.kt | 3 +-- .../vector/app/features/call/transfer/CallTransferResult.kt | 1 - .../app/features/call/transfer/CallTransferViewModel.kt | 6 ------ 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt index e21aaf8880..6575949552 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt @@ -56,7 +56,6 @@ import im.vector.app.features.call.dialpad.CallDialPadBottomSheet import im.vector.app.features.call.dialpad.DialPadFragment import im.vector.app.features.call.transfer.CallTransferActivity import im.vector.app.features.call.transfer.CallTransferResult -import im.vector.app.features.call.transfer.CallTransferViewEvents import im.vector.app.features.call.utils.EglUtils import im.vector.app.features.call.webrtc.WebRtcCall import im.vector.app.features.call.webrtc.WebRtcCallManager @@ -534,7 +533,7 @@ class VectorCallActivity : VectorBaseActivity(), CallContro private val callTransferActivityResultLauncher = registerStartForActivityResult { activityResult -> - when(activityResult.resultCode) { + when (activityResult.resultCode) { Activity.RESULT_CANCELED -> { callViewModel.handle(VectorCallViewActions.CallTransferSelectionCancelled) } diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferResult.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferResult.kt index 238c916634..8dc2db60b8 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferResult.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferResult.kt @@ -19,7 +19,6 @@ package im.vector.app.features.call.transfer import android.os.Parcelable import kotlinx.parcelize.Parcelize - sealed class CallTransferResult : Parcelable{ @Parcelize data class ConnectWithUserId(val consultFirst: Boolean, val selectedUserId: String) : CallTransferResult() @Parcelize data class ConnectWithPhoneNumber(val consultFirst: Boolean, val phoneNumber: String) : CallTransferResult() diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt index 64140eacf0..1765b58a02 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt @@ -22,15 +22,10 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory -import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.VectorViewModel -import im.vector.app.features.call.dialpad.DialPadLookup import im.vector.app.features.call.webrtc.WebRtcCall import im.vector.app.features.call.webrtc.WebRtcCallManager -import im.vector.app.features.createdirect.DirectRoomHelper -import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.call.CallState import org.matrix.android.sdk.api.session.call.MxCall @@ -68,5 +63,4 @@ class CallTransferViewModel @AssistedInject constructor(@Assisted initialState: } override fun handle(action: EmptyAction) { } - } From 74e72ed7a066a1351ed6fe5a24265ab41ba5b31a Mon Sep 17 00:00:00 2001 From: David Langley Date: Thu, 10 Feb 2022 19:34:14 +0000 Subject: [PATCH 041/302] lint --- .../vector/app/features/call/transfer/CallTransferActivity.kt | 1 - .../im/vector/app/features/call/transfer/CallTransferResult.kt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt index 4c0f092e3b..148ed5e7c2 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt @@ -16,7 +16,6 @@ package im.vector.app.features.call.transfer -import android.app.Activity import android.content.Context import android.content.Intent import android.os.Bundle diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferResult.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferResult.kt index 8dc2db60b8..0629e91d35 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferResult.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferResult.kt @@ -19,7 +19,7 @@ package im.vector.app.features.call.transfer import android.os.Parcelable import kotlinx.parcelize.Parcelize -sealed class CallTransferResult : Parcelable{ +sealed class CallTransferResult : Parcelable { @Parcelize data class ConnectWithUserId(val consultFirst: Boolean, val selectedUserId: String) : CallTransferResult() @Parcelize data class ConnectWithPhoneNumber(val consultFirst: Boolean, val phoneNumber: String) : CallTransferResult() } From 79d58fb1780864125e6350c65b059f249a9be182 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 9 Feb 2022 02:05:34 +0000 Subject: [PATCH 042/302] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (2785 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/ --- vector/src/main/res/values-zh-rTW/strings.xml | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index 3dcf132f92..ec901985ea 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -3038,4 +3038,37 @@ 位置 加密設定錯誤,因此您無法傳送訊息。點擊以開啟設定。 加密設定錯誤,因此您無法傳送訊息。請聯絡管理員將加密還原至有效的狀態。 + 顯示訊息泡泡 + 載入地圖失敗 + 地圖 + 注意:應用程式將會重新啟動 + 啟用討論串訊息 + 連線至伺服器 + 想要加入現有的伺服器? + 略過此問題 + 還不確定?您可以 %s + 社群 + 團隊 + 朋友與家人 + 我們將會協助您建立聯繫。 + 您與誰聊最多? + 您已經在檢視此討論串了! + 在聊天室中檢視 + 在討論串中回覆 + 可識別指令「%s」,但在討論串中不支援。 + 來自討論串 + 秘訣:長按訊息並使用「%s」。 + 討論串可以協助您的對話不離題且易於追蹤。 + 使用討論串來讓討論保持有條不紊 + 顯示您參與的所有討論串 + 我的討論串 + 從目前的聊天室顯示所有討論串 + 所有討論串 + 過濾 + 討論串 + 討論串 + 過濾聊天室中的討論串 + 複製連結至討論串 + 在聊天室中檢視 + 檢視討論串 \ No newline at end of file From 7ae006af50afe126a4edeb91601f907eb55cb0a0 Mon Sep 17 00:00:00 2001 From: random Date: Wed, 9 Feb 2022 10:03:16 +0000 Subject: [PATCH 043/302] Translated using Weblate (Italian) Currently translated at 100.0% (49 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/it/ --- fastlane/metadata/android/it-IT/changelogs/40103170.txt | 2 ++ fastlane/metadata/android/it-IT/changelogs/40103180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/it-IT/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/it-IT/changelogs/40103180.txt diff --git a/fastlane/metadata/android/it-IT/changelogs/40103170.txt b/fastlane/metadata/android/it-IT/changelogs/40103170.txt new file mode 100644 index 0000000000..f490bc3f0d --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: invia la tua posizione in qualsiasi stanza. Modifica dei sondaggi. +Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/it-IT/changelogs/40103180.txt b/fastlane/metadata/android/it-IT/changelogs/40103180.txt new file mode 100644 index 0000000000..9872ddcb9b --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: invia la tua posizione in qualsiasi stanza. Modifica dei sondaggi. +Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.3.18 From 736d3ab84255289552ddab9d64a3c85fdb06301b Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Thu, 10 Feb 2022 19:19:34 +0000 Subject: [PATCH 044/302] Translated using Weblate (Albanian) Currently translated at 99.5% (2772 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/ --- vector/src/main/res/values-sq/strings.xml | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index d93331777f..1f49d5ba43 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -3084,4 +3084,38 @@ Vendndodhje Fshehtëzimi është formësuar keq, që të mos dërgoni mesazhe. Klikoni që të hapni rregullimet. Fshehtëzimi është formësuar keq, që të mos dërgoni mesazhe. Ju lutemi, lidhuni me një nga përgjegjësit që ta ktheni fshehtëzimin në një gjendje të vlefshme. + Shfaq Flluska mesazhesh + S’u arrit të ngarkohej hartë + Hartë + Shënim: aplikacioni do të riniset + Aktivizoni Rrjedha Mesazhesh + Lidhu te shërbyesi + Po shihni për të marrë pjesë në një shërbyes ekzistues\? + anashkalojeni këtë pyetje + Ende i pasigurt\? Mundeni %s + Bashkësi + Ekipe + Shokë dhe familje + Do t’ju ndihmojmë të lidheni. + Me kë do të bisedoni më shumë\? + Po e shihni tashmë këtë rrjedhë! + Shiheni në Dhomë + Përgjigjuni Te Rrjedha + Urdhri “%s” njihet, por nuk mbulohet në rrjedha. + Nga një Rrjedhë + Ndihmëz: Prekni pakëz gjatë një mesazh dhe përdorni “%s”. + Rrjedhat ndihmojnë që të mbahet biseda juaj brenda temës dhe të ndiqet kollaj. + Mbajini diskutimet të sistemuara në rrjedha + Shfaq krejt rrjedhat ku keni marrë pjesë + Rrjedhat e Mia + Shfaq krejt rrjedhat në dhomën e tanishme + Krejt Rrjedhat + Filtrojeni + Rrjedha + Rrjedhë + Filtroni Rrjedha në dhomë + “Rage shake” që të njoftoni një të metë + Kopjoje lidhjen te rrjedha + Shiheni në dhomë + Shihni Rrjedha \ No newline at end of file From 2b050ed320f625eb8ad2315c0157bb9f5a230f31 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Tue, 8 Feb 2022 18:55:14 +0000 Subject: [PATCH 045/302] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2785 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/ --- vector/src/main/res/values-pt-rBR/strings.xml | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index 228b61cb6f..973a82ebfb 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -3097,4 +3097,37 @@ Comunicação segura e independente que lhe dá o mesmo nível de privacidade que conversa face-a-face em sua própria casa. Encriptação tem sido malconfigurada então você não pode enviar mensagens. Clique para abrir configurações. Encriptação tem sido malconfigurada então você não pode enviar mensagens. Por favor contacte um(a) admin para restaurar encriptação a um estado válido. + Mostrar Bolhas de mensagem + Falha para carregar mapa + Mapa + Nota: app vai ser recomeçado + Habilitar Mensagens de Thread + Conectar a servidor + Procurando se juntar a um servidor existente\? + pular esta pergunta + Não tem certeza ainda\? Você pode %s + Comunidades + Times + Amigas(os) e família + Nós vamos ajudá-la(o) a ficar conectada(o). + Com quem você vai fazer chat mais\? + Você já está visualizando esta thread! + Visualizar Em Sala + Responder Em Thread + O comando \"%s\" é reconhecido mas não suportado em threads. + De uma Thread + Dica: Toque longo numa mensagem e use “%s”. + Threads ajudam a manter suas conversas em-tópico e fáceis de rastrear. + Mantenha discussões organizadas com threads + Mostra todas as threads nas quais você tem participado + Minhas Threads + Mostra todas as threads de sala atual + Todas as Threads + Filtrar + Threads + Thread + Filtrar Threads em sala + Copiar link para thread + Visualizar em sala + Visualizar Threads \ No newline at end of file From e46eeaa5d352a7906054925d788d43a2bc98f7d0 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Thu, 10 Feb 2022 23:25:59 +0000 Subject: [PATCH 046/302] Translated using Weblate (Slovak) Currently translated at 96.0% (2676 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/ --- vector/src/main/res/values-sk/strings.xml | 252 +++++++++++++++++++--- 1 file changed, 219 insertions(+), 33 deletions(-) diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml index 68a3ebd1ff..88cf02d87d 100644 --- a/vector/src/main/res/values-sk/strings.xml +++ b/vector/src/main/res/values-sk/strings.xml @@ -581,7 +581,7 @@ Ciele oznámení Lokálne kontakty Právo pristupovať ku kontaktom - Krajna pre čísla zo zoznamu kontaktov + Krajina telefónneho zoznamu Úvodná obrazovka Pripnúť miestnosti so zmeškanými oznámeniami Pripnúť miestnosti s neprečítanými správami @@ -702,7 +702,7 @@ Kľúč relácie Overenie Odtlačok prsta Ed25519 - Exportovať end-to-end kľúče miestnosti + Exportovať šifrovacie kľúče miestnosti Exportovať kľúče miestnosti Exportovať kľúče do lokálneho súboru Exportovať @@ -711,7 +711,7 @@ Šifrovacie kľúče od miestnosti boli uložené do \'%s\'. \n \nUpozornenie: Tento súbor sa môže vymazaný, ak sa aplikácia odinštaluje. - Importovať end-to-end kľúče miestnosti + Importovať šifrovacie kľúče miestnosti Importovať kľúče miestnosti Importovať kľúče z lokálneho súboru Importovať @@ -915,7 +915,7 @@ Áno, chcem pomôcť! Chýba zadanie povinného argumentu. Argument nie je správny. - Ak chcete aj naďalej používať domovský server %1$s , mali by ste si prečítať a odsúhlasiť naše zmluvné podmienky. + Ak chcete aj naďalej používať domovský server %1$s , mali by ste si prečítať a odsúhlasiť zmluvné podmienky. Prečítať teraz Deaktivovať účet Tým sa vaše konto stane trvalo nepoužiteľným. Nebudete sa môcť prihlásiť a nikto nebude môcť opätovne zaregistrovať rovnaké ID používateľa. To spôsobí, že váš účet opustí všetky miestnosti, ktorých sa zúčastňuje, a odstráni údaje o vašom účte zo servera identity. Táto akcia je nezvratná. @@ -988,7 +988,7 @@ Nastaví tému aktuálnej miestnosti Vykáže zadaného používateľa z miestnosti Mení vaše zobrazované meno / prezývku - Zapína alebo vypína formátovanie textu pomocou markdown + Zapnutie/vypnutie formátovanie textu markdown Užitočné na opravu spravovania aplikácií matrix 1 člen @@ -1066,7 +1066,7 @@ \nProsím, skontrolujte nastavenia ${app_name}u. Povoliť Kontrola aplikácii Služby Google Play - Aplikácia Služby Google Playje k dispozícii a aktualizovaná. + Aplikácia Služby Google Play je k dispozícii a aktualizovaná. ${app_name} používa aplikáciu Služby Google Play na doručovanie oznámení. No zdá sa, že táto nie je správne nakonfigurovaná: \n%1$s Opraviť Služby Play @@ -1098,13 +1098,13 @@ Ak používateľ na nejaký čas ponechá zariadenie s vypnutou obrazovkou odložené odpojené od napájania, na zariadení sa použije režim Doze. Toto aplikáciám zabráni pristupovať k sieti, pozastaví ich naplánované úlohy, synchronizáciu aj bežné signály. Ignorovať optimalizáciu Zobraziť náhľady odkazov v konverzáciách (ak sú podporované domovským serverom). - Odosielať oznámenie keď píšete + Odosielať oznámenia pri písaní Umožniť ostatným používateľom vidieť, kedy píšete. Formátovanie pomocou Markdown - Formátovať správy použitím jazyka markdown. Umožňuje pokročilé formátovanie ako napríklad kurzívu hviezdičkami. + Formátovať správy pomocou syntaxe markdown pred ich odoslaním. To umožňuje pokročilé formátovanie, napríklad použitie hviezdičiek na zobrazenie textu kurzívou. Zobrazovať potvrdenia o prečítaní Klepnutím na potvrdenie o prečítaní zobrazíte podrobný zoznam. - Zobrazovať vstup do a opustenie miestnosti + Zobraziť udalosti vstupu a odchodu Pozvania, odstránenia a zákazy nie sú ovplyvnené. Zobrazovať udalosti účtu Zahŕňa zmeny zobrazovaného mena a obrázka v profile. @@ -1148,7 +1148,7 @@ Pokročilé nastavenia oznámení Dôležitosť oznámení pre udalosti Vlastné nastavenia. - Pozor, Pre typi udalostí, ktoré majú dôležitosť nastavenú na Tiché, sa zobrazí oznámenie bez zvukového upozornenia. + Všimnite si, že niektoré typy správ sú nastavené ako tiché ( vyvolajú oznámenie bez zvuku). Niektoré oznámenia máte zakázané v rozšírených nastaveniach. Nepodarilo sa načítať pravidlá oznámení. Prosím, skúste znovu. Skontrolovať nastavenia @@ -1165,7 +1165,7 @@ Nastaviť tiché oznámenia Vybrať farbu upozornení LED, vibrácie, zvuky… Správa šifrovacích kľúčov - Odosielať správy enterom + Odoslanie správy pomocou enter Stlačením klávesu enter na dotykovej klávesnici odošlete správu namiesto odriadkovania Režim šetrenia údajov aplikuje filter, ktorý potlačí aktualizácie prítomnosti a oznámenia pri písaní. Aktualizovať heslo @@ -1204,7 +1204,7 @@ Náhlad Odmietnuť Nebol nakonfigurovaný server totožnosti. - Hovor zlyhal kvôli zle nakonfigurovanému serveru + Hovor zlyhal z dôvodu nesprávne nastaveného servera Prosím, požiadajte administrátora vášho domovského serveru (%1$s) o konfiguráciu TURN serveru, aby hovory fungovali spoľahlivo. \n \nPrípadne môžete skúsiť použiť verejný server %2$s, ale nebude tak spoľahlivý a bude zdieľať vašu IP adresu s daným serverom. Môžete si to taktiež upraviť v Nastaveniach. @@ -1302,12 +1302,12 @@ Zabezpečte sa pred stratou šifrovaných správ a údajov zálohovaním šifrovacích kľúčov na vašom serveri. Vygenerujte nový bezpečnostný kľúč alebo nastavte novú bezpečnostnú frázu pre existujúcu zálohu. Toto nahradí váš aktuálny kľúč alebo frázu. - Zisťovanie - Spravovať nastavenia zisťovania. + Objavovanie + Spravovať nastavenia objavovania. Povoliť integrácie Správca integrácií Integrácie sú zakázané - Na vykonanie tejto akcie zaškrtnite \'Povoliť integrácie\' v nastaveniach zisťovania. + Ak to chcete urobiť, zapnite \"Povoliť integrácie\" v nastaveniach. Zakázať vstupovať %d používateľ Zakázať vstupovať %d používatelia @@ -1352,7 +1352,7 @@ Nie je nastavený žiadny správca integrácií. Spravovať integrácie Žiadne aktívne widgety - Skôr než budete pokračovať, mali by ste prijať podmienky poskytovania tejto služby. + Ak chcete pokračovať, musíte prijať podmienky tejto služby. Nová relácia žiada o šifrovacie kľúče. \nNázov relácie: %1$s \nPosledné prihlásenie: %2$s @@ -1505,7 +1505,7 @@ Šifrované správy s týmto používateľom sú zabezpečené E2E šifrou a nik okrem vás ich nemôže čítať. Rozumiem Nič sa neobjavuje\? Ešte nie všetci klienti podporujú interaktívne overenie. Použite pôvodný spôsob overenia. - Použiť pôvodný spôsob overenia. + Použiť starší spôsob overenia. Overenie kľúčov Žiadosť zrušená Protistrana prerušila overenie. @@ -1596,8 +1596,8 @@ Názov relácie: Url: Formát: - Hlas a video - Pomoc a o aplikácii + Zvuk a video + Pomoc a O aplikácii Zaregistrovať token Poslať návrh Nižšie napíšte obsah návrhu. @@ -1622,13 +1622,13 @@ Poslať priamu správu Zobraziť adresár miestností Názov alebo ID (#priklad:matrix.org) - Povoliť odpovedať švihnutím na časovej osy + Povoliť posunutím odpovedať na časovej osi Zobrazovať záložku oznámenia na hlavnej obrazovke. Odkaz skopírovaný do schránky Pridať matrix ID Vytváranie miestnosti… Nenájdený žiadny výsledok, ak chcete hľadať na servery, klepnite na pridať Matrix ID. - Výsledky uvidíte hneď, čo začnete písať + Začnite písať a uvidíte výsledky hneď Filtrovať zadaním používateľskeho mena alebo ID… Vstupovanie do miestnosti… Zobraziť históriu úprav @@ -1644,18 +1644,18 @@ Používate server totožností %1$s, aby vás ľudia, ktorých poznáte mohli nájsť a aby ste vy mohli vyhľadávať kontakty. Momentálne nepoužívate server totožností. Nižšie si ho môžete nastaviť, ak chcete vašim známym umožniť, aby vás mohli nájsť a ak aj vy chcete vyhľadávať kontakty. Emailové adresy, podľa ktorých je vás možné nájsť - Možnosti zisťovania sa zobrazia, až keď pridáte emailovú adresu. - Možnosti zisťovania sa zobrazia, až keď pridáte telefónne číslo. + Možnosti objavovania sa zobrazia, až keď pridáte emailovú adresu. + Možnosti objavovania sa zobrazia, až keď pridáte telefónne číslo. Odpojením sa od servera totožností znemožníte ostatným, aby vás našli a tiež nebudete môcť kontakty pozývať zadaním emailovej adresy alebo telefónneho čísla. Telefónne čísla, podľa ktorých je vás možné nájsť - Poslali sme vám potvrdzujúcu správu na adresu %s, skontrolujte si email a overte vašu emailovú adresu klepnutím na odkaz, ktorý obsahuje - Na adresu %s sme vám odoslali potvrdzujúcu správu, aby ste mohli pokračovať, skontrolujte si email a klepnite na odkaz, ktorý sme vám poslali + Odoslali sme vám potvrdzujúci e-mail na adresu %s, skontrolujte svoj e-mail a kliknite na potvrdzujúci odkaz + Odoslali sme vám potvrdzujúci e-mail na adresu %s, najskôr si prosím skontrolujte svoj e-mail a kliknite na potvrdzujúci odkaz Očakáva sa Zadajte URL adresu servera totožností Nie je možné sa pripojiť k serveru totožností Prosím, zadajte URL adresu servera totožností - Server totožností nezverejnil podmienky poskytovania služieb - Vami vybratý server totožností nezverejňuje podmienky používania služieb. Pokračujte len v prípade, že dôverujete vlastníkovi servera + Server totožností nemá podmienky poskytovania služieb + Vami vybratý server totožností nemá žiadne podmienky používania služieb. Pokračujte len v prípade, že dôverujete vlastníkovi servera Na číslo %s bola odoslaná textová správa. Prosím zadajte overovací kód, ktorý obsahuje. Overovací kód nie je správny. Emailové adresy a telefónne čísla zdieľate cez server totožností %1$s. Ak chcete toto zdieľanie zastaviť, mali by ste sa znovu pripojiť k serveru %2$s. @@ -2359,7 +2359,7 @@ Zadaný kód nie je správny. Skontrolujte ho, prosím. Práve sme odoslali e-mail na adresu %1$s. \nKliknutím na odkaz, ktorý obsahuje, pokračujte vo vytváraní účtu. - Akceptujte podmienky pre pokračovanie + Prijmite podmienky pre pokračovanie Vykonajte prosím výzvu captcha Vybrať vlastný domovský server Vybrať službu Element Matrix Services @@ -2487,7 +2487,7 @@ Používateľov sme nemohli pozvať. Skontrolujte používateľov, ktorých chcete pozvať, a skúste to znova. Ahoj, ozvi sa mi na ${app_name}: %s Nemohli sme vytvoriť vašu priamu správu. Skontrolujte používateľov, ktorých chcete pozvať, a skúste to znova. - Kvôli end-to-end šifrovaniu sa môže stať, že budete musieť počkať, kým vám od niekoho príde správa, pretože vám neboli správne odoslané šifrovacie kľúče. + Kvôli end-to-end šifrovaniu sa môže stať, že budete musieť chvíľu počkať, kým vám od niekoho príde správa, pretože vám neboli správne odoslané šifrovacie kľúče. Správy v tejto miestnosti sú šifrované od vás až k príjemcovi. Správy v tejto miestnosti sú end-to-end šifrované. Zistite viac a overte používateľov v ich profile. Správca vášho servera predvolene vypol šifrovanie end-to-end v súkromných miestnostiach a priamych správach. @@ -2549,8 +2549,8 @@ Ak chcete zistiť existujúce kontakty, potrebujete odoslať kontaktné informácie (e-maily a telefónne čísla) na server totožností. Pred odoslaním vaše údaje zahašujeme kvôli ochrane osobných údajov. Odoslať e-maily a telefónne čísla na %s Odoslať e-maily a telefónne čísla - Nedali ste súhlas na odosielanie e-mailov a telefónnych čísel na tento identifikačný server na zistenie ďalších používateľov z vašich kontaktov. - Dali ste súhlas na odosielanie e-mailov a telefónnych čísel na tento identifikačný server na zistenie ďalších používateľov z vašich kontaktov. + Nedali ste súhlas na odosielanie e-mailov a telefónnych čísel na tento server totožností na objavenie ďalších používateľov z vašich kontaktov. + Dali ste súhlas na odosielanie e-mailov a telefónnych čísel na tento server totožností na objavenie ďalších používateľov z vašich kontaktov. Odoslať e-maily a telefónne čísla Spravovať e-maily a telefónne čísla prepojené s vaším účtom Matrix Emaily a telefónne čísla @@ -2665,7 +2665,7 @@ %1$s odmietol tento hovor Tento hovor ste odmietli Nepodarilo sa overiť kód PIN, zadajte nový kód. - Vyberte si bezpečnostný kód PIN + Vyberte si bezpečnostný PIN kód Príliš veľa chýb, boli ste odhlásení Nepodarilo sa zrušiť zákaz používateľovi Zakázaný používateľom %1$s @@ -2818,7 +2818,7 @@ Limit nahrávania súborov na server Odhlásiť sa z tejto relácie Krížové podpisovanie nie je povolené - Vaša nová relácia je teraz overená. Má prístup k vašim šifrovaným správam a ostatný používatelia ju uvidia ako dôveryhodnú. + Vaša nová relácia je teraz overená. Má prístup k vašim šifrovaným správam a ostatní používatelia ju uvidia ako dôveryhodnú. Porovnajte kód s kódom zobrazeným na obrazovke druhého používateľa. Porovnajte jedinečné emoji a uistite sa, že sú zobrazené v rovnakom poradí. Aby ste si boli istý, urobte to osobne alebo použite iný dôveryhodný spôsob komunikácie. @@ -2884,4 +2884,190 @@ Zadajte tajnú frázu, ktorú poznáte len vy, a vygenerujte kľúč na zálohovanie. Vygenerujte bezpečnostný kľúč a uložte ho na bezpečné miesto, napríklad do správcu hesiel alebo trezora. Použiť bezpečnostný kľúč + Zdieľať môj kód + Chybne vytvorená udalosť + Odkaz bol nesprávne vytvorený + Otvoriť podmienky %s + Žiadosti o kľúče + Zobraziť celú históriu v zašifrovaných miestnostiach + Povolením tohto nastavenia sa pridá FLAG_SECURE ku všetkým činnostiam. Reštartujte aplikáciu, aby sa zmena prejavila. + Zabrániť snímkam obrazovky aplikácie + Potvrďte kód PIN, ak chcete deaktivovať kód PIN + Zmeňte svoj aktuálny kód PIN + PIN kód sa vyžaduje pri každom otvorení aplikácie ${app_name}. + PIN kód sa vyžaduje po 2 minútach nepoužívania ${app_name}. + Vyžadovať PIN po 2 minútach + PIN kód je jediný spôsob, ako odomknúť ${app_name}. + Povoliť biometriu špecifickú pre zariadenie, ako sú odtlačky prstov a rozpoznávanie tváre. + Ak chcete vynulovať kód PIN, ťuknite na položku Zabudnutý kód PIN, čím sa odhlásite a vynulujete ho. + Ak chcete obnoviť kód PIN, musíte sa znovu prihlásiť a vytvoriť nový. + Varovanie! Posledný pokus pred odhlásením! + + Nesprávny kód, zostáva %d pokus + Nesprávny kód, zostávajú %d pokusy + Nesprávny kód, zostáva %d pokusov + + Ochrana prístupu pomocou kódu PIN a biometrických údajov. + Ochrana prístupu + Zobrazenie oznámení + Objavovanie (%s) + Dokončiť nastavenie objavovania. + Udeliť súhlas + Odvolať môj súhlas + ${app_name} vyžaduje, aby ste na vykonanie tejto akcie zadali svoje poverenia. + Odstrániť všetky neúspešné správy + Správy sa nepodarilo odoslať + Vymazať neodoslané správy + Určite chcete vymazať všetky neodoslané správy v tejto miestnosti\? + Pozvať pomocou e-mailu + Zatiaľ preskočiť + Pripojiť sa aj tak + Tento alias nie je v súčasnosti dostupný. +\nSkúste to neskôr alebo požiadajte správcu miestnosti, aby skontroloval, či máte prístup. + Zatiaľ nie ste v žiadnej miestnosti. Nižšie sú uvedené niektoré navrhované miestnosti, ale ďalšie si môžete pozrieť pomocou zeleného tlačidla vpravo dole. + Vitajte v %1$s, %2$s. + Kompresia videa %d%% + %s vás pozval + V prípade ďalších otázok ma môžete kontaktovať + Ďakujeme, vaša spätná väzba bola úspešne odoslaná + Ospravedlňujeme sa, pri pokuse o pripojenie došlo k chybe: %s + Aktualizuje miestnosť na novšiu verziu + Buďte prosím trpezliví, môže to chvíľu trvať. + Aktualizovať verejnú miestnosť + Aktualizovať súkromnú miestnosť + Aktualizácia miestnosti je pokročilá akcia a zvyčajne sa odporúča, keď je miestnosť nestabilná kvôli chybám, chýbajúcim funkciám alebo bezpečnostným zraniteľnostiam. +\nZvyčajne to má vplyv len na spôsob spracovania miestnosti na serveri. + Túto miestnosť aktualizujete z %1$s na %2$s. + Na aktualizáciu miestnosti potrebujete povolenie + Táto miestnosť používa verziu miestnosti %s, ktorú tento domovský server označil ako nestabilnú. + Aktualizovať na odporúčanú verziu miestnosti + Prehrať hlasovú správu + Pozastaviť hlasovú správu + Povoliť hlasovú správu + Nie je možné prehrať túto hlasovú správu + Nemôžete odpovedať ani upravovať, kým je hlasová správa aktívna + Hlasová správa (%1$s) + Vezmite prosím na vedomie, že aktualizácia vytvorí novú verziu miestnosti. Všetky aktuálne správy zostanú v tejto archivovanej miestnosti. + Posunutím ukončíte hovor + Začal sa skupinový hovor + Prepojte tento e-mail so svojím účtom + Vyhľadávať podľa mena, ID alebo e-mailu + Otvoriť nastavenia objavovania + Pozvať e-mailom, nájsť kontakty a ďalšie… + Dokončiť nastavenie + Ignoruje používateľa a skryje pred vami jeho správy + Prestane ignorovať používateľa a začne zobrazovať jeho správy + Nastaví názov miestnosti + Zmení vaše zobrazované meno len v aktuálnej miestnosti + Zmení obrázok aktuálnej miestnosti + Zmení váš obrázok len pre túto miestnosť + Zobrazuje informácie o používateľovi + Zobraziť pravidlá a zásady servera totožností + Skryť pravidlá a zásady servera totožností + Server totožností neposkytuje žiadne pravidlá a zásady + Vaše kontakty sú súkromné. Aby sme mohli zistiť používateľov z vašich kontaktov, potrebujeme vaše povolenie na odoslanie kontaktných informácií na váš server totožností. + Otázka alebo téma ankety + Otázka alebo téma + Možnosť %1$d + PRIDAŤ MOŽNOSŤ + VYTVORIŤ ANKETU + Otázka nemôže byť prázdna + + Vyžaduje sa aspoň %1$s možnosť + Vyžadujú sa aspoň %1$s možnosti + Vyžaduje sa aspoň %1$s možností + + + Na základe %1$d hlasu + Na základe %1$d hlasov + Na základe %1$d hlasov + + + %1$d odovzdaný hlas. Hlasujte a pozrite si výsledky + %1$d odovzdané hlasy. Hlasujte a pozrite si výsledky + %1$d odovzdaných hlasov. Hlasujte a pozrite si výsledky + + + Konečný výsledok na základe %1$d hlasu + Konečný výsledok na základe %1$d hlasov + Konečný výsledok na základe %1$d hlasov + + Ukončiť túto anketu\? + Týmto sa zastaví možnosť hlasovania a zobrazia sa konečné výsledky ankety. + Určite chcete túto anketu odstrániť\? Po odstránení ju už nebudete môcť obnoviť. + Nesprávne nastavená úroveň dôveryhodnosti + UPRAVIŤ ANKETU + Typ ankety + Otvoriť anketu + Hlasujúci uvidia výsledky hneď po hlasovaní + Uzavretá anketa + Zobraziť vlákna + Príkaz \"%s\" bol rozpoznaný, ale nie je podporovaný vo vláknach. + Odpovedať vo vlákne + Zobraziť v miestnosti + Toto vlákno si už prezeráte! + S kým budete komunikovať najčastejšie\? + Pomôžeme vám pripojiť sa. + Priatelia a rodina + Tímy + Komunity + Ešte si nie ste istí\? Môžete %s + preskočiť túto otázku + Pripojiť sa k serveru + Povoliť správy vo vláknach + Poznámka: aplikácia sa reštartuje + Mapa + Nepodarilo sa načítať mapu + Zobraziť správy v bublinách + Ospravedlňujeme sa, pri pokuse o pripojenie ku konferencii došlo k chybe + Tento server sa už nachádza v zozname + Nemôžeme nájsť tento server alebo jeho zoznam miestností + Zadajte názov nového servera, ktorý chcete preskúmať. + Pridať nový server + Rozhodnite, kto môže túto miestnosť nájsť a pripojiť sa k nej. + Ktokoľvek môže nájsť miestnosť a pripojiť sa + Nájsť a pripojiť sa môžu len pozvaní ľudia + Súkromné (len pre pozvaných) + Neznáme nastavenie prístupu (%s) + Ktokoľvek môže zaklopať na miestnosť, členovia ho potom môžu prijať alebo odmietnuť + Nie je možné načítať viditeľnosť aktuálneho adresára miestnosti (%1$s). + Zverejniť túto miestnosť verejnosti v adresári miestností %1$s\? + Pre túto miestnosť nie sú žiadne miestne adresy + Pridať miestnu adresu + Nastavte adresy pre túto miestnosť, aby ju používatelia mohli nájsť prostredníctvom vášho domovského servera (%1$s) + Nová zverejnená adresa (napr. #alias:server) + Zatiaľ neboli zverejnené žiadne ďalšie adresy. + Zatiaľ neboli zverejnené žiadne ďalšie adresy, pridajte jednu nižšie. + Zverejniť túto miestnosť v adresári miestností %1$s\? + Vymazať adresu \"%1$s\"\? + Zrušiť zverejnenie adresy \"%1$s\"\? + Zverejnite novú adresu ručne + Toto je hlavná adresa + Zverejnené adresy môže použiť ktokoľvek na akomkoľvek serveri, aby sa pripojil k vašej miestnosti. Ak chcete zverejniť adresu, musíte ju najprv nastaviť ako miestnu adresu. + Zobraziť a spravovať adresy tejto miestnosti a jej viditeľnosť v adresári miestností. + Umožniť hosťom pripojiť sa + Kto má prístup\? + Zmeny týkajúce sa toho, kto môže čítať históriu, sa budú vzťahovať len na budúce správy v tejto miestnosti. Viditeľnosť existujúcej histórie zostane nezmenená. + Tento server neposkytuje žiadne zásady a pravidlá. + Pridať tlačidlo do editora správ na otvorenie klávesnice emodži + Zobraziť klávesnicu emodži + Použite príkaz /confetti alebo pošlite správu obsahujúcu ❄️ alebo 🎉 + Zobraziť efekty konverzácie + Relácia bola odhlásená! + Z vlákna + Tip: Dlho ťuknite na správu a použite \"%s\". + Vlákna pomáhajú udržiavať konverzácie v téme a ľahké sledovanie. + Udržujte diskusie organizované pomocou vlákien + Zobrazí všetky vlákna, v ktorých ste sa zúčastnili + Moje vlákna + Zobrazí všetky vlákna z aktuálnej miestnosti + Všetky vlákna + Filter + Vlákna + Vlákno + Filtrovať vlákna v miestnosti + Ukončenie hovoru… + Vyzváňanie hovoru… + Kopírovať odkaz na vlákno + Zobraziť v miestnosti \ No newline at end of file From 265e9d4879093f71ca702099844432dc573e614c Mon Sep 17 00:00:00 2001 From: noantiq Date: Wed, 9 Feb 2022 13:25:27 +0000 Subject: [PATCH 047/302] Translated using Weblate (German) Currently translated at 99.6% (2775 of 2785 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 | 39 +++++++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 2fb5b8450d..622db6324d 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -849,7 +849,7 @@ Alle Nachrichten (laut) Alle Nachrichten Nur Erwähnungen - Stumm + Stummschalten URL-Vorschau im Chat Vibriere beim Erwähnen eines Nutzers Benachrichtigungen @@ -1672,7 +1672,7 @@ Erweitere & individualisiere dein Benutzererlebnis Mit %1$s verbinden Mit Element Matrix Services verbinden - Mit einem benutzerdefinierten Server verbinden + Mit einem individuellen Server verbinden Bei %1$s anmelden Registrieren Anmelden @@ -3026,7 +3026,7 @@ Schließe die Konfiguration des Auffindbarkeitsdienstes ab. Du verwendest derzeit keinen Identitätsserver. Um Teammitglieder einzuladen und für sie auffindbar zu sein, müssen du einen solchen Server konfigurieren. Ich habe schon ein Konto - Vernetz dich mit jedem. + Sichere Nachrichtenübertragung. Besitze deine Konversationen. Richtlinie Um bestehende Kontakte ermitteln zu können, müsst du Kontaktinformationen (E-Mails und Telefonnummern) an Ihren Identitätsserver senden. Wir verschlüsseln deine Daten vor dem Senden, um den Datenschutz zu gewährleisten. @@ -3091,4 +3091,37 @@ Geteilte Standorte anzeigen Sobald aktiviert, kannst du deinen Standort in jeden Raum senden Hat den Standort geteilt + Threads aktivieren + Mit Server verbinden + Du schaust dir diesen Thread schon an! + Im Raum anzeigen + Der Befehl „%s“ wird erkannt, ist in Threads aber nicht unterstützt. + Tipp: Drücke lange auf eine Nachricht und wähle “%s”. + Organisiere Diskussionen mit Threads + Threads im Raum filtern + Möchtest du einem existierenden Server beitreten\? + Communities + Teams + Wir helfen dir, in Verbindung zu kommen. + Mit wem wirst du am meisten chatten\? + Link zu Thread kopieren + Threads anzeigen + Nachrichtenblasen anzeigen + Laden der Karte fehlgeschlagen + Karte + Hinweis: App wird neugestartet + diese Frage überspringen + Noch nicht sicher\? Du kannst %s + Freundschaften und Familie + In Thread antworten + Aus einem Thread + Filter + Im Raum anzeigen + Threads helfen dabei, dass deine Konversationen beim Thema und leicht nachverfolgbar bleiben. + Zeigt alle Threads, an denen du teilgenommen hast + Zeigt alle Threads des aktuellen Raums + Alle Threads + Meine Threads + Threads + Thread \ No newline at end of file From 4d8f09c96c4644a3b27118c194a03c80cf1900db Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Tue, 8 Feb 2022 21:30:12 +0000 Subject: [PATCH 048/302] Translated using Weblate (Swedish) Currently translated at 99.9% (2784 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/ --- vector/src/main/res/values-sv/strings.xml | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 3b541a3a34..c0d4b757e4 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -3096,4 +3096,37 @@ Plats Kryptering har felkonfigurerats så du kan inte skicka meddelanden. Klicka för att öppna inställningar. Kryptering har felkonfigurerats så du kan inte skicka meddelanden. Vänligen kontakta en admin för att återställa kryptering till ett giltigt tillstånd. + Visa meddelandebubblor + Misslyckades att ladda karta + Karta + Obs: appen kommer att startas om + Aktivera trådade meddelanden + Anslut till server + Vill du gå med i en existerande server\? + hoppa över frågan + Inte säker än\? Du kan %s + Gemenskaper + Team + Vänner och familj + Vi kommer att hjälpa dig att få kontakt. + Vem kommer du chatta med mest\? + Du visar redan den här tråden! + Visa i rum + Svara i tråd + Kommandot \"%s\" kändes igen men stöds inte i trådar. + Från en tråd + Tips: Tryck länge på ett meddelande och använd \"%s\". + Trådar hjälper till att hålla dina konversationer till ämnet och lätta att följa. + Håll diskussioner organiserade med trådar + Visar alla trådar du har deltagit i + Mina trådar + Visar alla trådar från det nuvarande rummet + Alla trådar + Filtrera + Trådar + Tråd + Filtrera trådar i rum + Kopiera länk till tråd + Visa i rum + Visa trådar \ No newline at end of file From 72163b4f8b065f2f42d692d5ada078b0806012b3 Mon Sep 17 00:00:00 2001 From: Hasan Date: Tue, 8 Feb 2022 22:49:55 +0000 Subject: [PATCH 049/302] Translated using Weblate (Turkish) Currently translated at 51.0% (25 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/tr/ --- .../android/tr-TR/changelogs/40103040.txt | 2 + .../android/tr-TR/changelogs/40103050.txt | 2 + .../android/tr-TR/changelogs/40103060.txt | 2 + .../android/tr-TR/changelogs/40103070.txt | 2 + .../android/tr-TR/changelogs/40103080.txt | 2 + .../android/tr-TR/changelogs/40103090.txt | 2 + .../android/tr-TR/changelogs/40103100.txt | 2 + .../android/tr-TR/changelogs/40103110.txt | 2 + .../android/tr-TR/changelogs/40103120.txt | 2 + .../android/tr-TR/changelogs/40103130.txt | 2 + .../android/tr-TR/changelogs/40103140.txt | 2 + .../android/tr-TR/changelogs/40103150.txt | 2 + .../android/tr-TR/changelogs/40103160.txt | 2 + .../android/tr-TR/changelogs/40103170.txt | 2 + .../android/tr-TR/changelogs/40103180.txt | 2 + .../android/tr-TR/full_description.txt | 48 ++++++++++++------- .../android/tr-TR/short_description.txt | 2 +- fastlane/metadata/android/tr-TR/title.txt | 2 +- 18 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103040.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103050.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103060.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103070.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103080.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103090.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103100.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103110.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103120.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103130.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103140.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103150.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103160.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103180.txt diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103040.txt b/fastlane/metadata/android/tr-TR/changelogs/40103040.txt new file mode 100644 index 0000000000..1b2f20e349 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103040.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Doğrudan Mesaj odası için Durum desteği ekleyin (not: durum devre dışı açık matrix.org ). Android Auto desteğini tekrar ekleyin. +Tam değişiklik listesi: https://github.com/vector-im/element-android/releases/tag/v1.3.4 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103050.txt b/fastlane/metadata/android/tr-TR/changelogs/40103050.txt new file mode 100644 index 0000000000..69ac8dcb1f --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103050.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Doğrudan Mesaj odası için Durum desteği ekleyin (not: durum devre dışı açık matrix.org ). Android Auto desteğini tekrar ekleyin. +Tam değişiklik listesi: https://github.com/vector-im/element-android/releases/tag/v1.3.5 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103060.txt b/fastlane/metadata/android/tr-TR/changelogs/40103060.txt new file mode 100644 index 0000000000..396cebd495 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103060.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Doğrudan Mesaj odası için Durum desteği ekleyin (not: durum devre dışı açık matrix.org ). Android Auto desteğini tekrar ekleyin. +Tam değişiklik listesi: https://github.com/vector-im/element-android/releases/tag/v1.3.6 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103070.txt b/fastlane/metadata/android/tr-TR/changelogs/40103070.txt new file mode 100644 index 0000000000..62b3fa8824 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103070.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Esas olarak bildirimlerle ilgili hata düzeltmeleri. +Tam değişiklik listesi: https://github.com/vector-im/element-android/releases/tag/v1.3.7-RC2 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103080.txt b/fastlane/metadata/android/tr-TR/changelogs/40103080.txt new file mode 100644 index 0000000000..6d802d09f7 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103080.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Hata düzeltmeleri! +Tam değişiklik listesi: https://github.com/vector-im/element-android/releases/tag/v1.3.8 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103090.txt b/fastlane/metadata/android/tr-TR/changelogs/40103090.txt new file mode 100644 index 0000000000..4acef8f885 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103090.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Sesli mesaj taslağı için destek ekleyin. Birçok hata düzeltmeleri! +Tam değişiklik listesi: https://github.com/vector-im/element-android/releases/tag/v1.3.9 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103100.txt b/fastlane/metadata/android/tr-TR/changelogs/40103100.txt new file mode 100644 index 0000000000..1ccdf8210e --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103100.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Anketler için destek ekleyin (laboratuarlarda). Yeni URL önizleme tasarımı. +Tam değişiklik listesi: https://github.com/vector-im/element-android/releases/tag/v1.3.10 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103110.txt b/fastlane/metadata/android/tr-TR/changelogs/40103110.txt new file mode 100644 index 0000000000..c59f57a897 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103110.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Hata düzeltmeleri! +Tam değişiklik listesi: https://github.com/vector-im/element-android/releases/tag/v1.3.11 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103120.txt b/fastlane/metadata/android/tr-TR/changelogs/40103120.txt new file mode 100644 index 0000000000..9ba7fa4556 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103120.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Hata düzeltmeleri! +Tam değişiklik listesi: https://github.com/vector-im/element-android/releases/tag/v1.3.12 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103130.txt b/fastlane/metadata/android/tr-TR/changelogs/40103130.txt new file mode 100644 index 0000000000..1f356f8360 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103130.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Analytics'in etkinleştirilmesi de dahil olmak üzere, ilk önce yerleşik ekranlardaki değişiklikler. Laboratuvarlara Matematik eklenmiş Etkinlikler için destek. +Tam değişiklik listesi: https://github.com/vector-im/element-android/releases/tag/v1.3.13 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103140.txt b/fastlane/metadata/android/tr-TR/changelogs/40103140.txt new file mode 100644 index 0000000000..d8e2d5f614 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103140.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Analytics'in etkinleştirilmesi de dahil olmak üzere, ilk önce yerleşik ekranlardaki değişiklikler. Laboratuvarlara Matematik eklenmiş Etkinlikler için destek. +Tam değişiklik listesi: https://github.com/vector-im/element-android/releases/tag/v1.3.14 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103150.txt b/fastlane/metadata/android/tr-TR/changelogs/40103150.txt new file mode 100644 index 0000000000..7e98b545e8 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103150.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Analytics'in etkinleştirilmesi de dahil olmak üzere, ilk önce yerleşik ekranlardaki değişiklikler. Laboratuvarlara Matematik eklenmiş Etkinlikler için destek. +Tam değişiklik listesi: https://github.com/vector-im/element-android/releases/tag/v1.3.15 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103160.txt b/fastlane/metadata/android/tr-TR/changelogs/40103160.txt new file mode 100644 index 0000000000..594b19dbfc --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103160.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: konumunuzu herhangi bir odaya gönderin. Anketi düzenleyin. +Tam değişiklik günlüğü: https://github.com/vector-im/element-android/releases/tag/v1.3.16 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103170.txt b/fastlane/metadata/android/tr-TR/changelogs/40103170.txt new file mode 100644 index 0000000000..4bb0b066b6 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: konumunuzu herhangi bir odaya gönderin. Anketi düzenleyin. +Tam değişiklik günlüğü: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103180.txt b/fastlane/metadata/android/tr-TR/changelogs/40103180.txt new file mode 100644 index 0000000000..ce1573e113 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: konumunuzu herhangi bir odaya gönderin. Anketi düzenleyin. +Tam değişiklik günlüğü: https://github.com/vector-im/element-android/releases/tag/v1.3.18 diff --git a/fastlane/metadata/android/tr-TR/full_description.txt b/fastlane/metadata/android/tr-TR/full_description.txt index 3895621620..8ce63e40a1 100644 --- a/fastlane/metadata/android/tr-TR/full_description.txt +++ b/fastlane/metadata/android/tr-TR/full_description.txt @@ -1,30 +1,42 @@ -Element, şu özelliklere sahip yeni bir tür mesajlaşma ve işbirliği uygulamasıdır: +Element, hem güvenli bir haberci hem de uzaktan çalışırken grup sohbetleri için ideal olan bir üretkenlik ekibi işbirliği uygulamasıdır. Bu sohbet uygulaması, güçlü video konferans, dosya paylaşımı ve sesli aramalar sağlamak için uçtan uca şifreleme kullanır. -1. Gizliliğinizi korumak için kontrolü size verir -2. Matrix ağındaki herkesle ve hatta Slack gibi uygulamalarla entegre olarak iletişim kurmanızı sağlar -3. Sizi reklamlardan, veri madenciliğinden ve walled gardenlardan korur -4. Başkalarını doğrulamak için çapraz imzalama ile uçtan uca şifreleme yoluyla güvenliğinizi sağlar + Elementin özellikleri şunları içerir: + - Gelişmiş çevrimiçi iletişim araçları + - Uzak çalışanlar için bile daha güvenli kurumsal iletişime izin vermek için tamamen şifrelenmiş mesajlar + - Matrix açık kaynak çerçevesine dayalı merkezi olmayan sohbet + - Projeleri yönetirken şifreli verilerle güvenli dosya paylaşımı + - IP üzerinden Ses ve ekran paylaşımı ile görüntülü sohbetler + - En sevdiğiniz çevrimiçi işbirliği araçları, proje yönetimi araçları, VoIP hizmetleri ve diğer ekip mesajlaşma uygulamalarıyla kolay entegrasyon -Element, dağıtık (decentralized) ve açık kaynak olduğu için diğer mesajlaşma ve işbirliği uygulamalarından tamamen farklıdır. + Element, diğer mesajlaşma ve işbirliği uygulamalarından tamamen farklıdır. Güvenli mesajlaşma ve merkezi olmayan iletişim için açık bir ağ olan Matrix üzerinde çalışır. Kendi kendine barındırmanın, kullanıcılara verilerinin ve mesajlarının maksimum sahipliğini ve kontrolünü vermesini sağlar. -Element kendi sunucunuzu kurmanıza yada bir sunucu seçmenizi izin verir, böylece verilerinizin ve sohbetlerinizin gizliliğine ve kontrolüne sahip olursunuz. Size açık bir ağa erişim sağlar; yani yalnızca diğer Element kullanıcılarıyla konuşmak zorunda kalmazsınız. Ve çok güvenlidir. + Gizlilik ve şifreli mesajlaşma + Element sizi istenmeyen reklamlardan, veri madenciliğinden ve duvarlarla çevrili bahçelerden korur. Ayrıca uçtan uca şifreleme ve çapraz imzalı cihaz doğrulama yoluyla tüm verilerinizi, bire bir video ve sesli iletişiminizi korur. -Element, açık, merkezi olmayan iletişim standardı olan Matrix üzerinde çalıştığı için tüm bunları yapabilir. + Element, Slack gibi uygulamalarla bütünleşerek Matrix ağındaki herhangi biriyle veya diğer iş işbirliği araçlarıyla güvenli bir şekilde iletişim kurmanıza izin verirken gizliliğiniz üzerinde kontrol sağlar. -Element, konuşmalarınızın sunucusunu seçmenize izin vererek kontrolü size verir. Element uygulamasından, farklı şekillerde sunucu seçebilirsiniz: + Öğe kendi kendine barındırılabilir + Hassas verileriniz ve konuşmalarınız üzerinde daha fazla kontrole izin vermek için Element, kendi kendine barındırılabilir veya açık kaynak, merkezi olmayan iletişim standardı olan Matrix tabanlı herhangi bir ana bilgisayarı seçebilirsiniz. Element size gizlilik, güvenlik uyumluluğu ve entegrasyon esnekliği sağlar. -1. Matrix geliştiricilerinin sahip olduğu matrix.org genel sunucusunda ücretsiz bir hesap edinin veya gönüllüler tarafından barındırılan binlerce genel sunucu arasından seçim yapın -2. Kendi donanımınız üzerinde bir sunucu çalıştırarak kendi hesabınızı barındırın -3. Element Matrix Hizmetleri sunucu platformuna abone olarak özel bir sunucuda hesap oluşturun + Verilerinizin sahibi olun + Verilerinizi ve mesajlarınızı nerede tutacağınıza siz karar verirsiniz. Veri madenciliği veya üçüncü şahıslardan erişim riski olmadan. -Neden Element'i Seçmelisiniz + Element, kontrolü farklı şekillerde size verir: + 1. Matrix geliştiricileri tarafından barındırılan matrix.org genel sunucusunda ücretsiz bir hesap edinin veya gönüllüler tarafından barındırılan binlerce genel sunucu arasından seçim yapın + 2. Kendi BT altyapınızda bir sunucu çalıştırarak hesabınızı kendiniz barındırın + 3. Element Matrix Services barındırma platformuna abone olarak özel bir sunucuda bir hesap için kaydolun -KENDİ VERİLERİNİZE SAHİP OLUN : Verilerinizi ve mesajlarınızı nerede saklayacağınıza siz karar verirsiniz. Verilerinize madencilik yapan veya üçüncü şahıslara erişim sağlayan bir BÜYÜKŞİRKETE verilerinizi vermiyorsunuz, onlara sahipsiniz ve kontrol ediyorsunuz. + Açık mesajlaşma ve ortak çalışma + Element, başka bir Matrix uygulaması veya farklı bir mesajlaşma uygulaması kullanıyor olsalar bile, Matrix ağındaki herkesle sohbet edebilirsiniz. -AÇIK MESAJLAŞMA VE İŞBİRLİĞİ: Element veya başka bir Matrix uygulamalarını kullanmaları fark etmeksizin, hatta Slack, IRC yada XMPP gibi farklı mesajlaşma uygulamaları kullanıyor olsalar bile, Matrix sunucusundaki herhangi biriyle konuşabilirsiniz + Süper güvenli + Gerçek uçtan uca şifreleme (yalnızca görüşmedekiler mesajların şifresini çözebilir) ve çapraz imzalı cihaz doğrulaması. -SÜPER GÜVENLİ: Gerçek uçtan uca şifreleme (yalnızca görüştüğünüz kişiler mesajların şifresini çözebilir) ve konuşma katılımcılarının cihazlarını doğrulamak için çapraz imzalama. + Tam iletişim ve entegrasyon + Mesajlaşma, sesli ve görüntülü aramalar, dosya paylaşımı, ekran paylaşımı ve bir sürü entegrasyon, bot ve widget. Odalar, topluluklar oluşturun, iletişimde kalın ve işlerinizi halledin. -TAM İLETİŞİM: Mesajlaşma, sesli ve görüntülü aramalar, dosya paylaşımı, ekran paylaşımı ve bir sürü entegrasyon, bot ve widgetlar. Odalar, topluluklar oluşturun, iletişimde kalın ve işlerinizi halledin. + Kaldığınız yerden devam edin + https://app.element.io adresinde tüm cihazlarınızda ve web'de tamamen senkronize edilmiş mesaj geçmişiyle nerede olursanız olun bağlantıda kalın -OLDUĞUNUZ HER YERDE: Nerede olursanız olun, tüm cihazlarınızda ve internette https://app.element.io adresinden tam senkronize mesaj geçmişiyle iletişimde kalın + Açık kaynak + Element Android, GitHub tarafından barındırılan açık kaynaklı bir projedir. Lütfen https://github.com/vector-im/element-android adresinde hataları bildirin ve/veya gelişimine katkıda bulunun. diff --git a/fastlane/metadata/android/tr-TR/short_description.txt b/fastlane/metadata/android/tr-TR/short_description.txt index f730519d33..7965a7c857 100644 --- a/fastlane/metadata/android/tr-TR/short_description.txt +++ b/fastlane/metadata/android/tr-TR/short_description.txt @@ -1 +1 @@ -Güvenli ve merkezsiz sohbet ve VoIP. Verilerinizi üçüncü taraflardan sakının. +Grup mesajlaşma - şifreli mesajlaşma, grup sohbeti ve görüntülü aramalar diff --git a/fastlane/metadata/android/tr-TR/title.txt b/fastlane/metadata/android/tr-TR/title.txt index 28088f3da4..bb365ccdd0 100644 --- a/fastlane/metadata/android/tr-TR/title.txt +++ b/fastlane/metadata/android/tr-TR/title.txt @@ -1 +1 @@ -Element (eskiden Riot.im) +Element - Güvenli Mesajlaşma From 12fb26fb383660eaf45f294efece09d8e298254d Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Wed, 9 Feb 2022 07:25:10 +0000 Subject: [PATCH 050/302] Translated using Weblate (Czech) Currently translated at 100.0% (2785 of 2785 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 | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index dbbb6d5238..6004d94ee7 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -3156,4 +3156,37 @@ Bezpečná a nezávislá komunikace, která vám poskytne stejnou úroveň soukromí jako osobní rozhovor u vás doma. Poloha Šifrování bylo špatně nakonfigurováno, takže nelze odesílat zprávy. Kliknutím otevřete nastavení. + Zobrazit bubliny zpráv + Nepodařilo se načíst mapu + Mapa + Poznámka: aplikace bude restartována + Povolit zprávy ve vláknech + Připojit se k serveru + Chcete se připojit k existujícímu serveru\? + přeskočit tuto otázku + Ještě si nejste jisti\? Můžete %s + Komunity + Týmy + Přátelé a rodina + Pomůžeme vám se připojit. + S kým si budete povídat nejčastěji\? + Již si prohlížíte toto vlákno! + Prohlédnout v místnosti + Odpovědět ve vlákně + Příkaz „%s“ je rozpoznán, ale není podporován ve vláknech. + Z vlákna + Tip: Dlouze klepněte na zprávu a použijte „%s“. + Vlákna pomáhají udržovat konverzace k tématu a snadno je sledovat. + Udržujte diskuse organizované pomocí vláken + Zobrazí všechna vlákna, kterých jste se zúčastnili + Moje vlákna + Zobrazí všechna vlákna z aktuální místnosti + Všechna vlákna + Filtr + Vlákna + Vlákno + Filtrovat vlákna v místnosti + Kopírovat odkaz na vlákno + Prohlédnout v místnosti + Zobrazit vlákna \ No newline at end of file From 47f1491069c26beb19449c55b86cfb08b80689b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Tue, 8 Feb 2022 22:39:20 +0000 Subject: [PATCH 051/302] Translated using Weblate (Estonian) Currently translated at 100.0% (49 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/et/ --- fastlane/metadata/android/et/changelogs/40103170.txt | 2 ++ fastlane/metadata/android/et/changelogs/40103180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/et/changelogs/40103180.txt diff --git a/fastlane/metadata/android/et/changelogs/40103170.txt b/fastlane/metadata/android/et/changelogs/40103170.txt new file mode 100644 index 0000000000..0dda39444a --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: oma asukoha saatmine jututuppa ja küsitluste muutmise võimalus. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/et/changelogs/40103180.txt b/fastlane/metadata/android/et/changelogs/40103180.txt new file mode 100644 index 0000000000..55f251f454 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: oma asukoha saatmine jututuppa ja küsitluste muutmise võimalus. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.3.18 From 967eb8ae76b3a4ce09d6a43df434b2c5890a033e Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Tue, 8 Feb 2022 21:21:05 +0000 Subject: [PATCH 052/302] Translated using Weblate (Swedish) Currently translated at 100.0% (49 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sv/ --- fastlane/metadata/android/sv-SE/changelogs/40103170.txt | 2 ++ fastlane/metadata/android/sv-SE/changelogs/40103180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/sv-SE/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/sv-SE/changelogs/40103180.txt diff --git a/fastlane/metadata/android/sv-SE/changelogs/40103170.txt b/fastlane/metadata/android/sv-SE/changelogs/40103170.txt new file mode 100644 index 0000000000..ae2be8bd17 --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: skicka din plats till vilket rum som helst. Redigera omröstningar. +Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/sv-SE/changelogs/40103180.txt b/fastlane/metadata/android/sv-SE/changelogs/40103180.txt new file mode 100644 index 0000000000..fe5b212d9c --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: skicka din plats till vilket rum som helst. Redigera omröstningar. +Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.3.18 From d96c276fad2a9ec7d4b3f7fc3cb105a0474ffbf9 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Wed, 9 Feb 2022 22:50:21 +0000 Subject: [PATCH 053/302] Translated using Weblate (Slovak) Currently translated at 100.0% (49 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sk/ --- .../metadata/android/sk/changelogs/40103170.txt | 2 ++ .../metadata/android/sk/changelogs/40103180.txt | 2 ++ fastlane/metadata/android/sk/full_description.txt | 13 +++++++------ 3 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 fastlane/metadata/android/sk/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/sk/changelogs/40103180.txt diff --git a/fastlane/metadata/android/sk/changelogs/40103170.txt b/fastlane/metadata/android/sk/changelogs/40103170.txt new file mode 100644 index 0000000000..58e5f1fa61 --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: odoslanie polohy do ľubovoľnej miestnosti. Úprava ankety. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/sk/changelogs/40103180.txt b/fastlane/metadata/android/sk/changelogs/40103180.txt new file mode 100644 index 0000000000..b5649471cb --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: odoslanie polohy do ľubovoľnej miestnosti. Úprava ankety. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases/tag/v1.3.18 diff --git a/fastlane/metadata/android/sk/full_description.txt b/fastlane/metadata/android/sk/full_description.txt index 78661e961e..d653933c48 100644 --- a/fastlane/metadata/android/sk/full_description.txt +++ b/fastlane/metadata/android/sk/full_description.txt @@ -1,4 +1,4 @@ -Element je zabezpečený messenger a zároveň aplikácia na tímovú spoluprácu, ktorá je ideálna na skupinové konverzácie pri práci na diaľku. Táto komunikačná aplikácia využíva end-to-end šifrovanie na poskytovanie výkonných videokonferencií, zdieľania súborov a hlasových hovorov. +Element je bezpečný messenger a zároveň aplikácia na tímovú spoluprácu, ktorá je ideálna na skupinové konverzácie pri práci na diaľku. Táto komunikačná aplikácia využíva end-to-end šifrovanie na poskytovanie výkonných videokonferencií, zdieľania súborov a hlasových hovorov. Funkcie aplikácie Element zahŕňajú: - Pokročilé nástroje na online komunikáciu @@ -11,14 +11,15 @@ Element je zabezpečený messenger a zároveň aplikácia na tímovú spoluprác Element sa úplne líši od ostatných aplikácií na zasielanie správ a spoluprácu. Funguje na Matrixe, otvorenej sieti na bezpečné posielanie správ a decentralizovanú komunikáciu. Umožňuje vlastný hosting, aby používatelia získali maximálne vlastníctvo a kontrolu nad svojimi údajmi a správami. Súkromie a šifrovanie správ -Element vás chráni pred nežiaducimi reklamami, ťažbou údajov a tzv. walled gardens. Zabezpečuje tiež všetky vaše údaje, video a hlasovú komunikáciu jeden na jedného prostredníctvom end-to-end šifrovania a overovania zariadení krížovým podpisovaním +Element vás chráni pred nežiaducimi reklamami, ťažbou údajov a tzv. walled gardens. Zabezpečuje tiež všetky vaše údaje, video a hlasovú komunikáciu jeden na jedného prostredníctvom end-to-end šifrovania a overovania zariadení krížovým podpisovaním. + Element vám poskytuje kontrolu nad vaším súkromím a zároveň vám umožňuje bezpečne komunikovať s kýmkoľvek v sieti Matrix alebo s inými nástrojmi na podnikovú spoluprácu vďaka integrácii s aplikáciami, ako je napríklad Slack. -Element môže byť na vašom vlastnom serveri. +Element môže byť na vašom vlastnom serveri Aby ste mali väčšiu kontrolu nad svojimi citlivými údajmi a konverzáciami, Element môže byť na vašom vlastnom serveri alebo si môžete vybrať ľubovoľný hosting založený na systéme Matrix - štandarde pre decentralizovanú komunikáciu s otvoreným zdrojovým kódom. Element vám poskytuje súkromie, súlad s bezpečnostnými predpismi a flexibilitu integrácie. Vlastnite svoje údaje -Vy rozhodujete o tom, kde budú vaše údaje a správy uložené. Bez rizika ťažby údajov alebo prístupu tretích strán. +Vy rozhodujete o tom, kde budú vaše údaje a správy uložené. Bez rizika získavania údajov alebo prístupu tretích strán. Element vám dáva kontrolu rôznymi spôsobmi: 1. Získajte bezplatné konto na verejnom serveri matrix.org, ktorý hostia vývojári Matrixu, alebo si vyberte z tisícov verejných serverov, ktoré hostia dobrovoľníci. @@ -32,10 +33,10 @@ Môžete komunikovať s kýmkoľvek v sieti Matrix, či už používa aplikáciu Skutočné end-to-end šifrovanie (správy môžu dešifrovať len účastníci konverzácie) a krížové overovanie zariadení. Kompletná komunikácia a integrácia -Správy, hlasové a video hovory, zdieľanie súborov, zdieľanie obrazovky a celý rad integrácií, botov a widgetov. Vytvárajte miestnosti, komunity, zostaňte v kontakte a vybavujte veci. +Správy, hlasové a video hovory, zdieľanie súborov, zdieľanie obrazovky a celý rad integrácií, botov a widgetov. Vytvárajte miestnosti, komunity, zostaňte v kontakte a vybavte veci. Nadviažte tam, kde ste skončili Buďte v kontakte, nech ste kdekoľvek, vďaka plne synchronizovanej histórii správ vo všetkých zariadeniach a na webe na adrese https://app.element.io. Otvorený zdroj -Element Android je projekt s otvoreným zdrojovým kódom, ktorého hostiteľom je GitHub. Nahlasujte chyby a/alebo prispievajte k jeho vývoju na adrese https://github.com/vector-im/element-android. +Element Android je projekt s otvoreným zdrojovým kódom, ktorého hostiteľom je GitHub. Nahláste prosím chyby a/alebo prispejte k jeho vývoju na https://github.com/vector-im/element-android From ad0dcc726a7f37f6df1c012ce7e1ee37b6682b75 Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Thu, 10 Feb 2022 13:03:47 +0000 Subject: [PATCH 054/302] Translated using Weblate (Korean) Currently translated at 47.4% (1322 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ko/ --- vector/src/main/res/values-ko/strings.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/vector/src/main/res/values-ko/strings.xml b/vector/src/main/res/values-ko/strings.xml index 05524c4f8f..630e830748 100644 --- a/vector/src/main/res/values-ko/strings.xml +++ b/vector/src/main/res/values-ko/strings.xml @@ -1502,4 +1502,22 @@ %1$s가 새로운 토론을 생성함 새로운 토론을 생성함 새로운 방을 생성함 + 표시 이름을 %1$s(으)로 변경했습니다 + 아바타를 변경했습니다 + %1$s님의 초대를 취소했습니다 + %1$s을 출입 금지했습니다 + %1$s님의 출입 금지를 풀었습니다 + %1$s님을 추방했습니다 + 초대를 거부했습니다 + 방을 떠났습니다 + %1$s님이 방을 떠났습니다 + 방을 떠났습니다 + 참가했습니다 + %1$s님이 참가했습니다 + 방에 참가했습니다 + %1$s님을 초대했습니다 + %1$s님이 새로운 방을 생성함 + 내가 보낸 초대 + 스티커를 보냈습니다. + 사진을 보냈습니다. \ No newline at end of file From 50e07c4358fdefc9039af75eb518b7c590e18d15 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Wed, 9 Feb 2022 11:48:29 +0000 Subject: [PATCH 055/302] Translated using Weblate (Hungarian) Currently translated at 100.0% (49 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/hu/ --- fastlane/metadata/android/hu-HU/changelogs/40103170.txt | 2 ++ fastlane/metadata/android/hu-HU/changelogs/40103180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40103180.txt diff --git a/fastlane/metadata/android/hu-HU/changelogs/40103170.txt b/fastlane/metadata/android/hu-HU/changelogs/40103170.txt new file mode 100644 index 0000000000..7882ee3eed --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Fő változás ebben a verzióban: földrajzi helyzet elküldése bármelyik szobába. Szavazás szerkesztése. +Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/hu-HU/changelogs/40103180.txt b/fastlane/metadata/android/hu-HU/changelogs/40103180.txt new file mode 100644 index 0000000000..0630b8ba11 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Fő változás ebben a verzióban: földrajzi helyzet elküldése bármelyik szobába. Szavazás szerkesztése. +Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.3.18 From d19a316da153340ad26e5f503c7ea2b2d1a0faab Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 9 Feb 2022 01:52:55 +0000 Subject: [PATCH 056/302] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (49 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/zh_Hant/ --- fastlane/metadata/android/zh-TW/changelogs/40103170.txt | 2 ++ fastlane/metadata/android/zh-TW/changelogs/40103180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/zh-TW/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/zh-TW/changelogs/40103180.txt diff --git a/fastlane/metadata/android/zh-TW/changelogs/40103170.txt b/fastlane/metadata/android/zh-TW/changelogs/40103170.txt new file mode 100644 index 0000000000..a8e353c2eb --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40103170.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:將您的位置傳送給任何聊天室。編輯投票。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/zh-TW/changelogs/40103180.txt b/fastlane/metadata/android/zh-TW/changelogs/40103180.txt new file mode 100644 index 0000000000..3eabe8b7cc --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40103180.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:將您的位置傳送給任何聊天室。編輯投票。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.3.18 From 4b7bd2ba06b04bd6a9f62024a8cc155dad48d138 Mon Sep 17 00:00:00 2001 From: Vladyslav Stepanov Date: Wed, 9 Feb 2022 10:09:18 +0000 Subject: [PATCH 057/302] Translated using Weblate (Russian) Currently translated at 100.0% (2785 of 2785 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 | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index f65f9ac9c9..a104696e4e 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -3195,4 +3195,37 @@ Включить Слежка за уведомлениями Вам не разрешено подключаться к этой комнате + Организуйте обсуждение в потоках + Показать все потоки в которых вы участвуете + Все Потоки + Просмотр Потоков + Вид в комнате + Показать всплывающие сообщения + Не удалось загрузить карту + Карта + Примечание: приложение будет перезапущено + Включить Сообщения Потока + Подключиться к серверу + Хотите присоединиться к существующему серверу\? + пропустить вопрос + Пока не уверенны\? Вы можете %s + Сообщества + Команды + Друзья и семья + Мы поможем вам подключится. + С кем вы будете общаться больше всего\? + Вы уже просматриваете этот Поток! + Вид в Комнате + Ответить в Поток + Команда «%s» распознается, но не поддерживается в потоках. + Из Потока + Совет: нажмите и удерживайте сообщение и используйте «%s». + Потоки помогают вести ваши разговоры тематически и легко отслеживающимися + Мои Потоки + Показать все потоки в текущей комнате + Фильтр + Потоки + Поток + Фильтровать Потоки в комнате + Скопировать ссылку в поток \ No newline at end of file From 3146ede690aa8f1d3cbc973675cc5b9ad05d36be Mon Sep 17 00:00:00 2001 From: a73435 Date: Wed, 9 Feb 2022 10:08:27 +0000 Subject: [PATCH 058/302] Translated using Weblate (Russian) Currently translated at 100.0% (2785 of 2785 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 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index a104696e4e..1ec34777db 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -3189,8 +3189,8 @@ Комната покинута! Шифрование было неправильно настроено, поэтому вы не можете отправлять сообщения. Нажмите, чтобы открыть настройки. Шифрование было неправильно настроено, поэтому вы не можете отправлять сообщения. Пожалуйста, обратитесь к администратору, чтобы восстановить работу шифрования. - Выбрать домашний сервер - Не удается связаться с домашним сервером по адресу %s. Пожалуйста, проверьте ссылку или выберите домашний сервер вручную. + Выберите домашний сервер + Не могу связаться с домашним сервером на URL %s. Пожалуйста, проверьте вашу ссылку или выберите домашний сервер вручную. Не сейчас Включить Слежка за уведомлениями From d91b34c4c84e960b8152dd46b8b923ad13837aef Mon Sep 17 00:00:00 2001 From: Vladyslav Stepanov Date: Wed, 9 Feb 2022 10:27:40 +0000 Subject: [PATCH 059/302] Translated using Weblate (Russian) Currently translated at 100.0% (49 of 49 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/40103050.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40103060.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40103070.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40103080.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40103090.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40103100.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40103110.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40103120.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40103130.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40103140.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40103150.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40103170.txt | 2 ++ fastlane/metadata/android/ru-RU/changelogs/40103180.txt | 2 ++ 13 files changed, 26 insertions(+) create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103050.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103060.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103070.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103080.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103090.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103100.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103110.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103120.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103130.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103140.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103150.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103180.txt diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103050.txt b/fastlane/metadata/android/ru-RU/changelogs/40103050.txt new file mode 100644 index 0000000000..6f864e59dc --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103050.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Добавлена поддержка присутствия для комнаты личных сообщений (примечание: присутствие отключено на matrix.org). Добавьте снова поддержку Android Auto. +Полный журнал изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.5 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103060.txt b/fastlane/metadata/android/ru-RU/changelogs/40103060.txt new file mode 100644 index 0000000000..975b92ef9b --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103060.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Добавлена поддержка присутствия для комнаты личных сообщений (примечание: присутствие отключено на matrix.org). Добавьте снова поддержку Android Auto. +Полный журнал изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.6 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103070.txt b/fastlane/metadata/android/ru-RU/changelogs/40103070.txt new file mode 100644 index 0000000000..8ba9ea6417 --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103070.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Исправлены ошибки, в основном касающиеся уведомлений. +Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.7-RC2 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103080.txt b/fastlane/metadata/android/ru-RU/changelogs/40103080.txt new file mode 100644 index 0000000000..bf47216dfb --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103080.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Исправлены ошибки! +Полный журнал изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.8 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103090.txt b/fastlane/metadata/android/ru-RU/changelogs/40103090.txt new file mode 100644 index 0000000000..95a482a48c --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103090.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Добавлена поддержка черновика голосового сообщения. Много исправлений! +Полный журнал изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.9 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103100.txt b/fastlane/metadata/android/ru-RU/changelogs/40103100.txt new file mode 100644 index 0000000000..73aab13115 --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103100.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Исправлены ошибки! +Полный журнал изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.11 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103110.txt b/fastlane/metadata/android/ru-RU/changelogs/40103110.txt new file mode 100644 index 0000000000..836fd5131e --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103110.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Исправлены ошибки! +Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.12 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103120.txt b/fastlane/metadata/android/ru-RU/changelogs/40103120.txt new file mode 100644 index 0000000000..fb1bf5cb37 --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103120.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Первое изменение экранов регистрации, включая подписку на Analytics. Добавлена поддержка событий с математикой в лабораториях. +Полный журнал изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.13 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103130.txt b/fastlane/metadata/android/ru-RU/changelogs/40103130.txt new file mode 100644 index 0000000000..fb1bf5cb37 --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103130.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Первое изменение экранов регистрации, включая подписку на Analytics. Добавлена поддержка событий с математикой в лабораториях. +Полный журнал изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.13 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103140.txt b/fastlane/metadata/android/ru-RU/changelogs/40103140.txt new file mode 100644 index 0000000000..f1144e7022 --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103140.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Первое изменение экранов регистрации, включая подписку на Analytics. Добавлена поддержка событий с математикой в лабораториях. +Полный журнал изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.14 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103150.txt b/fastlane/metadata/android/ru-RU/changelogs/40103150.txt new file mode 100644 index 0000000000..87becb7910 --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103150.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Первое изменение экранов регистрации, включая подписку на Analytics. Добавлена поддержка событий с математикой в лабораториях. +Полный журнал изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.15 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103170.txt b/fastlane/metadata/android/ru-RU/changelogs/40103170.txt new file mode 100644 index 0000000000..08286401e2 --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: отправка вашего местоположения в любую комнату. Изменить опрос. +Полный журнал изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103180.txt b/fastlane/metadata/android/ru-RU/changelogs/40103180.txt new file mode 100644 index 0000000000..08286401e2 --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: отправка вашего местоположения в любую комнату. Изменить опрос. +Полный журнал изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.17 From 72d742f8c716c749635b4e824253d47bdeeff129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Wed, 9 Feb 2022 07:28:17 +0000 Subject: [PATCH 060/302] Translated using Weblate (Estonian) Currently translated at 99.9% (2783 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/et/ --- vector/src/main/res/values-et/strings.xml | 35 ++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index 77f854f73b..2da0cc9125 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -2651,7 +2651,7 @@ Lisa olemasolevaid jututubasid ja kogukonnakeskuseid Lahku kogukonnakeskusest Lisa jututuba - Uuri jututubasid + Tutvu jututubadega %d sinu tuttav on juba liitunud %d sinu tuttavat on juba liitunud @@ -3097,4 +3097,37 @@ Asukoht Krüptimise seadistustes on viga ja sa ei saa sõnumeid saata. Seadistuste avamiseks klõpsi siin. Krüptimise seadistustes on viga ja sa ei saa sõnumeid saata. Kui soovid krüptimist töökorda saada, siis võta ühendust serveri haldajaga. + Me aitame sind Matrix\'i võrgu kasutamisel. + Alusta koduserveri kasutamist + Võta jutulõngad kasutusele + Märkus: palun käivita rakendus uuesti + Kaardi laadimine ei õnnestunud + Kaart + Näita jutumulle + Tahad kasutada mõnda olemasolevat koduserverit\? + jätta selle küsimuse vahele + Sa pole veel otsustanud\? Sa võid %s + Töökaaslased + Kogukonnad + Perekond ja sõbrad + Kellega sa kõige rohkem vestled\? + Sa juba vaatad seda jutulõnga! + Vaata jututoas + Vasta jutulõngas + „%s“ käsk on küll arusaadav, kuid ei ole jutulõngas kasutatav. + Jutulõngast + Soovitus: Vajuta sõnumil pikalt ning vali „%s“. + Jutulõngad aitavad hoida vestlused teemakohastena ning mugavalt loetavatena. + Halda vestlusi jutulõngadena + Näitab kõiki jutulõngasid, kus sa oled osalenud + Minu jutulõngad + Näitab kõiki praeguse jututoa jutulõngasid + Kõik jutulõngad + Filtreeri + Jutulõngad + Jutulõng + Sirvi jutulõngasid + Kopeeri jutulõnga link + Vaata jututoas + Vaata jutulõngana \ No newline at end of file From 6c5a900935e8113810661b083c6b11bf6666b527 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Tue, 8 Feb 2022 21:21:40 +0000 Subject: [PATCH 061/302] Translated using Weblate (Persian) Currently translated at 100.0% (2785 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/ --- vector/src/main/res/values-fa/strings.xml | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index 6dce34f7c7..1c912b9fd6 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -3097,4 +3097,37 @@ ارتباطات امن و مستقل که به شما همان سطح محرمانگی گفت‌وگوی رودررو در خانهٔ خودتان را می‌دهد. از آن‌جا که رمزنگاری بد پیکربندی شده، نمی‌توانید پیام بفرستید. برای گشودن تنظیمات، بزنید. از آن‌جا که رمزنگاری بد پیکربندی شده، نمی‌توانید پیام بفرستید. لطفاً برای بازگردانی رمزنگاری به یه وضعیت معتبر، با مدیری تماس بگیرید. + نمایش حباب‌های پیام + شکست در بار کردن نقشه + نقشه + نکته: کاره دوباره آغاز خواهد شد + به کار انداختن ویام‌های رشته‌ای + وصل شدن به کارساز + دنبال پیوستن به کارسازهای موجودید؟ + از این پرسش بگذرید + هنوز اطمینان ندارید؟ می‌توانید %s + اجتماع‌ها + گروه‌ها + دوستان و خانواده + کمکتان می‌کنیم وصل بمانید. + بیش‌تر با چه‌کسی گپ می‌زنید؟ + هم‌اکنون دارید این رشته را می‌بینید! + دیدن در اتاق + پاسخ در رشته + دستور «%s» شناخته شده است ولی در رشته‌ها پشتیبانی نمی‌شود. + از یک رشته + ایما: روی پیام نگه داشته و از «%s» استفاده کنید. + رشته‌ها در روی موضوع نگه داشت گفت‌وگوها و آسانی ردیابیشان کمک می‌کنند. + ساماندهی شده نگه داشتن گفت‌وگوها با رشته‌ها + نمایش تمامی رشته‌ّایی که در آن مشارکت داشته‌اید + رشته‌هایم + نمایش تمامی رشته‌ها از اتاق جاری + تمامی رشته‌ها + پالایش + رشته‌ها + رشته + پالایش رشته‌ها در اتاق + رونوشت از پیوند به رشته + دیدن در اتاق + دیدن رشته‌ها \ No newline at end of file From f7677707390e76c748eae14f719cebee18a64dc1 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 8 Feb 2022 20:20:12 +0000 Subject: [PATCH 062/302] Translated using Weblate (Ukrainian) Currently translated at 100.0% (2785 of 2785 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 | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index c9e8372cc9..25703d19cb 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -3199,4 +3199,37 @@ Місцеперебування Шифрування було налаштовано неправильно, тому ви не можете надсилати повідомлення. Торкніться, щоб відкрити налаштування. Шифрування було налаштовано неправильно, тому ви не можете надсилати повідомлення. Зверніться до адміністратора, щоб відновити роботу шифрування. + Показувати повідомлення у бульбашках + Не вдалося завантажити карту + Карта + Примітка: застосунок перезапуститься + Увімкнути тред повідомлень + Під\'єднатися до сервера + Бажаєте приєднання до наявного сервера\? + пропустити це питання + Досі не впевнені\? Ви можете %s + Спільноти + Команди + Друзі й сім\'я + Ми допоможемо вам з\'єднатися. + З ким ви спілкуватиметеся найчастіше\? + Ви вже переглядаєте цей тред! + Переглянути у кімнаті + Відповісти у тред + Команду «%s» розпізнано, але її не підтримують треди. + З треду + Порада: Торкніться й утримуйте повідомлення і виберіть «%s». + Спілкуйтеся за темою в тредах + Треди допомагають підтримувати розмови за темою та за ними легко стежити. + Показує всі треди, де ви брали участь + Мої треди + Показує всі треди цієї кімнати + Усі треди + Фільтрувати + Треди + Тред + Фільтрувати треди кімнати + Копіювати лінк треду + Переглянути у кімнаті + Переглянути треди \ No newline at end of file From e730a74f103ad36cc3be46beb411ab690d8d0b50 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Tue, 8 Feb 2022 18:55:24 +0000 Subject: [PATCH 063/302] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (49 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/pt_BR/ --- fastlane/metadata/android/pt-BR/changelogs/40103170.txt | 2 ++ fastlane/metadata/android/pt-BR/changelogs/40103180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/pt-BR/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/pt-BR/changelogs/40103180.txt diff --git a/fastlane/metadata/android/pt-BR/changelogs/40103170.txt b/fastlane/metadata/android/pt-BR/changelogs/40103170.txt new file mode 100644 index 0000000000..1266131db7 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: envie sua localização para qualquer sala. Editar sondagem. +Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/pt-BR/changelogs/40103180.txt b/fastlane/metadata/android/pt-BR/changelogs/40103180.txt new file mode 100644 index 0000000000..56e23a2be4 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: envie sua localização para qualquer sala. Editar sondagem. +Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.3.18 From 300040cee90aa1a26fe5668c0b3f7e5d5234d5d1 Mon Sep 17 00:00:00 2001 From: Linerly Date: Thu, 10 Feb 2022 00:14:59 +0000 Subject: [PATCH 064/302] Translated using Weblate (Indonesian) Currently translated at 100.0% (2785 of 2785 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 | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index 6f5e8eca49..afe1638b0f 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -3042,4 +3042,37 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Lokasi Enkripsi telah dikonfigurasi dengan salah sehingga Anda tidak dapat mengirim pesan. Klik untuk membuka pengaturan. Enkripsi telah dikonfigurasi dengan salah sehingga Anda tidak dapat mengirim pesan. Mohon hubungi sebuah admin untuk memulihkan enkripsi ke status yang valid. + Belum yakin\? Anda dapat %s + Tampilkan gelembung pesan + Gagal untuk memuat peta + Peta + Catatan: aplikasi akan dimulai ulang + Aktifkan Pesan Utasan + Hubungkan ke server + Ingin bergabung ke server yang sudah ada\? + melewati pertanyaan ini + Komunitas + Tim + Teman dan keluarga + Kami akan membantu Anda untuk terhubung. + Siapa saja yang sering Anda chat\? + Anda sudah menampilkan utasan ini! + Tampilkan Di Ruangan + Balas Di Utasan + Perintah \"%s\" dikenal tetapi tidak didukung dalam utasan. + Dari sebuah Utasan + Tip: Tekan lama pada sebuah pesan dan gunakan “%s”. + Utasan membantu membuat obrolan sesuai topik dan mudah untuk dilacak. + Buat diskusi tetap teratur dengan utasan + Menampilkan semua utasan yang Anda berpartisipasi + Utasan Saya + Tampilkan semua utama dari ruangan saat ini + Semua Utasan + Saring + Utasan + Utasan + Saring Utasan di ruangan + Salin tautan ke utasan + Tampilkan di ruangan + Tampilkan Utasan \ No newline at end of file From c02defe1425e9029ab150684a99f6189b1854649 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Wed, 9 Feb 2022 07:27:03 +0000 Subject: [PATCH 065/302] Translated using Weblate (Czech) Currently translated at 100.0% (49 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/cs/ --- fastlane/metadata/android/cs-CZ/changelogs/40103170.txt | 2 ++ fastlane/metadata/android/cs-CZ/changelogs/40103180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/cs-CZ/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/cs-CZ/changelogs/40103180.txt diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40103170.txt b/fastlane/metadata/android/cs-CZ/changelogs/40103170.txt new file mode 100644 index 0000000000..73ec686cb1 --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: odeslání svojí polohy do libovolné místnosti. Úpravy anket. +Úplný seznam změn: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40103180.txt b/fastlane/metadata/android/cs-CZ/changelogs/40103180.txt new file mode 100644 index 0000000000..502b318b3e --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: odeslání svojí polohy do libovolné místnosti. Úpravy anket. +Úplný seznam změn: https://github.com/vector-im/element-android/releases/tag/v1.3.18 From 617a03abf64438bc841526009a61e92def11f916 Mon Sep 17 00:00:00 2001 From: random Date: Wed, 9 Feb 2022 10:01:42 +0000 Subject: [PATCH 066/302] Translated using Weblate (Italian) Currently translated at 100.0% (2785 of 2785 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 | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index 221a996e0c..7e6433dca4 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -3087,4 +3087,37 @@ Posizione La crittografia è stata configurata male, perciò non puoi inviare messaggi. Clicca per aprire le impostazioni. La crittografia è stata configurata male, perciò non puoi inviare messaggi. Contatta l\'amministratore per reimpostare la crittografia ad uno stato valido. + Mostra bolle di messaggi + Caricamento mappa fallito + Mappa + Nota: l\'app verrà riavviata + Attiva messaggi in conversazioni + Connetti al server + Vuoi unirti ad un server esistente\? + saltare questa domanda + Ancora non lo sai\? Puoi %s + Comunità + Squadre + Amici e famiglia + Vi aiuteremo a connettervi. + Con chi parlerai di più\? + Stai già visualizzando questa conversazione! + Vedi nella stanza + Rispondi nella conversazione + Il comando \"%s\" è riconosciuto ma non supportato nelle conversazioni. + Da una conversazione + Consiglio: tieni premuto un messaggio ed usa “%s”. + Le conversazioni ti aiutano a tenere le tue discussioni in tema e rintracciabili. + Tieni le discussioni organizzate con gli argomenti + Mostra tutte le conversazioni a cui hai partecipato + Le mie conversazioni + Mostra tutte le conversazioni dalla stanza attuale + Tutte le conversazioni + Filtra + Conversazioni + Conversazione + Filtra conversazioni nella stanza + Copia link nella conversazione + Vedi nella stanza + Vedi conversazioni \ No newline at end of file From 7c2800f47f6fc50c724eded921c6fd9e2364d1db Mon Sep 17 00:00:00 2001 From: noantiq Date: Wed, 9 Feb 2022 14:05:57 +0000 Subject: [PATCH 067/302] Translated using Weblate (German) Currently translated at 100.0% (49 of 49 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/40103170.txt | 2 ++ fastlane/metadata/android/de-DE/changelogs/40103180.txt | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/de-DE/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/de-DE/changelogs/40103180.txt diff --git a/fastlane/metadata/android/de-DE/changelogs/40103170.txt b/fastlane/metadata/android/de-DE/changelogs/40103170.txt new file mode 100644 index 0000000000..4a93cfca52 --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Wichtigste Änderungen in dieser Version: Versende deinen Standort an jeden Raum deiner Wahl. Bearbeite Umfragen. +Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/de-DE/changelogs/40103180.txt b/fastlane/metadata/android/de-DE/changelogs/40103180.txt new file mode 100644 index 0000000000..28c954f326 --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Wichtigste Änderungen in dieser Version: Versende deinen Standort an jeden Raum deiner Wahl. Bearbeite Umfragen. +Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.3.18 From f44f37629a19829938664cf5a90972348b0e03dc Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Fri, 11 Feb 2022 08:56:15 +0000 Subject: [PATCH 068/302] Reduce verbosity of CleanupSession debug logs. Currently we wait up to 10s for this operation to complete. Replacing the two log lines with three, lets us halve the number of logs printed every 10ms, but always print exactly one log line each iteration of the loop. Rather than: ``` 02-10 19:58:48.880 3140 3140 D CleanupSession: Wait for all Realm instance to be closed (29 - 0) 02-10 19:58:48.880 3140 3140 D CleanupSession: Waiting 10ms 02-10 19:58:48.890 3140 3140 D CleanupSession: Wait for all Realm instance to be closed (29 - 0) 02-10 19:58:48.890 3140 3140 D CleanupSession: Waiting 10ms 02-10 19:58:48.900 3140 3140 D CleanupSession: Wait for all Realm instance to be closed (29 - 0) 02-10 19:58:48.900 3140 3140 D CleanupSession: Waiting 10ms 02-10 19:58:48.910 3140 3140 D CleanupSession: Wait for all Realm instance to be closed (29 - 0) 02-10 19:58:48.910 3140 3140 D CleanupSession: Waiting 10ms 02-10 19:58:48.920 3140 3140 D CleanupSession: Wait for all Realm instance to be closed (0 - 0) ``` We'll print: ``` 02-10 19:58:48.880 3140 3140 D CleanupSession: Waiting 10ms for all Realm instance to be closed (29 - 0) 02-10 19:58:48.890 3140 3140 D CleanupSession: Waiting 10ms for all Realm instance to be closed (29 - 0) 02-10 19:58:48.900 3140 3140 D CleanupSession: Waiting 10ms for all Realm instance to be closed (29 - 0) 02-10 19:58:48.910 3140 3140 D CleanupSession: Waiting 10ms for all Realm instance to be closed (29 - 0) 02-10 19:58:48.920 3140 3140 D CleanupSession: Finished waiting for all Realm instance to be closed (0 - 0) ``` The above example took 40ms to finish and saved 4 log lines; you can see how it adds up if you take 10000ms to finish. --- .../android/sdk/internal/session/cleanup/CleanupSession.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cleanup/CleanupSession.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cleanup/CleanupSession.kt index c42141a0aa..44fff45917 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cleanup/CleanupSession.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/cleanup/CleanupSession.kt @@ -94,12 +94,12 @@ internal class CleanupSession @Inject constructor( do { val sessionRealmCount = Realm.getGlobalInstanceCount(realmSessionConfiguration) val cryptoRealmCount = Realm.getGlobalInstanceCount(realmCryptoConfiguration) - Timber.d("Wait for all Realm instance to be closed ($sessionRealmCount - $cryptoRealmCount)") if (sessionRealmCount > 0 || cryptoRealmCount > 0) { - Timber.d("Waiting ${TIME_TO_WAIT_MILLIS}ms") + Timber.d("Waiting ${TIME_TO_WAIT_MILLIS}ms for all Realm instance to be closed ($sessionRealmCount - $cryptoRealmCount)") delay(TIME_TO_WAIT_MILLIS) timeToWaitMillis -= TIME_TO_WAIT_MILLIS } else { + Timber.d("Finished waiting for all Realm instance to be closed ($sessionRealmCount - $cryptoRealmCount)") timeToWaitMillis = 0 } } while (timeToWaitMillis > 0) From a9a1532e017c93de429dd551e4de34d6d936a1f7 Mon Sep 17 00:00:00 2001 From: Ahmed Radhouane Belkilani Date: Wed, 9 Feb 2022 11:08:46 +0100 Subject: [PATCH 069/302] #4640 - change unread counter badge view in item_room to be in consistent place on the screen, to left of date/time. - change unread badge color state for dark and light theme to align with iOS. - add changelog file related to the issue. Signed-off-by: Ahmed Radhouane Belkilani --- changelog.d/4640.bugfix | 5 +++++ library/ui-styles/src/main/res/values/colors.xml | 6 +++--- vector/src/main/res/layout/item_room.xml | 5 ++--- 3 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 changelog.d/4640.bugfix diff --git a/changelog.d/4640.bugfix b/changelog.d/4640.bugfix new file mode 100644 index 0000000000..5095217f2a --- /dev/null +++ b/changelog.d/4640.bugfix @@ -0,0 +1,5 @@ +# [[Issue #4640]](https://github.com/vector-im/element-android/issues/4640) The notification badge jumps around + +## Changes : +- change unread counter badge view in item_room to be in consistent place on the screen, to left of date/time. +- change unread badge color state for dark and light theme to align with iOS. \ No newline at end of file diff --git a/library/ui-styles/src/main/res/values/colors.xml b/library/ui-styles/src/main/res/values/colors.xml index ca6f6d3142..48ac48a8ca 100644 --- a/library/ui-styles/src/main/res/values/colors.xml +++ b/library/ui-styles/src/main/res/values/colors.xml @@ -58,9 +58,9 @@ - #FF61708B - #FF61708B - #FF61708B + @color/palette_gray_200 + @color/palette_gray_250 + @color/palette_gray_250 @android:color/white diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml index defff5eeeb..68e3a85008 100644 --- a/vector/src/main/res/layout/item_room.xml +++ b/vector/src/main/res/layout/item_room.xml @@ -165,7 +165,6 @@ android:visibility="gone" app:layout_constraintBottom_toBottomOf="@id/roomNameView" app:layout_constraintEnd_toStartOf="@id/roomLastEventTimeView" - app:layout_constraintStart_toEndOf="@id/roomDraftBadge" app:layout_constraintTop_toTopOf="@id/roomNameView" tools:background="@drawable/bg_unread_highlight" tools:text="4" @@ -190,9 +189,9 @@ android:layout_height="wrap_content" android:layout_marginTop="3dp" android:layout_marginEnd="8dp" - android:textAlignment="viewStart" android:ellipsize="end" android:maxLines="2" + android:textAlignment="viewStart" android:textColor="?vctr_content_secondary" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@id/roomNameView" @@ -203,12 +202,12 @@ android:id="@+id/roomTypingView" style="@style/Widget.Vector.TextView.Body" android:layout_width="0dp" - android:textAlignment="viewStart" android:layout_height="wrap_content" android:layout_marginTop="3dp" android:layout_marginEnd="8dp" android:ellipsize="end" android:maxLines="2" + android:textAlignment="viewStart" android:textColor="?colorPrimary" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" From 85414fa92e10d7af5a68d122652da64ea8c5bbaf Mon Sep 17 00:00:00 2001 From: Ahmed Radhouane Belkilani Date: Fri, 11 Feb 2022 11:44:55 +0100 Subject: [PATCH 070/302] #4640 - update changelog file. Signed-off-by: Ahmed Radhouane Belkilani --- changelog.d/4640.bugfix | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/changelog.d/4640.bugfix b/changelog.d/4640.bugfix index 5095217f2a..f5fa5a5bde 100644 --- a/changelog.d/4640.bugfix +++ b/changelog.d/4640.bugfix @@ -1,5 +1 @@ -# [[Issue #4640]](https://github.com/vector-im/element-android/issues/4640) The notification badge jumps around - -## Changes : -- change unread counter badge view in item_room to be in consistent place on the screen, to left of date/time. -- change unread badge color state for dark and light theme to align with iOS. \ No newline at end of file +Right align the notifications badge in the rooms list (and DMs) so that it's always in a consistent place on the screen. \ No newline at end of file From 6fd47594d488bfcc32b7850d81adc66320c401c6 Mon Sep 17 00:00:00 2001 From: David Langley Date: Fri, 11 Feb 2022 11:15:16 +0000 Subject: [PATCH 071/302] formatting --- .../vector/app/features/call/transfer/CallTransferActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt index 148ed5e7c2..d4b77c7739 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt @@ -104,7 +104,7 @@ class CallTransferActivity : VectorBaseActivity() { } companion object { - const val EXTRA_TRANSFER_RESULT = "EXTRA_TRANSFER_RESULT" + const val EXTRA_TRANSFER_RESULT = "EXTRA_TRANSFER_RESULT" fun newIntent(context: Context, callId: String): Intent { return Intent(context, CallTransferActivity::class.java).also { it.putExtra(Mavericks.KEY_ARG, CallTransferArgs(callId)) From a5f4413f6c4a9694e9bc3704d57b0cf70f6c04fc Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 10 Feb 2022 17:00:30 +0000 Subject: [PATCH 072/302] using a generic boolean capability model for booleans --- .../internal/session/homeserver/GetCapabilitiesResult.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt index b36d05b6c0..9e68309dad 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt @@ -37,9 +37,10 @@ internal data class GetCapabilitiesResult( internal data class Capabilities( /** * Capability to indicate if the user can change their password. + * True if the user can change their password, false otherwise. */ @Json(name = "m.change_password") - val changePassword: ChangePassword? = null, + val changePassword: BooleanCapability? = null, /** * This capability describes the default and available room versions a server supports, and at what level of stability. @@ -50,9 +51,9 @@ internal data class Capabilities( ) @JsonClass(generateAdapter = true) -internal data class ChangePassword( +internal data class BooleanCapability( /** - * Required. True if the user can change their password, false otherwise. + * Required. */ @Json(name = "enabled") val enabled: Boolean? From 0a52651e4036f1a137c3d95dd93a36d279adaac2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 11 Feb 2022 13:01:34 +0100 Subject: [PATCH 073/302] Reactions: update after remarks --- .../ui-styles/src/main/res/values/dimens.xml | 3 --- .../src/main/res/values/styles_timeline.xml | 11 ++++++++ .../im/vector/app/core/extensions/Context.kt | 13 ++++++++++ .../timeline/item/AbsBaseMessageItem.kt | 26 ++++++++++--------- .../detail/timeline/view/MessageBubbleView.kt | 2 -- .../reactions/widget/ReactionButton.kt | 9 +++---- .../src/main/res/layout/reaction_button.xml | 5 +--- 7 files changed, 42 insertions(+), 27 deletions(-) diff --git a/library/ui-styles/src/main/res/values/dimens.xml b/library/ui-styles/src/main/res/values/dimens.xml index c8f1ec5c86..be57f75dc8 100644 --- a/library/ui-styles/src/main/res/values/dimens.xml +++ b/library/ui-styles/src/main/res/values/dimens.xml @@ -61,9 +61,6 @@ 300dp 12dp - 28dp - 40dp - 0.05 0.95 diff --git a/library/ui-styles/src/main/res/values/styles_timeline.xml b/library/ui-styles/src/main/res/values/styles_timeline.xml index 3bd3543de2..c86eeb8efb 100644 --- a/library/ui-styles/src/main/res/values/styles_timeline.xml +++ b/library/ui-styles/src/main/res/values/styles_timeline.xml @@ -23,4 +23,15 @@ ?vctr_content_quinary + + + \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/core/extensions/Context.kt b/vector/src/main/java/im/vector/app/core/extensions/Context.kt index b8b367b740..b1e24c9502 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Context.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Context.kt @@ -18,6 +18,9 @@ package im.vector.app.core.extensions import android.content.Context import android.graphics.drawable.Drawable +import android.text.Spannable +import android.text.SpannableString +import android.text.style.ImageSpan import androidx.annotation.ColorInt import androidx.annotation.ColorRes import androidx.annotation.DrawableRes @@ -34,6 +37,16 @@ fun Context.singletonEntryPoint(): SingletonEntryPoint { return EntryPoints.get(applicationContext, SingletonEntryPoint::class.java) } +fun Context.getDrawableAsSpannable(@DrawableRes drawableRes: Int, alignment: Int = ImageSpan.ALIGN_BOTTOM): Spannable { + return SpannableString(" ").apply { + val span = ContextCompat.getDrawable(this@getDrawableAsSpannable, drawableRes)?.let { + it.setBounds(0, 0, it.intrinsicWidth, it.intrinsicHeight) + ImageSpan(it, alignment) + } + setSpan(span, 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE) + } +} + fun Context.getResTintedDrawable(@DrawableRes drawableRes: Int, @ColorRes tint: Int, @FloatRange(from = 0.0, to = 1.0) alpha: Float = 1f): Drawable? { return getTintedDrawable(drawableRes, ContextCompat.getColor(this, tint), alpha) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt index 21b58e0f4b..23f2aceff5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt @@ -17,17 +17,20 @@ package im.vector.app.features.home.room.detail.timeline.item import android.annotation.SuppressLint -import android.view.Gravity +import android.graphics.Typeface import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.annotation.IdRes +import androidx.appcompat.view.ContextThemeWrapper import androidx.core.content.ContextCompat.getDrawable import androidx.core.view.isVisible +import androidx.core.widget.TextViewCompat import im.vector.app.R import im.vector.app.core.epoxy.ClickListener import im.vector.app.core.epoxy.onClick +import im.vector.app.core.extensions.getDrawableAsSpannable import im.vector.app.core.ui.views.ShieldImageView import im.vector.app.core.utils.DimensionConverter import im.vector.app.features.home.AvatarRenderer @@ -35,6 +38,7 @@ import im.vector.app.features.home.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.view.TimelineMessageLayoutRenderer import im.vector.app.features.reactions.widget.ReactionButton +import im.vector.app.features.themes.ThemeUtils import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.room.send.SendState @@ -114,7 +118,7 @@ abstract class AbsBaseMessageItem : BaseEventItem holder.reactionsContainer.addView(reactionButton) } if (reactions.count() > MAX_REACTIONS_TO_SHOW) { - val showReactionsTextView = createReactionTextView(holder, 6) + val showReactionsTextView = createReactionTextView(holder) if (reactionsSummary.showAll) { showReactionsTextView.setText(R.string.message_reaction_show_less) showReactionsTextView.onClick { reactionsSummary.onShowLessClicked() } @@ -125,23 +129,21 @@ abstract class AbsBaseMessageItem : BaseEventItem } holder.reactionsContainer.addView(showReactionsTextView) } - val addMoreReactionsTextView = createReactionTextView(holder, 14) - addMoreReactionsTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_add_reaction_small, 0, 0, 0) + val addMoreReactionsTextView = createReactionTextView(holder) + + addMoreReactionsTextView.text = holder.view.context.getDrawableAsSpannable(R.drawable.ic_add_reaction_small) addMoreReactionsTextView.onClick { reactionsSummary.onAddMoreClicked() } holder.reactionsContainer.addView(addMoreReactionsTextView) holder.reactionsContainer.setOnLongClickListener(baseAttributes.itemLongClickListener) } } - private fun createReactionTextView(holder: H, horizontalPaddingDp: Int): TextView { - return TextView(holder.view.context).apply { - textSize = 10f - gravity = Gravity.CENTER - minimumHeight = resources.getDimensionPixelSize(R.dimen.chat_reaction_min_height) - minimumWidth = resources.getDimensionPixelSize(R.dimen.chat_reaction_min_width) + private fun createReactionTextView(holder: H): TextView { + return TextView(ContextThemeWrapper(holder.view.context, R.style.TimelineReactionView)).apply { background = getDrawable(context, R.drawable.reaction_rounded_rect_shape_off) - val padding = holder.dimensionConverter.dpToPx(horizontalPaddingDp) - setPadding(padding, 0, padding, 0) + TextViewCompat.setTextAppearance(this, R.style.TextAppearance_Vector_Micro) + setTypeface(typeface, Typeface.BOLD) + setTextColor(ThemeUtils.getColor(context, R.attr.vctr_content_secondary)) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt index bf5bb8d302..422dfb0dbd 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt @@ -31,7 +31,6 @@ import androidx.core.content.withStyledAttributes import androidx.core.graphics.drawable.DrawableCompat import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams -import com.google.android.flexbox.FlexDirection import com.google.android.material.shape.MaterialShapeDrawable import im.vector.app.R import im.vector.app.core.resources.LocaleProvider @@ -80,7 +79,6 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri views.messageThreadSummaryContainer.layoutDirection = layoutDirectionToSet views.bubbleWrapper.layoutDirection = layoutDirectionToSet views.bubbleView.layoutDirection = currentLayoutDirection - views.reactionsContainer.flexDirection = if (isIncoming) FlexDirection.ROW else FlexDirection.ROW_REVERSE bubbleDrawable = MaterialShapeDrawable() rippleMaskDrawable = MaterialShapeDrawable() diff --git a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt index 219ca166bb..7340953f32 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt @@ -18,7 +18,6 @@ package im.vector.app.features.reactions.widget import android.content.Context import android.graphics.drawable.Drawable import android.util.AttributeSet -import android.view.Gravity import android.view.View import android.widget.LinearLayout import androidx.core.content.ContextCompat @@ -37,8 +36,9 @@ import javax.inject.Inject @AndroidEntryPoint class ReactionButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, - defStyleAttr: Int = 0) : - LinearLayout(context, attrs, defStyleAttr), View.OnClickListener, View.OnLongClickListener { + defStyleAttr: Int = 0, + defStyleRes: Int = R.style.TimelineReactionView) : + LinearLayout(context, attrs, defStyleAttr, defStyleRes), View.OnClickListener, View.OnLongClickListener { @Inject lateinit var emojiSpanify: EmojiSpanify @@ -67,9 +67,6 @@ class ReactionButton @JvmOverloads constructor(context: Context, init { inflate(context, R.layout.reaction_button, this) orientation = HORIZONTAL - minimumHeight = resources.getDimensionPixelSize(R.dimen.chat_reaction_min_height) - minimumWidth = resources.getDimensionPixelSize(R.dimen.chat_reaction_min_width) - gravity = Gravity.CENTER layoutDirection = View.LAYOUT_DIRECTION_LOCALE views = ReactionButtonBinding.bind(this) views.reactionCount.text = TextUtils.formatCountToShortDecimal(reactionCount) diff --git a/vector/src/main/res/layout/reaction_button.xml b/vector/src/main/res/layout/reaction_button.xml index f0a8011220..ca1b17984b 100644 --- a/vector/src/main/res/layout/reaction_button.xml +++ b/vector/src/main/res/layout/reaction_button.xml @@ -3,11 +3,10 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" - android:layout_height="@dimen/chat_reaction_min_height" + android:layout_height="wrap_content" android:background="@drawable/reaction_rounded_rect_shape" android:clipChildren="false" android:gravity="center" - android:minWidth="@dimen/chat_reaction_min_width" tools:parentTag="android.widget.LinearLayout"> @@ -21,7 +20,6 @@ style="@style/Widget.Vector.TextView.Caption" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="6dp" android:ellipsize="middle" android:gravity="center" android:maxEms="10" @@ -35,7 +33,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="2dp" - android:layout_marginEnd="6dp" android:gravity="center" android:maxLines="1" android:textColor="?vctr_content_secondary" From d8d6358d15cc2aefd454d6f21ec76b9bd64fc008 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 11 Feb 2022 11:57:45 +0000 Subject: [PATCH 074/302] adding support for the homeserver display name and avatar capabilities - MSC3283 https://github.com/matrix-org/synapse/pull/11933 - includes session database migration --- .../homeserver/HomeServerCapabilities.kt | 13 ++++++++ .../database/RealmSessionStoreMigration.kt | 2 ++ .../mapper/HomeServerCapabilitiesMapper.kt | 3 ++ .../database/migration/MigrateSessionTo025.kt | 31 +++++++++++++++++++ .../model/HomeServerCapabilitiesEntity.kt | 3 ++ .../homeserver/GetCapabilitiesResult.kt | 25 +++++++++++---- .../GetHomeServerCapabilitiesTask.kt | 12 +++++-- 7 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo025.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt index 3ed6a7ebb2..2256dfb8f0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt @@ -21,6 +21,18 @@ data class HomeServerCapabilities( * True if it is possible to change the password of the account. */ val canChangePassword: Boolean = true, + /** + * True if it is possible to change the display name of the account. + */ + val canChangeDisplayName: Boolean = true, + /** + * True if it is possible to change the avatar of the account. + */ + val canChangeAvatar: Boolean = true, + /** + * True if it is possible to change the 3pid associations of the account. + */ + val canChange3pid: Boolean = true, /** * Max size of file which can be uploaded to the homeserver in bytes. [MAX_UPLOAD_FILE_SIZE_UNKNOWN] if unknown or not retrieved yet */ @@ -76,6 +88,7 @@ data class HomeServerCapabilities( } } } + fun isFeatureSupported(feature: String, byRoomVersion: String): Boolean { if (roomVersions?.capabilities == null) return false val info = roomVersions.capabilities[feature] ?: return false diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt index f4a8ae2c67..4bf352c06c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt @@ -42,6 +42,7 @@ import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo021 import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo022 import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo023 import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo024 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo025 import org.matrix.android.sdk.internal.util.Normalizer import timber.log.Timber import javax.inject.Inject @@ -85,5 +86,6 @@ internal class RealmSessionStoreMigration @Inject constructor( if (oldVersion < 22) MigrateSessionTo022(realm).perform() if (oldVersion < 23) MigrateSessionTo023(realm).perform() if (oldVersion < 24) MigrateSessionTo024(realm).perform() + if (oldVersion < 25) MigrateSessionTo025(realm).perform() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt index 8b6d263f8c..7869506015 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/HomeServerCapabilitiesMapper.kt @@ -35,6 +35,9 @@ internal object HomeServerCapabilitiesMapper { fun map(entity: HomeServerCapabilitiesEntity): HomeServerCapabilities { return HomeServerCapabilities( canChangePassword = entity.canChangePassword, + canChangeDisplayName = entity.canChangeDisplayName, + canChangeAvatar = entity.canChangeAvatar, + canChange3pid = entity.canChange3pid, maxUploadFileSize = entity.maxUploadFileSize, lastVersionIdentityServerSupported = entity.lastVersionIdentityServerSupported, defaultIdentityServerUrl = entity.defaultIdentityServerUrl, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo025.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo025.kt new file mode 100644 index 0000000000..35267d2a16 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo025.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 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.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +class MigrateSessionTo025(realm: DynamicRealm) : RealmMigrator(realm, 25) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("HomeServerCapabilitiesEntity") + ?.addField(HomeServerCapabilitiesEntityFields.CAN_CHANGE_DISPLAY_NAME, Boolean::class.java) + ?.addField(HomeServerCapabilitiesEntityFields.CAN_CHANGE_AVATAR, Boolean::class.java) + ?.addField(HomeServerCapabilitiesEntityFields.CAN_CHANGE3PID, Boolean::class.java) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt index 980449ddfb..08ecd5995e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/HomeServerCapabilitiesEntity.kt @@ -21,6 +21,9 @@ import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities internal open class HomeServerCapabilitiesEntity( var canChangePassword: Boolean = true, + var canChangeDisplayName: Boolean = true, + var canChangeAvatar: Boolean = true, + var canChange3pid: Boolean = true, var roomVersionsJson: String? = null, var maxUploadFileSize: Long = HomeServerCapabilities.MAX_UPLOAD_FILE_SIZE_UNKNOWN, var lastVersionIdentityServerSupported: Boolean = false, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt index 9e68309dad..830a58cd12 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetCapabilitiesResult.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.session.homeserver import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.api.extensions.orTrue import org.matrix.android.sdk.api.util.JsonDict /** @@ -42,6 +41,25 @@ internal data class Capabilities( @Json(name = "m.change_password") val changePassword: BooleanCapability? = null, + /** + * Capability to indicate if the user can change their display name. + * True if the user can change their display name, false otherwise. + */ + @Json(name = "m.set_displayname") + val changeDisplayName: BooleanCapability? = null, + + /** + * Capability to indicate if the user can change their avatar. + * True if the user can change their avatar, false otherwise. + */ + @Json(name = "m.set_avatar_url") + val changeAvatar: BooleanCapability? = null, + /** + * Capability to indicate if the user can change add, remove or change 3PID associations. + * True if the user can change their 3PID associations, false otherwise. + */ + @Json(name = "m.3pid_changes") + val change3pid: BooleanCapability? = null, /** * This capability describes the default and available room versions a server supports, and at what level of stability. * Clients should make use of this capability to determine if users need to be encouraged to upgrade their rooms. @@ -88,8 +106,3 @@ internal data class RoomVersions( @Json(name = "org.matrix.msc3244.room_capabilities") val roomCapabilities: JsonDict? = null ) - -// The spec says: If not present, the client should assume that password changes are possible via the API -internal fun GetCapabilitiesResult.canChangePassword(): Boolean { - return capabilities?.changePassword?.enabled.orTrue() -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt index 612b98f863..e822cbdcdb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/homeserver/GetHomeServerCapabilitiesTask.kt @@ -20,6 +20,7 @@ import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.api.MatrixPatterns.getDomain import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.api.auth.wellknown.WellknownResult +import org.matrix.android.sdk.api.extensions.orTrue import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities import org.matrix.android.sdk.internal.auth.version.Versions import org.matrix.android.sdk.internal.auth.version.isLoginAndRegistrationSupportedBySdk @@ -108,9 +109,16 @@ internal class DefaultGetHomeServerCapabilitiesTask @Inject constructor( val homeServerCapabilitiesEntity = HomeServerCapabilitiesEntity.getOrCreate(realm) if (getCapabilitiesResult != null) { - homeServerCapabilitiesEntity.canChangePassword = getCapabilitiesResult.canChangePassword() + val capabilities = getCapabilitiesResult.capabilities - homeServerCapabilitiesEntity.roomVersionsJson = getCapabilitiesResult.capabilities?.roomVersions?.let { + // The spec says: If not present, the client should assume that + // password, display name, avatar changes and 3pid changes are possible via the API + homeServerCapabilitiesEntity.canChangePassword = capabilities?.changePassword?.enabled.orTrue() + homeServerCapabilitiesEntity.canChangeDisplayName = capabilities?.changeDisplayName?.enabled.orTrue() + homeServerCapabilitiesEntity.canChangeAvatar = capabilities?.changeAvatar?.enabled.orTrue() + homeServerCapabilitiesEntity.canChange3pid = capabilities?.change3pid?.enabled.orTrue() + + homeServerCapabilitiesEntity.roomVersionsJson = capabilities?.roomVersions?.let { MoshiProvider.providesMoshi().adapter(RoomVersions::class.java).toJson(it) } } From 83cc88060a540a6b077ad78f84b99db2e16d7040 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 11 Feb 2022 12:01:10 +0000 Subject: [PATCH 075/302] adding changelog entry --- changelog.d/5207.sdk | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5207.sdk diff --git a/changelog.d/5207.sdk b/changelog.d/5207.sdk new file mode 100644 index 0000000000..3ba3e06fb7 --- /dev/null +++ b/changelog.d/5207.sdk @@ -0,0 +1 @@ +Adds support for MSC3283, additional homeserver capabilities \ No newline at end of file From edd95464ea351a023d40c7b1d756e5a92f6844c6 Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Fri, 11 Feb 2022 14:31:28 +0000 Subject: [PATCH 076/302] changelog.d --- changelog.d/5209.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5209.misc diff --git a/changelog.d/5209.misc b/changelog.d/5209.misc new file mode 100644 index 0000000000..a238da9d22 --- /dev/null +++ b/changelog.d/5209.misc @@ -0,0 +1 @@ +Reduce verbosity of debug logging, From c224a4b8137f8d7d027f9adac61be4df8e025fe5 Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Fri, 11 Feb 2022 15:28:16 +0000 Subject: [PATCH 077/302] Make sanity_test.yml use same configuration as integration_test.yml This makes it easier to reason about emulator failures. --- .github/workflows/sanity_test.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/sanity_test.yml b/.github/workflows/sanity_test.yml index 213c43b716..93e4686fe7 100644 --- a/.github/workflows/sanity_test.yml +++ b/.github/workflows/sanity_test.yml @@ -8,7 +8,7 @@ on: # Enrich gradle.properties for CI/CD env: CI_GRADLE_ARG_PROPERTIES: > - -Porg.gradle.jvmargs=-Xmx2g + -Porg.gradle.jvmargs=-Xmx4g -Porg.gradle.parallel=false jobs: @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - api-level: [ 29 ] + api-level: [ 28 ] steps: - uses: actions/checkout@v2 with: @@ -57,9 +57,11 @@ jobs: - name: Run sanity tests on API ${{ matrix.api-level }} uses: reactivecircus/android-emulator-runner@v2 with: - emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none api-level: ${{ matrix.api-level }} - profile: 24 # Pixel 5 + arch: x86 + profile: Nexus 5X + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none emulator-build: 7425822 # workaround to emulator bug: https://github.com/ReactiveCircus/android-emulator-runner/issues/160 script: | adb root @@ -67,12 +69,11 @@ jobs: touch emulator.log chmod 777 emulator.log adb logcat >> emulator.log & - ./gradlew $CI_GRADLE_ARG_PROPERTIES -PallWarningsAsErrors=false connectedGplayDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=im.vector.app.ui.UiAllScreensSanityTest || adb pull storage/emulated/0/Pictures/failure_screenshots && exit 1 - - name: Upload Failing Test Report Log + ./gradlew $CI_GRADLE_ARG_PROPERTIES -PallWarningsAsErrors=false connectedGplayDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=im.vector.app.ui.UiAllScreensSanityTest || adb pull storage/emulated/0/Pictures/failure_screenshots + - name: Upload Test Report Log uses: actions/upload-artifact@v2 - if: failure() with: name: sanity-error-results path: | emulator.log - failure_screenshots/ \ No newline at end of file + failure_screenshots/ From d173a8d15faede5e4566e220fe7988ec10d6d47e Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Fri, 11 Feb 2022 15:32:33 +0000 Subject: [PATCH 078/302] changelog.d --- changelog.d/5210.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5210.misc diff --git a/changelog.d/5210.misc b/changelog.d/5210.misc new file mode 100644 index 0000000000..0b68e8b23a --- /dev/null +++ b/changelog.d/5210.misc @@ -0,0 +1 @@ +Standardise emulator versions of GHA integration tests. From 91a419553742131c876b528273cc410d9233998e Mon Sep 17 00:00:00 2001 From: Sylvia van Os Date: Sat, 12 Feb 2022 15:18:53 +0100 Subject: [PATCH 079/302] Increase max heap size for build The F-Droid build ran OOM during R8 shrinking with 3GB, but worked fine with 4GB Signed-off-by: Sylvia van Os --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 5c99297107..6de52be607 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ # The setting is particularly useful for tweaking memory settings. # Build Time Optimizations -org.gradle.jvmargs=-Xmx3g -Xms512M -XX:MaxPermSize=2048m -XX:MaxMetaspaceSize=1g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC +org.gradle.jvmargs=-Xmx4g -Xms512M -XX:MaxPermSize=2048m -XX:MaxMetaspaceSize=1g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC org.gradle.configureondemand=true org.gradle.parallel=true org.gradle.vfs.watch=true From ff1c307ca06b0137fd9b465122e59193ab91d42d Mon Sep 17 00:00:00 2001 From: bmarty Date: Mon, 14 Feb 2022 00:03:37 +0000 Subject: [PATCH 080/302] Sync Emojis --- .../emoji_picker_datasource_formatted.json | 37 +++++++++++++------ .../main/res/raw/emoji_picker_datasource.json | 2 +- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/tools/emojis/emoji_picker_datasource_formatted.json b/tools/emojis/emoji_picker_datasource_formatted.json index 341cdc0c54..c1aa590003 100644 --- a/tools/emojis/emoji_picker_datasource_formatted.json +++ b/tools/emojis/emoji_picker_datasource_formatted.json @@ -2475,9 +2475,11 @@ "b": "1F636-200D-1F32B-FE0F", "j": [ "absentminded", - "face in clouds", "face in the fog", - "head in clouds" + "head in clouds", + "shower", + "steam", + "dream" ] }, "smirking-face": { @@ -2536,12 +2538,14 @@ "b": "1F62E-200D-1F4A8", "j": [ "exhale", - "face exhaling", "gasp", "groan", "relief", "whisper", - "whistle" + "whistle", + "relieve", + "tired", + "sigh" ] }, "lying-face": { @@ -2745,11 +2749,15 @@ "b": "1F635-200D-1F4AB", "j": [ "dizzy", - "face with spiral eyes", "hypnotized", "spiral", "trouble", - "whoa" + "whoa", + "sick", + "ill", + "confused", + "nauseous", + "nausea" ] }, "exploding-head": { @@ -3704,10 +3712,11 @@ "j": [ "burn", "heart", - "heart on fire", "love", "lust", - "sacred heart" + "sacred heart", + "passionate", + "enthusiastic" ] }, "mending-heart": { @@ -3717,10 +3726,12 @@ "healthier", "improving", "mending", - "mending heart", "recovering", "recuperating", - "well" + "well", + "broken heart", + "bandage", + "wounded" ] }, "red-heart": { @@ -4748,7 +4759,8 @@ "j": [ "beard", "man", - "man: beard" + "man: beard", + "facial hair" ] }, "woman-beard": { @@ -4757,7 +4769,8 @@ "j": [ "beard", "woman", - "woman: beard" + "woman: beard", + "facial hair" ] }, "man-red-hair": { diff --git a/vector/src/main/res/raw/emoji_picker_datasource.json b/vector/src/main/res/raw/emoji_picker_datasource.json index 80131cefac..f4fa7f812a 100644 --- a/vector/src/main/res/raw/emoji_picker_datasource.json +++ b/vector/src/main/res/raw/emoji_picker_datasource.json @@ -1 +1 @@ -{"compressed":true,"categories":[{"id":"smileys_&_emotion","name":"Smileys & Emotion","emojis":["grinning-face","grinning-face-with-big-eyes","grinning-face-with-smiling-eyes","beaming-face-with-smiling-eyes","grinning-squinting-face","grinning-face-with-sweat","rolling-on-the-floor-laughing","face-with-tears-of-joy","slightly-smiling-face","upsidedown-face","melting-face","winking-face","smiling-face-with-smiling-eyes","smiling-face-with-halo","smiling-face-with-hearts","smiling-face-with-hearteyes","starstruck","face-blowing-a-kiss","kissing-face","smiling-face","kissing-face-with-closed-eyes","kissing-face-with-smiling-eyes","smiling-face-with-tear","face-savoring-food","face-with-tongue","winking-face-with-tongue","zany-face","squinting-face-with-tongue","moneymouth-face","smiling-face-with-open-hands","face-with-hand-over-mouth","face-with-open-eyes-and-hand-over-mouth","face-with-peeking-eye","shushing-face","thinking-face","saluting-face","zippermouth-face","face-with-raised-eyebrow","neutral-face","expressionless-face","face-without-mouth","dotted-line-face","face-in-clouds","smirking-face","unamused-face","face-with-rolling-eyes","grimacing-face","face-exhaling","lying-face","relieved-face","pensive-face","sleepy-face","drooling-face","sleeping-face","face-with-medical-mask","face-with-thermometer","face-with-headbandage","nauseated-face","face-vomiting","sneezing-face","hot-face","cold-face","woozy-face","face-with-crossedout-eyes","face-with-spiral-eyes","exploding-head","cowboy-hat-face","partying-face","disguised-face","smiling-face-with-sunglasses","nerd-face","face-with-monocle","confused-face","face-with-diagonal-mouth","worried-face","slightly-frowning-face","frowning-face","face-with-open-mouth","hushed-face","astonished-face","flushed-face","pleading-face","face-holding-back-tears","frowning-face-with-open-mouth","anguished-face","fearful-face","anxious-face-with-sweat","sad-but-relieved-face","crying-face","loudly-crying-face","face-screaming-in-fear","confounded-face","persevering-face","disappointed-face","downcast-face-with-sweat","weary-face","tired-face","yawning-face","face-with-steam-from-nose","pouting-face","angry-face","face-with-symbols-on-mouth","smiling-face-with-horns","angry-face-with-horns","skull","skull-and-crossbones","pile-of-poo","clown-face","ogre","goblin","ghost","alien","alien-monster","robot","grinning-cat","grinning-cat-with-smiling-eyes","cat-with-tears-of-joy","smiling-cat-with-hearteyes","cat-with-wry-smile","kissing-cat","weary-cat","crying-cat","pouting-cat","seenoevil-monkey","hearnoevil-monkey","speaknoevil-monkey","kiss-mark","love-letter","heart-with-arrow","heart-with-ribbon","sparkling-heart","growing-heart","beating-heart","revolving-hearts","two-hearts","heart-decoration","heart-exclamation","broken-heart","heart-on-fire","mending-heart","red-heart","orange-heart","yellow-heart","green-heart","blue-heart","purple-heart","brown-heart","black-heart","white-heart","hundred-points","anger-symbol","collision","dizzy","sweat-droplets","dashing-away","hole","bomb","speech-balloon","eye-in-speech-bubble","left-speech-bubble","right-anger-bubble","thought-balloon","zzz"]},{"id":"people_&_body","name":"People & Body","emojis":["waving-hand","raised-back-of-hand","hand-with-fingers-splayed","raised-hand","vulcan-salute","rightwards-hand","leftwards-hand","palm-down-hand","palm-up-hand","ok-hand","pinched-fingers","pinching-hand","victory-hand","crossed-fingers","hand-with-index-finger-and-thumb-crossed","loveyou-gesture","sign-of-the-horns","call-me-hand","backhand-index-pointing-left","backhand-index-pointing-right","backhand-index-pointing-up","middle-finger","backhand-index-pointing-down","index-pointing-up","index-pointing-at-the-viewer","thumbs-up","thumbs-down","raised-fist","oncoming-fist","leftfacing-fist","rightfacing-fist","clapping-hands","raising-hands","heart-hands","open-hands","palms-up-together","handshake","folded-hands","writing-hand","nail-polish","selfie","flexed-biceps","mechanical-arm","mechanical-leg","leg","foot","ear","ear-with-hearing-aid","nose","brain","anatomical-heart","lungs","tooth","bone","eyes","eye","tongue","mouth","biting-lip","baby","child","boy","girl","person","person-blond-hair","man","person-beard","man-beard","woman-beard","man-red-hair","man-curly-hair","man-white-hair","man-bald","woman","woman-red-hair","person-red-hair","woman-curly-hair","person-curly-hair","woman-white-hair","person-white-hair","woman-bald","person-bald","woman-blond-hair","man-blond-hair","older-person","old-man","old-woman","person-frowning","man-frowning","woman-frowning","person-pouting","man-pouting","woman-pouting","person-gesturing-no","man-gesturing-no","woman-gesturing-no","person-gesturing-ok","man-gesturing-ok","woman-gesturing-ok","person-tipping-hand","man-tipping-hand","woman-tipping-hand","person-raising-hand","man-raising-hand","woman-raising-hand","deaf-person","deaf-man","deaf-woman","person-bowing","man-bowing","woman-bowing","person-facepalming","man-facepalming","woman-facepalming","person-shrugging","man-shrugging","woman-shrugging","health-worker","man-health-worker","woman-health-worker","student","man-student","woman-student","teacher","man-teacher","woman-teacher","judge","man-judge","woman-judge","farmer","man-farmer","woman-farmer","cook","man-cook","woman-cook","mechanic","man-mechanic","woman-mechanic","factory-worker","man-factory-worker","woman-factory-worker","office-worker","man-office-worker","woman-office-worker","scientist","man-scientist","woman-scientist","technologist","man-technologist","woman-technologist","singer","man-singer","woman-singer","artist","man-artist","woman-artist","pilot","man-pilot","woman-pilot","astronaut","man-astronaut","woman-astronaut","firefighter","man-firefighter","woman-firefighter","police-officer","man-police-officer","woman-police-officer","detective","man-detective","woman-detective","guard","man-guard","woman-guard","ninja","construction-worker","man-construction-worker","woman-construction-worker","person-with-crown","prince","princess","person-wearing-turban","man-wearing-turban","woman-wearing-turban","person-with-skullcap","woman-with-headscarf","person-in-tuxedo","man-in-tuxedo","woman-in-tuxedo","person-with-veil","man-with-veil","woman-with-veil","pregnant-woman","pregnant-man","pregnant-person","breastfeeding","woman-feeding-baby","man-feeding-baby","person-feeding-baby","baby-angel","santa-claus","mrs-claus","mx-claus","superhero","man-superhero","woman-superhero","supervillain","man-supervillain","woman-supervillain","mage","man-mage","woman-mage","fairy","man-fairy","woman-fairy","vampire","man-vampire","woman-vampire","merperson","merman","mermaid","elf","man-elf","woman-elf","genie","man-genie","woman-genie","zombie","man-zombie","woman-zombie","troll","person-getting-massage","man-getting-massage","woman-getting-massage","person-getting-haircut","man-getting-haircut","woman-getting-haircut","person-walking","man-walking","woman-walking","person-standing","man-standing","woman-standing","person-kneeling","man-kneeling","woman-kneeling","person-with-white-cane","man-with-white-cane","woman-with-white-cane","person-in-motorized-wheelchair","man-in-motorized-wheelchair","woman-in-motorized-wheelchair","person-in-manual-wheelchair","man-in-manual-wheelchair","woman-in-manual-wheelchair","person-running","man-running","woman-running","woman-dancing","man-dancing","person-in-suit-levitating","people-with-bunny-ears","men-with-bunny-ears","women-with-bunny-ears","person-in-steamy-room","man-in-steamy-room","woman-in-steamy-room","person-climbing","man-climbing","woman-climbing","person-fencing","horse-racing","skier","snowboarder","person-golfing","man-golfing","woman-golfing","person-surfing","man-surfing","woman-surfing","person-rowing-boat","man-rowing-boat","woman-rowing-boat","person-swimming","man-swimming","woman-swimming","person-bouncing-ball","man-bouncing-ball","woman-bouncing-ball","person-lifting-weights","man-lifting-weights","woman-lifting-weights","person-biking","man-biking","woman-biking","person-mountain-biking","man-mountain-biking","woman-mountain-biking","person-cartwheeling","man-cartwheeling","woman-cartwheeling","people-wrestling","men-wrestling","women-wrestling","person-playing-water-polo","man-playing-water-polo","woman-playing-water-polo","person-playing-handball","man-playing-handball","woman-playing-handball","person-juggling","man-juggling","woman-juggling","person-in-lotus-position","man-in-lotus-position","woman-in-lotus-position","person-taking-bath","person-in-bed","people-holding-hands","women-holding-hands","woman-and-man-holding-hands","men-holding-hands","kiss","kiss-woman-man","kiss-man-man","kiss-woman-woman","couple-with-heart","couple-with-heart-woman-man","couple-with-heart-man-man","couple-with-heart-woman-woman","family","family-man-woman-boy","family-man-woman-girl","family-man-woman-girl-boy","family-man-woman-boy-boy","family-man-woman-girl-girl","family-man-man-boy","family-man-man-girl","family-man-man-girl-boy","family-man-man-boy-boy","family-man-man-girl-girl","family-woman-woman-boy","family-woman-woman-girl","family-woman-woman-girl-boy","family-woman-woman-boy-boy","family-woman-woman-girl-girl","family-man-boy","family-man-boy-boy","family-man-girl","family-man-girl-boy","family-man-girl-girl","family-woman-boy","family-woman-boy-boy","family-woman-girl","family-woman-girl-boy","family-woman-girl-girl","speaking-head","bust-in-silhouette","busts-in-silhouette","people-hugging","footprints"]},{"id":"animals_&_nature","name":"Animals & Nature","emojis":["monkey-face","monkey","gorilla","orangutan","dog-face","dog","guide-dog","service-dog","poodle","wolf","fox","raccoon","cat-face","cat","black-cat","lion","tiger-face","tiger","leopard","horse-face","horse","unicorn","zebra","deer","bison","cow-face","ox","water-buffalo","cow","pig-face","pig","boar","pig-nose","ram","ewe","goat","camel","twohump-camel","llama","giraffe","elephant","mammoth","rhinoceros","hippopotamus","mouse-face","mouse","rat","hamster","rabbit-face","rabbit","chipmunk","beaver","hedgehog","bat","bear","polar-bear","koala","panda","sloth","otter","skunk","kangaroo","badger","paw-prints","turkey","chicken","rooster","hatching-chick","baby-chick","frontfacing-baby-chick","bird","penguin","dove","eagle","duck","swan","owl","dodo","feather","flamingo","peacock","parrot","frog","crocodile","turtle","lizard","snake","dragon-face","dragon","sauropod","trex","spouting-whale","whale","dolphin","seal","fish","tropical-fish","blowfish","shark","octopus","spiral-shell","coral","snail","butterfly","bug","ant","honeybee","beetle","lady-beetle","cricket","cockroach","spider","spider-web","scorpion","mosquito","fly","worm","microbe","bouquet","cherry-blossom","white-flower","lotus","rosette","rose","wilted-flower","hibiscus","sunflower","blossom","tulip","seedling","potted-plant","evergreen-tree","deciduous-tree","palm-tree","cactus","sheaf-of-rice","herb","shamrock","four-leaf-clover","maple-leaf","fallen-leaf","leaf-fluttering-in-wind","empty-nest","nest-with-eggs"]},{"id":"food_&_drink","name":"Food & Drink","emojis":["grapes","melon","watermelon","tangerine","lemon","banana","pineapple","mango","red-apple","green-apple","pear","peach","cherries","strawberry","blueberries","kiwi-fruit","tomato","olive","coconut","avocado","eggplant","potato","carrot","ear-of-corn","hot-pepper","bell-pepper","cucumber","leafy-green","broccoli","garlic","onion","mushroom","peanuts","beans","chestnut","bread","croissant","baguette-bread","flatbread","pretzel","bagel","pancakes","waffle","cheese-wedge","meat-on-bone","poultry-leg","cut-of-meat","bacon","hamburger","french-fries","pizza","hot-dog","sandwich","taco","burrito","tamale","stuffed-flatbread","falafel","egg","cooking","shallow-pan-of-food","pot-of-food","fondue","bowl-with-spoon","green-salad","popcorn","butter","salt","canned-food","bento-box","rice-cracker","rice-ball","cooked-rice","curry-rice","steaming-bowl","spaghetti","roasted-sweet-potato","oden","sushi","fried-shrimp","fish-cake-with-swirl","moon-cake","dango","dumpling","fortune-cookie","takeout-box","crab","lobster","shrimp","squid","oyster","soft-ice-cream","shaved-ice","ice-cream","doughnut","cookie","birthday-cake","shortcake","cupcake","pie","chocolate-bar","candy","lollipop","custard","honey-pot","baby-bottle","glass-of-milk","hot-beverage","teapot","teacup-without-handle","sake","bottle-with-popping-cork","wine-glass","cocktail-glass","tropical-drink","beer-mug","clinking-beer-mugs","clinking-glasses","tumbler-glass","pouring-liquid","cup-with-straw","bubble-tea","beverage-box","mate","ice","chopsticks","fork-and-knife-with-plate","fork-and-knife","spoon","kitchen-knife","jar","amphora"]},{"id":"travel_&_places","name":"Travel & Places","emojis":["globe-showing-europeafrica","globe-showing-americas","globe-showing-asiaaustralia","globe-with-meridians","world-map","map-of-japan","compass","snowcapped-mountain","mountain","volcano","mount-fuji","camping","beach-with-umbrella","desert","desert-island","national-park","stadium","classical-building","building-construction","brick","rock","wood","hut","houses","derelict-house","house","house-with-garden","office-building","japanese-post-office","post-office","hospital","bank","hotel","love-hotel","convenience-store","school","department-store","factory","japanese-castle","castle","wedding","tokyo-tower","statue-of-liberty","church","mosque","hindu-temple","synagogue","shinto-shrine","kaaba","fountain","tent","foggy","night-with-stars","cityscape","sunrise-over-mountains","sunrise","cityscape-at-dusk","sunset","bridge-at-night","hot-springs","carousel-horse","playground-slide","ferris-wheel","roller-coaster","barber-pole","circus-tent","locomotive","railway-car","highspeed-train","bullet-train","train","metro","light-rail","station","tram","monorail","mountain-railway","tram-car","bus","oncoming-bus","trolleybus","minibus","ambulance","fire-engine","police-car","oncoming-police-car","taxi","oncoming-taxi","automobile","oncoming-automobile","sport-utility-vehicle","pickup-truck","delivery-truck","articulated-lorry","tractor","racing-car","motorcycle","motor-scooter","manual-wheelchair","motorized-wheelchair","auto-rickshaw","bicycle","kick-scooter","skateboard","roller-skate","bus-stop","motorway","railway-track","oil-drum","fuel-pump","wheel","police-car-light","horizontal-traffic-light","vertical-traffic-light","stop-sign","construction","anchor","ring-buoy","sailboat","canoe","speedboat","passenger-ship","ferry","motor-boat","ship","airplane","small-airplane","airplane-departure","airplane-arrival","parachute","seat","helicopter","suspension-railway","mountain-cableway","aerial-tramway","satellite","rocket","flying-saucer","bellhop-bell","luggage","hourglass-done","hourglass-not-done","watch","alarm-clock","stopwatch","timer-clock","mantelpiece-clock","twelve-oclock","twelvethirty","one-oclock","onethirty","two-oclock","twothirty","three-oclock","threethirty","four-oclock","fourthirty","five-oclock","fivethirty","six-oclock","sixthirty","seven-oclock","seventhirty","eight-oclock","eightthirty","nine-oclock","ninethirty","ten-oclock","tenthirty","eleven-oclock","eleventhirty","new-moon","waxing-crescent-moon","first-quarter-moon","waxing-gibbous-moon","full-moon","waning-gibbous-moon","last-quarter-moon","waning-crescent-moon","crescent-moon","new-moon-face","first-quarter-moon-face","last-quarter-moon-face","thermometer","sun","full-moon-face","sun-with-face","ringed-planet","star","glowing-star","shooting-star","milky-way","cloud","sun-behind-cloud","cloud-with-lightning-and-rain","sun-behind-small-cloud","sun-behind-large-cloud","sun-behind-rain-cloud","cloud-with-rain","cloud-with-snow","cloud-with-lightning","tornado","fog","wind-face","cyclone","rainbow","closed-umbrella","umbrella","umbrella-with-rain-drops","umbrella-on-ground","high-voltage","snowflake","snowman","snowman-without-snow","comet","fire","droplet","water-wave"]},{"id":"activities","name":"Activities","emojis":["jackolantern","christmas-tree","fireworks","sparkler","firecracker","sparkles","balloon","party-popper","confetti-ball","tanabata-tree","pine-decoration","japanese-dolls","carp-streamer","wind-chime","moon-viewing-ceremony","red-envelope","ribbon","wrapped-gift","reminder-ribbon","admission-tickets","ticket","military-medal","trophy","sports-medal","1st-place-medal","2nd-place-medal","3rd-place-medal","soccer-ball","baseball","softball","basketball","volleyball","american-football","rugby-football","tennis","flying-disc","bowling","cricket-game","field-hockey","ice-hockey","lacrosse","ping-pong","badminton","boxing-glove","martial-arts-uniform","goal-net","flag-in-hole","ice-skate","fishing-pole","diving-mask","running-shirt","skis","sled","curling-stone","bullseye","yoyo","kite","pool-8-ball","crystal-ball","magic-wand","nazar-amulet","hamsa","video-game","joystick","slot-machine","game-die","puzzle-piece","teddy-bear","piata","mirror-ball","nesting-dolls","spade-suit","heart-suit","diamond-suit","club-suit","chess-pawn","joker","mahjong-red-dragon","flower-playing-cards","performing-arts","framed-picture","artist-palette","thread","sewing-needle","yarn","knot"]},{"id":"objects","name":"Objects","emojis":["glasses","sunglasses","goggles","lab-coat","safety-vest","necktie","tshirt","jeans","scarf","gloves","coat","socks","dress","kimono","sari","onepiece-swimsuit","briefs","shorts","bikini","womans-clothes","purse","handbag","clutch-bag","shopping-bags","backpack","thong-sandal","mans-shoe","running-shoe","hiking-boot","flat-shoe","highheeled-shoe","womans-sandal","ballet-shoes","womans-boot","crown","womans-hat","top-hat","graduation-cap","billed-cap","military-helmet","rescue-workers-helmet","prayer-beads","lipstick","ring","gem-stone","muted-speaker","speaker-low-volume","speaker-medium-volume","speaker-high-volume","loudspeaker","megaphone","postal-horn","bell","bell-with-slash","musical-score","musical-note","musical-notes","studio-microphone","level-slider","control-knobs","microphone","headphone","radio","saxophone","accordion","guitar","musical-keyboard","trumpet","violin","banjo","drum","long-drum","mobile-phone","mobile-phone-with-arrow","telephone","telephone-receiver","pager","fax-machine","battery","low-battery","electric-plug","laptop","desktop-computer","printer","keyboard","computer-mouse","trackball","computer-disk","floppy-disk","optical-disk","dvd","abacus","movie-camera","film-frames","film-projector","clapper-board","television","camera","camera-with-flash","video-camera","videocassette","magnifying-glass-tilted-left","magnifying-glass-tilted-right","candle","light-bulb","flashlight","red-paper-lantern","diya-lamp","notebook-with-decorative-cover","closed-book","open-book","green-book","blue-book","orange-book","books","notebook","ledger","page-with-curl","scroll","page-facing-up","newspaper","rolledup-newspaper","bookmark-tabs","bookmark","label","money-bag","coin","yen-banknote","dollar-banknote","euro-banknote","pound-banknote","money-with-wings","credit-card","receipt","chart-increasing-with-yen","envelope","email","incoming-envelope","envelope-with-arrow","outbox-tray","inbox-tray","package","closed-mailbox-with-raised-flag","closed-mailbox-with-lowered-flag","open-mailbox-with-raised-flag","open-mailbox-with-lowered-flag","postbox","ballot-box-with-ballot","pencil","black-nib","fountain-pen","pen","paintbrush","crayon","memo","briefcase","file-folder","open-file-folder","card-index-dividers","calendar","tearoff-calendar","spiral-notepad","spiral-calendar","card-index","chart-increasing","chart-decreasing","bar-chart","clipboard","pushpin","round-pushpin","paperclip","linked-paperclips","straight-ruler","triangular-ruler","scissors","card-file-box","file-cabinet","wastebasket","locked","unlocked","locked-with-pen","locked-with-key","key","old-key","hammer","axe","pick","hammer-and-pick","hammer-and-wrench","dagger","crossed-swords","water-pistol","boomerang","bow-and-arrow","shield","carpentry-saw","wrench","screwdriver","nut-and-bolt","gear","clamp","balance-scale","white-cane","link","chains","hook","toolbox","magnet","ladder","alembic","test-tube","petri-dish","dna","microscope","telescope","satellite-antenna","syringe","drop-of-blood","pill","adhesive-bandage","crutch","stethoscope","xray","door","elevator","mirror","window","bed","couch-and-lamp","chair","toilet","plunger","shower","bathtub","mouse-trap","razor","lotion-bottle","safety-pin","broom","basket","roll-of-paper","bucket","soap","bubbles","toothbrush","sponge","fire-extinguisher","shopping-cart","cigarette","coffin","headstone","funeral-urn","moai","placard","identification-card"]},{"id":"symbols","name":"Symbols","emojis":["atm-sign","litter-in-bin-sign","potable-water","wheelchair-symbol","mens-room","womens-room","restroom","baby-symbol","water-closet","passport-control","customs","baggage-claim","left-luggage","warning","children-crossing","no-entry","prohibited","no-bicycles","no-smoking","no-littering","nonpotable-water","no-pedestrians","no-mobile-phones","no-one-under-eighteen","radioactive","biohazard","up-arrow","upright-arrow","right-arrow","downright-arrow","down-arrow","downleft-arrow","left-arrow","upleft-arrow","updown-arrow","leftright-arrow","right-arrow-curving-left","left-arrow-curving-right","right-arrow-curving-up","right-arrow-curving-down","clockwise-vertical-arrows","counterclockwise-arrows-button","back-arrow","end-arrow","on-arrow","soon-arrow","top-arrow","place-of-worship","atom-symbol","om","star-of-david","wheel-of-dharma","yin-yang","latin-cross","orthodox-cross","star-and-crescent","peace-symbol","menorah","dotted-sixpointed-star","aries","taurus","gemini","cancer","leo","virgo","libra","scorpio","sagittarius","capricorn","aquarius","pisces","ophiuchus","shuffle-tracks-button","repeat-button","repeat-single-button","play-button","fastforward-button","next-track-button","play-or-pause-button","reverse-button","fast-reverse-button","last-track-button","upwards-button","fast-up-button","downwards-button","fast-down-button","pause-button","stop-button","record-button","eject-button","cinema","dim-button","bright-button","antenna-bars","vibration-mode","mobile-phone-off","female-sign","male-sign","transgender-symbol","multiply","plus","minus","divide","heavy-equals-sign","infinity","double-exclamation-mark","exclamation-question-mark","red-question-mark","white-question-mark","white-exclamation-mark","red-exclamation-mark","wavy-dash","currency-exchange","heavy-dollar-sign","medical-symbol","recycling-symbol","fleurdelis","trident-emblem","name-badge","japanese-symbol-for-beginner","hollow-red-circle","check-mark-button","check-box-with-check","check-mark","cross-mark","cross-mark-button","curly-loop","double-curly-loop","part-alternation-mark","eightspoked-asterisk","eightpointed-star","sparkle","copyright","registered","trade-mark","keycap","keycap","keycap-0","keycap-1","keycap-2","keycap-3","keycap-4","keycap-5","keycap-6","keycap-7","keycap-8","keycap-9","keycap-10","input-latin-uppercase","input-latin-lowercase","input-numbers","input-symbols","input-latin-letters","a-button-blood-type","ab-button-blood-type","b-button-blood-type","cl-button","cool-button","free-button","information","id-button","circled-m","new-button","ng-button","o-button-blood-type","ok-button","p-button","sos-button","up-button","vs-button","japanese-here-button","japanese-service-charge-button","japanese-monthly-amount-button","japanese-not-free-of-charge-button","japanese-reserved-button","japanese-bargain-button","japanese-discount-button","japanese-free-of-charge-button","japanese-prohibited-button","japanese-acceptable-button","japanese-application-button","japanese-passing-grade-button","japanese-vacancy-button","japanese-congratulations-button","japanese-secret-button","japanese-open-for-business-button","japanese-no-vacancy-button","red-circle","orange-circle","yellow-circle","green-circle","blue-circle","purple-circle","brown-circle","black-circle","white-circle","red-square","orange-square","yellow-square","green-square","blue-square","purple-square","brown-square","black-large-square","white-large-square","black-medium-square","white-medium-square","black-mediumsmall-square","white-mediumsmall-square","black-small-square","white-small-square","large-orange-diamond","large-blue-diamond","small-orange-diamond","small-blue-diamond","red-triangle-pointed-up","red-triangle-pointed-down","diamond-with-a-dot","radio-button","white-square-button","black-square-button"]},{"id":"flags","name":"Flags","emojis":["chequered-flag","triangular-flag","crossed-flags","black-flag","white-flag","rainbow-flag","transgender-flag","pirate-flag","flag-ascension-island","flag-andorra","flag-united-arab-emirates","flag-afghanistan","flag-antigua--barbuda","flag-anguilla","flag-albania","flag-armenia","flag-angola","flag-antarctica","flag-argentina","flag-american-samoa","flag-austria","flag-australia","flag-aruba","flag-land-islands","flag-azerbaijan","flag-bosnia--herzegovina","flag-barbados","flag-bangladesh","flag-belgium","flag-burkina-faso","flag-bulgaria","flag-bahrain","flag-burundi","flag-benin","flag-st-barthlemy","flag-bermuda","flag-brunei","flag-bolivia","flag-caribbean-netherlands","flag-brazil","flag-bahamas","flag-bhutan","flag-bouvet-island","flag-botswana","flag-belarus","flag-belize","flag-canada","flag-cocos-keeling-islands","flag-congo--kinshasa","flag-central-african-republic","flag-congo--brazzaville","flag-switzerland","flag-cte-divoire","flag-cook-islands","flag-chile","flag-cameroon","flag-china","flag-colombia","flag-clipperton-island","flag-costa-rica","flag-cuba","flag-cape-verde","flag-curaao","flag-christmas-island","flag-cyprus","flag-czechia","flag-germany","flag-diego-garcia","flag-djibouti","flag-denmark","flag-dominica","flag-dominican-republic","flag-algeria","flag-ceuta--melilla","flag-ecuador","flag-estonia","flag-egypt","flag-western-sahara","flag-eritrea","flag-spain","flag-ethiopia","flag-european-union","flag-finland","flag-fiji","flag-falkland-islands","flag-micronesia","flag-faroe-islands","flag-france","flag-gabon","flag-united-kingdom","flag-grenada","flag-georgia","flag-french-guiana","flag-guernsey","flag-ghana","flag-gibraltar","flag-greenland","flag-gambia","flag-guinea","flag-guadeloupe","flag-equatorial-guinea","flag-greece","flag-south-georgia--south-sandwich-islands","flag-guatemala","flag-guam","flag-guineabissau","flag-guyana","flag-hong-kong-sar-china","flag-heard--mcdonald-islands","flag-honduras","flag-croatia","flag-haiti","flag-hungary","flag-canary-islands","flag-indonesia","flag-ireland","flag-israel","flag-isle-of-man","flag-india","flag-british-indian-ocean-territory","flag-iraq","flag-iran","flag-iceland","flag-italy","flag-jersey","flag-jamaica","flag-jordan","flag-japan","flag-kenya","flag-kyrgyzstan","flag-cambodia","flag-kiribati","flag-comoros","flag-st-kitts--nevis","flag-north-korea","flag-south-korea","flag-kuwait","flag-cayman-islands","flag-kazakhstan","flag-laos","flag-lebanon","flag-st-lucia","flag-liechtenstein","flag-sri-lanka","flag-liberia","flag-lesotho","flag-lithuania","flag-luxembourg","flag-latvia","flag-libya","flag-morocco","flag-monaco","flag-moldova","flag-montenegro","flag-st-martin","flag-madagascar","flag-marshall-islands","flag-north-macedonia","flag-mali","flag-myanmar-burma","flag-mongolia","flag-macao-sar-china","flag-northern-mariana-islands","flag-martinique","flag-mauritania","flag-montserrat","flag-malta","flag-mauritius","flag-maldives","flag-malawi","flag-mexico","flag-malaysia","flag-mozambique","flag-namibia","flag-new-caledonia","flag-niger","flag-norfolk-island","flag-nigeria","flag-nicaragua","flag-netherlands","flag-norway","flag-nepal","flag-nauru","flag-niue","flag-new-zealand","flag-oman","flag-panama","flag-peru","flag-french-polynesia","flag-papua-new-guinea","flag-philippines","flag-pakistan","flag-poland","flag-st-pierre--miquelon","flag-pitcairn-islands","flag-puerto-rico","flag-palestinian-territories","flag-portugal","flag-palau","flag-paraguay","flag-qatar","flag-runion","flag-romania","flag-serbia","flag-russia","flag-rwanda","flag-saudi-arabia","flag-solomon-islands","flag-seychelles","flag-sudan","flag-sweden","flag-singapore","flag-st-helena","flag-slovenia","flag-svalbard--jan-mayen","flag-slovakia","flag-sierra-leone","flag-san-marino","flag-senegal","flag-somalia","flag-suriname","flag-south-sudan","flag-so-tom--prncipe","flag-el-salvador","flag-sint-maarten","flag-syria","flag-eswatini","flag-tristan-da-cunha","flag-turks--caicos-islands","flag-chad","flag-french-southern-territories","flag-togo","flag-thailand","flag-tajikistan","flag-tokelau","flag-timorleste","flag-turkmenistan","flag-tunisia","flag-tonga","flag-turkey","flag-trinidad--tobago","flag-tuvalu","flag-taiwan","flag-tanzania","flag-ukraine","flag-uganda","flag-us-outlying-islands","flag-united-nations","flag-united-states","flag-uruguay","flag-uzbekistan","flag-vatican-city","flag-st-vincent--grenadines","flag-venezuela","flag-british-virgin-islands","flag-us-virgin-islands","flag-vietnam","flag-vanuatu","flag-wallis--futuna","flag-samoa","flag-kosovo","flag-yemen","flag-mayotte","flag-south-africa","flag-zambia","flag-zimbabwe","flag-england","flag-scotland","flag-wales"]}],"emojis":{"grinning-face":{"a":"Grinning Face","b":"1F600","j":["face","grin","smile","happy","joy",":D"]},"grinning-face-with-big-eyes":{"a":"Grinning Face with Big Eyes","b":"1F603","j":["face","mouth","open","smile","happy","joy","haha",":D",":)","funny"]},"grinning-face-with-smiling-eyes":{"a":"Grinning Face with Smiling Eyes","b":"1F604","j":["eye","face","mouth","open","smile","happy","joy","funny","haha","laugh","like",":D",":)"]},"beaming-face-with-smiling-eyes":{"a":"Beaming Face with Smiling Eyes","b":"1F601","j":["eye","face","grin","smile","happy","joy","kawaii"]},"grinning-squinting-face":{"a":"Grinning Squinting Face","b":"1F606","j":["face","laugh","mouth","satisfied","smile","happy","joy","lol","haha","glad","XD"]},"grinning-face-with-sweat":{"a":"Grinning Face with Sweat","b":"1F605","j":["cold","face","open","smile","sweat","hot","happy","laugh","relief"]},"rolling-on-the-floor-laughing":{"a":"Rolling on the Floor Laughing","b":"1F923","j":["face","floor","laugh","rofl","rolling","rotfl","laughing","lol","haha"]},"face-with-tears-of-joy":{"a":"Face with Tears of Joy","b":"1F602","j":["face","joy","laugh","tear","cry","tears","weep","happy","happytears","haha"]},"slightly-smiling-face":{"a":"Slightly Smiling Face","b":"1F642","j":["face","smile"]},"upsidedown-face":{"a":"Upside-Down Face","b":"1F643","j":["face","upside-down","upside_down_face","flipped","silly","smile"]},"melting-face":{"a":"⊛ Melting Face","b":"1FAE0","j":["disappear","dissolve","liquid","melt"]},"winking-face":{"a":"Winking Face","b":"1F609","j":["face","wink","happy","mischievous","secret",";)","smile","eye"]},"smiling-face-with-smiling-eyes":{"a":"Smiling Face with Smiling Eyes","b":"1F60A","j":["blush","eye","face","smile","happy","flushed","crush","embarrassed","shy","joy"]},"smiling-face-with-halo":{"a":"Smiling Face with Halo","b":"1F607","j":["angel","face","fantasy","halo","innocent","heaven"]},"smiling-face-with-hearts":{"a":"Smiling Face with Hearts","b":"1F970","j":["adore","crush","hearts","in love","face","love","like","affection","valentines","infatuation"]},"smiling-face-with-hearteyes":{"a":"Smiling Face with Heart-Eyes","b":"1F60D","j":["eye","face","love","smile","smiling face with heart-eyes","smiling_face_with_heart_eyes","like","affection","valentines","infatuation","crush","heart"]},"starstruck":{"a":"Star-Struck","b":"1F929","j":["eyes","face","grinning","star","star-struck","starry-eyed","star_struck","smile","starry"]},"face-blowing-a-kiss":{"a":"Face Blowing a Kiss","b":"1F618","j":["face","kiss","love","like","affection","valentines","infatuation"]},"kissing-face":{"a":"Kissing Face","b":"1F617","j":["face","kiss","love","like","3","valentines","infatuation"]},"smiling-face":{"a":"Smiling Face","b":"263A","j":["face","outlined","relaxed","smile","blush","massage","happiness"]},"kissing-face-with-closed-eyes":{"a":"Kissing Face with Closed Eyes","b":"1F61A","j":["closed","eye","face","kiss","love","like","affection","valentines","infatuation"]},"kissing-face-with-smiling-eyes":{"a":"Kissing Face with Smiling Eyes","b":"1F619","j":["eye","face","kiss","smile","affection","valentines","infatuation"]},"smiling-face-with-tear":{"a":"Smiling Face with Tear","b":"1F972","j":["grateful","proud","relieved","smiling","tear","touched","sad","cry","pretend"]},"face-savoring-food":{"a":"Face Savoring Food","b":"1F60B","j":["delicious","face","savouring","smile","yum","happy","joy","tongue","silly","yummy","nom"]},"face-with-tongue":{"a":"Face with Tongue","b":"1F61B","j":["face","tongue","prank","childish","playful","mischievous","smile"]},"winking-face-with-tongue":{"a":"Winking Face with Tongue","b":"1F61C","j":["eye","face","joke","tongue","wink","prank","childish","playful","mischievous","smile"]},"zany-face":{"a":"Zany Face","b":"1F92A","j":["eye","goofy","large","small","face","crazy"]},"squinting-face-with-tongue":{"a":"Squinting Face with Tongue","b":"1F61D","j":["eye","face","horrible","taste","tongue","prank","playful","mischievous","smile"]},"moneymouth-face":{"a":"Money-Mouth Face","b":"1F911","j":["face","money","money-mouth face","mouth","money_mouth_face","rich","dollar"]},"smiling-face-with-open-hands":{"a":"Smiling Face with Open Hands","b":"1F917","j":["face","hug","hugging","open hands","smiling face","hugging_face","smile"]},"face-with-hand-over-mouth":{"a":"Face with Hand over Mouth","b":"1F92D","j":["whoops","shock","sudden realization","surprise","face"]},"face-with-open-eyes-and-hand-over-mouth":{"a":"⊛ Face with Open Eyes and Hand over Mouth","b":"1FAE2","j":["amazement","awe","disbelief","embarrass","scared","surprise"]},"face-with-peeking-eye":{"a":"⊛ Face with Peeking Eye","b":"1FAE3","j":["captivated","peep","stare"]},"shushing-face":{"a":"Shushing Face","b":"1F92B","j":["quiet","shush","face","shhh"]},"thinking-face":{"a":"Thinking Face","b":"1F914","j":["face","thinking","hmmm","think","consider"]},"saluting-face":{"a":"⊛ Saluting Face","b":"1FAE1","j":["ok","salute","sunny","troops","yes"]},"zippermouth-face":{"a":"Zipper-Mouth Face","b":"1F910","j":["face","mouth","zipper","zipper-mouth face","zipper_mouth_face","sealed","secret"]},"face-with-raised-eyebrow":{"a":"Face with Raised Eyebrow","b":"1F928","j":["distrust","skeptic","disapproval","disbelief","mild surprise","scepticism","face","surprise"]},"neutral-face":{"a":"Neutral Face","b":"1F610","j":["deadpan","face","meh","neutral","indifference",":|"]},"expressionless-face":{"a":"Expressionless Face","b":"1F611","j":["expressionless","face","inexpressive","meh","unexpressive","indifferent","-_-","deadpan"]},"face-without-mouth":{"a":"Face Without Mouth","b":"1F636","j":["face","mouth","quiet","silent","hellokitty"]},"dotted-line-face":{"a":"⊛ Dotted Line Face","b":"1FAE5","j":["depressed","disappear","hide","introvert","invisible"]},"face-in-clouds":{"a":"Face in Clouds","b":"1F636-200D-1F32B-FE0F","j":["absentminded","face in clouds","face in the fog","head in clouds"]},"smirking-face":{"a":"Smirking Face","b":"1F60F","j":["face","smirk","smile","mean","prank","smug","sarcasm"]},"unamused-face":{"a":"Unamused Face","b":"1F612","j":["face","unamused","unhappy","indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"]},"face-with-rolling-eyes":{"a":"Face with Rolling Eyes","b":"1F644","j":["eyeroll","eyes","face","rolling","frustrated"]},"grimacing-face":{"a":"Grimacing Face","b":"1F62C","j":["face","grimace","teeth"]},"face-exhaling":{"a":"Face Exhaling","b":"1F62E-200D-1F4A8","j":["exhale","face exhaling","gasp","groan","relief","whisper","whistle"]},"lying-face":{"a":"Lying Face","b":"1F925","j":["face","lie","pinocchio"]},"relieved-face":{"a":"Relieved Face","b":"1F60C","j":["face","relieved","relaxed","phew","massage","happiness"]},"pensive-face":{"a":"Pensive Face","b":"1F614","j":["dejected","face","pensive","sad","depressed","upset"]},"sleepy-face":{"a":"Sleepy Face","b":"1F62A","j":["face","sleep","tired","rest","nap"]},"drooling-face":{"a":"Drooling Face","b":"1F924","j":["drooling","face"]},"sleeping-face":{"a":"Sleeping Face","b":"1F634","j":["face","sleep","zzz","tired","sleepy","night"]},"face-with-medical-mask":{"a":"Face with Medical Mask","b":"1F637","j":["cold","doctor","face","mask","sick","ill","disease"]},"face-with-thermometer":{"a":"Face with Thermometer","b":"1F912","j":["face","ill","sick","thermometer","temperature","cold","fever"]},"face-with-headbandage":{"a":"Face with Head-Bandage","b":"1F915","j":["bandage","face","face with head-bandage","hurt","injury","face_with_head_bandage","injured","clumsy"]},"nauseated-face":{"a":"Nauseated Face","b":"1F922","j":["face","nauseated","vomit","gross","green","sick","throw up","ill"]},"face-vomiting":{"a":"Face Vomiting","b":"1F92E","j":["puke","sick","vomit","face"]},"sneezing-face":{"a":"Sneezing Face","b":"1F927","j":["face","gesundheit","sneeze","sick","allergy"]},"hot-face":{"a":"Hot Face","b":"1F975","j":["feverish","heat stroke","hot","red-faced","sweating","face","heat","red"]},"cold-face":{"a":"Cold Face","b":"1F976","j":["blue-faced","cold","freezing","frostbite","icicles","face","blue","frozen"]},"woozy-face":{"a":"Woozy Face","b":"1F974","j":["dizzy","intoxicated","tipsy","uneven eyes","wavy mouth","face","wavy"]},"face-with-crossedout-eyes":{"a":"Face with Crossed-out Eyes","b":"1F635","j":["crossed-out eyes","dead","face","face with crossed-out eyes","knocked out","dizzy_face","spent","unconscious","xox","dizzy"]},"face-with-spiral-eyes":{"a":"Face with Spiral Eyes","b":"1F635-200D-1F4AB","j":["dizzy","face with spiral eyes","hypnotized","spiral","trouble","whoa"]},"exploding-head":{"a":"Exploding Head","b":"1F92F","j":["mind blown","shocked","face","mind","blown"]},"cowboy-hat-face":{"a":"Cowboy Hat Face","b":"1F920","j":["cowboy","cowgirl","face","hat"]},"partying-face":{"a":"Partying Face","b":"1F973","j":["celebration","hat","horn","party","face","woohoo"]},"disguised-face":{"a":"Disguised Face","b":"1F978","j":["disguise","face","glasses","incognito","nose","pretent","brows","moustache"]},"smiling-face-with-sunglasses":{"a":"Smiling Face with Sunglasses","b":"1F60E","j":["bright","cool","face","sun","sunglasses","smile","summer","beach","sunglass"]},"nerd-face":{"a":"Nerd Face","b":"1F913","j":["face","geek","nerd","nerdy","dork"]},"face-with-monocle":{"a":"Face with Monocle","b":"1F9D0","j":["stuffy","wealthy","face"]},"confused-face":{"a":"Confused Face","b":"1F615","j":["confused","face","meh","indifference","huh","weird","hmmm",":/"]},"face-with-diagonal-mouth":{"a":"⊛ Face with Diagonal Mouth","b":"1FAE4","j":["disappointed","meh","skeptical","unsure"]},"worried-face":{"a":"Worried Face","b":"1F61F","j":["face","worried","concern","nervous",":("]},"slightly-frowning-face":{"a":"Slightly Frowning Face","b":"1F641","j":["face","frown","frowning","disappointed","sad","upset"]},"frowning-face":{"a":"Frowning Face","b":"2639","j":["face","frown","sad","upset"]},"face-with-open-mouth":{"a":"Face with Open Mouth","b":"1F62E","j":["face","mouth","open","sympathy","surprise","impressed","wow","whoa",":O"]},"hushed-face":{"a":"Hushed Face","b":"1F62F","j":["face","hushed","stunned","surprised","woo","shh"]},"astonished-face":{"a":"Astonished Face","b":"1F632","j":["astonished","face","shocked","totally","xox","surprised","poisoned"]},"flushed-face":{"a":"Flushed Face","b":"1F633","j":["dazed","face","flushed","blush","shy","flattered"]},"pleading-face":{"a":"Pleading Face","b":"1F97A","j":["begging","mercy","puppy eyes","face"]},"face-holding-back-tears":{"a":"⊛ Face Holding Back Tears","b":"1F979","j":["angry","cry","proud","resist","sad"]},"frowning-face-with-open-mouth":{"a":"Frowning Face with Open Mouth","b":"1F626","j":["face","frown","mouth","open","aw","what"]},"anguished-face":{"a":"Anguished Face","b":"1F627","j":["anguished","face","stunned","nervous"]},"fearful-face":{"a":"Fearful Face","b":"1F628","j":["face","fear","fearful","scared","terrified","nervous","oops","huh"]},"anxious-face-with-sweat":{"a":"Anxious Face with Sweat","b":"1F630","j":["blue","cold","face","rushed","sweat","nervous"]},"sad-but-relieved-face":{"a":"Sad but Relieved Face","b":"1F625","j":["disappointed","face","relieved","whew","phew","sweat","nervous"]},"crying-face":{"a":"Crying Face","b":"1F622","j":["cry","face","sad","tear","tears","depressed","upset",":'("]},"loudly-crying-face":{"a":"Loudly Crying Face","b":"1F62D","j":["cry","face","sad","sob","tear","tears","upset","depressed"]},"face-screaming-in-fear":{"a":"Face Screaming in Fear","b":"1F631","j":["face","fear","munch","scared","scream","omg"]},"confounded-face":{"a":"Confounded Face","b":"1F616","j":["confounded","face","confused","sick","unwell","oops",":S"]},"persevering-face":{"a":"Persevering Face","b":"1F623","j":["face","persevere","sick","no","upset","oops"]},"disappointed-face":{"a":"Disappointed Face","b":"1F61E","j":["disappointed","face","sad","upset","depressed",":("]},"downcast-face-with-sweat":{"a":"Downcast Face with Sweat","b":"1F613","j":["cold","face","sweat","hot","sad","tired","exercise"]},"weary-face":{"a":"Weary Face","b":"1F629","j":["face","tired","weary","sleepy","sad","frustrated","upset"]},"tired-face":{"a":"Tired Face","b":"1F62B","j":["face","tired","sick","whine","upset","frustrated"]},"yawning-face":{"a":"Yawning Face","b":"1F971","j":["bored","tired","yawn","sleepy"]},"face-with-steam-from-nose":{"a":"Face with Steam From Nose","b":"1F624","j":["face","triumph","won","gas","phew","proud","pride"]},"pouting-face":{"a":"Pouting Face","b":"1F621","j":["angry","face","mad","pouting","rage","red","hate","despise"]},"angry-face":{"a":"Angry Face","b":"1F620","j":["anger","angry","face","mad","annoyed","frustrated"]},"face-with-symbols-on-mouth":{"a":"Face with Symbols on Mouth","b":"1F92C","j":["swearing","cursing","face","cussing","profanity","expletive"]},"smiling-face-with-horns":{"a":"Smiling Face with Horns","b":"1F608","j":["face","fairy tale","fantasy","horns","smile","devil"]},"angry-face-with-horns":{"a":"Angry Face with Horns","b":"1F47F","j":["demon","devil","face","fantasy","imp","angry","horns"]},"skull":{"a":"Skull","b":"1F480","j":["death","face","fairy tale","monster","dead","skeleton","creepy"]},"skull-and-crossbones":{"a":"Skull and Crossbones","b":"2620","j":["crossbones","death","face","monster","skull","poison","danger","deadly","scary","pirate","evil"]},"pile-of-poo":{"a":"Pile of Poo","b":"1F4A9","j":["dung","face","monster","poo","poop","hankey","shitface","fail","turd","shit"]},"clown-face":{"a":"Clown Face","b":"1F921","j":["clown","face"]},"ogre":{"a":"Ogre","b":"1F479","j":["creature","face","fairy tale","fantasy","monster","troll","red","mask","halloween","scary","creepy","devil","demon","japanese"]},"goblin":{"a":"Goblin","b":"1F47A","j":["creature","face","fairy tale","fantasy","monster","red","evil","mask","scary","creepy","japanese"]},"ghost":{"a":"Ghost","b":"1F47B","j":["creature","face","fairy tale","fantasy","monster","halloween","spooky","scary"]},"alien":{"a":"Alien","b":"1F47D","j":["creature","extraterrestrial","face","fantasy","ufo","UFO","paul","weird","outer_space"]},"alien-monster":{"a":"Alien Monster","b":"1F47E","j":["alien","creature","extraterrestrial","face","monster","ufo","game","arcade","play"]},"robot":{"a":"Robot","b":"1F916","j":["face","monster","computer","machine","bot"]},"grinning-cat":{"a":"Grinning Cat","b":"1F63A","j":["cat","face","grinning","mouth","open","smile","animal","cats","happy"]},"grinning-cat-with-smiling-eyes":{"a":"Grinning Cat with Smiling Eyes","b":"1F638","j":["cat","eye","face","grin","smile","animal","cats"]},"cat-with-tears-of-joy":{"a":"Cat with Tears of Joy","b":"1F639","j":["cat","face","joy","tear","animal","cats","haha","happy","tears"]},"smiling-cat-with-hearteyes":{"a":"Smiling Cat with Heart-Eyes","b":"1F63B","j":["cat","eye","face","heart","love","smile","smiling cat with heart-eyes","smiling_cat_with_heart_eyes","animal","like","affection","cats","valentines"]},"cat-with-wry-smile":{"a":"Cat with Wry Smile","b":"1F63C","j":["cat","face","ironic","smile","wry","animal","cats","smirk"]},"kissing-cat":{"a":"Kissing Cat","b":"1F63D","j":["cat","eye","face","kiss","animal","cats"]},"weary-cat":{"a":"Weary Cat","b":"1F640","j":["cat","face","oh","surprised","weary","animal","cats","munch","scared","scream"]},"crying-cat":{"a":"Crying Cat","b":"1F63F","j":["cat","cry","face","sad","tear","animal","tears","weep","cats","upset"]},"pouting-cat":{"a":"Pouting Cat","b":"1F63E","j":["cat","face","pouting","animal","cats"]},"seenoevil-monkey":{"a":"See-No-Evil Monkey","b":"1F648","j":["evil","face","forbidden","monkey","see","see-no-evil monkey","see_no_evil_monkey","animal","nature","haha"]},"hearnoevil-monkey":{"a":"Hear-No-Evil Monkey","b":"1F649","j":["evil","face","forbidden","hear","hear-no-evil monkey","monkey","hear_no_evil_monkey","animal","nature"]},"speaknoevil-monkey":{"a":"Speak-No-Evil Monkey","b":"1F64A","j":["evil","face","forbidden","monkey","speak","speak-no-evil monkey","speak_no_evil_monkey","animal","nature","omg"]},"kiss-mark":{"a":"Kiss Mark","b":"1F48B","j":["kiss","lips","face","love","like","affection","valentines"]},"love-letter":{"a":"Love Letter","b":"1F48C","j":["heart","letter","love","mail","email","like","affection","envelope","valentines"]},"heart-with-arrow":{"a":"Heart with Arrow","b":"1F498","j":["arrow","cupid","love","like","heart","affection","valentines"]},"heart-with-ribbon":{"a":"Heart with Ribbon","b":"1F49D","j":["ribbon","valentine","love","valentines"]},"sparkling-heart":{"a":"Sparkling Heart","b":"1F496","j":["excited","sparkle","love","like","affection","valentines"]},"growing-heart":{"a":"Growing Heart","b":"1F497","j":["excited","growing","nervous","pulse","like","love","affection","valentines","pink"]},"beating-heart":{"a":"Beating Heart","b":"1F493","j":["beating","heartbeat","pulsating","love","like","affection","valentines","pink","heart"]},"revolving-hearts":{"a":"Revolving Hearts","b":"1F49E","j":["revolving","love","like","affection","valentines"]},"two-hearts":{"a":"Two Hearts","b":"1F495","j":["love","like","affection","valentines","heart"]},"heart-decoration":{"a":"Heart Decoration","b":"1F49F","j":["heart","purple-square","love","like"]},"heart-exclamation":{"a":"Heart Exclamation","b":"2763","j":["exclamation","mark","punctuation","decoration","love"]},"broken-heart":{"a":"Broken Heart","b":"1F494","j":["break","broken","sad","sorry","heart","heartbreak"]},"heart-on-fire":{"a":"Heart on Fire","b":"2764-FE0F-200D-1F525","j":["burn","heart","heart on fire","love","lust","sacred heart"]},"mending-heart":{"a":"Mending Heart","b":"2764-FE0F-200D-1FA79","j":["healthier","improving","mending","mending heart","recovering","recuperating","well"]},"red-heart":{"a":"Red Heart","b":"2764","j":["heart","love","like","valentines"]},"orange-heart":{"a":"Orange Heart","b":"1F9E1","j":["orange","love","like","affection","valentines"]},"yellow-heart":{"a":"Yellow Heart","b":"1F49B","j":["yellow","love","like","affection","valentines"]},"green-heart":{"a":"Green Heart","b":"1F49A","j":["green","love","like","affection","valentines"]},"blue-heart":{"a":"Blue Heart","b":"1F499","j":["blue","love","like","affection","valentines"]},"purple-heart":{"a":"Purple Heart","b":"1F49C","j":["purple","love","like","affection","valentines"]},"brown-heart":{"a":"Brown Heart","b":"1F90E","j":["brown","heart","coffee"]},"black-heart":{"a":"Black Heart","b":"1F5A4","j":["black","evil","wicked"]},"white-heart":{"a":"White Heart","b":"1F90D","j":["heart","white","pure"]},"hundred-points":{"a":"Hundred Points","b":"1F4AF","j":["100","full","hundred","score","perfect","numbers","century","exam","quiz","test","pass"]},"anger-symbol":{"a":"Anger Symbol","b":"1F4A2","j":["angry","comic","mad"]},"collision":{"a":"Collision","b":"1F4A5","j":["boom","comic","bomb","explode","explosion","blown"]},"dizzy":{"a":"Dizzy","b":"1F4AB","j":["comic","star","sparkle","shoot","magic"]},"sweat-droplets":{"a":"Sweat Droplets","b":"1F4A6","j":["comic","splashing","sweat","water","drip","oops"]},"dashing-away":{"a":"Dashing Away","b":"1F4A8","j":["comic","dash","running","wind","air","fast","shoo","fart","smoke","puff"]},"hole":{"a":"Hole","b":"1F573","j":["embarrassing"]},"bomb":{"a":"Bomb","b":"1F4A3","j":["comic","boom","explode","explosion","terrorism"]},"speech-balloon":{"a":"Speech Balloon","b":"1F4AC","j":["balloon","bubble","comic","dialog","speech","words","message","talk","chatting"]},"eye-in-speech-bubble":{"a":"Eye in Speech Bubble","b":"1F441-FE0F-200D-1F5E8-FE0F","j":["eye","speech bubble","witness","info"]},"left-speech-bubble":{"a":"Left Speech Bubble","b":"1F5E8","j":["dialog","speech","words","message","talk","chatting"]},"right-anger-bubble":{"a":"Right Anger Bubble","b":"1F5EF","j":["angry","balloon","bubble","mad","caption","speech","thinking"]},"thought-balloon":{"a":"Thought Balloon","b":"1F4AD","j":["balloon","bubble","comic","thought","cloud","speech","thinking","dream"]},"zzz":{"a":"Zzz","b":"1F4A4","j":["comic","sleep","sleepy","tired","dream"]},"waving-hand":{"a":"Waving Hand","b":"1F44B","j":["hand","wave","waving","hands","gesture","goodbye","solong","farewell","hello","hi","palm"]},"raised-back-of-hand":{"a":"Raised Back of Hand","b":"1F91A","j":["backhand","raised","fingers"]},"hand-with-fingers-splayed":{"a":"Hand with Fingers Splayed","b":"1F590","j":["finger","hand","splayed","fingers","palm"]},"raised-hand":{"a":"Raised Hand","b":"270B","j":["hand","high 5","high five","fingers","stop","highfive","palm","ban"]},"vulcan-salute":{"a":"Vulcan Salute","b":"1F596","j":["finger","hand","spock","vulcan","fingers","star trek"]},"rightwards-hand":{"a":"⊛ Rightwards Hand","b":"1FAF1","j":["hand","right","rightward"]},"leftwards-hand":{"a":"⊛ Leftwards Hand","b":"1FAF2","j":["hand","left","leftward"]},"palm-down-hand":{"a":"⊛ Palm Down Hand","b":"1FAF3","j":["dismiss","drop","shoo"]},"palm-up-hand":{"a":"⊛ Palm Up Hand","b":"1FAF4","j":["beckon","catch","come","offer"]},"ok-hand":{"a":"Ok Hand","b":"1F44C","j":["hand","OK","fingers","limbs","perfect","ok","okay"]},"pinched-fingers":{"a":"Pinched Fingers","b":"1F90C","j":["fingers","hand gesture","interrogation","pinched","sarcastic","size","tiny","small"]},"pinching-hand":{"a":"Pinching Hand","b":"1F90F","j":["small amount","tiny","small","size"]},"victory-hand":{"a":"Victory Hand","b":"270C","j":["hand","v","victory","fingers","ohyeah","peace","two"]},"crossed-fingers":{"a":"Crossed Fingers","b":"1F91E","j":["cross","finger","hand","luck","good","lucky"]},"hand-with-index-finger-and-thumb-crossed":{"a":"⊛ Hand with Index Finger and Thumb Crossed","b":"1FAF0","j":["expensive","heart","love","money","snap"]},"loveyou-gesture":{"a":"Love-You Gesture","b":"1F91F","j":["hand","ILY","love-you gesture","love_you_gesture","fingers","gesture"]},"sign-of-the-horns":{"a":"Sign of the Horns","b":"1F918","j":["finger","hand","horns","rock-on","fingers","evil_eye","sign_of_horns","rock_on"]},"call-me-hand":{"a":"Call Me Hand","b":"1F919","j":["call","hand","hands","gesture","shaka"]},"backhand-index-pointing-left":{"a":"Backhand Index Pointing Left","b":"1F448","j":["backhand","finger","hand","index","point","direction","fingers","left"]},"backhand-index-pointing-right":{"a":"Backhand Index Pointing Right","b":"1F449","j":["backhand","finger","hand","index","point","fingers","direction","right"]},"backhand-index-pointing-up":{"a":"Backhand Index Pointing Up","b":"1F446","j":["backhand","finger","hand","point","up","fingers","direction"]},"middle-finger":{"a":"Middle Finger","b":"1F595","j":["finger","hand","fingers","rude","middle","flipping"]},"backhand-index-pointing-down":{"a":"Backhand Index Pointing Down","b":"1F447","j":["backhand","down","finger","hand","point","fingers","direction"]},"index-pointing-up":{"a":"Index Pointing Up","b":"261D","j":["finger","hand","index","point","up","fingers","direction"]},"index-pointing-at-the-viewer":{"a":"⊛ Index Pointing at the Viewer","b":"1FAF5","j":["point","you"]},"thumbs-up":{"a":"Thumbs Up","b":"1F44D","j":["+1","hand","thumb","up","thumbsup","yes","awesome","good","agree","accept","cool","like"]},"thumbs-down":{"a":"Thumbs Down","b":"1F44E","j":["-1","down","hand","thumb","thumbsdown","no","dislike"]},"raised-fist":{"a":"Raised Fist","b":"270A","j":["clenched","fist","hand","punch","fingers","grasp"]},"oncoming-fist":{"a":"Oncoming Fist","b":"1F44A","j":["clenched","fist","hand","punch","angry","violence","hit","attack"]},"leftfacing-fist":{"a":"Left-Facing Fist","b":"1F91B","j":["fist","left-facing fist","leftwards","left_facing_fist","hand","fistbump"]},"rightfacing-fist":{"a":"Right-Facing Fist","b":"1F91C","j":["fist","right-facing fist","rightwards","right_facing_fist","hand","fistbump"]},"clapping-hands":{"a":"Clapping Hands","b":"1F44F","j":["clap","hand","hands","praise","applause","congrats","yay"]},"raising-hands":{"a":"Raising Hands","b":"1F64C","j":["celebration","gesture","hand","hooray","raised","yea","hands"]},"heart-hands":{"a":"⊛ Heart Hands","b":"1FAF6","j":["love"]},"open-hands":{"a":"Open Hands","b":"1F450","j":["hand","open","fingers","butterfly","hands"]},"palms-up-together":{"a":"Palms Up Together","b":"1F932","j":["prayer","cupped hands","hands","gesture","cupped"]},"handshake":{"a":"Handshake","b":"1F91D","j":["agreement","hand","meeting","shake"]},"folded-hands":{"a":"Folded Hands","b":"1F64F","j":["ask","hand","high 5","high five","please","pray","thanks","hope","wish","namaste","highfive"]},"writing-hand":{"a":"Writing Hand","b":"270D","j":["hand","write","lower_left_ballpoint_pen","stationery","compose"]},"nail-polish":{"a":"Nail Polish","b":"1F485","j":["care","cosmetics","manicure","nail","polish","beauty","finger","fashion"]},"selfie":{"a":"Selfie","b":"1F933","j":["camera","phone"]},"flexed-biceps":{"a":"Flexed Biceps","b":"1F4AA","j":["biceps","comic","flex","muscle","arm","hand","summer","strong"]},"mechanical-arm":{"a":"Mechanical Arm","b":"1F9BE","j":["accessibility","prosthetic"]},"mechanical-leg":{"a":"Mechanical Leg","b":"1F9BF","j":["accessibility","prosthetic"]},"leg":{"a":"Leg","b":"1F9B5","j":["kick","limb"]},"foot":{"a":"Foot","b":"1F9B6","j":["kick","stomp"]},"ear":{"a":"Ear","b":"1F442","j":["body","face","hear","sound","listen"]},"ear-with-hearing-aid":{"a":"Ear with Hearing Aid","b":"1F9BB","j":["accessibility","hard of hearing"]},"nose":{"a":"Nose","b":"1F443","j":["body","smell","sniff"]},"brain":{"a":"Brain","b":"1F9E0","j":["intelligent","smart"]},"anatomical-heart":{"a":"Anatomical Heart","b":"1FAC0","j":["anatomical","cardiology","heart","organ","pulse","health","heartbeat"]},"lungs":{"a":"Lungs","b":"1FAC1","j":["breath","exhalation","inhalation","organ","respiration","breathe"]},"tooth":{"a":"Tooth","b":"1F9B7","j":["dentist","teeth"]},"bone":{"a":"Bone","b":"1F9B4","j":["skeleton"]},"eyes":{"a":"Eyes","b":"1F440","j":["eye","face","look","watch","stalk","peek","see"]},"eye":{"a":"Eye","b":"1F441","j":["body","face","look","see","watch","stare"]},"tongue":{"a":"Tongue","b":"1F445","j":["body","mouth","playful"]},"mouth":{"a":"Mouth","b":"1F444","j":["lips","kiss"]},"biting-lip":{"a":"⊛ Biting Lip","b":"1FAE6","j":["anxious","fear","flirting","nervous","uncomfortable","worried"]},"baby":{"a":"Baby","b":"1F476","j":["young","child","boy","girl","toddler"]},"child":{"a":"Child","b":"1F9D2","j":["gender-neutral","unspecified gender","young"]},"boy":{"a":"Boy","b":"1F466","j":["young","man","male","guy","teenager"]},"girl":{"a":"Girl","b":"1F467","j":["Virgo","young","zodiac","female","woman","teenager"]},"person":{"a":"Person","b":"1F9D1","j":["adult","gender-neutral","unspecified gender"]},"person-blond-hair":{"a":"Person: Blond Hair","b":"1F471","j":["blond","blond-haired person","hair","person: blond hair","hairstyle"]},"man":{"a":"Man","b":"1F468","j":["adult","mustache","father","dad","guy","classy","sir","moustache"]},"person-beard":{"a":"Person: Beard","b":"1F9D4","j":["beard","person","person: beard","bewhiskered","man_beard"]},"man-beard":{"a":"Man: Beard","b":"1F9D4-200D-2642-FE0F","j":["beard","man","man: beard"]},"woman-beard":{"a":"Woman: Beard","b":"1F9D4-200D-2640-FE0F","j":["beard","woman","woman: beard"]},"man-red-hair":{"a":"Man: Red Hair","b":"1F468-200D-1F9B0","j":["adult","man","red hair","hairstyle"]},"man-curly-hair":{"a":"Man: Curly Hair","b":"1F468-200D-1F9B1","j":["adult","curly hair","man","hairstyle"]},"man-white-hair":{"a":"Man: White Hair","b":"1F468-200D-1F9B3","j":["adult","man","white hair","old","elder"]},"man-bald":{"a":"Man: Bald","b":"1F468-200D-1F9B2","j":["adult","bald","man","hairless"]},"woman":{"a":"Woman","b":"1F469","j":["adult","female","girls","lady"]},"woman-red-hair":{"a":"Woman: Red Hair","b":"1F469-200D-1F9B0","j":["adult","red hair","woman","hairstyle"]},"person-red-hair":{"a":"Person: Red Hair","b":"1F9D1-200D-1F9B0","j":["adult","gender-neutral","person","red hair","unspecified gender","hairstyle"]},"woman-curly-hair":{"a":"Woman: Curly Hair","b":"1F469-200D-1F9B1","j":["adult","curly hair","woman","hairstyle"]},"person-curly-hair":{"a":"Person: Curly Hair","b":"1F9D1-200D-1F9B1","j":["adult","curly hair","gender-neutral","person","unspecified gender","hairstyle"]},"woman-white-hair":{"a":"Woman: White Hair","b":"1F469-200D-1F9B3","j":["adult","white hair","woman","old","elder"]},"person-white-hair":{"a":"Person: White Hair","b":"1F9D1-200D-1F9B3","j":["adult","gender-neutral","person","unspecified gender","white hair","elder","old"]},"woman-bald":{"a":"Woman: Bald","b":"1F469-200D-1F9B2","j":["adult","bald","woman","hairless"]},"person-bald":{"a":"Person: Bald","b":"1F9D1-200D-1F9B2","j":["adult","bald","gender-neutral","person","unspecified gender","hairless"]},"woman-blond-hair":{"a":"Woman: Blond Hair","b":"1F471-200D-2640-FE0F","j":["blond-haired woman","blonde","hair","woman","woman: blond hair","female","girl","person"]},"man-blond-hair":{"a":"Man: Blond Hair","b":"1F471-200D-2642-FE0F","j":["blond","blond-haired man","hair","man","man: blond hair","male","boy","blonde","guy","person"]},"older-person":{"a":"Older Person","b":"1F9D3","j":["adult","gender-neutral","old","unspecified gender","human","elder","senior"]},"old-man":{"a":"Old Man","b":"1F474","j":["adult","man","old","human","male","men","elder","senior"]},"old-woman":{"a":"Old Woman","b":"1F475","j":["adult","old","woman","human","female","women","lady","elder","senior"]},"person-frowning":{"a":"Person Frowning","b":"1F64D","j":["frown","gesture","worried"]},"man-frowning":{"a":"Man Frowning","b":"1F64D-200D-2642-FE0F","j":["frowning","gesture","man","male","boy","sad","depressed","discouraged","unhappy"]},"woman-frowning":{"a":"Woman Frowning","b":"1F64D-200D-2640-FE0F","j":["frowning","gesture","woman","female","girl","sad","depressed","discouraged","unhappy"]},"person-pouting":{"a":"Person Pouting","b":"1F64E","j":["gesture","pouting","upset"]},"man-pouting":{"a":"Man Pouting","b":"1F64E-200D-2642-FE0F","j":["gesture","man","pouting","male","boy"]},"woman-pouting":{"a":"Woman Pouting","b":"1F64E-200D-2640-FE0F","j":["gesture","pouting","woman","female","girl"]},"person-gesturing-no":{"a":"Person Gesturing No","b":"1F645","j":["forbidden","gesture","hand","person gesturing NO","prohibited","decline"]},"man-gesturing-no":{"a":"Man Gesturing No","b":"1F645-200D-2642-FE0F","j":["forbidden","gesture","hand","man","man gesturing NO","prohibited","male","boy","nope"]},"woman-gesturing-no":{"a":"Woman Gesturing No","b":"1F645-200D-2640-FE0F","j":["forbidden","gesture","hand","prohibited","woman","woman gesturing NO","female","girl","nope"]},"person-gesturing-ok":{"a":"Person Gesturing Ok","b":"1F646","j":["gesture","hand","OK","person gesturing OK","agree"]},"man-gesturing-ok":{"a":"Man Gesturing Ok","b":"1F646-200D-2642-FE0F","j":["gesture","hand","man","man gesturing OK","OK","men","boy","male","blue","human"]},"woman-gesturing-ok":{"a":"Woman Gesturing Ok","b":"1F646-200D-2640-FE0F","j":["gesture","hand","OK","woman","woman gesturing OK","women","girl","female","pink","human"]},"person-tipping-hand":{"a":"Person Tipping Hand","b":"1F481","j":["hand","help","information","sassy","tipping"]},"man-tipping-hand":{"a":"Man Tipping Hand","b":"1F481-200D-2642-FE0F","j":["man","sassy","tipping hand","male","boy","human","information"]},"woman-tipping-hand":{"a":"Woman Tipping Hand","b":"1F481-200D-2640-FE0F","j":["sassy","tipping hand","woman","female","girl","human","information"]},"person-raising-hand":{"a":"Person Raising Hand","b":"1F64B","j":["gesture","hand","happy","raised","question"]},"man-raising-hand":{"a":"Man Raising Hand","b":"1F64B-200D-2642-FE0F","j":["gesture","man","raising hand","male","boy"]},"woman-raising-hand":{"a":"Woman Raising Hand","b":"1F64B-200D-2640-FE0F","j":["gesture","raising hand","woman","female","girl"]},"deaf-person":{"a":"Deaf Person","b":"1F9CF","j":["accessibility","deaf","ear","hear"]},"deaf-man":{"a":"Deaf Man","b":"1F9CF-200D-2642-FE0F","j":["deaf","man","accessibility"]},"deaf-woman":{"a":"Deaf Woman","b":"1F9CF-200D-2640-FE0F","j":["deaf","woman","accessibility"]},"person-bowing":{"a":"Person Bowing","b":"1F647","j":["apology","bow","gesture","sorry","respectiful"]},"man-bowing":{"a":"Man Bowing","b":"1F647-200D-2642-FE0F","j":["apology","bowing","favor","gesture","man","sorry","male","boy"]},"woman-bowing":{"a":"Woman Bowing","b":"1F647-200D-2640-FE0F","j":["apology","bowing","favor","gesture","sorry","woman","female","girl"]},"person-facepalming":{"a":"Person Facepalming","b":"1F926","j":["disbelief","exasperation","face","palm","disappointed"]},"man-facepalming":{"a":"Man Facepalming","b":"1F926-200D-2642-FE0F","j":["disbelief","exasperation","facepalm","man","male","boy"]},"woman-facepalming":{"a":"Woman Facepalming","b":"1F926-200D-2640-FE0F","j":["disbelief","exasperation","facepalm","woman","female","girl"]},"person-shrugging":{"a":"Person Shrugging","b":"1F937","j":["doubt","ignorance","indifference","shrug","regardless"]},"man-shrugging":{"a":"Man Shrugging","b":"1F937-200D-2642-FE0F","j":["doubt","ignorance","indifference","man","shrug","male","boy","confused","indifferent"]},"woman-shrugging":{"a":"Woman Shrugging","b":"1F937-200D-2640-FE0F","j":["doubt","ignorance","indifference","shrug","woman","female","girl","confused","indifferent"]},"health-worker":{"a":"Health Worker","b":"1F9D1-200D-2695-FE0F","j":["doctor","healthcare","nurse","therapist","hospital"]},"man-health-worker":{"a":"Man Health Worker","b":"1F468-200D-2695-FE0F","j":["doctor","healthcare","man","nurse","therapist","human"]},"woman-health-worker":{"a":"Woman Health Worker","b":"1F469-200D-2695-FE0F","j":["doctor","healthcare","nurse","therapist","woman","human"]},"student":{"a":"Student","b":"1F9D1-200D-1F393","j":["graduate","learn"]},"man-student":{"a":"Man Student","b":"1F468-200D-1F393","j":["graduate","man","student","human"]},"woman-student":{"a":"Woman Student","b":"1F469-200D-1F393","j":["graduate","student","woman","human"]},"teacher":{"a":"Teacher","b":"1F9D1-200D-1F3EB","j":["instructor","professor"]},"man-teacher":{"a":"Man Teacher","b":"1F468-200D-1F3EB","j":["instructor","man","professor","teacher","human"]},"woman-teacher":{"a":"Woman Teacher","b":"1F469-200D-1F3EB","j":["instructor","professor","teacher","woman","human"]},"judge":{"a":"Judge","b":"1F9D1-200D-2696-FE0F","j":["justice","scales","law"]},"man-judge":{"a":"Man Judge","b":"1F468-200D-2696-FE0F","j":["judge","justice","man","scales","court","human"]},"woman-judge":{"a":"Woman Judge","b":"1F469-200D-2696-FE0F","j":["judge","justice","scales","woman","court","human"]},"farmer":{"a":"Farmer","b":"1F9D1-200D-1F33E","j":["gardener","rancher","crops"]},"man-farmer":{"a":"Man Farmer","b":"1F468-200D-1F33E","j":["farmer","gardener","man","rancher","human"]},"woman-farmer":{"a":"Woman Farmer","b":"1F469-200D-1F33E","j":["farmer","gardener","rancher","woman","human"]},"cook":{"a":"Cook","b":"1F9D1-200D-1F373","j":["chef","food","kitchen","culinary"]},"man-cook":{"a":"Man Cook","b":"1F468-200D-1F373","j":["chef","cook","man","human"]},"woman-cook":{"a":"Woman Cook","b":"1F469-200D-1F373","j":["chef","cook","woman","human"]},"mechanic":{"a":"Mechanic","b":"1F9D1-200D-1F527","j":["electrician","plumber","tradesperson","worker","technician"]},"man-mechanic":{"a":"Man Mechanic","b":"1F468-200D-1F527","j":["electrician","man","mechanic","plumber","tradesperson","human","wrench"]},"woman-mechanic":{"a":"Woman Mechanic","b":"1F469-200D-1F527","j":["electrician","mechanic","plumber","tradesperson","woman","human","wrench"]},"factory-worker":{"a":"Factory Worker","b":"1F9D1-200D-1F3ED","j":["assembly","factory","industrial","worker","labor"]},"man-factory-worker":{"a":"Man Factory Worker","b":"1F468-200D-1F3ED","j":["assembly","factory","industrial","man","worker","human"]},"woman-factory-worker":{"a":"Woman Factory Worker","b":"1F469-200D-1F3ED","j":["assembly","factory","industrial","woman","worker","human"]},"office-worker":{"a":"Office Worker","b":"1F9D1-200D-1F4BC","j":["architect","business","manager","white-collar"]},"man-office-worker":{"a":"Man Office Worker","b":"1F468-200D-1F4BC","j":["architect","business","man","manager","white-collar","human"]},"woman-office-worker":{"a":"Woman Office Worker","b":"1F469-200D-1F4BC","j":["architect","business","manager","white-collar","woman","human"]},"scientist":{"a":"Scientist","b":"1F9D1-200D-1F52C","j":["biologist","chemist","engineer","physicist","chemistry"]},"man-scientist":{"a":"Man Scientist","b":"1F468-200D-1F52C","j":["biologist","chemist","engineer","man","physicist","scientist","human"]},"woman-scientist":{"a":"Woman Scientist","b":"1F469-200D-1F52C","j":["biologist","chemist","engineer","physicist","scientist","woman","human"]},"technologist":{"a":"Technologist","b":"1F9D1-200D-1F4BB","j":["coder","developer","inventor","software","computer"]},"man-technologist":{"a":"Man Technologist","b":"1F468-200D-1F4BB","j":["coder","developer","inventor","man","software","technologist","engineer","programmer","human","laptop","computer"]},"woman-technologist":{"a":"Woman Technologist","b":"1F469-200D-1F4BB","j":["coder","developer","inventor","software","technologist","woman","engineer","programmer","human","laptop","computer"]},"singer":{"a":"Singer","b":"1F9D1-200D-1F3A4","j":["actor","entertainer","rock","star","song","artist","performer"]},"man-singer":{"a":"Man Singer","b":"1F468-200D-1F3A4","j":["actor","entertainer","man","rock","singer","star","rockstar","human"]},"woman-singer":{"a":"Woman Singer","b":"1F469-200D-1F3A4","j":["actor","entertainer","rock","singer","star","woman","rockstar","human"]},"artist":{"a":"Artist","b":"1F9D1-200D-1F3A8","j":["palette","painting","draw","creativity"]},"man-artist":{"a":"Man Artist","b":"1F468-200D-1F3A8","j":["artist","man","palette","painter","human"]},"woman-artist":{"a":"Woman Artist","b":"1F469-200D-1F3A8","j":["artist","palette","woman","painter","human"]},"pilot":{"a":"Pilot","b":"1F9D1-200D-2708-FE0F","j":["plane","fly","airplane"]},"man-pilot":{"a":"Man Pilot","b":"1F468-200D-2708-FE0F","j":["man","pilot","plane","aviator","human"]},"woman-pilot":{"a":"Woman Pilot","b":"1F469-200D-2708-FE0F","j":["pilot","plane","woman","aviator","human"]},"astronaut":{"a":"Astronaut","b":"1F9D1-200D-1F680","j":["rocket","outerspace"]},"man-astronaut":{"a":"Man Astronaut","b":"1F468-200D-1F680","j":["astronaut","man","rocket","space","human"]},"woman-astronaut":{"a":"Woman Astronaut","b":"1F469-200D-1F680","j":["astronaut","rocket","woman","space","human"]},"firefighter":{"a":"Firefighter","b":"1F9D1-200D-1F692","j":["firetruck","fire"]},"man-firefighter":{"a":"Man Firefighter","b":"1F468-200D-1F692","j":["firefighter","firetruck","man","fireman","human"]},"woman-firefighter":{"a":"Woman Firefighter","b":"1F469-200D-1F692","j":["firefighter","firetruck","woman","fireman","human"]},"police-officer":{"a":"Police Officer","b":"1F46E","j":["cop","officer","police"]},"man-police-officer":{"a":"Man Police Officer","b":"1F46E-200D-2642-FE0F","j":["cop","man","officer","police","law","legal","enforcement","arrest","911"]},"woman-police-officer":{"a":"Woman Police Officer","b":"1F46E-200D-2640-FE0F","j":["cop","officer","police","woman","law","legal","enforcement","arrest","911","female"]},"detective":{"a":"Detective","b":"1F575","j":["sleuth","spy","human"]},"man-detective":{"a":"Man Detective","b":"1F575-FE0F-200D-2642-FE0F","j":["detective","man","sleuth","spy","crime"]},"woman-detective":{"a":"Woman Detective","b":"1F575-FE0F-200D-2640-FE0F","j":["detective","sleuth","spy","woman","human","female"]},"guard":{"a":"Guard","b":"1F482","j":["protect"]},"man-guard":{"a":"Man Guard","b":"1F482-200D-2642-FE0F","j":["guard","man","uk","gb","british","male","guy","royal"]},"woman-guard":{"a":"Woman Guard","b":"1F482-200D-2640-FE0F","j":["guard","woman","uk","gb","british","female","royal"]},"ninja":{"a":"Ninja","b":"1F977","j":["fighter","hidden","stealth","ninjutsu","skills","japanese"]},"construction-worker":{"a":"Construction Worker","b":"1F477","j":["construction","hat","worker","labor","build"]},"man-construction-worker":{"a":"Man Construction Worker","b":"1F477-200D-2642-FE0F","j":["construction","man","worker","male","human","wip","guy","build","labor"]},"woman-construction-worker":{"a":"Woman Construction Worker","b":"1F477-200D-2640-FE0F","j":["construction","woman","worker","female","human","wip","build","labor"]},"person-with-crown":{"a":"⊛ Person with Crown","b":"1FAC5","j":["monarch","noble","regal","royalty"]},"prince":{"a":"Prince","b":"1F934","j":["boy","man","male","crown","royal","king"]},"princess":{"a":"Princess","b":"1F478","j":["fairy tale","fantasy","girl","woman","female","blond","crown","royal","queen"]},"person-wearing-turban":{"a":"Person Wearing Turban","b":"1F473","j":["turban","headdress"]},"man-wearing-turban":{"a":"Man Wearing Turban","b":"1F473-200D-2642-FE0F","j":["man","turban","male","indian","hinduism","arabs"]},"woman-wearing-turban":{"a":"Woman Wearing Turban","b":"1F473-200D-2640-FE0F","j":["turban","woman","female","indian","hinduism","arabs"]},"person-with-skullcap":{"a":"Person with Skullcap","b":"1F472","j":["cap","gua pi mao","hat","person","skullcap","man_with_skullcap","male","boy","chinese"]},"woman-with-headscarf":{"a":"Woman with Headscarf","b":"1F9D5","j":["headscarf","hijab","mantilla","tichel","bandana","head kerchief","female"]},"person-in-tuxedo":{"a":"Person in Tuxedo","b":"1F935","j":["groom","person","tuxedo","man_in_tuxedo","couple","marriage","wedding"]},"man-in-tuxedo":{"a":"Man in Tuxedo","b":"1F935-200D-2642-FE0F","j":["man","tuxedo","formal","fashion"]},"woman-in-tuxedo":{"a":"Woman in Tuxedo","b":"1F935-200D-2640-FE0F","j":["tuxedo","woman","formal","fashion"]},"person-with-veil":{"a":"Person with Veil","b":"1F470","j":["bride","person","veil","wedding","bride_with_veil","couple","marriage","woman"]},"man-with-veil":{"a":"Man with Veil","b":"1F470-200D-2642-FE0F","j":["man","veil","wedding","marriage"]},"woman-with-veil":{"a":"Woman with Veil","b":"1F470-200D-2640-FE0F","j":["veil","woman","wedding","marriage"]},"pregnant-woman":{"a":"Pregnant Woman","b":"1F930","j":["pregnant","woman","baby"]},"pregnant-man":{"a":"⊛ Pregnant Man","b":"1FAC3","j":["belly","bloated","full","pregnant"]},"pregnant-person":{"a":"⊛ Pregnant Person","b":"1FAC4","j":["belly","bloated","full","pregnant"]},"breastfeeding":{"a":"Breast-Feeding","b":"1F931","j":["baby","breast","breast-feeding","nursing","breast_feeding"]},"woman-feeding-baby":{"a":"Woman Feeding Baby","b":"1F469-200D-1F37C","j":["baby","feeding","nursing","woman","birth","food"]},"man-feeding-baby":{"a":"Man Feeding Baby","b":"1F468-200D-1F37C","j":["baby","feeding","man","nursing","birth","food"]},"person-feeding-baby":{"a":"Person Feeding Baby","b":"1F9D1-200D-1F37C","j":["baby","feeding","nursing","person","birth","food"]},"baby-angel":{"a":"Baby Angel","b":"1F47C","j":["angel","baby","face","fairy tale","fantasy","heaven","wings","halo"]},"santa-claus":{"a":"Santa Claus","b":"1F385","j":["celebration","Christmas","claus","father","santa","festival","man","male","xmas","father christmas"]},"mrs-claus":{"a":"Mrs. Claus","b":"1F936","j":["celebration","Christmas","claus","mother","Mrs.","woman","female","xmas","mother christmas"]},"mx-claus":{"a":"Mx Claus","b":"1F9D1-200D-1F384","j":["Claus, christmas","christmas"]},"superhero":{"a":"Superhero","b":"1F9B8","j":["good","hero","heroine","superpower","marvel"]},"man-superhero":{"a":"Man Superhero","b":"1F9B8-200D-2642-FE0F","j":["good","hero","man","superpower","male","superpowers"]},"woman-superhero":{"a":"Woman Superhero","b":"1F9B8-200D-2640-FE0F","j":["good","hero","heroine","superpower","woman","female","superpowers"]},"supervillain":{"a":"Supervillain","b":"1F9B9","j":["criminal","evil","superpower","villain","marvel"]},"man-supervillain":{"a":"Man Supervillain","b":"1F9B9-200D-2642-FE0F","j":["criminal","evil","man","superpower","villain","male","bad","hero","superpowers"]},"woman-supervillain":{"a":"Woman Supervillain","b":"1F9B9-200D-2640-FE0F","j":["criminal","evil","superpower","villain","woman","female","bad","heroine","superpowers"]},"mage":{"a":"Mage","b":"1F9D9","j":["sorcerer","sorceress","witch","wizard","magic"]},"man-mage":{"a":"Man Mage","b":"1F9D9-200D-2642-FE0F","j":["sorcerer","wizard","man","male","mage"]},"woman-mage":{"a":"Woman Mage","b":"1F9D9-200D-2640-FE0F","j":["sorceress","witch","woman","female","mage"]},"fairy":{"a":"Fairy","b":"1F9DA","j":["Oberon","Puck","Titania","wings","magical"]},"man-fairy":{"a":"Man Fairy","b":"1F9DA-200D-2642-FE0F","j":["Oberon","Puck","man","male"]},"woman-fairy":{"a":"Woman Fairy","b":"1F9DA-200D-2640-FE0F","j":["Titania","woman","female"]},"vampire":{"a":"Vampire","b":"1F9DB","j":["Dracula","undead","blood","twilight"]},"man-vampire":{"a":"Man Vampire","b":"1F9DB-200D-2642-FE0F","j":["Dracula","undead","man","male","dracula"]},"woman-vampire":{"a":"Woman Vampire","b":"1F9DB-200D-2640-FE0F","j":["undead","woman","female"]},"merperson":{"a":"Merperson","b":"1F9DC","j":["mermaid","merman","merwoman","sea"]},"merman":{"a":"Merman","b":"1F9DC-200D-2642-FE0F","j":["Triton","man","male","triton"]},"mermaid":{"a":"Mermaid","b":"1F9DC-200D-2640-FE0F","j":["merwoman","woman","female","ariel"]},"elf":{"a":"Elf","b":"1F9DD","j":["magical","LOTR style"]},"man-elf":{"a":"Man Elf","b":"1F9DD-200D-2642-FE0F","j":["magical","man","male"]},"woman-elf":{"a":"Woman Elf","b":"1F9DD-200D-2640-FE0F","j":["magical","woman","female"]},"genie":{"a":"Genie","b":"1F9DE","j":["djinn","(non-human color)","magical","wishes"]},"man-genie":{"a":"Man Genie","b":"1F9DE-200D-2642-FE0F","j":["djinn","man","male"]},"woman-genie":{"a":"Woman Genie","b":"1F9DE-200D-2640-FE0F","j":["djinn","woman","female"]},"zombie":{"a":"Zombie","b":"1F9DF","j":["undead","walking dead","(non-human color)","dead"]},"man-zombie":{"a":"Man Zombie","b":"1F9DF-200D-2642-FE0F","j":["undead","walking dead","man","male","dracula"]},"woman-zombie":{"a":"Woman Zombie","b":"1F9DF-200D-2640-FE0F","j":["undead","walking dead","woman","female"]},"troll":{"a":"⊛ Troll","b":"1F9CC","j":["fairy tale","fantasy","monster"]},"person-getting-massage":{"a":"Person Getting Massage","b":"1F486","j":["face","massage","salon","relax"]},"man-getting-massage":{"a":"Man Getting Massage","b":"1F486-200D-2642-FE0F","j":["face","man","massage","male","boy","head"]},"woman-getting-massage":{"a":"Woman Getting Massage","b":"1F486-200D-2640-FE0F","j":["face","massage","woman","female","girl","head"]},"person-getting-haircut":{"a":"Person Getting Haircut","b":"1F487","j":["barber","beauty","haircut","parlor","hairstyle"]},"man-getting-haircut":{"a":"Man Getting Haircut","b":"1F487-200D-2642-FE0F","j":["haircut","man","male","boy"]},"woman-getting-haircut":{"a":"Woman Getting Haircut","b":"1F487-200D-2640-FE0F","j":["haircut","woman","female","girl"]},"person-walking":{"a":"Person Walking","b":"1F6B6","j":["hike","walk","walking","move"]},"man-walking":{"a":"Man Walking","b":"1F6B6-200D-2642-FE0F","j":["hike","man","walk","human","feet","steps"]},"woman-walking":{"a":"Woman Walking","b":"1F6B6-200D-2640-FE0F","j":["hike","walk","woman","human","feet","steps","female"]},"person-standing":{"a":"Person Standing","b":"1F9CD","j":["stand","standing","still"]},"man-standing":{"a":"Man Standing","b":"1F9CD-200D-2642-FE0F","j":["man","standing","still"]},"woman-standing":{"a":"Woman Standing","b":"1F9CD-200D-2640-FE0F","j":["standing","woman","still"]},"person-kneeling":{"a":"Person Kneeling","b":"1F9CE","j":["kneel","kneeling","pray","respectful"]},"man-kneeling":{"a":"Man Kneeling","b":"1F9CE-200D-2642-FE0F","j":["kneeling","man","pray","respectful"]},"woman-kneeling":{"a":"Woman Kneeling","b":"1F9CE-200D-2640-FE0F","j":["kneeling","woman","respectful","pray"]},"person-with-white-cane":{"a":"Person with White Cane","b":"1F9D1-200D-1F9AF","j":["accessibility","blind","person_with_probing_cane"]},"man-with-white-cane":{"a":"Man with White Cane","b":"1F468-200D-1F9AF","j":["accessibility","blind","man","man_with_probing_cane"]},"woman-with-white-cane":{"a":"Woman with White Cane","b":"1F469-200D-1F9AF","j":["accessibility","blind","woman","woman_with_probing_cane"]},"person-in-motorized-wheelchair":{"a":"Person in Motorized Wheelchair","b":"1F9D1-200D-1F9BC","j":["accessibility","wheelchair","disability"]},"man-in-motorized-wheelchair":{"a":"Man in Motorized Wheelchair","b":"1F468-200D-1F9BC","j":["accessibility","man","wheelchair","disability"]},"woman-in-motorized-wheelchair":{"a":"Woman in Motorized Wheelchair","b":"1F469-200D-1F9BC","j":["accessibility","wheelchair","woman","disability"]},"person-in-manual-wheelchair":{"a":"Person in Manual Wheelchair","b":"1F9D1-200D-1F9BD","j":["accessibility","wheelchair","disability"]},"man-in-manual-wheelchair":{"a":"Man in Manual Wheelchair","b":"1F468-200D-1F9BD","j":["accessibility","man","wheelchair","disability"]},"woman-in-manual-wheelchair":{"a":"Woman in Manual Wheelchair","b":"1F469-200D-1F9BD","j":["accessibility","wheelchair","woman","disability"]},"person-running":{"a":"Person Running","b":"1F3C3","j":["marathon","running","move"]},"man-running":{"a":"Man Running","b":"1F3C3-200D-2642-FE0F","j":["man","marathon","racing","running","walking","exercise","race"]},"woman-running":{"a":"Woman Running","b":"1F3C3-200D-2640-FE0F","j":["marathon","racing","running","woman","walking","exercise","race","female"]},"woman-dancing":{"a":"Woman Dancing","b":"1F483","j":["dance","dancing","woman","female","girl","fun"]},"man-dancing":{"a":"Man Dancing","b":"1F57A","j":["dance","dancing","man","male","boy","fun","dancer"]},"person-in-suit-levitating":{"a":"Person in Suit Levitating","b":"1F574","j":["business","person","suit","man_in_suit_levitating","levitate","hover","jump"]},"people-with-bunny-ears":{"a":"People with Bunny Ears","b":"1F46F","j":["bunny ear","dancer","partying","perform","costume"]},"men-with-bunny-ears":{"a":"Men with Bunny Ears","b":"1F46F-200D-2642-FE0F","j":["bunny ear","dancer","men","partying","male","bunny","boys"]},"women-with-bunny-ears":{"a":"Women with Bunny Ears","b":"1F46F-200D-2640-FE0F","j":["bunny ear","dancer","partying","women","female","bunny","girls"]},"person-in-steamy-room":{"a":"Person in Steamy Room","b":"1F9D6","j":["sauna","steam room","hamam","steambath","relax","spa"]},"man-in-steamy-room":{"a":"Man in Steamy Room","b":"1F9D6-200D-2642-FE0F","j":["sauna","steam room","male","man","spa","steamroom"]},"woman-in-steamy-room":{"a":"Woman in Steamy Room","b":"1F9D6-200D-2640-FE0F","j":["sauna","steam room","female","woman","spa","steamroom"]},"person-climbing":{"a":"Person Climbing","b":"1F9D7","j":["climber","sport"]},"man-climbing":{"a":"Man Climbing","b":"1F9D7-200D-2642-FE0F","j":["climber","sports","hobby","man","male","rock"]},"woman-climbing":{"a":"Woman Climbing","b":"1F9D7-200D-2640-FE0F","j":["climber","sports","hobby","woman","female","rock"]},"person-fencing":{"a":"Person Fencing","b":"1F93A","j":["fencer","fencing","sword","sports"]},"horse-racing":{"a":"Horse Racing","b":"1F3C7","j":["horse","jockey","racehorse","racing","animal","betting","competition","gambling","luck"]},"skier":{"a":"Skier","b":"26F7","j":["ski","snow","sports","winter"]},"snowboarder":{"a":"Snowboarder","b":"1F3C2","j":["ski","snow","snowboard","sports","winter"]},"person-golfing":{"a":"Person Golfing","b":"1F3CC","j":["ball","golf","sports","business"]},"man-golfing":{"a":"Man Golfing","b":"1F3CC-FE0F-200D-2642-FE0F","j":["golf","man","sport"]},"woman-golfing":{"a":"Woman Golfing","b":"1F3CC-FE0F-200D-2640-FE0F","j":["golf","woman","sports","business","female"]},"person-surfing":{"a":"Person Surfing","b":"1F3C4","j":["surfing","sport","sea"]},"man-surfing":{"a":"Man Surfing","b":"1F3C4-200D-2642-FE0F","j":["man","surfing","sports","ocean","sea","summer","beach"]},"woman-surfing":{"a":"Woman Surfing","b":"1F3C4-200D-2640-FE0F","j":["surfing","woman","sports","ocean","sea","summer","beach","female"]},"person-rowing-boat":{"a":"Person Rowing Boat","b":"1F6A3","j":["boat","rowboat","sport","move"]},"man-rowing-boat":{"a":"Man Rowing Boat","b":"1F6A3-200D-2642-FE0F","j":["boat","man","rowboat","sports","hobby","water","ship"]},"woman-rowing-boat":{"a":"Woman Rowing Boat","b":"1F6A3-200D-2640-FE0F","j":["boat","rowboat","woman","sports","hobby","water","ship","female"]},"person-swimming":{"a":"Person Swimming","b":"1F3CA","j":["swim","sport","pool"]},"man-swimming":{"a":"Man Swimming","b":"1F3CA-200D-2642-FE0F","j":["man","swim","sports","exercise","human","athlete","water","summer"]},"woman-swimming":{"a":"Woman Swimming","b":"1F3CA-200D-2640-FE0F","j":["swim","woman","sports","exercise","human","athlete","water","summer","female"]},"person-bouncing-ball":{"a":"Person Bouncing Ball","b":"26F9","j":["ball","sports","human"]},"man-bouncing-ball":{"a":"Man Bouncing Ball","b":"26F9-FE0F-200D-2642-FE0F","j":["ball","man","sport"]},"woman-bouncing-ball":{"a":"Woman Bouncing Ball","b":"26F9-FE0F-200D-2640-FE0F","j":["ball","woman","sports","human","female"]},"person-lifting-weights":{"a":"Person Lifting Weights","b":"1F3CB","j":["lifter","weight","sports","training","exercise"]},"man-lifting-weights":{"a":"Man Lifting Weights","b":"1F3CB-FE0F-200D-2642-FE0F","j":["man","weight lifter","sport"]},"woman-lifting-weights":{"a":"Woman Lifting Weights","b":"1F3CB-FE0F-200D-2640-FE0F","j":["weight lifter","woman","sports","training","exercise","female"]},"person-biking":{"a":"Person Biking","b":"1F6B4","j":["bicycle","biking","cyclist","sport","move"]},"man-biking":{"a":"Man Biking","b":"1F6B4-200D-2642-FE0F","j":["bicycle","biking","cyclist","man","sports","bike","exercise","hipster"]},"woman-biking":{"a":"Woman Biking","b":"1F6B4-200D-2640-FE0F","j":["bicycle","biking","cyclist","woman","sports","bike","exercise","hipster","female"]},"person-mountain-biking":{"a":"Person Mountain Biking","b":"1F6B5","j":["bicycle","bicyclist","bike","cyclist","mountain","sport","move"]},"man-mountain-biking":{"a":"Man Mountain Biking","b":"1F6B5-200D-2642-FE0F","j":["bicycle","bike","cyclist","man","mountain","transportation","sports","human","race"]},"woman-mountain-biking":{"a":"Woman Mountain Biking","b":"1F6B5-200D-2640-FE0F","j":["bicycle","bike","biking","cyclist","mountain","woman","transportation","sports","human","race","female"]},"person-cartwheeling":{"a":"Person Cartwheeling","b":"1F938","j":["cartwheel","gymnastics","sport","gymnastic"]},"man-cartwheeling":{"a":"Man Cartwheeling","b":"1F938-200D-2642-FE0F","j":["cartwheel","gymnastics","man"]},"woman-cartwheeling":{"a":"Woman Cartwheeling","b":"1F938-200D-2640-FE0F","j":["cartwheel","gymnastics","woman"]},"people-wrestling":{"a":"People Wrestling","b":"1F93C","j":["wrestle","wrestler","sport"]},"men-wrestling":{"a":"Men Wrestling","b":"1F93C-200D-2642-FE0F","j":["men","wrestle","sports","wrestlers"]},"women-wrestling":{"a":"Women Wrestling","b":"1F93C-200D-2640-FE0F","j":["women","wrestle","sports","wrestlers"]},"person-playing-water-polo":{"a":"Person Playing Water Polo","b":"1F93D","j":["polo","water","sport"]},"man-playing-water-polo":{"a":"Man Playing Water Polo","b":"1F93D-200D-2642-FE0F","j":["man","water polo","sports","pool"]},"woman-playing-water-polo":{"a":"Woman Playing Water Polo","b":"1F93D-200D-2640-FE0F","j":["water polo","woman","sports","pool"]},"person-playing-handball":{"a":"Person Playing Handball","b":"1F93E","j":["ball","handball","sport"]},"man-playing-handball":{"a":"Man Playing Handball","b":"1F93E-200D-2642-FE0F","j":["handball","man","sports"]},"woman-playing-handball":{"a":"Woman Playing Handball","b":"1F93E-200D-2640-FE0F","j":["handball","woman","sports"]},"person-juggling":{"a":"Person Juggling","b":"1F939","j":["balance","juggle","multitask","skill","performance"]},"man-juggling":{"a":"Man Juggling","b":"1F939-200D-2642-FE0F","j":["juggling","man","multitask","juggle","balance","skill"]},"woman-juggling":{"a":"Woman Juggling","b":"1F939-200D-2640-FE0F","j":["juggling","multitask","woman","juggle","balance","skill"]},"person-in-lotus-position":{"a":"Person in Lotus Position","b":"1F9D8","j":["meditation","yoga","serenity","meditate"]},"man-in-lotus-position":{"a":"Man in Lotus Position","b":"1F9D8-200D-2642-FE0F","j":["meditation","yoga","man","male","serenity","zen","mindfulness"]},"woman-in-lotus-position":{"a":"Woman in Lotus Position","b":"1F9D8-200D-2640-FE0F","j":["meditation","yoga","woman","female","serenity","zen","mindfulness"]},"person-taking-bath":{"a":"Person Taking Bath","b":"1F6C0","j":["bath","bathtub","clean","shower","bathroom"]},"person-in-bed":{"a":"Person in Bed","b":"1F6CC","j":["hotel","sleep","bed","rest"]},"people-holding-hands":{"a":"People Holding Hands","b":"1F9D1-200D-1F91D-200D-1F9D1","j":["couple","hand","hold","holding hands","person","friendship"]},"women-holding-hands":{"a":"Women Holding Hands","b":"1F46D","j":["couple","hand","holding hands","women","pair","friendship","love","like","female","people","human"]},"woman-and-man-holding-hands":{"a":"Woman and Man Holding Hands","b":"1F46B","j":["couple","hand","hold","holding hands","man","woman","pair","people","human","love","date","dating","like","affection","valentines","marriage"]},"men-holding-hands":{"a":"Men Holding Hands","b":"1F46C","j":["couple","Gemini","holding hands","man","men","twins","zodiac","pair","love","like","bromance","friendship","people","human"]},"kiss":{"a":"Kiss","b":"1F48F","j":["couple","pair","valentines","love","like","dating","marriage"]},"kiss-woman-man":{"a":"Kiss: Woman, Man","b":"1F469-200D-2764-FE0F-200D-1F48B-200D-1F468","j":["couple","kiss","man","woman","love"]},"kiss-man-man":{"a":"Kiss: Man, Man","b":"1F468-200D-2764-FE0F-200D-1F48B-200D-1F468","j":["couple","kiss","man","pair","valentines","love","like","dating","marriage"]},"kiss-woman-woman":{"a":"Kiss: Woman, Woman","b":"1F469-200D-2764-FE0F-200D-1F48B-200D-1F469","j":["couple","kiss","woman","pair","valentines","love","like","dating","marriage"]},"couple-with-heart":{"a":"Couple with Heart","b":"1F491","j":["couple","love","pair","like","affection","human","dating","valentines","marriage"]},"couple-with-heart-woman-man":{"a":"Couple with Heart: Woman, Man","b":"1F469-200D-2764-FE0F-200D-1F468","j":["couple","couple with heart","love","man","woman"]},"couple-with-heart-man-man":{"a":"Couple with Heart: Man, Man","b":"1F468-200D-2764-FE0F-200D-1F468","j":["couple","couple with heart","love","man","pair","like","affection","human","dating","valentines","marriage"]},"couple-with-heart-woman-woman":{"a":"Couple with Heart: Woman, Woman","b":"1F469-200D-2764-FE0F-200D-1F469","j":["couple","couple with heart","love","woman","pair","like","affection","human","dating","valentines","marriage"]},"family":{"a":"Family","b":"1F46A","j":["home","parents","child","mom","dad","father","mother","people","human"]},"family-man-woman-boy":{"a":"Family: Man, Woman, Boy","b":"1F468-200D-1F469-200D-1F466","j":["boy","family","man","woman","love"]},"family-man-woman-girl":{"a":"Family: Man, Woman, Girl","b":"1F468-200D-1F469-200D-1F467","j":["family","girl","man","woman","home","parents","people","human","child"]},"family-man-woman-girl-boy":{"a":"Family: Man, Woman, Girl, Boy","b":"1F468-200D-1F469-200D-1F467-200D-1F466","j":["boy","family","girl","man","woman","home","parents","people","human","children"]},"family-man-woman-boy-boy":{"a":"Family: Man, Woman, Boy, Boy","b":"1F468-200D-1F469-200D-1F466-200D-1F466","j":["boy","family","man","woman","home","parents","people","human","children"]},"family-man-woman-girl-girl":{"a":"Family: Man, Woman, Girl, Girl","b":"1F468-200D-1F469-200D-1F467-200D-1F467","j":["family","girl","man","woman","home","parents","people","human","children"]},"family-man-man-boy":{"a":"Family: Man, Man, Boy","b":"1F468-200D-1F468-200D-1F466","j":["boy","family","man","home","parents","people","human","children"]},"family-man-man-girl":{"a":"Family: Man, Man, Girl","b":"1F468-200D-1F468-200D-1F467","j":["family","girl","man","home","parents","people","human","children"]},"family-man-man-girl-boy":{"a":"Family: Man, Man, Girl, Boy","b":"1F468-200D-1F468-200D-1F467-200D-1F466","j":["boy","family","girl","man","home","parents","people","human","children"]},"family-man-man-boy-boy":{"a":"Family: Man, Man, Boy, Boy","b":"1F468-200D-1F468-200D-1F466-200D-1F466","j":["boy","family","man","home","parents","people","human","children"]},"family-man-man-girl-girl":{"a":"Family: Man, Man, Girl, Girl","b":"1F468-200D-1F468-200D-1F467-200D-1F467","j":["family","girl","man","home","parents","people","human","children"]},"family-woman-woman-boy":{"a":"Family: Woman, Woman, Boy","b":"1F469-200D-1F469-200D-1F466","j":["boy","family","woman","home","parents","people","human","children"]},"family-woman-woman-girl":{"a":"Family: Woman, Woman, Girl","b":"1F469-200D-1F469-200D-1F467","j":["family","girl","woman","home","parents","people","human","children"]},"family-woman-woman-girl-boy":{"a":"Family: Woman, Woman, Girl, Boy","b":"1F469-200D-1F469-200D-1F467-200D-1F466","j":["boy","family","girl","woman","home","parents","people","human","children"]},"family-woman-woman-boy-boy":{"a":"Family: Woman, Woman, Boy, Boy","b":"1F469-200D-1F469-200D-1F466-200D-1F466","j":["boy","family","woman","home","parents","people","human","children"]},"family-woman-woman-girl-girl":{"a":"Family: Woman, Woman, Girl, Girl","b":"1F469-200D-1F469-200D-1F467-200D-1F467","j":["family","girl","woman","home","parents","people","human","children"]},"family-man-boy":{"a":"Family: Man, Boy","b":"1F468-200D-1F466","j":["boy","family","man","home","parent","people","human","child"]},"family-man-boy-boy":{"a":"Family: Man, Boy, Boy","b":"1F468-200D-1F466-200D-1F466","j":["boy","family","man","home","parent","people","human","children"]},"family-man-girl":{"a":"Family: Man, Girl","b":"1F468-200D-1F467","j":["family","girl","man","home","parent","people","human","child"]},"family-man-girl-boy":{"a":"Family: Man, Girl, Boy","b":"1F468-200D-1F467-200D-1F466","j":["boy","family","girl","man","home","parent","people","human","children"]},"family-man-girl-girl":{"a":"Family: Man, Girl, Girl","b":"1F468-200D-1F467-200D-1F467","j":["family","girl","man","home","parent","people","human","children"]},"family-woman-boy":{"a":"Family: Woman, Boy","b":"1F469-200D-1F466","j":["boy","family","woman","home","parent","people","human","child"]},"family-woman-boy-boy":{"a":"Family: Woman, Boy, Boy","b":"1F469-200D-1F466-200D-1F466","j":["boy","family","woman","home","parent","people","human","children"]},"family-woman-girl":{"a":"Family: Woman, Girl","b":"1F469-200D-1F467","j":["family","girl","woman","home","parent","people","human","child"]},"family-woman-girl-boy":{"a":"Family: Woman, Girl, Boy","b":"1F469-200D-1F467-200D-1F466","j":["boy","family","girl","woman","home","parent","people","human","children"]},"family-woman-girl-girl":{"a":"Family: Woman, Girl, Girl","b":"1F469-200D-1F467-200D-1F467","j":["family","girl","woman","home","parent","people","human","children"]},"speaking-head":{"a":"Speaking Head","b":"1F5E3","j":["face","head","silhouette","speak","speaking","user","person","human","sing","say","talk"]},"bust-in-silhouette":{"a":"Bust in Silhouette","b":"1F464","j":["bust","silhouette","user","person","human"]},"busts-in-silhouette":{"a":"Busts in Silhouette","b":"1F465","j":["bust","silhouette","user","person","human","group","team"]},"people-hugging":{"a":"People Hugging","b":"1FAC2","j":["goodbye","hello","hug","thanks","care"]},"footprints":{"a":"Footprints","b":"1F463","j":["clothing","footprint","print","feet","tracking","walking","beach"]},"red-hair":{"a":"Red Hair","b":"1F9B0","j":["ginger","red hair","redhead"]},"curly-hair":{"a":"Curly Hair","b":"1F9B1","j":["afro","curly","curly hair","ringlets"]},"white-hair":{"a":"White Hair","b":"1F9B3","j":["gray","hair","old","white"]},"bald":{"a":"Bald","b":"1F9B2","j":["bald","chemotherapy","hairless","no hair","shaven"]},"monkey-face":{"a":"Monkey Face","b":"1F435","j":["face","monkey","animal","nature","circus"]},"monkey":{"a":"Monkey","b":"1F412","j":["animal","nature","banana","circus"]},"gorilla":{"a":"Gorilla","b":"1F98D","j":["animal","nature","circus"]},"orangutan":{"a":"Orangutan","b":"1F9A7","j":["ape","animal"]},"dog-face":{"a":"Dog Face","b":"1F436","j":["dog","face","pet","animal","friend","nature","woof","puppy","faithful"]},"dog":{"a":"Dog","b":"1F415","j":["pet","animal","nature","friend","doge","faithful"]},"guide-dog":{"a":"Guide Dog","b":"1F9AE","j":["accessibility","blind","guide","animal"]},"service-dog":{"a":"Service Dog","b":"1F415-200D-1F9BA","j":["accessibility","assistance","dog","service","blind","animal"]},"poodle":{"a":"Poodle","b":"1F429","j":["dog","animal","101","nature","pet"]},"wolf":{"a":"Wolf","b":"1F43A","j":["face","animal","nature","wild"]},"fox":{"a":"Fox","b":"1F98A","j":["face","animal","nature"]},"raccoon":{"a":"Raccoon","b":"1F99D","j":["curious","sly","animal","nature"]},"cat-face":{"a":"Cat Face","b":"1F431","j":["cat","face","pet","animal","meow","nature","kitten"]},"cat":{"a":"Cat","b":"1F408","j":["pet","animal","meow","cats"]},"black-cat":{"a":"Black Cat","b":"1F408-200D-2B1B","j":["black","cat","unlucky","superstition","luck"]},"lion":{"a":"Lion","b":"1F981","j":["face","Leo","zodiac","animal","nature"]},"tiger-face":{"a":"Tiger Face","b":"1F42F","j":["face","tiger","animal","cat","danger","wild","nature","roar"]},"tiger":{"a":"Tiger","b":"1F405","j":["animal","nature","roar"]},"leopard":{"a":"Leopard","b":"1F406","j":["animal","nature"]},"horse-face":{"a":"Horse Face","b":"1F434","j":["face","horse","animal","brown","nature"]},"horse":{"a":"Horse","b":"1F40E","j":["equestrian","racehorse","racing","animal","gamble","luck"]},"unicorn":{"a":"Unicorn","b":"1F984","j":["face","animal","nature","mystical"]},"zebra":{"a":"Zebra","b":"1F993","j":["stripe","animal","nature","stripes","safari"]},"deer":{"a":"Deer","b":"1F98C","j":["animal","nature","horns","venison"]},"bison":{"a":"Bison","b":"1F9AC","j":["buffalo","herd","wisent","ox"]},"cow-face":{"a":"Cow Face","b":"1F42E","j":["cow","face","beef","ox","animal","nature","moo","milk"]},"ox":{"a":"Ox","b":"1F402","j":["bull","Taurus","zodiac","animal","cow","beef"]},"water-buffalo":{"a":"Water Buffalo","b":"1F403","j":["buffalo","water","animal","nature","ox","cow"]},"cow":{"a":"Cow","b":"1F404","j":["beef","ox","animal","nature","moo","milk"]},"pig-face":{"a":"Pig Face","b":"1F437","j":["face","pig","animal","oink","nature"]},"pig":{"a":"Pig","b":"1F416","j":["sow","animal","nature"]},"boar":{"a":"Boar","b":"1F417","j":["pig","animal","nature"]},"pig-nose":{"a":"Pig Nose","b":"1F43D","j":["face","nose","pig","animal","oink"]},"ram":{"a":"Ram","b":"1F40F","j":["Aries","male","sheep","zodiac","animal","nature"]},"ewe":{"a":"Ewe","b":"1F411","j":["female","sheep","animal","nature","wool","shipit"]},"goat":{"a":"Goat","b":"1F410","j":["Capricorn","zodiac","animal","nature"]},"camel":{"a":"Camel","b":"1F42A","j":["dromedary","hump","animal","hot","desert"]},"twohump-camel":{"a":"Two-Hump Camel","b":"1F42B","j":["bactrian","camel","hump","two-hump camel","two_hump_camel","animal","nature","hot","desert"]},"llama":{"a":"Llama","b":"1F999","j":["alpaca","guanaco","vicuña","wool","animal","nature"]},"giraffe":{"a":"Giraffe","b":"1F992","j":["spots","animal","nature","safari"]},"elephant":{"a":"Elephant","b":"1F418","j":["animal","nature","nose","th","circus"]},"mammoth":{"a":"Mammoth","b":"1F9A3","j":["extinction","large","tusk","woolly","elephant","tusks"]},"rhinoceros":{"a":"Rhinoceros","b":"1F98F","j":["animal","nature","horn"]},"hippopotamus":{"a":"Hippopotamus","b":"1F99B","j":["hippo","animal","nature"]},"mouse-face":{"a":"Mouse Face","b":"1F42D","j":["face","mouse","animal","nature","cheese_wedge","rodent"]},"mouse":{"a":"Mouse","b":"1F401","j":["animal","nature","rodent"]},"rat":{"a":"Rat","b":"1F400","j":["animal","mouse","rodent"]},"hamster":{"a":"Hamster","b":"1F439","j":["face","pet","animal","nature"]},"rabbit-face":{"a":"Rabbit Face","b":"1F430","j":["bunny","face","pet","rabbit","animal","nature","spring","magic"]},"rabbit":{"a":"Rabbit","b":"1F407","j":["bunny","pet","animal","nature","magic","spring"]},"chipmunk":{"a":"Chipmunk","b":"1F43F","j":["squirrel","animal","nature","rodent"]},"beaver":{"a":"Beaver","b":"1F9AB","j":["dam","animal","rodent"]},"hedgehog":{"a":"Hedgehog","b":"1F994","j":["spiny","animal","nature"]},"bat":{"a":"Bat","b":"1F987","j":["vampire","animal","nature","blind"]},"bear":{"a":"Bear","b":"1F43B","j":["face","animal","nature","wild"]},"polar-bear":{"a":"Polar Bear","b":"1F43B-200D-2744-FE0F","j":["arctic","bear","white","animal"]},"koala":{"a":"Koala","b":"1F428","j":["face","marsupial","animal","nature"]},"panda":{"a":"Panda","b":"1F43C","j":["face","animal","nature"]},"sloth":{"a":"Sloth","b":"1F9A5","j":["lazy","slow","animal"]},"otter":{"a":"Otter","b":"1F9A6","j":["fishing","playful","animal"]},"skunk":{"a":"Skunk","b":"1F9A8","j":["stink","animal"]},"kangaroo":{"a":"Kangaroo","b":"1F998","j":["Australia","joey","jump","marsupial","animal","nature","australia","hop"]},"badger":{"a":"Badger","b":"1F9A1","j":["honey badger","pester","animal","nature","honey"]},"paw-prints":{"a":"Paw Prints","b":"1F43E","j":["feet","paw","print","animal","tracking","footprints","dog","cat","pet"]},"turkey":{"a":"Turkey","b":"1F983","j":["bird","animal"]},"chicken":{"a":"Chicken","b":"1F414","j":["bird","animal","cluck","nature"]},"rooster":{"a":"Rooster","b":"1F413","j":["bird","animal","nature","chicken"]},"hatching-chick":{"a":"Hatching Chick","b":"1F423","j":["baby","bird","chick","hatching","animal","chicken","egg","born"]},"baby-chick":{"a":"Baby Chick","b":"1F424","j":["baby","bird","chick","animal","chicken"]},"frontfacing-baby-chick":{"a":"Front-Facing Baby Chick","b":"1F425","j":["baby","bird","chick","front-facing baby chick","front_facing_baby_chick","animal","chicken"]},"bird":{"a":"Bird","b":"1F426","j":["animal","nature","fly","tweet","spring"]},"penguin":{"a":"Penguin","b":"1F427","j":["bird","animal","nature"]},"dove":{"a":"Dove","b":"1F54A","j":["bird","fly","peace","animal"]},"eagle":{"a":"Eagle","b":"1F985","j":["bird","animal","nature"]},"duck":{"a":"Duck","b":"1F986","j":["bird","animal","nature","mallard"]},"swan":{"a":"Swan","b":"1F9A2","j":["bird","cygnet","ugly duckling","animal","nature"]},"owl":{"a":"Owl","b":"1F989","j":["bird","wise","animal","nature","hoot"]},"dodo":{"a":"Dodo","b":"1F9A4","j":["extinction","large","Mauritius","animal","bird"]},"feather":{"a":"Feather","b":"1FAB6","j":["bird","flight","light","plumage","fly"]},"flamingo":{"a":"Flamingo","b":"1F9A9","j":["flamboyant","tropical","animal"]},"peacock":{"a":"Peacock","b":"1F99A","j":["bird","ostentatious","peahen","proud","animal","nature"]},"parrot":{"a":"Parrot","b":"1F99C","j":["bird","pirate","talk","animal","nature"]},"frog":{"a":"Frog","b":"1F438","j":["face","animal","nature","croak","toad"]},"crocodile":{"a":"Crocodile","b":"1F40A","j":["animal","nature","reptile","lizard","alligator"]},"turtle":{"a":"Turtle","b":"1F422","j":["terrapin","tortoise","animal","slow","nature"]},"lizard":{"a":"Lizard","b":"1F98E","j":["reptile","animal","nature"]},"snake":{"a":"Snake","b":"1F40D","j":["bearer","Ophiuchus","serpent","zodiac","animal","evil","nature","hiss","python"]},"dragon-face":{"a":"Dragon Face","b":"1F432","j":["dragon","face","fairy tale","animal","myth","nature","chinese","green"]},"dragon":{"a":"Dragon","b":"1F409","j":["fairy tale","animal","myth","nature","chinese","green"]},"sauropod":{"a":"Sauropod","b":"1F995","j":["brachiosaurus","brontosaurus","diplodocus","animal","nature","dinosaur","extinct"]},"trex":{"a":"T-Rex","b":"1F996","j":["Tyrannosaurus Rex","t_rex","animal","nature","dinosaur","tyrannosaurus","extinct"]},"spouting-whale":{"a":"Spouting Whale","b":"1F433","j":["face","spouting","whale","animal","nature","sea","ocean"]},"whale":{"a":"Whale","b":"1F40B","j":["animal","nature","sea","ocean"]},"dolphin":{"a":"Dolphin","b":"1F42C","j":["flipper","animal","nature","fish","sea","ocean","fins","beach"]},"seal":{"a":"Seal","b":"1F9AD","j":["sea lion","animal","creature","sea"]},"fish":{"a":"Fish","b":"1F41F","j":["Pisces","zodiac","animal","food","nature"]},"tropical-fish":{"a":"Tropical Fish","b":"1F420","j":["fish","tropical","animal","swim","ocean","beach","nemo"]},"blowfish":{"a":"Blowfish","b":"1F421","j":["fish","animal","nature","food","sea","ocean"]},"shark":{"a":"Shark","b":"1F988","j":["fish","animal","nature","sea","ocean","jaws","fins","beach"]},"octopus":{"a":"Octopus","b":"1F419","j":["animal","creature","ocean","sea","nature","beach"]},"spiral-shell":{"a":"Spiral Shell","b":"1F41A","j":["shell","spiral","nature","sea","beach"]},"coral":{"a":"⊛ Coral","b":"1FAB8","j":["ocean","reef"]},"snail":{"a":"Snail","b":"1F40C","j":["slow","animal","shell"]},"butterfly":{"a":"Butterfly","b":"1F98B","j":["insect","pretty","animal","nature","caterpillar"]},"bug":{"a":"Bug","b":"1F41B","j":["insect","animal","nature","worm"]},"ant":{"a":"Ant","b":"1F41C","j":["insect","animal","nature","bug"]},"honeybee":{"a":"Honeybee","b":"1F41D","j":["bee","insect","animal","nature","bug","spring","honey"]},"beetle":{"a":"Beetle","b":"1FAB2","j":["bug","insect"]},"lady-beetle":{"a":"Lady Beetle","b":"1F41E","j":["beetle","insect","ladybird","ladybug","animal","nature"]},"cricket":{"a":"Cricket","b":"1F997","j":["grasshopper","Orthoptera","animal","chirp"]},"cockroach":{"a":"Cockroach","b":"1FAB3","j":["insect","pest","roach","pests"]},"spider":{"a":"Spider","b":"1F577","j":["insect","animal","arachnid"]},"spider-web":{"a":"Spider Web","b":"1F578","j":["spider","web","animal","insect","arachnid","silk"]},"scorpion":{"a":"Scorpion","b":"1F982","j":["scorpio","Scorpio","zodiac","animal","arachnid"]},"mosquito":{"a":"Mosquito","b":"1F99F","j":["disease","fever","malaria","pest","virus","animal","nature","insect"]},"fly":{"a":"Fly","b":"1FAB0","j":["disease","maggot","pest","rotting","insect"]},"worm":{"a":"Worm","b":"1FAB1","j":["annelid","earthworm","parasite","animal"]},"microbe":{"a":"Microbe","b":"1F9A0","j":["amoeba","bacteria","virus","germs"]},"bouquet":{"a":"Bouquet","b":"1F490","j":["flower","flowers","nature","spring"]},"cherry-blossom":{"a":"Cherry Blossom","b":"1F338","j":["blossom","cherry","flower","nature","plant","spring"]},"white-flower":{"a":"White Flower","b":"1F4AE","j":["flower","japanese","spring"]},"lotus":{"a":"⊛ Lotus","b":"1FAB7","j":["Buddhism","flower","Hinduism","India","purity","Vietnam"]},"rosette":{"a":"Rosette","b":"1F3F5","j":["plant","flower","decoration","military"]},"rose":{"a":"Rose","b":"1F339","j":["flower","flowers","valentines","love","spring"]},"wilted-flower":{"a":"Wilted Flower","b":"1F940","j":["flower","wilted","plant","nature"]},"hibiscus":{"a":"Hibiscus","b":"1F33A","j":["flower","plant","vegetable","flowers","beach"]},"sunflower":{"a":"Sunflower","b":"1F33B","j":["flower","sun","nature","plant","fall"]},"blossom":{"a":"Blossom","b":"1F33C","j":["flower","nature","flowers","yellow"]},"tulip":{"a":"Tulip","b":"1F337","j":["flower","flowers","plant","nature","summer","spring"]},"seedling":{"a":"Seedling","b":"1F331","j":["young","plant","nature","grass","lawn","spring"]},"potted-plant":{"a":"Potted Plant","b":"1FAB4","j":["boring","grow","house","nurturing","plant","useless","greenery"]},"evergreen-tree":{"a":"Evergreen Tree","b":"1F332","j":["tree","plant","nature"]},"deciduous-tree":{"a":"Deciduous Tree","b":"1F333","j":["deciduous","shedding","tree","plant","nature"]},"palm-tree":{"a":"Palm Tree","b":"1F334","j":["palm","tree","plant","vegetable","nature","summer","beach","mojito","tropical"]},"cactus":{"a":"Cactus","b":"1F335","j":["plant","vegetable","nature"]},"sheaf-of-rice":{"a":"Sheaf of Rice","b":"1F33E","j":["ear","grain","rice","nature","plant"]},"herb":{"a":"Herb","b":"1F33F","j":["leaf","vegetable","plant","medicine","weed","grass","lawn"]},"shamrock":{"a":"Shamrock","b":"2618","j":["plant","vegetable","nature","irish","clover"]},"four-leaf-clover":{"a":"Four Leaf Clover","b":"1F340","j":["4","clover","four","four-leaf clover","leaf","vegetable","plant","nature","lucky","irish"]},"maple-leaf":{"a":"Maple Leaf","b":"1F341","j":["falling","leaf","maple","nature","plant","vegetable","ca","fall"]},"fallen-leaf":{"a":"Fallen Leaf","b":"1F342","j":["falling","leaf","nature","plant","vegetable","leaves"]},"leaf-fluttering-in-wind":{"a":"Leaf Fluttering in Wind","b":"1F343","j":["blow","flutter","leaf","wind","nature","plant","tree","vegetable","grass","lawn","spring"]},"empty-nest":{"a":"⊛ Empty Nest","b":"1FAB9","j":["nesting"]},"nest-with-eggs":{"a":"⊛ Nest with Eggs","b":"1FABA","j":["nesting"]},"grapes":{"a":"Grapes","b":"1F347","j":["fruit","grape","food","wine"]},"melon":{"a":"Melon","b":"1F348","j":["fruit","nature","food"]},"watermelon":{"a":"Watermelon","b":"1F349","j":["fruit","food","picnic","summer"]},"tangerine":{"a":"Tangerine","b":"1F34A","j":["fruit","orange","food","nature"]},"lemon":{"a":"Lemon","b":"1F34B","j":["citrus","fruit","nature"]},"banana":{"a":"Banana","b":"1F34C","j":["fruit","food","monkey"]},"pineapple":{"a":"Pineapple","b":"1F34D","j":["fruit","nature","food"]},"mango":{"a":"Mango","b":"1F96D","j":["fruit","tropical","food"]},"red-apple":{"a":"Red Apple","b":"1F34E","j":["apple","fruit","red","mac","school"]},"green-apple":{"a":"Green Apple","b":"1F34F","j":["apple","fruit","green","nature"]},"pear":{"a":"Pear","b":"1F350","j":["fruit","nature","food"]},"peach":{"a":"Peach","b":"1F351","j":["fruit","nature","food"]},"cherries":{"a":"Cherries","b":"1F352","j":["berries","cherry","fruit","red","food"]},"strawberry":{"a":"Strawberry","b":"1F353","j":["berry","fruit","food","nature"]},"blueberries":{"a":"Blueberries","b":"1FAD0","j":["berry","bilberry","blue","blueberry","fruit"]},"kiwi-fruit":{"a":"Kiwi Fruit","b":"1F95D","j":["food","fruit","kiwi"]},"tomato":{"a":"Tomato","b":"1F345","j":["fruit","vegetable","nature","food"]},"olive":{"a":"Olive","b":"1FAD2","j":["food","fruit"]},"coconut":{"a":"Coconut","b":"1F965","j":["palm","piña colada","fruit","nature","food"]},"avocado":{"a":"Avocado","b":"1F951","j":["food","fruit"]},"eggplant":{"a":"Eggplant","b":"1F346","j":["aubergine","vegetable","nature","food"]},"potato":{"a":"Potato","b":"1F954","j":["food","vegetable","tuber","vegatable","starch"]},"carrot":{"a":"Carrot","b":"1F955","j":["food","vegetable","orange"]},"ear-of-corn":{"a":"Ear of Corn","b":"1F33D","j":["corn","ear","maize","maze","food","vegetable","plant"]},"hot-pepper":{"a":"Hot Pepper","b":"1F336","j":["hot","pepper","food","spicy","chilli","chili"]},"bell-pepper":{"a":"Bell Pepper","b":"1FAD1","j":["capsicum","pepper","vegetable","fruit","plant"]},"cucumber":{"a":"Cucumber","b":"1F952","j":["food","pickle","vegetable","fruit"]},"leafy-green":{"a":"Leafy Green","b":"1F96C","j":["bok choy","cabbage","kale","lettuce","food","vegetable","plant"]},"broccoli":{"a":"Broccoli","b":"1F966","j":["wild cabbage","fruit","food","vegetable"]},"garlic":{"a":"Garlic","b":"1F9C4","j":["flavoring","food","spice","cook"]},"onion":{"a":"Onion","b":"1F9C5","j":["flavoring","cook","food","spice"]},"mushroom":{"a":"Mushroom","b":"1F344","j":["toadstool","plant","vegetable"]},"peanuts":{"a":"Peanuts","b":"1F95C","j":["food","nut","peanut","vegetable"]},"beans":{"a":"⊛ Beans","b":"1FAD8","j":["food","kidney","legume"]},"chestnut":{"a":"Chestnut","b":"1F330","j":["plant","food","squirrel"]},"bread":{"a":"Bread","b":"1F35E","j":["loaf","food","wheat","breakfast","toast"]},"croissant":{"a":"Croissant","b":"1F950","j":["bread","breakfast","food","french","roll"]},"baguette-bread":{"a":"Baguette Bread","b":"1F956","j":["baguette","bread","food","french"]},"flatbread":{"a":"Flatbread","b":"1FAD3","j":["arepa","lavash","naan","pita","flour","food"]},"pretzel":{"a":"Pretzel","b":"1F968","j":["twisted","convoluted","food","bread"]},"bagel":{"a":"Bagel","b":"1F96F","j":["bakery","breakfast","schmear","food","bread"]},"pancakes":{"a":"Pancakes","b":"1F95E","j":["breakfast","crêpe","food","hotcake","pancake","flapjacks","hotcakes"]},"waffle":{"a":"Waffle","b":"1F9C7","j":["breakfast","indecisive","iron","food"]},"cheese-wedge":{"a":"Cheese Wedge","b":"1F9C0","j":["cheese","food","chadder"]},"meat-on-bone":{"a":"Meat on Bone","b":"1F356","j":["bone","meat","good","food","drumstick"]},"poultry-leg":{"a":"Poultry Leg","b":"1F357","j":["bone","chicken","drumstick","leg","poultry","food","meat","bird","turkey"]},"cut-of-meat":{"a":"Cut of Meat","b":"1F969","j":["chop","lambchop","porkchop","steak","food","cow","meat","cut"]},"bacon":{"a":"Bacon","b":"1F953","j":["breakfast","food","meat","pork","pig"]},"hamburger":{"a":"Hamburger","b":"1F354","j":["burger","meat","fast food","beef","cheeseburger","mcdonalds","burger king"]},"french-fries":{"a":"French Fries","b":"1F35F","j":["french","fries","chips","snack","fast food"]},"pizza":{"a":"Pizza","b":"1F355","j":["cheese","slice","food","party"]},"hot-dog":{"a":"Hot Dog","b":"1F32D","j":["frankfurter","hotdog","sausage","food"]},"sandwich":{"a":"Sandwich","b":"1F96A","j":["bread","food","lunch"]},"taco":{"a":"Taco","b":"1F32E","j":["mexican","food"]},"burrito":{"a":"Burrito","b":"1F32F","j":["mexican","wrap","food"]},"tamale":{"a":"Tamale","b":"1FAD4","j":["mexican","wrapped","food","masa"]},"stuffed-flatbread":{"a":"Stuffed Flatbread","b":"1F959","j":["falafel","flatbread","food","gyro","kebab","stuffed"]},"falafel":{"a":"Falafel","b":"1F9C6","j":["chickpea","meatball","food"]},"egg":{"a":"Egg","b":"1F95A","j":["breakfast","food","chicken"]},"cooking":{"a":"Cooking","b":"1F373","j":["breakfast","egg","frying","pan","food","kitchen"]},"shallow-pan-of-food":{"a":"Shallow Pan of Food","b":"1F958","j":["casserole","food","paella","pan","shallow","cooking"]},"pot-of-food":{"a":"Pot of Food","b":"1F372","j":["pot","stew","food","meat","soup"]},"fondue":{"a":"Fondue","b":"1FAD5","j":["cheese","chocolate","melted","pot","Swiss","food"]},"bowl-with-spoon":{"a":"Bowl with Spoon","b":"1F963","j":["breakfast","cereal","congee","oatmeal","porridge","food"]},"green-salad":{"a":"Green Salad","b":"1F957","j":["food","green","salad","healthy","lettuce"]},"popcorn":{"a":"Popcorn","b":"1F37F","j":["food","movie theater","films","snack"]},"butter":{"a":"Butter","b":"1F9C8","j":["dairy","food","cook"]},"salt":{"a":"Salt","b":"1F9C2","j":["condiment","shaker"]},"canned-food":{"a":"Canned Food","b":"1F96B","j":["can","food","soup"]},"bento-box":{"a":"Bento Box","b":"1F371","j":["bento","box","food","japanese"]},"rice-cracker":{"a":"Rice Cracker","b":"1F358","j":["cracker","rice","food","japanese"]},"rice-ball":{"a":"Rice Ball","b":"1F359","j":["ball","Japanese","rice","food","japanese"]},"cooked-rice":{"a":"Cooked Rice","b":"1F35A","j":["cooked","rice","food","china","asian"]},"curry-rice":{"a":"Curry Rice","b":"1F35B","j":["curry","rice","food","spicy","hot","indian"]},"steaming-bowl":{"a":"Steaming Bowl","b":"1F35C","j":["bowl","noodle","ramen","steaming","food","japanese","chopsticks"]},"spaghetti":{"a":"Spaghetti","b":"1F35D","j":["pasta","food","italian","noodle"]},"roasted-sweet-potato":{"a":"Roasted Sweet Potato","b":"1F360","j":["potato","roasted","sweet","food","nature"]},"oden":{"a":"Oden","b":"1F362","j":["kebab","seafood","skewer","stick","food","japanese"]},"sushi":{"a":"Sushi","b":"1F363","j":["food","fish","japanese","rice"]},"fried-shrimp":{"a":"Fried Shrimp","b":"1F364","j":["fried","prawn","shrimp","tempura","food","animal","appetizer","summer"]},"fish-cake-with-swirl":{"a":"Fish Cake with Swirl","b":"1F365","j":["cake","fish","pastry","swirl","food","japan","sea","beach","narutomaki","pink","kamaboko","surimi","ramen"]},"moon-cake":{"a":"Moon Cake","b":"1F96E","j":["autumn","festival","yuèbǐng","food"]},"dango":{"a":"Dango","b":"1F361","j":["dessert","Japanese","skewer","stick","sweet","food","japanese","barbecue","meat"]},"dumpling":{"a":"Dumpling","b":"1F95F","j":["empanada","gyōza","jiaozi","pierogi","potsticker","food"]},"fortune-cookie":{"a":"Fortune Cookie","b":"1F960","j":["prophecy","food"]},"takeout-box":{"a":"Takeout Box","b":"1F961","j":["oyster pail","food","leftovers"]},"crab":{"a":"Crab","b":"1F980","j":["Cancer","zodiac","animal","crustacean"]},"lobster":{"a":"Lobster","b":"1F99E","j":["bisque","claws","seafood","animal","nature"]},"shrimp":{"a":"Shrimp","b":"1F990","j":["food","shellfish","small","animal","ocean","nature","seafood"]},"squid":{"a":"Squid","b":"1F991","j":["food","molusc","animal","nature","ocean","sea"]},"oyster":{"a":"Oyster","b":"1F9AA","j":["diving","pearl","food"]},"soft-ice-cream":{"a":"Soft Ice Cream","b":"1F366","j":["cream","dessert","ice","icecream","soft","sweet","food","hot","summer"]},"shaved-ice":{"a":"Shaved Ice","b":"1F367","j":["dessert","ice","shaved","sweet","hot","summer"]},"ice-cream":{"a":"Ice Cream","b":"1F368","j":["cream","dessert","ice","sweet","food","hot"]},"doughnut":{"a":"Doughnut","b":"1F369","j":["breakfast","dessert","donut","sweet","food","snack"]},"cookie":{"a":"Cookie","b":"1F36A","j":["dessert","sweet","food","snack","oreo","chocolate"]},"birthday-cake":{"a":"Birthday Cake","b":"1F382","j":["birthday","cake","celebration","dessert","pastry","sweet","food"]},"shortcake":{"a":"Shortcake","b":"1F370","j":["cake","dessert","pastry","slice","sweet","food"]},"cupcake":{"a":"Cupcake","b":"1F9C1","j":["bakery","sweet","food","dessert"]},"pie":{"a":"Pie","b":"1F967","j":["filling","pastry","fruit","meat","food","dessert"]},"chocolate-bar":{"a":"Chocolate Bar","b":"1F36B","j":["bar","chocolate","dessert","sweet","food","snack"]},"candy":{"a":"Candy","b":"1F36C","j":["dessert","sweet","snack","lolly"]},"lollipop":{"a":"Lollipop","b":"1F36D","j":["candy","dessert","sweet","food","snack"]},"custard":{"a":"Custard","b":"1F36E","j":["dessert","pudding","sweet","food"]},"honey-pot":{"a":"Honey Pot","b":"1F36F","j":["honey","honeypot","pot","sweet","bees","kitchen"]},"baby-bottle":{"a":"Baby Bottle","b":"1F37C","j":["baby","bottle","drink","milk","food","container"]},"glass-of-milk":{"a":"Glass of Milk","b":"1F95B","j":["drink","glass","milk","beverage","cow"]},"hot-beverage":{"a":"Hot Beverage","b":"2615","j":["beverage","coffee","drink","hot","steaming","tea","caffeine","latte","espresso"]},"teapot":{"a":"Teapot","b":"1FAD6","j":["drink","pot","tea","hot"]},"teacup-without-handle":{"a":"Teacup Without Handle","b":"1F375","j":["beverage","cup","drink","tea","teacup","bowl","breakfast","green","british"]},"sake":{"a":"Sake","b":"1F376","j":["bar","beverage","bottle","cup","drink","wine","drunk","japanese","alcohol","booze"]},"bottle-with-popping-cork":{"a":"Bottle with Popping Cork","b":"1F37E","j":["bar","bottle","cork","drink","popping","wine","celebration"]},"wine-glass":{"a":"Wine Glass","b":"1F377","j":["bar","beverage","drink","glass","wine","drunk","alcohol","booze"]},"cocktail-glass":{"a":"Cocktail Glass","b":"1F378","j":["bar","cocktail","drink","glass","drunk","alcohol","beverage","booze","mojito"]},"tropical-drink":{"a":"Tropical Drink","b":"1F379","j":["bar","drink","tropical","beverage","cocktail","summer","beach","alcohol","booze","mojito"]},"beer-mug":{"a":"Beer Mug","b":"1F37A","j":["bar","beer","drink","mug","relax","beverage","drunk","party","pub","summer","alcohol","booze"]},"clinking-beer-mugs":{"a":"Clinking Beer Mugs","b":"1F37B","j":["bar","beer","clink","drink","mug","relax","beverage","drunk","party","pub","summer","alcohol","booze"]},"clinking-glasses":{"a":"Clinking Glasses","b":"1F942","j":["celebrate","clink","drink","glass","beverage","party","alcohol","cheers","wine","champagne","toast"]},"tumbler-glass":{"a":"Tumbler Glass","b":"1F943","j":["glass","liquor","shot","tumbler","whisky","drink","beverage","drunk","alcohol","booze","bourbon","scotch"]},"pouring-liquid":{"a":"⊛ Pouring Liquid","b":"1FAD7","j":["drink","empty","glass","spill"]},"cup-with-straw":{"a":"Cup with Straw","b":"1F964","j":["juice","soda","malt","soft drink","water","drink"]},"bubble-tea":{"a":"Bubble Tea","b":"1F9CB","j":["bubble","milk","pearl","tea","taiwan","boba","milk tea","straw"]},"beverage-box":{"a":"Beverage Box","b":"1F9C3","j":["beverage","box","juice","straw","sweet","drink"]},"mate":{"a":"Mate","b":"1F9C9","j":["drink","tea","beverage"]},"ice":{"a":"Ice","b":"1F9CA","j":["cold","ice cube","iceberg","water"]},"chopsticks":{"a":"Chopsticks","b":"1F962","j":["hashi","jeotgarak","kuaizi","food"]},"fork-and-knife-with-plate":{"a":"Fork and Knife with Plate","b":"1F37D","j":["cooking","fork","knife","plate","food","eat","meal","lunch","dinner","restaurant"]},"fork-and-knife":{"a":"Fork and Knife","b":"1F374","j":["cooking","cutlery","fork","knife","kitchen"]},"spoon":{"a":"Spoon","b":"1F944","j":["tableware","cutlery","kitchen"]},"kitchen-knife":{"a":"Kitchen Knife","b":"1F52A","j":["cooking","hocho","knife","tool","weapon","blade","cutlery","kitchen"]},"jar":{"a":"⊛ Jar","b":"1FAD9","j":["condiment","container","empty","sauce","store"]},"amphora":{"a":"Amphora","b":"1F3FA","j":["Aquarius","cooking","drink","jug","zodiac","vase","jar"]},"globe-showing-europeafrica":{"a":"Globe Showing Europe-Africa","b":"1F30D","j":["Africa","earth","Europe","globe","globe showing Europe-Africa","world","globe_showing_europe_africa","international"]},"globe-showing-americas":{"a":"Globe Showing Americas","b":"1F30E","j":["Americas","earth","globe","globe showing Americas","world","USA","international"]},"globe-showing-asiaaustralia":{"a":"Globe Showing Asia-Australia","b":"1F30F","j":["Asia","Australia","earth","globe","globe showing Asia-Australia","world","globe_showing_asia_australia","east","international"]},"globe-with-meridians":{"a":"Globe with Meridians","b":"1F310","j":["earth","globe","meridians","world","international","internet","interweb","i18n"]},"world-map":{"a":"World Map","b":"1F5FA","j":["map","world","location","direction"]},"map-of-japan":{"a":"Map of Japan","b":"1F5FE","j":["Japan","map","map of Japan","nation","country","japanese","asia"]},"compass":{"a":"Compass","b":"1F9ED","j":["magnetic","navigation","orienteering"]},"snowcapped-mountain":{"a":"Snow-Capped Mountain","b":"1F3D4","j":["cold","mountain","snow","snow-capped mountain","snow_capped_mountain","photo","nature","environment","winter"]},"mountain":{"a":"Mountain","b":"26F0","j":["photo","nature","environment"]},"volcano":{"a":"Volcano","b":"1F30B","j":["eruption","mountain","photo","nature","disaster"]},"mount-fuji":{"a":"Mount Fuji","b":"1F5FB","j":["fuji","mountain","photo","nature","japanese"]},"camping":{"a":"Camping","b":"1F3D5","j":["photo","outdoors","tent"]},"beach-with-umbrella":{"a":"Beach with Umbrella","b":"1F3D6","j":["beach","umbrella","weather","summer","sunny","sand","mojito"]},"desert":{"a":"Desert","b":"1F3DC","j":["photo","warm","saharah"]},"desert-island":{"a":"Desert Island","b":"1F3DD","j":["desert","island","photo","tropical","mojito"]},"national-park":{"a":"National Park","b":"1F3DE","j":["park","photo","environment","nature"]},"stadium":{"a":"Stadium","b":"1F3DF","j":["photo","place","sports","concert","venue"]},"classical-building":{"a":"Classical Building","b":"1F3DB","j":["classical","art","culture","history"]},"building-construction":{"a":"Building Construction","b":"1F3D7","j":["construction","wip","working","progress"]},"brick":{"a":"Brick","b":"1F9F1","j":["bricks","clay","mortar","wall"]},"rock":{"a":"Rock","b":"1FAA8","j":["boulder","heavy","solid","stone"]},"wood":{"a":"Wood","b":"1FAB5","j":["log","lumber","timber","nature","trunk"]},"hut":{"a":"Hut","b":"1F6D6","j":["house","roundhouse","yurt","structure"]},"houses":{"a":"Houses","b":"1F3D8","j":["buildings","photo"]},"derelict-house":{"a":"Derelict House","b":"1F3DA","j":["derelict","house","abandon","evict","broken","building"]},"house":{"a":"House","b":"1F3E0","j":["home","building"]},"house-with-garden":{"a":"House with Garden","b":"1F3E1","j":["garden","home","house","plant","nature"]},"office-building":{"a":"Office Building","b":"1F3E2","j":["building","bureau","work"]},"japanese-post-office":{"a":"Japanese Post Office","b":"1F3E3","j":["Japanese","Japanese post office","post","building","envelope","communication"]},"post-office":{"a":"Post Office","b":"1F3E4","j":["European","post","building","email"]},"hospital":{"a":"Hospital","b":"1F3E5","j":["doctor","medicine","building","health","surgery"]},"bank":{"a":"Bank","b":"1F3E6","j":["building","money","sales","cash","business","enterprise"]},"hotel":{"a":"Hotel","b":"1F3E8","j":["building","accomodation","checkin"]},"love-hotel":{"a":"Love Hotel","b":"1F3E9","j":["hotel","love","like","affection","dating"]},"convenience-store":{"a":"Convenience Store","b":"1F3EA","j":["convenience","store","building","shopping","groceries"]},"school":{"a":"School","b":"1F3EB","j":["building","student","education","learn","teach"]},"department-store":{"a":"Department Store","b":"1F3EC","j":["department","store","building","shopping","mall"]},"factory":{"a":"Factory","b":"1F3ED","j":["building","industry","pollution","smoke"]},"japanese-castle":{"a":"Japanese Castle","b":"1F3EF","j":["castle","Japanese","photo","building"]},"castle":{"a":"Castle","b":"1F3F0","j":["European","building","royalty","history"]},"wedding":{"a":"Wedding","b":"1F492","j":["chapel","romance","love","like","affection","couple","marriage","bride","groom"]},"tokyo-tower":{"a":"Tokyo Tower","b":"1F5FC","j":["Tokyo","tower","photo","japanese"]},"statue-of-liberty":{"a":"Statue of Liberty","b":"1F5FD","j":["liberty","statue","american","newyork"]},"church":{"a":"Church","b":"26EA","j":["Christian","cross","religion","building","christ"]},"mosque":{"a":"Mosque","b":"1F54C","j":["islam","Muslim","religion","worship","minaret"]},"hindu-temple":{"a":"Hindu Temple","b":"1F6D5","j":["hindu","temple","religion"]},"synagogue":{"a":"Synagogue","b":"1F54D","j":["Jew","Jewish","religion","temple","judaism","worship","jewish"]},"shinto-shrine":{"a":"Shinto Shrine","b":"26E9","j":["religion","shinto","shrine","temple","japan","kyoto"]},"kaaba":{"a":"Kaaba","b":"1F54B","j":["islam","Muslim","religion","mecca","mosque"]},"fountain":{"a":"Fountain","b":"26F2","j":["photo","summer","water","fresh"]},"tent":{"a":"Tent","b":"26FA","j":["camping","photo","outdoors"]},"foggy":{"a":"Foggy","b":"1F301","j":["fog","photo","mountain"]},"night-with-stars":{"a":"Night with Stars","b":"1F303","j":["night","star","evening","city","downtown"]},"cityscape":{"a":"Cityscape","b":"1F3D9","j":["city","photo","night life","urban"]},"sunrise-over-mountains":{"a":"Sunrise over Mountains","b":"1F304","j":["morning","mountain","sun","sunrise","view","vacation","photo"]},"sunrise":{"a":"Sunrise","b":"1F305","j":["morning","sun","view","vacation","photo"]},"cityscape-at-dusk":{"a":"Cityscape at Dusk","b":"1F306","j":["city","dusk","evening","landscape","sunset","photo","sky","buildings"]},"sunset":{"a":"Sunset","b":"1F307","j":["dusk","sun","photo","good morning","dawn"]},"bridge-at-night":{"a":"Bridge at Night","b":"1F309","j":["bridge","night","photo","sanfrancisco"]},"hot-springs":{"a":"Hot Springs","b":"2668","j":["hot","hotsprings","springs","steaming","bath","warm","relax"]},"carousel-horse":{"a":"Carousel Horse","b":"1F3A0","j":["carousel","horse","photo","carnival"]},"playground-slide":{"a":"⊛ Playground Slide","b":"1F6DD","j":["amusement park","play"]},"ferris-wheel":{"a":"Ferris Wheel","b":"1F3A1","j":["amusement park","ferris","wheel","photo","carnival","londoneye"]},"roller-coaster":{"a":"Roller Coaster","b":"1F3A2","j":["amusement park","coaster","roller","carnival","playground","photo","fun"]},"barber-pole":{"a":"Barber Pole","b":"1F488","j":["barber","haircut","pole","hair","salon","style"]},"circus-tent":{"a":"Circus Tent","b":"1F3AA","j":["circus","tent","festival","carnival","party"]},"locomotive":{"a":"Locomotive","b":"1F682","j":["engine","railway","steam","train","transportation","vehicle"]},"railway-car":{"a":"Railway Car","b":"1F683","j":["car","electric","railway","train","tram","trolleybus","transportation","vehicle"]},"highspeed-train":{"a":"High-Speed Train","b":"1F684","j":["high-speed train","railway","shinkansen","speed","train","high_speed_train","transportation","vehicle"]},"bullet-train":{"a":"Bullet Train","b":"1F685","j":["bullet","railway","shinkansen","speed","train","transportation","vehicle","fast","public","travel"]},"train":{"a":"Train","b":"1F686","j":["railway","transportation","vehicle"]},"metro":{"a":"Metro","b":"1F687","j":["subway","transportation","blue-square","mrt","underground","tube"]},"light-rail":{"a":"Light Rail","b":"1F688","j":["railway","transportation","vehicle"]},"station":{"a":"Station","b":"1F689","j":["railway","train","transportation","vehicle","public"]},"tram":{"a":"Tram","b":"1F68A","j":["trolleybus","transportation","vehicle"]},"monorail":{"a":"Monorail","b":"1F69D","j":["vehicle","transportation"]},"mountain-railway":{"a":"Mountain Railway","b":"1F69E","j":["car","mountain","railway","transportation","vehicle"]},"tram-car":{"a":"Tram Car","b":"1F68B","j":["car","tram","trolleybus","transportation","vehicle","carriage","public","travel"]},"bus":{"a":"Bus","b":"1F68C","j":["vehicle","car","transportation"]},"oncoming-bus":{"a":"Oncoming Bus","b":"1F68D","j":["bus","oncoming","vehicle","transportation"]},"trolleybus":{"a":"Trolleybus","b":"1F68E","j":["bus","tram","trolley","bart","transportation","vehicle"]},"minibus":{"a":"Minibus","b":"1F690","j":["bus","vehicle","car","transportation"]},"ambulance":{"a":"Ambulance","b":"1F691","j":["vehicle","health","911","hospital"]},"fire-engine":{"a":"Fire Engine","b":"1F692","j":["engine","fire","truck","transportation","cars","vehicle"]},"police-car":{"a":"Police Car","b":"1F693","j":["car","patrol","police","vehicle","cars","transportation","law","legal","enforcement"]},"oncoming-police-car":{"a":"Oncoming Police Car","b":"1F694","j":["car","oncoming","police","vehicle","law","legal","enforcement","911"]},"taxi":{"a":"Taxi","b":"1F695","j":["vehicle","uber","cars","transportation"]},"oncoming-taxi":{"a":"Oncoming Taxi","b":"1F696","j":["oncoming","taxi","vehicle","cars","uber"]},"automobile":{"a":"Automobile","b":"1F697","j":["car","red","transportation","vehicle"]},"oncoming-automobile":{"a":"Oncoming Automobile","b":"1F698","j":["automobile","car","oncoming","vehicle","transportation"]},"sport-utility-vehicle":{"a":"Sport Utility Vehicle","b":"1F699","j":["recreational","sport utility","transportation","vehicle"]},"pickup-truck":{"a":"Pickup Truck","b":"1F6FB","j":["pick-up","pickup","truck","car","transportation"]},"delivery-truck":{"a":"Delivery Truck","b":"1F69A","j":["delivery","truck","cars","transportation"]},"articulated-lorry":{"a":"Articulated Lorry","b":"1F69B","j":["lorry","semi","truck","vehicle","cars","transportation","express"]},"tractor":{"a":"Tractor","b":"1F69C","j":["vehicle","car","farming","agriculture"]},"racing-car":{"a":"Racing Car","b":"1F3CE","j":["car","racing","sports","race","fast","formula","f1"]},"motorcycle":{"a":"Motorcycle","b":"1F3CD","j":["racing","race","sports","fast"]},"motor-scooter":{"a":"Motor Scooter","b":"1F6F5","j":["motor","scooter","vehicle","vespa","sasha"]},"manual-wheelchair":{"a":"Manual Wheelchair","b":"1F9BD","j":["accessibility"]},"motorized-wheelchair":{"a":"Motorized Wheelchair","b":"1F9BC","j":["accessibility"]},"auto-rickshaw":{"a":"Auto Rickshaw","b":"1F6FA","j":["tuk tuk","move","transportation"]},"bicycle":{"a":"Bicycle","b":"1F6B2","j":["bike","sports","exercise","hipster"]},"kick-scooter":{"a":"Kick Scooter","b":"1F6F4","j":["kick","scooter","vehicle","razor"]},"skateboard":{"a":"Skateboard","b":"1F6F9","j":["board"]},"roller-skate":{"a":"Roller Skate","b":"1F6FC","j":["roller","skate","footwear","sports"]},"bus-stop":{"a":"Bus Stop","b":"1F68F","j":["bus","stop","transportation","wait"]},"motorway":{"a":"Motorway","b":"1F6E3","j":["highway","road","cupertino","interstate"]},"railway-track":{"a":"Railway Track","b":"1F6E4","j":["railway","train","transportation"]},"oil-drum":{"a":"Oil Drum","b":"1F6E2","j":["drum","oil","barrell"]},"fuel-pump":{"a":"Fuel Pump","b":"26FD","j":["diesel","fuel","fuelpump","gas","pump","station","gas station","petroleum"]},"wheel":{"a":"⊛ Wheel","b":"1F6DE","j":["circle","tire","turn"]},"police-car-light":{"a":"Police Car Light","b":"1F6A8","j":["beacon","car","light","police","revolving","ambulance","911","emergency","alert","error","pinged","law","legal"]},"horizontal-traffic-light":{"a":"Horizontal Traffic Light","b":"1F6A5","j":["light","signal","traffic","transportation"]},"vertical-traffic-light":{"a":"Vertical Traffic Light","b":"1F6A6","j":["light","signal","traffic","transportation","driving"]},"stop-sign":{"a":"Stop Sign","b":"1F6D1","j":["octagonal","sign","stop"]},"construction":{"a":"Construction","b":"1F6A7","j":["barrier","wip","progress","caution","warning"]},"anchor":{"a":"Anchor","b":"2693","j":["ship","tool","ferry","sea","boat"]},"ring-buoy":{"a":"⊛ Ring Buoy","b":"1F6DF","j":["float","life preserver","life saver","rescue","safety"]},"sailboat":{"a":"Sailboat","b":"26F5","j":["boat","resort","sea","yacht","ship","summer","transportation","water","sailing"]},"canoe":{"a":"Canoe","b":"1F6F6","j":["boat","paddle","water","ship"]},"speedboat":{"a":"Speedboat","b":"1F6A4","j":["boat","ship","transportation","vehicle","summer"]},"passenger-ship":{"a":"Passenger Ship","b":"1F6F3","j":["passenger","ship","yacht","cruise","ferry"]},"ferry":{"a":"Ferry","b":"26F4","j":["boat","passenger","ship","yacht"]},"motor-boat":{"a":"Motor Boat","b":"1F6E5","j":["boat","motorboat","ship"]},"ship":{"a":"Ship","b":"1F6A2","j":["boat","passenger","transportation","titanic","deploy"]},"airplane":{"a":"Airplane","b":"2708","j":["aeroplane","vehicle","transportation","flight","fly"]},"small-airplane":{"a":"Small Airplane","b":"1F6E9","j":["aeroplane","airplane","flight","transportation","fly","vehicle"]},"airplane-departure":{"a":"Airplane Departure","b":"1F6EB","j":["aeroplane","airplane","check-in","departure","departures","airport","flight","landing"]},"airplane-arrival":{"a":"Airplane Arrival","b":"1F6EC","j":["aeroplane","airplane","arrivals","arriving","landing","airport","flight","boarding"]},"parachute":{"a":"Parachute","b":"1FA82","j":["hang-glide","parasail","skydive","fly","glide"]},"seat":{"a":"Seat","b":"1F4BA","j":["chair","sit","airplane","transport","bus","flight","fly"]},"helicopter":{"a":"Helicopter","b":"1F681","j":["vehicle","transportation","fly"]},"suspension-railway":{"a":"Suspension Railway","b":"1F69F","j":["railway","suspension","vehicle","transportation"]},"mountain-cableway":{"a":"Mountain Cableway","b":"1F6A0","j":["cable","gondola","mountain","transportation","vehicle","ski"]},"aerial-tramway":{"a":"Aerial Tramway","b":"1F6A1","j":["aerial","cable","car","gondola","tramway","transportation","vehicle","ski"]},"satellite":{"a":"Satellite","b":"1F6F0","j":["space","communication","gps","orbit","spaceflight","NASA","ISS"]},"rocket":{"a":"Rocket","b":"1F680","j":["space","launch","ship","staffmode","NASA","outer space","outer_space","fly"]},"flying-saucer":{"a":"Flying Saucer","b":"1F6F8","j":["UFO","transportation","vehicle","ufo"]},"bellhop-bell":{"a":"Bellhop Bell","b":"1F6CE","j":["bell","bellhop","hotel","service"]},"luggage":{"a":"Luggage","b":"1F9F3","j":["packing","travel"]},"hourglass-done":{"a":"Hourglass Done","b":"231B","j":["sand","timer","time","clock","oldschool","limit","exam","quiz","test"]},"hourglass-not-done":{"a":"Hourglass Not Done","b":"23F3","j":["hourglass","sand","timer","oldschool","time","countdown"]},"watch":{"a":"Watch","b":"231A","j":["clock","time","accessories"]},"alarm-clock":{"a":"Alarm Clock","b":"23F0","j":["alarm","clock","time","wake"]},"stopwatch":{"a":"Stopwatch","b":"23F1","j":["clock","time","deadline"]},"timer-clock":{"a":"Timer Clock","b":"23F2","j":["clock","timer","alarm"]},"mantelpiece-clock":{"a":"Mantelpiece Clock","b":"1F570","j":["clock","time"]},"twelve-oclock":{"a":"Twelve O’Clock","b":"1F55B","j":["00","12","12:00","clock","o’clock","twelve","twelve_o_clock","time","noon","midnight","midday","late","early","schedule"]},"twelvethirty":{"a":"Twelve-Thirty","b":"1F567","j":["12","12:30","clock","thirty","twelve","twelve-thirty","twelve_thirty","time","late","early","schedule"]},"one-oclock":{"a":"One O’Clock","b":"1F550","j":["00","1","1:00","clock","o’clock","one","one_o_clock","time","late","early","schedule"]},"onethirty":{"a":"One-Thirty","b":"1F55C","j":["1","1:30","clock","one","one-thirty","thirty","one_thirty","time","late","early","schedule"]},"two-oclock":{"a":"Two O’Clock","b":"1F551","j":["00","2","2:00","clock","o’clock","two","two_o_clock","time","late","early","schedule"]},"twothirty":{"a":"Two-Thirty","b":"1F55D","j":["2","2:30","clock","thirty","two","two-thirty","two_thirty","time","late","early","schedule"]},"three-oclock":{"a":"Three O’Clock","b":"1F552","j":["00","3","3:00","clock","o’clock","three","three_o_clock","time","late","early","schedule"]},"threethirty":{"a":"Three-Thirty","b":"1F55E","j":["3","3:30","clock","thirty","three","three-thirty","three_thirty","time","late","early","schedule"]},"four-oclock":{"a":"Four O’Clock","b":"1F553","j":["00","4","4:00","clock","four","o’clock","four_o_clock","time","late","early","schedule"]},"fourthirty":{"a":"Four-Thirty","b":"1F55F","j":["4","4:30","clock","four","four-thirty","thirty","four_thirty","time","late","early","schedule"]},"five-oclock":{"a":"Five O’Clock","b":"1F554","j":["00","5","5:00","clock","five","o’clock","five_o_clock","time","late","early","schedule"]},"fivethirty":{"a":"Five-Thirty","b":"1F560","j":["5","5:30","clock","five","five-thirty","thirty","five_thirty","time","late","early","schedule"]},"six-oclock":{"a":"Six O’Clock","b":"1F555","j":["00","6","6:00","clock","o’clock","six","six_o_clock","time","late","early","schedule","dawn","dusk"]},"sixthirty":{"a":"Six-Thirty","b":"1F561","j":["6","6:30","clock","six","six-thirty","thirty","six_thirty","time","late","early","schedule"]},"seven-oclock":{"a":"Seven O’Clock","b":"1F556","j":["00","7","7:00","clock","o’clock","seven","seven_o_clock","time","late","early","schedule"]},"seventhirty":{"a":"Seven-Thirty","b":"1F562","j":["7","7:30","clock","seven","seven-thirty","thirty","seven_thirty","time","late","early","schedule"]},"eight-oclock":{"a":"Eight O’Clock","b":"1F557","j":["00","8","8:00","clock","eight","o’clock","eight_o_clock","time","late","early","schedule"]},"eightthirty":{"a":"Eight-Thirty","b":"1F563","j":["8","8:30","clock","eight","eight-thirty","thirty","eight_thirty","time","late","early","schedule"]},"nine-oclock":{"a":"Nine O’Clock","b":"1F558","j":["00","9","9:00","clock","nine","o’clock","nine_o_clock","time","late","early","schedule"]},"ninethirty":{"a":"Nine-Thirty","b":"1F564","j":["9","9:30","clock","nine","nine-thirty","thirty","nine_thirty","time","late","early","schedule"]},"ten-oclock":{"a":"Ten O’Clock","b":"1F559","j":["00","10","10:00","clock","o’clock","ten","ten_o_clock","time","late","early","schedule"]},"tenthirty":{"a":"Ten-Thirty","b":"1F565","j":["10","10:30","clock","ten","ten-thirty","thirty","ten_thirty","time","late","early","schedule"]},"eleven-oclock":{"a":"Eleven O’Clock","b":"1F55A","j":["00","11","11:00","clock","eleven","o’clock","eleven_o_clock","time","late","early","schedule"]},"eleventhirty":{"a":"Eleven-Thirty","b":"1F566","j":["11","11:30","clock","eleven","eleven-thirty","thirty","eleven_thirty","time","late","early","schedule"]},"new-moon":{"a":"New Moon","b":"1F311","j":["dark","moon","nature","twilight","planet","space","night","evening","sleep"]},"waxing-crescent-moon":{"a":"Waxing Crescent Moon","b":"1F312","j":["crescent","moon","waxing","nature","twilight","planet","space","night","evening","sleep"]},"first-quarter-moon":{"a":"First Quarter Moon","b":"1F313","j":["moon","quarter","nature","twilight","planet","space","night","evening","sleep"]},"waxing-gibbous-moon":{"a":"Waxing Gibbous Moon","b":"1F314","j":["gibbous","moon","waxing","nature","night","sky","gray","twilight","planet","space","evening","sleep"]},"full-moon":{"a":"Full Moon","b":"1F315","j":["full","moon","nature","yellow","twilight","planet","space","night","evening","sleep"]},"waning-gibbous-moon":{"a":"Waning Gibbous Moon","b":"1F316","j":["gibbous","moon","waning","nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"]},"last-quarter-moon":{"a":"Last Quarter Moon","b":"1F317","j":["moon","quarter","nature","twilight","planet","space","night","evening","sleep"]},"waning-crescent-moon":{"a":"Waning Crescent Moon","b":"1F318","j":["crescent","moon","waning","nature","twilight","planet","space","night","evening","sleep"]},"crescent-moon":{"a":"Crescent Moon","b":"1F319","j":["crescent","moon","night","sleep","sky","evening","magic"]},"new-moon-face":{"a":"New Moon Face","b":"1F31A","j":["face","moon","nature","twilight","planet","space","night","evening","sleep"]},"first-quarter-moon-face":{"a":"First Quarter Moon Face","b":"1F31B","j":["face","moon","quarter","nature","twilight","planet","space","night","evening","sleep"]},"last-quarter-moon-face":{"a":"Last Quarter Moon Face","b":"1F31C","j":["face","moon","quarter","nature","twilight","planet","space","night","evening","sleep"]},"thermometer":{"a":"Thermometer","b":"1F321","j":["weather","temperature","hot","cold"]},"sun":{"a":"Sun","b":"2600","j":["bright","rays","sunny","weather","nature","brightness","summer","beach","spring"]},"full-moon-face":{"a":"Full Moon Face","b":"1F31D","j":["bright","face","full","moon","nature","twilight","planet","space","night","evening","sleep"]},"sun-with-face":{"a":"Sun with Face","b":"1F31E","j":["bright","face","sun","nature","morning","sky"]},"ringed-planet":{"a":"Ringed Planet","b":"1FA90","j":["saturn","saturnine","outerspace"]},"star":{"a":"Star","b":"2B50","j":["night","yellow"]},"glowing-star":{"a":"Glowing Star","b":"1F31F","j":["glittery","glow","shining","sparkle","star","night","awesome","good","magic"]},"shooting-star":{"a":"Shooting Star","b":"1F320","j":["falling","shooting","star","night","photo"]},"milky-way":{"a":"Milky Way","b":"1F30C","j":["space","photo","stars"]},"cloud":{"a":"Cloud","b":"2601","j":["weather","sky"]},"sun-behind-cloud":{"a":"Sun Behind Cloud","b":"26C5","j":["cloud","sun","weather","nature","cloudy","morning","fall","spring"]},"cloud-with-lightning-and-rain":{"a":"Cloud with Lightning and Rain","b":"26C8","j":["cloud","rain","thunder","weather","lightning"]},"sun-behind-small-cloud":{"a":"Sun Behind Small Cloud","b":"1F324","j":["cloud","sun","weather"]},"sun-behind-large-cloud":{"a":"Sun Behind Large Cloud","b":"1F325","j":["cloud","sun","weather"]},"sun-behind-rain-cloud":{"a":"Sun Behind Rain Cloud","b":"1F326","j":["cloud","rain","sun","weather"]},"cloud-with-rain":{"a":"Cloud with Rain","b":"1F327","j":["cloud","rain","weather"]},"cloud-with-snow":{"a":"Cloud with Snow","b":"1F328","j":["cloud","cold","snow","weather"]},"cloud-with-lightning":{"a":"Cloud with Lightning","b":"1F329","j":["cloud","lightning","weather","thunder"]},"tornado":{"a":"Tornado","b":"1F32A","j":["cloud","whirlwind","weather","cyclone","twister"]},"fog":{"a":"Fog","b":"1F32B","j":["cloud","weather"]},"wind-face":{"a":"Wind Face","b":"1F32C","j":["blow","cloud","face","wind","gust","air"]},"cyclone":{"a":"Cyclone","b":"1F300","j":["dizzy","hurricane","twister","typhoon","weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado"]},"rainbow":{"a":"Rainbow","b":"1F308","j":["rain","nature","happy","unicorn_face","photo","sky","spring"]},"closed-umbrella":{"a":"Closed Umbrella","b":"1F302","j":["clothing","rain","umbrella","weather","drizzle"]},"umbrella":{"a":"Umbrella","b":"2602","j":["clothing","rain","weather","spring"]},"umbrella-with-rain-drops":{"a":"Umbrella with Rain Drops","b":"2614","j":["clothing","drop","rain","umbrella","rainy","weather","spring"]},"umbrella-on-ground":{"a":"Umbrella on Ground","b":"26F1","j":["rain","sun","umbrella","weather","summer"]},"high-voltage":{"a":"High Voltage","b":"26A1","j":["danger","electric","lightning","voltage","zap","thunder","weather","lightning bolt","fast"]},"snowflake":{"a":"Snowflake","b":"2744","j":["cold","snow","winter","season","weather","christmas","xmas"]},"snowman":{"a":"Snowman","b":"2603","j":["cold","snow","winter","season","weather","christmas","xmas","frozen"]},"snowman-without-snow":{"a":"Snowman Without Snow","b":"26C4","j":["cold","snow","snowman","winter","season","weather","christmas","xmas","frozen","without_snow"]},"comet":{"a":"Comet","b":"2604","j":["space"]},"fire":{"a":"Fire","b":"1F525","j":["flame","tool","hot","cook"]},"droplet":{"a":"Droplet","b":"1F4A7","j":["cold","comic","drop","sweat","water","drip","faucet","spring"]},"water-wave":{"a":"Water Wave","b":"1F30A","j":["ocean","water","wave","sea","nature","tsunami","disaster"]},"jackolantern":{"a":"Jack-O-Lantern","b":"1F383","j":["celebration","halloween","jack","jack-o-lantern","lantern","jack_o_lantern","light","pumpkin","creepy","fall"]},"christmas-tree":{"a":"Christmas Tree","b":"1F384","j":["celebration","Christmas","tree","festival","vacation","december","xmas"]},"fireworks":{"a":"Fireworks","b":"1F386","j":["celebration","photo","festival","carnival","congratulations"]},"sparkler":{"a":"Sparkler","b":"1F387","j":["celebration","fireworks","sparkle","stars","night","shine"]},"firecracker":{"a":"Firecracker","b":"1F9E8","j":["dynamite","explosive","fireworks","boom","explode","explosion"]},"sparkles":{"a":"Sparkles","b":"2728","j":["*","sparkle","star","stars","shine","shiny","cool","awesome","good","magic"]},"balloon":{"a":"Balloon","b":"1F388","j":["celebration","party","birthday","circus"]},"party-popper":{"a":"Party Popper","b":"1F389","j":["celebration","party","popper","tada","congratulations","birthday","magic","circus"]},"confetti-ball":{"a":"Confetti Ball","b":"1F38A","j":["ball","celebration","confetti","festival","party","birthday","circus"]},"tanabata-tree":{"a":"Tanabata Tree","b":"1F38B","j":["banner","celebration","Japanese","tree","plant","nature","branch","summer"]},"pine-decoration":{"a":"Pine Decoration","b":"1F38D","j":["bamboo","celebration","Japanese","pine","plant","nature","vegetable","panda"]},"japanese-dolls":{"a":"Japanese Dolls","b":"1F38E","j":["celebration","doll","festival","Japanese","Japanese dolls","japanese","toy","kimono"]},"carp-streamer":{"a":"Carp Streamer","b":"1F38F","j":["carp","celebration","streamer","fish","japanese","koinobori","banner"]},"wind-chime":{"a":"Wind Chime","b":"1F390","j":["bell","celebration","chime","wind","nature","ding","spring"]},"moon-viewing-ceremony":{"a":"Moon Viewing Ceremony","b":"1F391","j":["celebration","ceremony","moon","photo","japan","asia","tsukimi"]},"red-envelope":{"a":"Red Envelope","b":"1F9E7","j":["gift","good luck","hóngbāo","lai see","money"]},"ribbon":{"a":"Ribbon","b":"1F380","j":["celebration","decoration","pink","girl","bowtie"]},"wrapped-gift":{"a":"Wrapped Gift","b":"1F381","j":["box","celebration","gift","present","wrapped","birthday","christmas","xmas"]},"reminder-ribbon":{"a":"Reminder Ribbon","b":"1F397","j":["celebration","reminder","ribbon","sports","cause","support","awareness"]},"admission-tickets":{"a":"Admission Tickets","b":"1F39F","j":["admission","ticket","sports","concert","entrance"]},"ticket":{"a":"Ticket","b":"1F3AB","j":["admission","event","concert","pass"]},"military-medal":{"a":"Military Medal","b":"1F396","j":["celebration","medal","military","award","winning","army"]},"trophy":{"a":"Trophy","b":"1F3C6","j":["prize","win","award","contest","place","ftw","ceremony"]},"sports-medal":{"a":"Sports Medal","b":"1F3C5","j":["medal","award","winning"]},"1st-place-medal":{"a":"1st Place Medal","b":"1F947","j":["first","gold","medal","award","winning"]},"2nd-place-medal":{"a":"2nd Place Medal","b":"1F948","j":["medal","second","silver","award"]},"3rd-place-medal":{"a":"3rd Place Medal","b":"1F949","j":["bronze","medal","third","award"]},"soccer-ball":{"a":"Soccer Ball","b":"26BD","j":["ball","football","soccer","sports"]},"baseball":{"a":"Baseball","b":"26BE","j":["ball","sports","balls"]},"softball":{"a":"Softball","b":"1F94E","j":["ball","glove","underarm","sports","balls"]},"basketball":{"a":"Basketball","b":"1F3C0","j":["ball","hoop","sports","balls","NBA"]},"volleyball":{"a":"Volleyball","b":"1F3D0","j":["ball","game","sports","balls"]},"american-football":{"a":"American Football","b":"1F3C8","j":["american","ball","football","sports","balls","NFL"]},"rugby-football":{"a":"Rugby Football","b":"1F3C9","j":["ball","football","rugby","sports","team"]},"tennis":{"a":"Tennis","b":"1F3BE","j":["ball","racquet","sports","balls","green"]},"flying-disc":{"a":"Flying Disc","b":"1F94F","j":["ultimate","sports","frisbee"]},"bowling":{"a":"Bowling","b":"1F3B3","j":["ball","game","sports","fun","play"]},"cricket-game":{"a":"Cricket Game","b":"1F3CF","j":["ball","bat","game","sports"]},"field-hockey":{"a":"Field Hockey","b":"1F3D1","j":["ball","field","game","hockey","stick","sports"]},"ice-hockey":{"a":"Ice Hockey","b":"1F3D2","j":["game","hockey","ice","puck","stick","sports"]},"lacrosse":{"a":"Lacrosse","b":"1F94D","j":["ball","goal","stick","sports"]},"ping-pong":{"a":"Ping Pong","b":"1F3D3","j":["ball","bat","game","paddle","table tennis","sports","pingpong"]},"badminton":{"a":"Badminton","b":"1F3F8","j":["birdie","game","racquet","shuttlecock","sports"]},"boxing-glove":{"a":"Boxing Glove","b":"1F94A","j":["boxing","glove","sports","fighting"]},"martial-arts-uniform":{"a":"Martial Arts Uniform","b":"1F94B","j":["judo","karate","martial arts","taekwondo","uniform"]},"goal-net":{"a":"Goal Net","b":"1F945","j":["goal","net","sports"]},"flag-in-hole":{"a":"Flag in Hole","b":"26F3","j":["golf","hole","sports","business","flag","summer"]},"ice-skate":{"a":"Ice Skate","b":"26F8","j":["ice","skate","sports"]},"fishing-pole":{"a":"Fishing Pole","b":"1F3A3","j":["fish","pole","food","hobby","summer"]},"diving-mask":{"a":"Diving Mask","b":"1F93F","j":["diving","scuba","snorkeling","sport","ocean"]},"running-shirt":{"a":"Running Shirt","b":"1F3BD","j":["athletics","running","sash","shirt","play","pageant"]},"skis":{"a":"Skis","b":"1F3BF","j":["ski","snow","sports","winter","cold"]},"sled":{"a":"Sled","b":"1F6F7","j":["sledge","sleigh","luge","toboggan"]},"curling-stone":{"a":"Curling Stone","b":"1F94C","j":["game","rock","sports"]},"bullseye":{"a":"Bullseye","b":"1F3AF","j":["dart","direct hit","game","hit","target","direct_hit","play","bar"]},"yoyo":{"a":"Yo-Yo","b":"1FA80","j":["fluctuate","toy","yo-yo","yo_yo"]},"kite":{"a":"Kite","b":"1FA81","j":["fly","soar","wind"]},"pool-8-ball":{"a":"Pool 8 Ball","b":"1F3B1","j":["8","ball","billiard","eight","game","pool","hobby","luck","magic"]},"crystal-ball":{"a":"Crystal Ball","b":"1F52E","j":["ball","crystal","fairy tale","fantasy","fortune","tool","disco","party","magic","circus","fortune_teller"]},"magic-wand":{"a":"Magic Wand","b":"1FA84","j":["magic","witch","wizard","supernature","power"]},"nazar-amulet":{"a":"Nazar Amulet","b":"1F9FF","j":["bead","charm","evil-eye","nazar","talisman"]},"hamsa":{"a":"⊛ Hamsa","b":"1FAAC","j":["amulet","Fatima","hand","Mary","Miriam","protection"]},"video-game":{"a":"Video Game","b":"1F3AE","j":["controller","game","play","console","PS4"]},"joystick":{"a":"Joystick","b":"1F579","j":["game","video game","play"]},"slot-machine":{"a":"Slot Machine","b":"1F3B0","j":["game","slot","bet","gamble","vegas","fruit machine","luck","casino"]},"game-die":{"a":"Game Die","b":"1F3B2","j":["dice","die","game","random","tabletop","play","luck"]},"puzzle-piece":{"a":"Puzzle Piece","b":"1F9E9","j":["clue","interlocking","jigsaw","piece","puzzle"]},"teddy-bear":{"a":"Teddy Bear","b":"1F9F8","j":["plaything","plush","stuffed","toy"]},"piata":{"a":"Piñata","b":"1FA85","j":["celebration","party","piñata","pinata","mexico","candy"]},"mirror-ball":{"a":"⊛ Mirror Ball","b":"1FAA9","j":["dance","disco","glitter","party"]},"nesting-dolls":{"a":"Nesting Dolls","b":"1FA86","j":["doll","nesting","russia","matryoshka","toy"]},"spade-suit":{"a":"Spade Suit","b":"2660","j":["card","game","poker","cards","suits","magic"]},"heart-suit":{"a":"Heart Suit","b":"2665","j":["card","game","poker","cards","magic","suits"]},"diamond-suit":{"a":"Diamond Suit","b":"2666","j":["card","game","poker","cards","magic","suits"]},"club-suit":{"a":"Club Suit","b":"2663","j":["card","game","poker","cards","magic","suits"]},"chess-pawn":{"a":"Chess Pawn","b":"265F","j":["chess","dupe","expendable"]},"joker":{"a":"Joker","b":"1F0CF","j":["card","game","wildcard","poker","cards","play","magic"]},"mahjong-red-dragon":{"a":"Mahjong Red Dragon","b":"1F004","j":["game","mahjong","red","play","chinese","kanji"]},"flower-playing-cards":{"a":"Flower Playing Cards","b":"1F3B4","j":["card","flower","game","Japanese","playing","sunset","red"]},"performing-arts":{"a":"Performing Arts","b":"1F3AD","j":["art","mask","performing","theater","theatre","acting","drama"]},"framed-picture":{"a":"Framed Picture","b":"1F5BC","j":["art","frame","museum","painting","picture","photography"]},"artist-palette":{"a":"Artist Palette","b":"1F3A8","j":["art","museum","painting","palette","design","paint","draw","colors"]},"thread":{"a":"Thread","b":"1F9F5","j":["needle","sewing","spool","string"]},"sewing-needle":{"a":"Sewing Needle","b":"1FAA1","j":["embroidery","needle","sewing","stitches","sutures","tailoring"]},"yarn":{"a":"Yarn","b":"1F9F6","j":["ball","crochet","knit"]},"knot":{"a":"Knot","b":"1FAA2","j":["rope","tangled","tie","twine","twist","scout"]},"glasses":{"a":"Glasses","b":"1F453","j":["clothing","eye","eyeglasses","eyewear","fashion","accessories","eyesight","nerdy","dork","geek"]},"sunglasses":{"a":"Sunglasses","b":"1F576","j":["dark","eye","eyewear","glasses","face","cool","accessories"]},"goggles":{"a":"Goggles","b":"1F97D","j":["eye protection","swimming","welding","eyes","protection","safety"]},"lab-coat":{"a":"Lab Coat","b":"1F97C","j":["doctor","experiment","scientist","chemist"]},"safety-vest":{"a":"Safety Vest","b":"1F9BA","j":["emergency","safety","vest","protection"]},"necktie":{"a":"Necktie","b":"1F454","j":["clothing","tie","shirt","suitup","formal","fashion","cloth","business"]},"tshirt":{"a":"T-Shirt","b":"1F455","j":["clothing","shirt","t-shirt","t_shirt","fashion","cloth","casual","tee"]},"jeans":{"a":"Jeans","b":"1F456","j":["clothing","pants","trousers","fashion","shopping"]},"scarf":{"a":"Scarf","b":"1F9E3","j":["neck","winter","clothes"]},"gloves":{"a":"Gloves","b":"1F9E4","j":["hand","hands","winter","clothes"]},"coat":{"a":"Coat","b":"1F9E5","j":["jacket"]},"socks":{"a":"Socks","b":"1F9E6","j":["stocking","stockings","clothes"]},"dress":{"a":"Dress","b":"1F457","j":["clothing","clothes","fashion","shopping"]},"kimono":{"a":"Kimono","b":"1F458","j":["clothing","dress","fashion","women","female","japanese"]},"sari":{"a":"Sari","b":"1F97B","j":["clothing","dress"]},"onepiece-swimsuit":{"a":"One-Piece Swimsuit","b":"1FA71","j":["bathing suit","one-piece swimsuit","one_piece_swimsuit","fashion"]},"briefs":{"a":"Briefs","b":"1FA72","j":["bathing suit","one-piece","swimsuit","underwear","clothing"]},"shorts":{"a":"Shorts","b":"1FA73","j":["bathing suit","pants","underwear","clothing"]},"bikini":{"a":"Bikini","b":"1F459","j":["clothing","swim","swimming","female","woman","girl","fashion","beach","summer"]},"womans-clothes":{"a":"Woman’S Clothes","b":"1F45A","j":["clothing","woman","woman’s clothes","woman_s_clothes","fashion","shopping_bags","female"]},"purse":{"a":"Purse","b":"1F45B","j":["clothing","coin","fashion","accessories","money","sales","shopping"]},"handbag":{"a":"Handbag","b":"1F45C","j":["bag","clothing","purse","fashion","accessory","accessories","shopping"]},"clutch-bag":{"a":"Clutch Bag","b":"1F45D","j":["bag","clothing","pouch","accessories","shopping"]},"shopping-bags":{"a":"Shopping Bags","b":"1F6CD","j":["bag","hotel","shopping","mall","buy","purchase"]},"backpack":{"a":"Backpack","b":"1F392","j":["bag","rucksack","satchel","school","student","education"]},"thong-sandal":{"a":"Thong Sandal","b":"1FA74","j":["beach sandals","sandals","thong sandals","thongs","zōri","footwear","summer"]},"mans-shoe":{"a":"Man’S Shoe","b":"1F45E","j":["clothing","man","man’s shoe","shoe","man_s_shoe","fashion","male"]},"running-shoe":{"a":"Running Shoe","b":"1F45F","j":["athletic","clothing","shoe","sneaker","shoes","sports","sneakers"]},"hiking-boot":{"a":"Hiking Boot","b":"1F97E","j":["backpacking","boot","camping","hiking"]},"flat-shoe":{"a":"Flat Shoe","b":"1F97F","j":["ballet flat","slip-on","slipper","ballet"]},"highheeled-shoe":{"a":"High-Heeled Shoe","b":"1F460","j":["clothing","heel","high-heeled shoe","shoe","woman","high_heeled_shoe","fashion","shoes","female","pumps","stiletto"]},"womans-sandal":{"a":"Woman’S Sandal","b":"1F461","j":["clothing","sandal","shoe","woman","woman’s sandal","woman_s_sandal","shoes","fashion","flip flops"]},"ballet-shoes":{"a":"Ballet Shoes","b":"1FA70","j":["ballet","dance"]},"womans-boot":{"a":"Woman’S Boot","b":"1F462","j":["boot","clothing","shoe","woman","woman’s boot","woman_s_boot","shoes","fashion"]},"crown":{"a":"Crown","b":"1F451","j":["clothing","king","queen","kod","leader","royalty","lord"]},"womans-hat":{"a":"Woman’S Hat","b":"1F452","j":["clothing","hat","woman","woman’s hat","woman_s_hat","fashion","accessories","female","lady","spring"]},"top-hat":{"a":"Top Hat","b":"1F3A9","j":["clothing","hat","top","tophat","magic","gentleman","classy","circus"]},"graduation-cap":{"a":"Graduation Cap","b":"1F393","j":["cap","celebration","clothing","graduation","hat","school","college","degree","university","legal","learn","education"]},"billed-cap":{"a":"Billed Cap","b":"1F9E2","j":["baseball cap","cap","baseball"]},"military-helmet":{"a":"Military Helmet","b":"1FA96","j":["army","helmet","military","soldier","warrior","protection"]},"rescue-workers-helmet":{"a":"Rescue Worker’S Helmet","b":"26D1","j":["aid","cross","face","hat","helmet","rescue worker’s helmet","rescue_worker_s_helmet","construction","build"]},"prayer-beads":{"a":"Prayer Beads","b":"1F4FF","j":["beads","clothing","necklace","prayer","religion","dhikr","religious"]},"lipstick":{"a":"Lipstick","b":"1F484","j":["cosmetics","makeup","female","girl","fashion","woman"]},"ring":{"a":"Ring","b":"1F48D","j":["diamond","wedding","propose","marriage","valentines","fashion","jewelry","gem","engagement"]},"gem-stone":{"a":"Gem Stone","b":"1F48E","j":["diamond","gem","jewel","blue","ruby","jewelry"]},"muted-speaker":{"a":"Muted Speaker","b":"1F507","j":["mute","quiet","silent","speaker","sound","volume","silence"]},"speaker-low-volume":{"a":"Speaker Low Volume","b":"1F508","j":["soft","sound","volume","silence","broadcast"]},"speaker-medium-volume":{"a":"Speaker Medium Volume","b":"1F509","j":["medium","volume","speaker","broadcast"]},"speaker-high-volume":{"a":"Speaker High Volume","b":"1F50A","j":["loud","volume","noise","noisy","speaker","broadcast"]},"loudspeaker":{"a":"Loudspeaker","b":"1F4E2","j":["loud","public address","volume","sound"]},"megaphone":{"a":"Megaphone","b":"1F4E3","j":["cheering","sound","speaker","volume"]},"postal-horn":{"a":"Postal Horn","b":"1F4EF","j":["horn","post","postal","instrument","music"]},"bell":{"a":"Bell","b":"1F514","j":["sound","notification","christmas","xmas","chime"]},"bell-with-slash":{"a":"Bell with Slash","b":"1F515","j":["bell","forbidden","mute","quiet","silent","sound","volume"]},"musical-score":{"a":"Musical Score","b":"1F3BC","j":["music","score","treble","clef","compose"]},"musical-note":{"a":"Musical Note","b":"1F3B5","j":["music","note","score","tone","sound"]},"musical-notes":{"a":"Musical Notes","b":"1F3B6","j":["music","note","notes","score"]},"studio-microphone":{"a":"Studio Microphone","b":"1F399","j":["mic","microphone","music","studio","sing","recording","artist","talkshow"]},"level-slider":{"a":"Level Slider","b":"1F39A","j":["level","music","slider","scale"]},"control-knobs":{"a":"Control Knobs","b":"1F39B","j":["control","knobs","music","dial"]},"microphone":{"a":"Microphone","b":"1F3A4","j":["karaoke","mic","sound","music","PA","sing","talkshow"]},"headphone":{"a":"Headphone","b":"1F3A7","j":["earbud","music","score","gadgets"]},"radio":{"a":"Radio","b":"1F4FB","j":["video","communication","music","podcast","program"]},"saxophone":{"a":"Saxophone","b":"1F3B7","j":["instrument","music","sax","jazz","blues"]},"accordion":{"a":"Accordion","b":"1FA97","j":["concertina","squeeze box","music"]},"guitar":{"a":"Guitar","b":"1F3B8","j":["instrument","music"]},"musical-keyboard":{"a":"Musical Keyboard","b":"1F3B9","j":["instrument","keyboard","music","piano","compose"]},"trumpet":{"a":"Trumpet","b":"1F3BA","j":["instrument","music","brass"]},"violin":{"a":"Violin","b":"1F3BB","j":["instrument","music","orchestra","symphony"]},"banjo":{"a":"Banjo","b":"1FA95","j":["music","stringed","instructment"]},"drum":{"a":"Drum","b":"1F941","j":["drumsticks","music","instrument","snare"]},"long-drum":{"a":"Long Drum","b":"1FA98","j":["beat","conga","drum","rhythm","music"]},"mobile-phone":{"a":"Mobile Phone","b":"1F4F1","j":["cell","mobile","phone","telephone","technology","apple","gadgets","dial"]},"mobile-phone-with-arrow":{"a":"Mobile Phone with Arrow","b":"1F4F2","j":["arrow","cell","mobile","phone","receive","iphone","incoming"]},"telephone":{"a":"Telephone","b":"260E","j":["phone","technology","communication","dial"]},"telephone-receiver":{"a":"Telephone Receiver","b":"1F4DE","j":["phone","receiver","telephone","technology","communication","dial"]},"pager":{"a":"Pager","b":"1F4DF","j":["bbcall","oldschool","90s"]},"fax-machine":{"a":"Fax Machine","b":"1F4E0","j":["fax","communication","technology"]},"battery":{"a":"Battery","b":"1F50B","j":["power","energy","sustain"]},"low-battery":{"a":"⊛ Low Battery","b":"1FAAB","j":["electronic","low energy"]},"electric-plug":{"a":"Electric Plug","b":"1F50C","j":["electric","electricity","plug","charger","power"]},"laptop":{"a":"Laptop","b":"1F4BB","j":["computer","pc","personal","technology","screen","display","monitor"]},"desktop-computer":{"a":"Desktop Computer","b":"1F5A5","j":["computer","desktop","technology","computing","screen"]},"printer":{"a":"Printer","b":"1F5A8","j":["computer","paper","ink"]},"keyboard":{"a":"Keyboard","b":"2328","j":["computer","technology","type","input","text"]},"computer-mouse":{"a":"Computer Mouse","b":"1F5B1","j":["computer","click"]},"trackball":{"a":"Trackball","b":"1F5B2","j":["computer","technology","trackpad"]},"computer-disk":{"a":"Computer Disk","b":"1F4BD","j":["computer","disk","minidisk","optical","technology","record","data","90s"]},"floppy-disk":{"a":"Floppy Disk","b":"1F4BE","j":["computer","disk","floppy","oldschool","technology","save","90s","80s"]},"optical-disk":{"a":"Optical Disk","b":"1F4BF","j":["cd","computer","disk","optical","technology","dvd","disc","90s"]},"dvd":{"a":"Dvd","b":"1F4C0","j":["blu-ray","computer","disk","optical","cd","disc"]},"abacus":{"a":"Abacus","b":"1F9EE","j":["calculation"]},"movie-camera":{"a":"Movie Camera","b":"1F3A5","j":["camera","cinema","movie","film","record"]},"film-frames":{"a":"Film Frames","b":"1F39E","j":["cinema","film","frames","movie"]},"film-projector":{"a":"Film Projector","b":"1F4FD","j":["cinema","film","movie","projector","video","tape","record"]},"clapper-board":{"a":"Clapper Board","b":"1F3AC","j":["clapper","movie","film","record"]},"television":{"a":"Television","b":"1F4FA","j":["tv","video","technology","program","oldschool","show"]},"camera":{"a":"Camera","b":"1F4F7","j":["video","gadgets","photography"]},"camera-with-flash":{"a":"Camera with Flash","b":"1F4F8","j":["camera","flash","video","photography","gadgets"]},"video-camera":{"a":"Video Camera","b":"1F4F9","j":["camera","video","film","record"]},"videocassette":{"a":"Videocassette","b":"1F4FC","j":["tape","vhs","video","record","oldschool","90s","80s"]},"magnifying-glass-tilted-left":{"a":"Magnifying Glass Tilted Left","b":"1F50D","j":["glass","magnifying","search","tool","zoom","find","detective"]},"magnifying-glass-tilted-right":{"a":"Magnifying Glass Tilted Right","b":"1F50E","j":["glass","magnifying","search","tool","zoom","find","detective"]},"candle":{"a":"Candle","b":"1F56F","j":["light","fire","wax"]},"light-bulb":{"a":"Light Bulb","b":"1F4A1","j":["bulb","comic","electric","idea","light","electricity"]},"flashlight":{"a":"Flashlight","b":"1F526","j":["electric","light","tool","torch","dark","camping","sight","night"]},"red-paper-lantern":{"a":"Red Paper Lantern","b":"1F3EE","j":["bar","lantern","light","red","paper","halloween","spooky"]},"diya-lamp":{"a":"Diya Lamp","b":"1FA94","j":["diya","lamp","oil","lighting"]},"notebook-with-decorative-cover":{"a":"Notebook with Decorative Cover","b":"1F4D4","j":["book","cover","decorated","notebook","classroom","notes","record","paper","study"]},"closed-book":{"a":"Closed Book","b":"1F4D5","j":["book","closed","read","library","knowledge","textbook","learn"]},"open-book":{"a":"Open Book","b":"1F4D6","j":["book","open","read","library","knowledge","literature","learn","study"]},"green-book":{"a":"Green Book","b":"1F4D7","j":["book","green","read","library","knowledge","study"]},"blue-book":{"a":"Blue Book","b":"1F4D8","j":["blue","book","read","library","knowledge","learn","study"]},"orange-book":{"a":"Orange Book","b":"1F4D9","j":["book","orange","read","library","knowledge","textbook","study"]},"books":{"a":"Books","b":"1F4DA","j":["book","literature","library","study"]},"notebook":{"a":"Notebook","b":"1F4D3","j":["stationery","record","notes","paper","study"]},"ledger":{"a":"Ledger","b":"1F4D2","j":["notebook","notes","paper"]},"page-with-curl":{"a":"Page with Curl","b":"1F4C3","j":["curl","document","page","documents","office","paper"]},"scroll":{"a":"Scroll","b":"1F4DC","j":["paper","documents","ancient","history"]},"page-facing-up":{"a":"Page Facing Up","b":"1F4C4","j":["document","page","documents","office","paper","information"]},"newspaper":{"a":"Newspaper","b":"1F4F0","j":["news","paper","press","headline"]},"rolledup-newspaper":{"a":"Rolled-Up Newspaper","b":"1F5DE","j":["news","newspaper","paper","rolled","rolled-up newspaper","rolled_up_newspaper","press","headline"]},"bookmark-tabs":{"a":"Bookmark Tabs","b":"1F4D1","j":["bookmark","mark","marker","tabs","favorite","save","order","tidy"]},"bookmark":{"a":"Bookmark","b":"1F516","j":["mark","favorite","label","save"]},"label":{"a":"Label","b":"1F3F7","j":["sale","tag"]},"money-bag":{"a":"Money Bag","b":"1F4B0","j":["bag","dollar","money","moneybag","payment","coins","sale"]},"coin":{"a":"Coin","b":"1FA99","j":["gold","metal","money","silver","treasure","currency"]},"yen-banknote":{"a":"Yen Banknote","b":"1F4B4","j":["banknote","bill","currency","money","note","yen","sales","japanese","dollar"]},"dollar-banknote":{"a":"Dollar Banknote","b":"1F4B5","j":["banknote","bill","currency","dollar","money","note","sales"]},"euro-banknote":{"a":"Euro Banknote","b":"1F4B6","j":["banknote","bill","currency","euro","money","note","sales","dollar"]},"pound-banknote":{"a":"Pound Banknote","b":"1F4B7","j":["banknote","bill","currency","money","note","pound","british","sterling","sales","bills","uk","england"]},"money-with-wings":{"a":"Money with Wings","b":"1F4B8","j":["banknote","bill","fly","money","wings","dollar","bills","payment","sale"]},"credit-card":{"a":"Credit Card","b":"1F4B3","j":["card","credit","money","sales","dollar","bill","payment","shopping"]},"receipt":{"a":"Receipt","b":"1F9FE","j":["accounting","bookkeeping","evidence","proof","expenses"]},"chart-increasing-with-yen":{"a":"Chart Increasing with Yen","b":"1F4B9","j":["chart","graph","growth","money","yen","green-square","presentation","stats"]},"envelope":{"a":"Envelope","b":"2709","j":["email","letter","postal","inbox","communication"]},"email":{"a":"E-Mail","b":"1F4E7","j":["e-mail","letter","mail","e_mail","communication","inbox"]},"incoming-envelope":{"a":"Incoming Envelope","b":"1F4E8","j":["e-mail","email","envelope","incoming","letter","receive","inbox"]},"envelope-with-arrow":{"a":"Envelope with Arrow","b":"1F4E9","j":["arrow","e-mail","email","envelope","outgoing","communication"]},"outbox-tray":{"a":"Outbox Tray","b":"1F4E4","j":["box","letter","mail","outbox","sent","tray","inbox","email"]},"inbox-tray":{"a":"Inbox Tray","b":"1F4E5","j":["box","inbox","letter","mail","receive","tray","email","documents"]},"package":{"a":"Package","b":"1F4E6","j":["box","parcel","mail","gift","cardboard","moving"]},"closed-mailbox-with-raised-flag":{"a":"Closed Mailbox with Raised Flag","b":"1F4EB","j":["closed","mail","mailbox","postbox","email","inbox","communication"]},"closed-mailbox-with-lowered-flag":{"a":"Closed Mailbox with Lowered Flag","b":"1F4EA","j":["closed","lowered","mail","mailbox","postbox","email","communication","inbox"]},"open-mailbox-with-raised-flag":{"a":"Open Mailbox with Raised Flag","b":"1F4EC","j":["mail","mailbox","open","postbox","email","inbox","communication"]},"open-mailbox-with-lowered-flag":{"a":"Open Mailbox with Lowered Flag","b":"1F4ED","j":["lowered","mail","mailbox","open","postbox","email","inbox"]},"postbox":{"a":"Postbox","b":"1F4EE","j":["mail","mailbox","email","letter","envelope"]},"ballot-box-with-ballot":{"a":"Ballot Box with Ballot","b":"1F5F3","j":["ballot","box","election","vote"]},"pencil":{"a":"Pencil","b":"270F","j":["stationery","write","paper","writing","school","study"]},"black-nib":{"a":"Black Nib","b":"2712","j":["nib","pen","stationery","writing","write"]},"fountain-pen":{"a":"Fountain Pen","b":"1F58B","j":["fountain","pen","stationery","writing","write"]},"pen":{"a":"Pen","b":"1F58A","j":["ballpoint","stationery","writing","write"]},"paintbrush":{"a":"Paintbrush","b":"1F58C","j":["painting","drawing","creativity","art"]},"crayon":{"a":"Crayon","b":"1F58D","j":["drawing","creativity"]},"memo":{"a":"Memo","b":"1F4DD","j":["pencil","write","documents","stationery","paper","writing","legal","exam","quiz","test","study","compose"]},"briefcase":{"a":"Briefcase","b":"1F4BC","j":["business","documents","work","law","legal","job","career"]},"file-folder":{"a":"File Folder","b":"1F4C1","j":["file","folder","documents","business","office"]},"open-file-folder":{"a":"Open File Folder","b":"1F4C2","j":["file","folder","open","documents","load"]},"card-index-dividers":{"a":"Card Index Dividers","b":"1F5C2","j":["card","dividers","index","organizing","business","stationery"]},"calendar":{"a":"Calendar","b":"1F4C5","j":["date","schedule"]},"tearoff-calendar":{"a":"Tear-off Calendar","b":"1F4C6","j":["calendar","tear-off calendar","tear_off_calendar","schedule","date","planning"]},"spiral-notepad":{"a":"Spiral Notepad","b":"1F5D2","j":["note","pad","spiral","memo","stationery"]},"spiral-calendar":{"a":"Spiral Calendar","b":"1F5D3","j":["calendar","pad","spiral","date","schedule","planning"]},"card-index":{"a":"Card Index","b":"1F4C7","j":["card","index","rolodex","business","stationery"]},"chart-increasing":{"a":"Chart Increasing","b":"1F4C8","j":["chart","graph","growth","trend","upward","presentation","stats","recovery","business","economics","money","sales","good","success"]},"chart-decreasing":{"a":"Chart Decreasing","b":"1F4C9","j":["chart","down","graph","trend","presentation","stats","recession","business","economics","money","sales","bad","failure"]},"bar-chart":{"a":"Bar Chart","b":"1F4CA","j":["bar","chart","graph","presentation","stats"]},"clipboard":{"a":"Clipboard","b":"1F4CB","j":["stationery","documents"]},"pushpin":{"a":"Pushpin","b":"1F4CC","j":["pin","stationery","mark","here"]},"round-pushpin":{"a":"Round Pushpin","b":"1F4CD","j":["pin","pushpin","stationery","location","map","here"]},"paperclip":{"a":"Paperclip","b":"1F4CE","j":["documents","stationery"]},"linked-paperclips":{"a":"Linked Paperclips","b":"1F587","j":["link","paperclip","documents","stationery"]},"straight-ruler":{"a":"Straight Ruler","b":"1F4CF","j":["ruler","straight edge","stationery","calculate","length","math","school","drawing","architect","sketch"]},"triangular-ruler":{"a":"Triangular Ruler","b":"1F4D0","j":["ruler","set","triangle","stationery","math","architect","sketch"]},"scissors":{"a":"Scissors","b":"2702","j":["cutting","tool","stationery","cut"]},"card-file-box":{"a":"Card File Box","b":"1F5C3","j":["box","card","file","business","stationery"]},"file-cabinet":{"a":"File Cabinet","b":"1F5C4","j":["cabinet","file","filing","organizing"]},"wastebasket":{"a":"Wastebasket","b":"1F5D1","j":["bin","trash","rubbish","garbage","toss"]},"locked":{"a":"Locked","b":"1F512","j":["closed","security","password","padlock"]},"unlocked":{"a":"Unlocked","b":"1F513","j":["lock","open","unlock","privacy","security"]},"locked-with-pen":{"a":"Locked with Pen","b":"1F50F","j":["ink","lock","nib","pen","privacy","security","secret"]},"locked-with-key":{"a":"Locked with Key","b":"1F510","j":["closed","key","lock","secure","security","privacy"]},"key":{"a":"Key","b":"1F511","j":["lock","password","door"]},"old-key":{"a":"Old Key","b":"1F5DD","j":["clue","key","lock","old","door","password"]},"hammer":{"a":"Hammer","b":"1F528","j":["tool","tools","build","create"]},"axe":{"a":"Axe","b":"1FA93","j":["chop","hatchet","split","wood","tool","cut"]},"pick":{"a":"Pick","b":"26CF","j":["mining","tool","tools","dig"]},"hammer-and-pick":{"a":"Hammer and Pick","b":"2692","j":["hammer","pick","tool","tools","build","create"]},"hammer-and-wrench":{"a":"Hammer and Wrench","b":"1F6E0","j":["hammer","spanner","tool","wrench","tools","build","create"]},"dagger":{"a":"Dagger","b":"1F5E1","j":["knife","weapon"]},"crossed-swords":{"a":"Crossed Swords","b":"2694","j":["crossed","swords","weapon"]},"water-pistol":{"a":"Water Pistol","b":"1F52B","j":["gun","handgun","pistol","revolver","tool","water","weapon","violence"]},"boomerang":{"a":"Boomerang","b":"1FA83","j":["australia","rebound","repercussion","weapon"]},"bow-and-arrow":{"a":"Bow and Arrow","b":"1F3F9","j":["archer","arrow","bow","Sagittarius","zodiac","sports"]},"shield":{"a":"Shield","b":"1F6E1","j":["weapon","protection","security"]},"carpentry-saw":{"a":"Carpentry Saw","b":"1FA9A","j":["carpenter","lumber","saw","tool","cut","chop"]},"wrench":{"a":"Wrench","b":"1F527","j":["spanner","tool","tools","diy","ikea","fix","maintainer"]},"screwdriver":{"a":"Screwdriver","b":"1FA9B","j":["screw","tool","tools"]},"nut-and-bolt":{"a":"Nut and Bolt","b":"1F529","j":["bolt","nut","tool","handy","tools","fix"]},"gear":{"a":"Gear","b":"2699","j":["cog","cogwheel","tool"]},"clamp":{"a":"Clamp","b":"1F5DC","j":["compress","tool","vice"]},"balance-scale":{"a":"Balance Scale","b":"2696","j":["balance","justice","Libra","scale","zodiac","law","fairness","weight"]},"white-cane":{"a":"White Cane","b":"1F9AF","j":["accessibility","blind","probing_cane"]},"link":{"a":"Link","b":"1F517","j":["rings","url"]},"chains":{"a":"Chains","b":"26D3","j":["chain","lock","arrest"]},"hook":{"a":"Hook","b":"1FA9D","j":["catch","crook","curve","ensnare","selling point","tools"]},"toolbox":{"a":"Toolbox","b":"1F9F0","j":["chest","mechanic","tool","tools","diy","fix","maintainer"]},"magnet":{"a":"Magnet","b":"1F9F2","j":["attraction","horseshoe","magnetic"]},"ladder":{"a":"Ladder","b":"1FA9C","j":["climb","rung","step","tools"]},"alembic":{"a":"Alembic","b":"2697","j":["chemistry","tool","distilling","science","experiment"]},"test-tube":{"a":"Test Tube","b":"1F9EA","j":["chemist","chemistry","experiment","lab","science"]},"petri-dish":{"a":"Petri Dish","b":"1F9EB","j":["bacteria","biologist","biology","culture","lab"]},"dna":{"a":"Dna","b":"1F9EC","j":["biologist","evolution","gene","genetics","life"]},"microscope":{"a":"Microscope","b":"1F52C","j":["science","tool","laboratory","experiment","zoomin","study"]},"telescope":{"a":"Telescope","b":"1F52D","j":["science","tool","stars","space","zoom","astronomy"]},"satellite-antenna":{"a":"Satellite Antenna","b":"1F4E1","j":["antenna","dish","satellite","communication","future","radio","space"]},"syringe":{"a":"Syringe","b":"1F489","j":["medicine","needle","shot","sick","health","hospital","drugs","blood","doctor","nurse"]},"drop-of-blood":{"a":"Drop of Blood","b":"1FA78","j":["bleed","blood donation","injury","medicine","menstruation","period","hurt","harm","wound"]},"pill":{"a":"Pill","b":"1F48A","j":["doctor","medicine","sick","health","pharmacy","drug"]},"adhesive-bandage":{"a":"Adhesive Bandage","b":"1FA79","j":["bandage","heal"]},"crutch":{"a":"⊛ Crutch","b":"1FA7C","j":["cane","disability","hurt","mobility aid","stick"]},"stethoscope":{"a":"Stethoscope","b":"1FA7A","j":["doctor","heart","medicine","health"]},"xray":{"a":"⊛ X-Ray","b":"1FA7B","j":["bones","doctor","medical","skeleton"]},"door":{"a":"Door","b":"1F6AA","j":["house","entry","exit"]},"elevator":{"a":"Elevator","b":"1F6D7","j":["accessibility","hoist","lift"]},"mirror":{"a":"Mirror","b":"1FA9E","j":["reflection","reflector","speculum"]},"window":{"a":"Window","b":"1FA9F","j":["frame","fresh air","opening","transparent","view","scenery"]},"bed":{"a":"Bed","b":"1F6CF","j":["hotel","sleep","rest"]},"couch-and-lamp":{"a":"Couch and Lamp","b":"1F6CB","j":["couch","hotel","lamp","read","chill"]},"chair":{"a":"Chair","b":"1FA91","j":["seat","sit","furniture"]},"toilet":{"a":"Toilet","b":"1F6BD","j":["restroom","wc","washroom","bathroom","potty"]},"plunger":{"a":"Plunger","b":"1FAA0","j":["force cup","plumber","suction","toilet"]},"shower":{"a":"Shower","b":"1F6BF","j":["water","clean","bathroom"]},"bathtub":{"a":"Bathtub","b":"1F6C1","j":["bath","clean","shower","bathroom"]},"mouse-trap":{"a":"Mouse Trap","b":"1FAA4","j":["bait","mousetrap","snare","trap","cheese"]},"razor":{"a":"Razor","b":"1FA92","j":["sharp","shave","cut"]},"lotion-bottle":{"a":"Lotion Bottle","b":"1F9F4","j":["lotion","moisturizer","shampoo","sunscreen"]},"safety-pin":{"a":"Safety Pin","b":"1F9F7","j":["diaper","punk rock"]},"broom":{"a":"Broom","b":"1F9F9","j":["cleaning","sweeping","witch"]},"basket":{"a":"Basket","b":"1F9FA","j":["farming","laundry","picnic"]},"roll-of-paper":{"a":"Roll of Paper","b":"1F9FB","j":["paper towels","toilet paper","roll"]},"bucket":{"a":"Bucket","b":"1FAA3","j":["cask","pail","vat","water","container"]},"soap":{"a":"Soap","b":"1F9FC","j":["bar","bathing","cleaning","lather","soapdish"]},"bubbles":{"a":"⊛ Bubbles","b":"1FAE7","j":["burp","clean","soap","underwater"]},"toothbrush":{"a":"Toothbrush","b":"1FAA5","j":["bathroom","brush","clean","dental","hygiene","teeth"]},"sponge":{"a":"Sponge","b":"1F9FD","j":["absorbing","cleaning","porous"]},"fire-extinguisher":{"a":"Fire Extinguisher","b":"1F9EF","j":["extinguish","fire","quench"]},"shopping-cart":{"a":"Shopping Cart","b":"1F6D2","j":["cart","shopping","trolley"]},"cigarette":{"a":"Cigarette","b":"1F6AC","j":["smoking","kills","tobacco","joint","smoke"]},"coffin":{"a":"Coffin","b":"26B0","j":["death","vampire","dead","die","rip","graveyard","cemetery","casket","funeral","box"]},"headstone":{"a":"Headstone","b":"1FAA6","j":["cemetery","grave","graveyard","tombstone","death","rip"]},"funeral-urn":{"a":"Funeral Urn","b":"26B1","j":["ashes","death","funeral","urn","dead","die","rip"]},"moai":{"a":"Moai","b":"1F5FF","j":["face","moyai","statue","rock","easter island"]},"placard":{"a":"Placard","b":"1FAA7","j":["demonstration","picket","protest","sign","announcement"]},"identification-card":{"a":"⊛ Identification Card","b":"1FAAA","j":["credentials","ID","license","security"]},"atm-sign":{"a":"Atm Sign","b":"1F3E7","j":["atm","ATM sign","automated","bank","teller","money","sales","cash","blue-square","payment"]},"litter-in-bin-sign":{"a":"Litter in Bin Sign","b":"1F6AE","j":["litter","litter bin","blue-square","sign","human","info"]},"potable-water":{"a":"Potable Water","b":"1F6B0","j":["drinking","potable","water","blue-square","liquid","restroom","cleaning","faucet"]},"wheelchair-symbol":{"a":"Wheelchair Symbol","b":"267F","j":["access","blue-square","disabled","accessibility"]},"mens-room":{"a":"Men’S Room","b":"1F6B9","j":["lavatory","man","men’s room","restroom","wc","men_s_room","toilet","blue-square","gender","male"]},"womens-room":{"a":"Women’S Room","b":"1F6BA","j":["lavatory","restroom","wc","woman","women’s room","women_s_room","purple-square","female","toilet","loo","gender"]},"restroom":{"a":"Restroom","b":"1F6BB","j":["lavatory","WC","blue-square","toilet","refresh","wc","gender"]},"baby-symbol":{"a":"Baby Symbol","b":"1F6BC","j":["baby","changing","orange-square","child"]},"water-closet":{"a":"Water Closet","b":"1F6BE","j":["closet","lavatory","restroom","water","wc","toilet","blue-square"]},"passport-control":{"a":"Passport Control","b":"1F6C2","j":["control","passport","custom","blue-square"]},"customs":{"a":"Customs","b":"1F6C3","j":["passport","border","blue-square"]},"baggage-claim":{"a":"Baggage Claim","b":"1F6C4","j":["baggage","claim","blue-square","airport","transport"]},"left-luggage":{"a":"Left Luggage","b":"1F6C5","j":["baggage","locker","luggage","blue-square","travel"]},"warning":{"a":"Warning","b":"26A0","j":["exclamation","wip","alert","error","problem","issue"]},"children-crossing":{"a":"Children Crossing","b":"1F6B8","j":["child","crossing","pedestrian","traffic","school","warning","danger","sign","driving","yellow-diamond"]},"no-entry":{"a":"No Entry","b":"26D4","j":["entry","forbidden","no","not","prohibited","traffic","limit","security","privacy","bad","denied","stop","circle"]},"prohibited":{"a":"Prohibited","b":"1F6AB","j":["entry","forbidden","no","not","forbid","stop","limit","denied","disallow","circle"]},"no-bicycles":{"a":"No Bicycles","b":"1F6B3","j":["bicycle","bike","forbidden","no","prohibited","cyclist","circle"]},"no-smoking":{"a":"No Smoking","b":"1F6AD","j":["forbidden","no","not","prohibited","smoking","cigarette","blue-square","smell","smoke"]},"no-littering":{"a":"No Littering","b":"1F6AF","j":["forbidden","litter","no","not","prohibited","trash","bin","garbage","circle"]},"nonpotable-water":{"a":"Non-Potable Water","b":"1F6B1","j":["non-drinking","non-potable","water","non_potable_water","drink","faucet","tap","circle"]},"no-pedestrians":{"a":"No Pedestrians","b":"1F6B7","j":["forbidden","no","not","pedestrian","prohibited","rules","crossing","walking","circle"]},"no-mobile-phones":{"a":"No Mobile Phones","b":"1F4F5","j":["cell","forbidden","mobile","no","phone","iphone","mute","circle"]},"no-one-under-eighteen":{"a":"No One Under Eighteen","b":"1F51E","j":["18","age restriction","eighteen","prohibited","underage","drink","pub","night","minor","circle"]},"radioactive":{"a":"Radioactive","b":"2622","j":["sign","nuclear","danger"]},"biohazard":{"a":"Biohazard","b":"2623","j":["sign","danger"]},"up-arrow":{"a":"Up Arrow","b":"2B06","j":["arrow","cardinal","direction","north","blue-square","continue","top"]},"upright-arrow":{"a":"Up-Right Arrow","b":"2197","j":["arrow","direction","intercardinal","northeast","up-right arrow","up_right_arrow","blue-square","point","diagonal"]},"right-arrow":{"a":"Right Arrow","b":"27A1","j":["arrow","cardinal","direction","east","blue-square","next"]},"downright-arrow":{"a":"Down-Right Arrow","b":"2198","j":["arrow","direction","down-right arrow","intercardinal","southeast","down_right_arrow","blue-square","diagonal"]},"down-arrow":{"a":"Down Arrow","b":"2B07","j":["arrow","cardinal","direction","down","south","blue-square","bottom"]},"downleft-arrow":{"a":"Down-Left Arrow","b":"2199","j":["arrow","direction","down-left arrow","intercardinal","southwest","down_left_arrow","blue-square","diagonal"]},"left-arrow":{"a":"Left Arrow","b":"2B05","j":["arrow","cardinal","direction","west","blue-square","previous","back"]},"upleft-arrow":{"a":"Up-Left Arrow","b":"2196","j":["arrow","direction","intercardinal","northwest","up-left arrow","up_left_arrow","blue-square","point","diagonal"]},"updown-arrow":{"a":"Up-Down Arrow","b":"2195","j":["arrow","up-down arrow","up_down_arrow","blue-square","direction","way","vertical"]},"leftright-arrow":{"a":"Left-Right Arrow","b":"2194","j":["arrow","left-right arrow","left_right_arrow","shape","direction","horizontal","sideways"]},"right-arrow-curving-left":{"a":"Right Arrow Curving Left","b":"21A9","j":["arrow","back","return","blue-square","undo","enter"]},"left-arrow-curving-right":{"a":"Left Arrow Curving Right","b":"21AA","j":["arrow","blue-square","return","rotate","direction"]},"right-arrow-curving-up":{"a":"Right Arrow Curving Up","b":"2934","j":["arrow","blue-square","direction","top"]},"right-arrow-curving-down":{"a":"Right Arrow Curving Down","b":"2935","j":["arrow","down","blue-square","direction","bottom"]},"clockwise-vertical-arrows":{"a":"Clockwise Vertical Arrows","b":"1F503","j":["arrow","clockwise","reload","sync","cycle","round","repeat"]},"counterclockwise-arrows-button":{"a":"Counterclockwise Arrows Button","b":"1F504","j":["anticlockwise","arrow","counterclockwise","withershins","blue-square","sync","cycle"]},"back-arrow":{"a":"Back Arrow","b":"1F519","j":["arrow","back","BACK arrow","words","return"]},"end-arrow":{"a":"End Arrow","b":"1F51A","j":["arrow","end","END arrow","words"]},"on-arrow":{"a":"On! Arrow","b":"1F51B","j":["arrow","mark","on","ON! arrow","words"]},"soon-arrow":{"a":"Soon Arrow","b":"1F51C","j":["arrow","soon","SOON arrow","words"]},"top-arrow":{"a":"Top Arrow","b":"1F51D","j":["arrow","top","TOP arrow","up","words","blue-square"]},"place-of-worship":{"a":"Place of Worship","b":"1F6D0","j":["religion","worship","church","temple","prayer"]},"atom-symbol":{"a":"Atom Symbol","b":"269B","j":["atheist","atom","science","physics","chemistry"]},"om":{"a":"Om","b":"1F549","j":["Hindu","religion","hinduism","buddhism","sikhism","jainism"]},"star-of-david":{"a":"Star of David","b":"2721","j":["David","Jew","Jewish","religion","star","star of David","judaism"]},"wheel-of-dharma":{"a":"Wheel of Dharma","b":"2638","j":["Buddhist","dharma","religion","wheel","hinduism","buddhism","sikhism","jainism"]},"yin-yang":{"a":"Yin Yang","b":"262F","j":["religion","tao","taoist","yang","yin","balance"]},"latin-cross":{"a":"Latin Cross","b":"271D","j":["Christian","cross","religion","christianity"]},"orthodox-cross":{"a":"Orthodox Cross","b":"2626","j":["Christian","cross","religion","suppedaneum"]},"star-and-crescent":{"a":"Star and Crescent","b":"262A","j":["islam","Muslim","religion"]},"peace-symbol":{"a":"Peace Symbol","b":"262E","j":["peace","hippie"]},"menorah":{"a":"Menorah","b":"1F54E","j":["candelabrum","candlestick","religion","hanukkah","candles","jewish"]},"dotted-sixpointed-star":{"a":"Dotted Six-Pointed Star","b":"1F52F","j":["dotted six-pointed star","fortune","star","dotted_six_pointed_star","purple-square","religion","jewish","hexagram"]},"aries":{"a":"Aries","b":"2648","j":["ram","zodiac","sign","purple-square","astrology"]},"taurus":{"a":"Taurus","b":"2649","j":["bull","ox","zodiac","purple-square","sign","astrology"]},"gemini":{"a":"Gemini","b":"264A","j":["twins","zodiac","sign","purple-square","astrology"]},"cancer":{"a":"Cancer","b":"264B","j":["crab","zodiac","sign","purple-square","astrology"]},"leo":{"a":"Leo","b":"264C","j":["lion","zodiac","sign","purple-square","astrology"]},"virgo":{"a":"Virgo","b":"264D","j":["zodiac","sign","purple-square","astrology"]},"libra":{"a":"Libra","b":"264E","j":["balance","justice","scales","zodiac","sign","purple-square","astrology"]},"scorpio":{"a":"Scorpio","b":"264F","j":["scorpion","scorpius","zodiac","sign","purple-square","astrology"]},"sagittarius":{"a":"Sagittarius","b":"2650","j":["archer","zodiac","sign","purple-square","astrology"]},"capricorn":{"a":"Capricorn","b":"2651","j":["goat","zodiac","sign","purple-square","astrology"]},"aquarius":{"a":"Aquarius","b":"2652","j":["bearer","water","zodiac","sign","purple-square","astrology"]},"pisces":{"a":"Pisces","b":"2653","j":["fish","zodiac","purple-square","sign","astrology"]},"ophiuchus":{"a":"Ophiuchus","b":"26CE","j":["bearer","serpent","snake","zodiac","sign","purple-square","constellation","astrology"]},"shuffle-tracks-button":{"a":"Shuffle Tracks Button","b":"1F500","j":["arrow","crossed","blue-square","shuffle","music","random"]},"repeat-button":{"a":"Repeat Button","b":"1F501","j":["arrow","clockwise","repeat","loop","record"]},"repeat-single-button":{"a":"Repeat Single Button","b":"1F502","j":["arrow","clockwise","once","blue-square","loop"]},"play-button":{"a":"Play Button","b":"25B6","j":["arrow","play","right","triangle","blue-square","direction"]},"fastforward-button":{"a":"Fast-Forward Button","b":"23E9","j":["arrow","double","fast","fast-forward button","forward","fast_forward_button","blue-square","play","speed","continue"]},"next-track-button":{"a":"Next Track Button","b":"23ED","j":["arrow","next scene","next track","triangle","forward","next","blue-square"]},"play-or-pause-button":{"a":"Play or Pause Button","b":"23EF","j":["arrow","pause","play","right","triangle","blue-square"]},"reverse-button":{"a":"Reverse Button","b":"25C0","j":["arrow","left","reverse","triangle","blue-square","direction"]},"fast-reverse-button":{"a":"Fast Reverse Button","b":"23EA","j":["arrow","double","rewind","play","blue-square"]},"last-track-button":{"a":"Last Track Button","b":"23EE","j":["arrow","previous scene","previous track","triangle","backward"]},"upwards-button":{"a":"Upwards Button","b":"1F53C","j":["arrow","button","red","blue-square","triangle","direction","point","forward","top"]},"fast-up-button":{"a":"Fast Up Button","b":"23EB","j":["arrow","double","blue-square","direction","top"]},"downwards-button":{"a":"Downwards Button","b":"1F53D","j":["arrow","button","down","red","blue-square","direction","bottom"]},"fast-down-button":{"a":"Fast Down Button","b":"23EC","j":["arrow","double","down","blue-square","direction","bottom"]},"pause-button":{"a":"Pause Button","b":"23F8","j":["bar","double","pause","vertical","blue-square"]},"stop-button":{"a":"Stop Button","b":"23F9","j":["square","stop","blue-square"]},"record-button":{"a":"Record Button","b":"23FA","j":["circle","record","blue-square"]},"eject-button":{"a":"Eject Button","b":"23CF","j":["eject","blue-square"]},"cinema":{"a":"Cinema","b":"1F3A6","j":["camera","film","movie","blue-square","record","curtain","stage","theater"]},"dim-button":{"a":"Dim Button","b":"1F505","j":["brightness","dim","low","sun","afternoon","warm","summer"]},"bright-button":{"a":"Bright Button","b":"1F506","j":["bright","brightness","sun","light"]},"antenna-bars":{"a":"Antenna Bars","b":"1F4F6","j":["antenna","bar","cell","mobile","phone","blue-square","reception","internet","connection","wifi","bluetooth","bars"]},"vibration-mode":{"a":"Vibration Mode","b":"1F4F3","j":["cell","mobile","mode","phone","telephone","vibration","orange-square"]},"mobile-phone-off":{"a":"Mobile Phone off","b":"1F4F4","j":["cell","mobile","off","phone","telephone","mute","orange-square","silence","quiet"]},"female-sign":{"a":"Female Sign","b":"2640","j":["woman","women","lady","girl"]},"male-sign":{"a":"Male Sign","b":"2642","j":["man","boy","men"]},"transgender-symbol":{"a":"Transgender Symbol","b":"26A7","j":["transgender","lgbtq"]},"multiply":{"a":"Multiply","b":"2716","j":["×","cancel","multiplication","sign","x","multiplication_sign","math","calculation"]},"plus":{"a":"Plus","b":"2795","j":["+","math","sign","plus_sign","calculation","addition","more","increase"]},"minus":{"a":"Minus","b":"2796","j":["-","−","math","sign","minus_sign","calculation","subtract","less"]},"divide":{"a":"Divide","b":"2797","j":["÷","division","math","sign","division_sign","calculation"]},"heavy-equals-sign":{"a":"⊛ Heavy Equals Sign","b":"1F7F0","j":["equality","math"]},"infinity":{"a":"Infinity","b":"267E","j":["forever","unbounded","universal"]},"double-exclamation-mark":{"a":"Double Exclamation Mark","b":"203C","j":["!","!!","bangbang","exclamation","mark","surprise"]},"exclamation-question-mark":{"a":"Exclamation Question Mark","b":"2049","j":["!","!?","?","exclamation","interrobang","mark","punctuation","question","wat","surprise"]},"red-question-mark":{"a":"Red Question Mark","b":"2753","j":["?","mark","punctuation","question","question_mark","doubt","confused"]},"white-question-mark":{"a":"White Question Mark","b":"2754","j":["?","mark","outlined","punctuation","question","doubts","gray","huh","confused"]},"white-exclamation-mark":{"a":"White Exclamation Mark","b":"2755","j":["!","exclamation","mark","outlined","punctuation","surprise","gray","wow","warning"]},"red-exclamation-mark":{"a":"Red Exclamation Mark","b":"2757","j":["!","exclamation","mark","punctuation","exclamation_mark","heavy_exclamation_mark","danger","surprise","wow","warning"]},"wavy-dash":{"a":"Wavy Dash","b":"3030","j":["dash","punctuation","wavy","draw","line","moustache","mustache","squiggle","scribble"]},"currency-exchange":{"a":"Currency Exchange","b":"1F4B1","j":["bank","currency","exchange","money","sales","dollar","travel"]},"heavy-dollar-sign":{"a":"Heavy Dollar Sign","b":"1F4B2","j":["currency","dollar","money","sales","payment","buck"]},"medical-symbol":{"a":"Medical Symbol","b":"2695","j":["aesculapius","medicine","staff","health","hospital"]},"recycling-symbol":{"a":"Recycling Symbol","b":"267B","j":["recycle","arrow","environment","garbage","trash"]},"fleurdelis":{"a":"Fleur-De-Lis","b":"269C","j":["fleur-de-lis","fleur_de_lis","decorative","scout"]},"trident-emblem":{"a":"Trident Emblem","b":"1F531","j":["anchor","emblem","ship","tool","trident","weapon","spear"]},"name-badge":{"a":"Name Badge","b":"1F4DB","j":["badge","name","fire","forbid"]},"japanese-symbol-for-beginner":{"a":"Japanese Symbol for Beginner","b":"1F530","j":["beginner","chevron","Japanese","Japanese symbol for beginner","leaf","badge","shield"]},"hollow-red-circle":{"a":"Hollow Red Circle","b":"2B55","j":["circle","large","o","red","round"]},"check-mark-button":{"a":"Check Mark Button","b":"2705","j":["✓","button","check","mark","green-square","ok","agree","vote","election","answer","tick"]},"check-box-with-check":{"a":"Check Box with Check","b":"2611","j":["✓","box","check","ok","agree","confirm","black-square","vote","election","yes","tick"]},"check-mark":{"a":"Check Mark","b":"2714","j":["✓","check","mark","ok","nike","answer","yes","tick"]},"cross-mark":{"a":"Cross Mark","b":"274C","j":["×","cancel","cross","mark","multiplication","multiply","x","no","delete","remove","red"]},"cross-mark-button":{"a":"Cross Mark Button","b":"274E","j":["×","mark","square","x","green-square","no","deny"]},"curly-loop":{"a":"Curly Loop","b":"27B0","j":["curl","loop","scribble","draw","shape","squiggle"]},"double-curly-loop":{"a":"Double Curly Loop","b":"27BF","j":["curl","double","loop","tape","cassette"]},"part-alternation-mark":{"a":"Part Alternation Mark","b":"303D","j":["mark","part","graph","presentation","stats","business","economics","bad"]},"eightspoked-asterisk":{"a":"Eight-Spoked Asterisk","b":"2733","j":["*","asterisk","eight-spoked asterisk","eight_spoked_asterisk","star","sparkle","green-square"]},"eightpointed-star":{"a":"Eight-Pointed Star","b":"2734","j":["*","eight-pointed star","star","eight_pointed_star","orange-square","shape","polygon"]},"sparkle":{"a":"Sparkle","b":"2747","j":["*","stars","green-square","awesome","good","fireworks"]},"copyright":{"a":"Copyright","b":"00A9","j":["c","ip","license","circle","law","legal"]},"registered":{"a":"Registered","b":"00AE","j":["r","alphabet","circle"]},"trade-mark":{"a":"Trade Mark","b":"2122","j":["mark","tm","trademark","brand","law","legal"]},"keycap":{"a":"Keycap: *","b":"002A-FE0F-20E3","j":["keycap_","star"]},"keycap-0":{"a":"Keycap: 0","b":"0030-FE0F-20E3","j":["keycap","0","numbers","blue-square","null"]},"keycap-1":{"a":"Keycap: 1","b":"0031-FE0F-20E3","j":["keycap","blue-square","numbers","1"]},"keycap-2":{"a":"Keycap: 2","b":"0032-FE0F-20E3","j":["keycap","numbers","2","prime","blue-square"]},"keycap-3":{"a":"Keycap: 3","b":"0033-FE0F-20E3","j":["keycap","3","numbers","prime","blue-square"]},"keycap-4":{"a":"Keycap: 4","b":"0034-FE0F-20E3","j":["keycap","4","numbers","blue-square"]},"keycap-5":{"a":"Keycap: 5","b":"0035-FE0F-20E3","j":["keycap","5","numbers","blue-square","prime"]},"keycap-6":{"a":"Keycap: 6","b":"0036-FE0F-20E3","j":["keycap","6","numbers","blue-square"]},"keycap-7":{"a":"Keycap: 7","b":"0037-FE0F-20E3","j":["keycap","7","numbers","blue-square","prime"]},"keycap-8":{"a":"Keycap: 8","b":"0038-FE0F-20E3","j":["keycap","8","blue-square","numbers"]},"keycap-9":{"a":"Keycap: 9","b":"0039-FE0F-20E3","j":["keycap","blue-square","numbers","9"]},"keycap-10":{"a":"Keycap: 10","b":"1F51F","j":["keycap","numbers","10","blue-square"]},"input-latin-uppercase":{"a":"Input Latin Uppercase","b":"1F520","j":["ABCD","input","latin","letters","uppercase","alphabet","words","blue-square"]},"input-latin-lowercase":{"a":"Input Latin Lowercase","b":"1F521","j":["abcd","input","latin","letters","lowercase","blue-square","alphabet"]},"input-numbers":{"a":"Input Numbers","b":"1F522","j":["1234","input","numbers","blue-square"]},"input-symbols":{"a":"Input Symbols","b":"1F523","j":["〒♪&%","input","blue-square","music","note","ampersand","percent","glyphs","characters"]},"input-latin-letters":{"a":"Input Latin Letters","b":"1F524","j":["abc","alphabet","input","latin","letters","blue-square"]},"a-button-blood-type":{"a":"A Button (Blood Type)","b":"1F170","j":["a","A button (blood type)","blood type","a_button","red-square","alphabet","letter"]},"ab-button-blood-type":{"a":"Ab Button (Blood Type)","b":"1F18E","j":["ab","AB button (blood type)","blood type","ab_button","red-square","alphabet"]},"b-button-blood-type":{"a":"B Button (Blood Type)","b":"1F171","j":["b","B button (blood type)","blood type","b_button","red-square","alphabet","letter"]},"cl-button":{"a":"Cl Button","b":"1F191","j":["cl","CL button","alphabet","words","red-square"]},"cool-button":{"a":"Cool Button","b":"1F192","j":["cool","COOL button","words","blue-square"]},"free-button":{"a":"Free Button","b":"1F193","j":["free","FREE button","blue-square","words"]},"information":{"a":"Information","b":"2139","j":["i","blue-square","alphabet","letter"]},"id-button":{"a":"Id Button","b":"1F194","j":["id","ID button","identity","purple-square","words"]},"circled-m":{"a":"Circled M","b":"24C2","j":["circle","circled M","m","alphabet","blue-circle","letter"]},"new-button":{"a":"New Button","b":"1F195","j":["new","NEW button","blue-square","words","start"]},"ng-button":{"a":"Ng Button","b":"1F196","j":["ng","NG button","blue-square","words","shape","icon"]},"o-button-blood-type":{"a":"O Button (Blood Type)","b":"1F17E","j":["blood type","o","O button (blood type)","o_button","alphabet","red-square","letter"]},"ok-button":{"a":"Ok Button","b":"1F197","j":["OK","OK button","good","agree","yes","blue-square"]},"p-button":{"a":"P Button","b":"1F17F","j":["P button","parking","cars","blue-square","alphabet","letter"]},"sos-button":{"a":"Sos Button","b":"1F198","j":["help","sos","SOS button","red-square","words","emergency","911"]},"up-button":{"a":"Up! Button","b":"1F199","j":["mark","up","UP! button","blue-square","above","high"]},"vs-button":{"a":"Vs Button","b":"1F19A","j":["versus","vs","VS button","words","orange-square"]},"japanese-here-button":{"a":"Japanese “Here” Button","b":"1F201","j":["“here”","Japanese","Japanese “here” button","katakana","ココ","blue-square","here","japanese","destination"]},"japanese-service-charge-button":{"a":"Japanese “Service Charge” Button","b":"1F202","j":["“service charge”","Japanese","Japanese “service charge” button","katakana","サ","japanese","blue-square"]},"japanese-monthly-amount-button":{"a":"Japanese “Monthly Amount” Button","b":"1F237","j":["“monthly amount”","ideograph","Japanese","Japanese “monthly amount” button","月","chinese","month","moon","japanese","orange-square","kanji"]},"japanese-not-free-of-charge-button":{"a":"Japanese “Not Free of Charge” Button","b":"1F236","j":["“not free of charge”","ideograph","Japanese","Japanese “not free of charge” button","有","orange-square","chinese","have","kanji"]},"japanese-reserved-button":{"a":"Japanese “Reserved” Button","b":"1F22F","j":["“reserved”","ideograph","Japanese","Japanese “reserved” button","指","chinese","point","green-square","kanji"]},"japanese-bargain-button":{"a":"Japanese “Bargain” Button","b":"1F250","j":["“bargain”","ideograph","Japanese","Japanese “bargain” button","得","chinese","kanji","obtain","get","circle"]},"japanese-discount-button":{"a":"Japanese “Discount” Button","b":"1F239","j":["“discount”","ideograph","Japanese","Japanese “discount” button","割","cut","divide","chinese","kanji","pink-square"]},"japanese-free-of-charge-button":{"a":"Japanese “Free of Charge” Button","b":"1F21A","j":["“free of charge”","ideograph","Japanese","Japanese “free of charge” button","無","nothing","chinese","kanji","japanese","orange-square"]},"japanese-prohibited-button":{"a":"Japanese “Prohibited” Button","b":"1F232","j":["“prohibited”","ideograph","Japanese","Japanese “prohibited” button","禁","kanji","japanese","chinese","forbidden","limit","restricted","red-square"]},"japanese-acceptable-button":{"a":"Japanese “Acceptable” Button","b":"1F251","j":["“acceptable”","ideograph","Japanese","Japanese “acceptable” button","可","ok","good","chinese","kanji","agree","yes","orange-circle"]},"japanese-application-button":{"a":"Japanese “Application” Button","b":"1F238","j":["“application”","ideograph","Japanese","Japanese “application” button","申","chinese","japanese","kanji","orange-square"]},"japanese-passing-grade-button":{"a":"Japanese “Passing Grade” Button","b":"1F234","j":["“passing grade”","ideograph","Japanese","Japanese “passing grade” button","合","japanese","chinese","join","kanji","red-square"]},"japanese-vacancy-button":{"a":"Japanese “Vacancy” Button","b":"1F233","j":["“vacancy”","ideograph","Japanese","Japanese “vacancy” button","空","kanji","japanese","chinese","empty","sky","blue-square"]},"japanese-congratulations-button":{"a":"Japanese “Congratulations” Button","b":"3297","j":["“congratulations”","ideograph","Japanese","Japanese “congratulations” button","祝","chinese","kanji","japanese","red-circle"]},"japanese-secret-button":{"a":"Japanese “Secret” Button","b":"3299","j":["“secret”","ideograph","Japanese","Japanese “secret” button","秘","privacy","chinese","sshh","kanji","red-circle"]},"japanese-open-for-business-button":{"a":"Japanese “Open for Business” Button","b":"1F23A","j":["“open for business”","ideograph","Japanese","Japanese “open for business” button","営","japanese","opening hours","orange-square"]},"japanese-no-vacancy-button":{"a":"Japanese “No Vacancy” Button","b":"1F235","j":["“no vacancy”","ideograph","Japanese","Japanese “no vacancy” button","満","full","chinese","japanese","red-square","kanji"]},"red-circle":{"a":"Red Circle","b":"1F534","j":["circle","geometric","red","shape","error","danger"]},"orange-circle":{"a":"Orange Circle","b":"1F7E0","j":["circle","orange","round"]},"yellow-circle":{"a":"Yellow Circle","b":"1F7E1","j":["circle","yellow","round"]},"green-circle":{"a":"Green Circle","b":"1F7E2","j":["circle","green","round"]},"blue-circle":{"a":"Blue Circle","b":"1F535","j":["blue","circle","geometric","shape","icon","button"]},"purple-circle":{"a":"Purple Circle","b":"1F7E3","j":["circle","purple","round"]},"brown-circle":{"a":"Brown Circle","b":"1F7E4","j":["brown","circle","round"]},"black-circle":{"a":"Black Circle","b":"26AB","j":["circle","geometric","shape","button","round"]},"white-circle":{"a":"White Circle","b":"26AA","j":["circle","geometric","shape","round"]},"red-square":{"a":"Red Square","b":"1F7E5","j":["red","square"]},"orange-square":{"a":"Orange Square","b":"1F7E7","j":["orange","square"]},"yellow-square":{"a":"Yellow Square","b":"1F7E8","j":["square","yellow"]},"green-square":{"a":"Green Square","b":"1F7E9","j":["green","square"]},"blue-square":{"a":"Blue Square","b":"1F7E6","j":["blue","square"]},"purple-square":{"a":"Purple Square","b":"1F7EA","j":["purple","square"]},"brown-square":{"a":"Brown Square","b":"1F7EB","j":["brown","square"]},"black-large-square":{"a":"Black Large Square","b":"2B1B","j":["geometric","square","shape","icon","button"]},"white-large-square":{"a":"White Large Square","b":"2B1C","j":["geometric","square","shape","icon","stone","button"]},"black-medium-square":{"a":"Black Medium Square","b":"25FC","j":["geometric","square","shape","button","icon"]},"white-medium-square":{"a":"White Medium Square","b":"25FB","j":["geometric","square","shape","stone","icon"]},"black-mediumsmall-square":{"a":"Black Medium-Small Square","b":"25FE","j":["black medium-small square","geometric","square","black_medium_small_square","icon","shape","button"]},"white-mediumsmall-square":{"a":"White Medium-Small Square","b":"25FD","j":["geometric","square","white medium-small square","white_medium_small_square","shape","stone","icon","button"]},"black-small-square":{"a":"Black Small Square","b":"25AA","j":["geometric","square","shape","icon"]},"white-small-square":{"a":"White Small Square","b":"25AB","j":["geometric","square","shape","icon"]},"large-orange-diamond":{"a":"Large Orange Diamond","b":"1F536","j":["diamond","geometric","orange","shape","jewel","gem"]},"large-blue-diamond":{"a":"Large Blue Diamond","b":"1F537","j":["blue","diamond","geometric","shape","jewel","gem"]},"small-orange-diamond":{"a":"Small Orange Diamond","b":"1F538","j":["diamond","geometric","orange","shape","jewel","gem"]},"small-blue-diamond":{"a":"Small Blue Diamond","b":"1F539","j":["blue","diamond","geometric","shape","jewel","gem"]},"red-triangle-pointed-up":{"a":"Red Triangle Pointed Up","b":"1F53A","j":["geometric","red","shape","direction","up","top"]},"red-triangle-pointed-down":{"a":"Red Triangle Pointed Down","b":"1F53B","j":["down","geometric","red","shape","direction","bottom"]},"diamond-with-a-dot":{"a":"Diamond with a Dot","b":"1F4A0","j":["comic","diamond","geometric","inside","jewel","blue","gem","crystal","fancy"]},"radio-button":{"a":"Radio Button","b":"1F518","j":["button","geometric","radio","input","old","music","circle"]},"white-square-button":{"a":"White Square Button","b":"1F533","j":["button","geometric","outlined","square","shape","input"]},"black-square-button":{"a":"Black Square Button","b":"1F532","j":["button","geometric","square","shape","input","frame"]},"chequered-flag":{"a":"Chequered Flag","b":"1F3C1","j":["checkered","chequered","racing","contest","finishline","race","gokart"]},"triangular-flag":{"a":"Triangular Flag","b":"1F6A9","j":["post","mark","milestone","place"]},"crossed-flags":{"a":"Crossed Flags","b":"1F38C","j":["celebration","cross","crossed","Japanese","japanese","nation","country","border"]},"black-flag":{"a":"Black Flag","b":"1F3F4","j":["waving","pirate"]},"white-flag":{"a":"White Flag","b":"1F3F3","j":["waving","losing","loser","lost","surrender","give up","fail"]},"rainbow-flag":{"a":"Rainbow Flag","b":"1F3F3-FE0F-200D-1F308","j":["pride","rainbow","flag","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"]},"transgender-flag":{"a":"Transgender Flag","b":"1F3F3-FE0F-200D-26A7-FE0F","j":["flag","light blue","pink","transgender","white","lgbtq"]},"pirate-flag":{"a":"Pirate Flag","b":"1F3F4-200D-2620-FE0F","j":["Jolly Roger","pirate","plunder","treasure","skull","crossbones","flag","banner"]},"flag-ascension-island":{"a":"Flag: Ascension Island","b":"1F1E6-1F1E8","j":["flag"]},"flag-andorra":{"a":"Flag: Andorra","b":"1F1E6-1F1E9","j":["flag","ad","nation","country","banner","andorra"]},"flag-united-arab-emirates":{"a":"Flag: United Arab Emirates","b":"1F1E6-1F1EA","j":["flag","united","arab","emirates","nation","country","banner","united_arab_emirates"]},"flag-afghanistan":{"a":"Flag: Afghanistan","b":"1F1E6-1F1EB","j":["flag","af","nation","country","banner","afghanistan"]},"flag-antigua--barbuda":{"a":"Flag: Antigua & Barbuda","b":"1F1E6-1F1EC","j":["flag","flag_antigua_barbuda","antigua","barbuda","nation","country","banner","antigua_barbuda"]},"flag-anguilla":{"a":"Flag: Anguilla","b":"1F1E6-1F1EE","j":["flag","ai","nation","country","banner","anguilla"]},"flag-albania":{"a":"Flag: Albania","b":"1F1E6-1F1F1","j":["flag","al","nation","country","banner","albania"]},"flag-armenia":{"a":"Flag: Armenia","b":"1F1E6-1F1F2","j":["flag","am","nation","country","banner","armenia"]},"flag-angola":{"a":"Flag: Angola","b":"1F1E6-1F1F4","j":["flag","ao","nation","country","banner","angola"]},"flag-antarctica":{"a":"Flag: Antarctica","b":"1F1E6-1F1F6","j":["flag","aq","nation","country","banner","antarctica"]},"flag-argentina":{"a":"Flag: Argentina","b":"1F1E6-1F1F7","j":["flag","ar","nation","country","banner","argentina"]},"flag-american-samoa":{"a":"Flag: American Samoa","b":"1F1E6-1F1F8","j":["flag","american","ws","nation","country","banner","american_samoa"]},"flag-austria":{"a":"Flag: Austria","b":"1F1E6-1F1F9","j":["flag","at","nation","country","banner","austria"]},"flag-australia":{"a":"Flag: Australia","b":"1F1E6-1F1FA","j":["flag","au","nation","country","banner","australia"]},"flag-aruba":{"a":"Flag: Aruba","b":"1F1E6-1F1FC","j":["flag","aw","nation","country","banner","aruba"]},"flag-land-islands":{"a":"Flag: Åland Islands","b":"1F1E6-1F1FD","j":["flag","flag_aland_islands","Åland","islands","nation","country","banner","aland_islands"]},"flag-azerbaijan":{"a":"Flag: Azerbaijan","b":"1F1E6-1F1FF","j":["flag","az","nation","country","banner","azerbaijan"]},"flag-bosnia--herzegovina":{"a":"Flag: Bosnia & Herzegovina","b":"1F1E7-1F1E6","j":["flag","flag_bosnia_herzegovina","bosnia","herzegovina","nation","country","banner","bosnia_herzegovina"]},"flag-barbados":{"a":"Flag: Barbados","b":"1F1E7-1F1E7","j":["flag","bb","nation","country","banner","barbados"]},"flag-bangladesh":{"a":"Flag: Bangladesh","b":"1F1E7-1F1E9","j":["flag","bd","nation","country","banner","bangladesh"]},"flag-belgium":{"a":"Flag: Belgium","b":"1F1E7-1F1EA","j":["flag","be","nation","country","banner","belgium"]},"flag-burkina-faso":{"a":"Flag: Burkina Faso","b":"1F1E7-1F1EB","j":["flag","burkina","faso","nation","country","banner","burkina_faso"]},"flag-bulgaria":{"a":"Flag: Bulgaria","b":"1F1E7-1F1EC","j":["flag","bg","nation","country","banner","bulgaria"]},"flag-bahrain":{"a":"Flag: Bahrain","b":"1F1E7-1F1ED","j":["flag","bh","nation","country","banner","bahrain"]},"flag-burundi":{"a":"Flag: Burundi","b":"1F1E7-1F1EE","j":["flag","bi","nation","country","banner","burundi"]},"flag-benin":{"a":"Flag: Benin","b":"1F1E7-1F1EF","j":["flag","bj","nation","country","banner","benin"]},"flag-st-barthlemy":{"a":"Flag: St. Barthélemy","b":"1F1E7-1F1F1","j":["flag","flag_st_barthelemy","saint","barthélemy","nation","country","banner","st_barthelemy"]},"flag-bermuda":{"a":"Flag: Bermuda","b":"1F1E7-1F1F2","j":["flag","bm","nation","country","banner","bermuda"]},"flag-brunei":{"a":"Flag: Brunei","b":"1F1E7-1F1F3","j":["flag","bn","darussalam","nation","country","banner","brunei"]},"flag-bolivia":{"a":"Flag: Bolivia","b":"1F1E7-1F1F4","j":["flag","bo","nation","country","banner","bolivia"]},"flag-caribbean-netherlands":{"a":"Flag: Caribbean Netherlands","b":"1F1E7-1F1F6","j":["flag","bonaire","nation","country","banner","caribbean_netherlands"]},"flag-brazil":{"a":"Flag: Brazil","b":"1F1E7-1F1F7","j":["flag","br","nation","country","banner","brazil"]},"flag-bahamas":{"a":"Flag: Bahamas","b":"1F1E7-1F1F8","j":["flag","bs","nation","country","banner","bahamas"]},"flag-bhutan":{"a":"Flag: Bhutan","b":"1F1E7-1F1F9","j":["flag","bt","nation","country","banner","bhutan"]},"flag-bouvet-island":{"a":"Flag: Bouvet Island","b":"1F1E7-1F1FB","j":["flag","norway"]},"flag-botswana":{"a":"Flag: Botswana","b":"1F1E7-1F1FC","j":["flag","bw","nation","country","banner","botswana"]},"flag-belarus":{"a":"Flag: Belarus","b":"1F1E7-1F1FE","j":["flag","by","nation","country","banner","belarus"]},"flag-belize":{"a":"Flag: Belize","b":"1F1E7-1F1FF","j":["flag","bz","nation","country","banner","belize"]},"flag-canada":{"a":"Flag: Canada","b":"1F1E8-1F1E6","j":["flag","ca","nation","country","banner","canada"]},"flag-cocos-keeling-islands":{"a":"Flag: Cocos (Keeling) Islands","b":"1F1E8-1F1E8","j":["flag","flag_cocos_islands","cocos","keeling","islands","nation","country","banner","cocos_islands"]},"flag-congo--kinshasa":{"a":"Flag: Congo - Kinshasa","b":"1F1E8-1F1E9","j":["flag","flag_congo_kinshasa","congo","democratic","republic","nation","country","banner","congo_kinshasa"]},"flag-central-african-republic":{"a":"Flag: Central African Republic","b":"1F1E8-1F1EB","j":["flag","central","african","republic","nation","country","banner","central_african_republic"]},"flag-congo--brazzaville":{"a":"Flag: Congo - Brazzaville","b":"1F1E8-1F1EC","j":["flag","flag_congo_brazzaville","congo","nation","country","banner","congo_brazzaville"]},"flag-switzerland":{"a":"Flag: Switzerland","b":"1F1E8-1F1ED","j":["flag","ch","nation","country","banner","switzerland"]},"flag-cte-divoire":{"a":"Flag: Côte D’Ivoire","b":"1F1E8-1F1EE","j":["flag","flag_cote_d_ivoire","ivory","coast","nation","country","banner","cote_d_ivoire"]},"flag-cook-islands":{"a":"Flag: Cook Islands","b":"1F1E8-1F1F0","j":["flag","cook","islands","nation","country","banner","cook_islands"]},"flag-chile":{"a":"Flag: Chile","b":"1F1E8-1F1F1","j":["flag","nation","country","banner","chile"]},"flag-cameroon":{"a":"Flag: Cameroon","b":"1F1E8-1F1F2","j":["flag","cm","nation","country","banner","cameroon"]},"flag-china":{"a":"Flag: China","b":"1F1E8-1F1F3","j":["flag","china","chinese","prc","country","nation","banner"]},"flag-colombia":{"a":"Flag: Colombia","b":"1F1E8-1F1F4","j":["flag","co","nation","country","banner","colombia"]},"flag-clipperton-island":{"a":"Flag: Clipperton Island","b":"1F1E8-1F1F5","j":["flag"]},"flag-costa-rica":{"a":"Flag: Costa Rica","b":"1F1E8-1F1F7","j":["flag","costa","rica","nation","country","banner","costa_rica"]},"flag-cuba":{"a":"Flag: Cuba","b":"1F1E8-1F1FA","j":["flag","cu","nation","country","banner","cuba"]},"flag-cape-verde":{"a":"Flag: Cape Verde","b":"1F1E8-1F1FB","j":["flag","cabo","verde","nation","country","banner","cape_verde"]},"flag-curaao":{"a":"Flag: Curaçao","b":"1F1E8-1F1FC","j":["flag","flag_curacao","curaçao","nation","country","banner","curacao"]},"flag-christmas-island":{"a":"Flag: Christmas Island","b":"1F1E8-1F1FD","j":["flag","christmas","island","nation","country","banner","christmas_island"]},"flag-cyprus":{"a":"Flag: Cyprus","b":"1F1E8-1F1FE","j":["flag","cy","nation","country","banner","cyprus"]},"flag-czechia":{"a":"Flag: Czechia","b":"1F1E8-1F1FF","j":["flag","cz","nation","country","banner","czechia"]},"flag-germany":{"a":"Flag: Germany","b":"1F1E9-1F1EA","j":["flag","german","nation","country","banner","germany"]},"flag-diego-garcia":{"a":"Flag: Diego Garcia","b":"1F1E9-1F1EC","j":["flag"]},"flag-djibouti":{"a":"Flag: Djibouti","b":"1F1E9-1F1EF","j":["flag","dj","nation","country","banner","djibouti"]},"flag-denmark":{"a":"Flag: Denmark","b":"1F1E9-1F1F0","j":["flag","dk","nation","country","banner","denmark"]},"flag-dominica":{"a":"Flag: Dominica","b":"1F1E9-1F1F2","j":["flag","dm","nation","country","banner","dominica"]},"flag-dominican-republic":{"a":"Flag: Dominican Republic","b":"1F1E9-1F1F4","j":["flag","dominican","republic","nation","country","banner","dominican_republic"]},"flag-algeria":{"a":"Flag: Algeria","b":"1F1E9-1F1FF","j":["flag","dz","nation","country","banner","algeria"]},"flag-ceuta--melilla":{"a":"Flag: Ceuta & Melilla","b":"1F1EA-1F1E6","j":["flag","flag_ceuta_melilla"]},"flag-ecuador":{"a":"Flag: Ecuador","b":"1F1EA-1F1E8","j":["flag","ec","nation","country","banner","ecuador"]},"flag-estonia":{"a":"Flag: Estonia","b":"1F1EA-1F1EA","j":["flag","ee","nation","country","banner","estonia"]},"flag-egypt":{"a":"Flag: Egypt","b":"1F1EA-1F1EC","j":["flag","eg","nation","country","banner","egypt"]},"flag-western-sahara":{"a":"Flag: Western Sahara","b":"1F1EA-1F1ED","j":["flag","western","sahara","nation","country","banner","western_sahara"]},"flag-eritrea":{"a":"Flag: Eritrea","b":"1F1EA-1F1F7","j":["flag","er","nation","country","banner","eritrea"]},"flag-spain":{"a":"Flag: Spain","b":"1F1EA-1F1F8","j":["flag","spain","nation","country","banner"]},"flag-ethiopia":{"a":"Flag: Ethiopia","b":"1F1EA-1F1F9","j":["flag","et","nation","country","banner","ethiopia"]},"flag-european-union":{"a":"Flag: European Union","b":"1F1EA-1F1FA","j":["flag","european","union","banner"]},"flag-finland":{"a":"Flag: Finland","b":"1F1EB-1F1EE","j":["flag","fi","nation","country","banner","finland"]},"flag-fiji":{"a":"Flag: Fiji","b":"1F1EB-1F1EF","j":["flag","fj","nation","country","banner","fiji"]},"flag-falkland-islands":{"a":"Flag: Falkland Islands","b":"1F1EB-1F1F0","j":["flag","falkland","islands","malvinas","nation","country","banner","falkland_islands"]},"flag-micronesia":{"a":"Flag: Micronesia","b":"1F1EB-1F1F2","j":["flag","micronesia","federated","states","nation","country","banner"]},"flag-faroe-islands":{"a":"Flag: Faroe Islands","b":"1F1EB-1F1F4","j":["flag","faroe","islands","nation","country","banner","faroe_islands"]},"flag-france":{"a":"Flag: France","b":"1F1EB-1F1F7","j":["flag","banner","nation","france","french","country"]},"flag-gabon":{"a":"Flag: Gabon","b":"1F1EC-1F1E6","j":["flag","ga","nation","country","banner","gabon"]},"flag-united-kingdom":{"a":"Flag: United Kingdom","b":"1F1EC-1F1E7","j":["flag","united","kingdom","great","britain","northern","ireland","nation","country","banner","british","UK","english","england","union jack","united_kingdom"]},"flag-grenada":{"a":"Flag: Grenada","b":"1F1EC-1F1E9","j":["flag","gd","nation","country","banner","grenada"]},"flag-georgia":{"a":"Flag: Georgia","b":"1F1EC-1F1EA","j":["flag","ge","nation","country","banner","georgia"]},"flag-french-guiana":{"a":"Flag: French Guiana","b":"1F1EC-1F1EB","j":["flag","french","guiana","nation","country","banner","french_guiana"]},"flag-guernsey":{"a":"Flag: Guernsey","b":"1F1EC-1F1EC","j":["flag","gg","nation","country","banner","guernsey"]},"flag-ghana":{"a":"Flag: Ghana","b":"1F1EC-1F1ED","j":["flag","gh","nation","country","banner","ghana"]},"flag-gibraltar":{"a":"Flag: Gibraltar","b":"1F1EC-1F1EE","j":["flag","gi","nation","country","banner","gibraltar"]},"flag-greenland":{"a":"Flag: Greenland","b":"1F1EC-1F1F1","j":["flag","gl","nation","country","banner","greenland"]},"flag-gambia":{"a":"Flag: Gambia","b":"1F1EC-1F1F2","j":["flag","gm","nation","country","banner","gambia"]},"flag-guinea":{"a":"Flag: Guinea","b":"1F1EC-1F1F3","j":["flag","gn","nation","country","banner","guinea"]},"flag-guadeloupe":{"a":"Flag: Guadeloupe","b":"1F1EC-1F1F5","j":["flag","gp","nation","country","banner","guadeloupe"]},"flag-equatorial-guinea":{"a":"Flag: Equatorial Guinea","b":"1F1EC-1F1F6","j":["flag","equatorial","gn","nation","country","banner","equatorial_guinea"]},"flag-greece":{"a":"Flag: Greece","b":"1F1EC-1F1F7","j":["flag","gr","nation","country","banner","greece"]},"flag-south-georgia--south-sandwich-islands":{"a":"Flag: South Georgia & South Sandwich Islands","b":"1F1EC-1F1F8","j":["flag","flag_south_georgia_south_sandwich_islands","south","georgia","sandwich","islands","nation","country","banner","south_georgia_south_sandwich_islands"]},"flag-guatemala":{"a":"Flag: Guatemala","b":"1F1EC-1F1F9","j":["flag","gt","nation","country","banner","guatemala"]},"flag-guam":{"a":"Flag: Guam","b":"1F1EC-1F1FA","j":["flag","gu","nation","country","banner","guam"]},"flag-guineabissau":{"a":"Flag: Guinea-Bissau","b":"1F1EC-1F1FC","j":["flag","flag_guinea_bissau","gw","bissau","nation","country","banner","guinea_bissau"]},"flag-guyana":{"a":"Flag: Guyana","b":"1F1EC-1F1FE","j":["flag","gy","nation","country","banner","guyana"]},"flag-hong-kong-sar-china":{"a":"Flag: Hong Kong Sar China","b":"1F1ED-1F1F0","j":["flag","hong","kong","nation","country","banner","hong_kong_sar_china"]},"flag-heard--mcdonald-islands":{"a":"Flag: Heard & Mcdonald Islands","b":"1F1ED-1F1F2","j":["flag","flag_heard_mcdonald_islands"]},"flag-honduras":{"a":"Flag: Honduras","b":"1F1ED-1F1F3","j":["flag","hn","nation","country","banner","honduras"]},"flag-croatia":{"a":"Flag: Croatia","b":"1F1ED-1F1F7","j":["flag","hr","nation","country","banner","croatia"]},"flag-haiti":{"a":"Flag: Haiti","b":"1F1ED-1F1F9","j":["flag","ht","nation","country","banner","haiti"]},"flag-hungary":{"a":"Flag: Hungary","b":"1F1ED-1F1FA","j":["flag","hu","nation","country","banner","hungary"]},"flag-canary-islands":{"a":"Flag: Canary Islands","b":"1F1EE-1F1E8","j":["flag","canary","islands","nation","country","banner","canary_islands"]},"flag-indonesia":{"a":"Flag: Indonesia","b":"1F1EE-1F1E9","j":["flag","nation","country","banner","indonesia"]},"flag-ireland":{"a":"Flag: Ireland","b":"1F1EE-1F1EA","j":["flag","ie","nation","country","banner","ireland"]},"flag-israel":{"a":"Flag: Israel","b":"1F1EE-1F1F1","j":["flag","il","nation","country","banner","israel"]},"flag-isle-of-man":{"a":"Flag: Isle of Man","b":"1F1EE-1F1F2","j":["flag","isle","man","nation","country","banner","isle_of_man"]},"flag-india":{"a":"Flag: India","b":"1F1EE-1F1F3","j":["flag","in","nation","country","banner","india"]},"flag-british-indian-ocean-territory":{"a":"Flag: British Indian Ocean Territory","b":"1F1EE-1F1F4","j":["flag","british","indian","ocean","territory","nation","country","banner","british_indian_ocean_territory"]},"flag-iraq":{"a":"Flag: Iraq","b":"1F1EE-1F1F6","j":["flag","iq","nation","country","banner","iraq"]},"flag-iran":{"a":"Flag: Iran","b":"1F1EE-1F1F7","j":["flag","iran","islamic","republic","nation","country","banner"]},"flag-iceland":{"a":"Flag: Iceland","b":"1F1EE-1F1F8","j":["flag","is","nation","country","banner","iceland"]},"flag-italy":{"a":"Flag: Italy","b":"1F1EE-1F1F9","j":["flag","italy","nation","country","banner"]},"flag-jersey":{"a":"Flag: Jersey","b":"1F1EF-1F1EA","j":["flag","je","nation","country","banner","jersey"]},"flag-jamaica":{"a":"Flag: Jamaica","b":"1F1EF-1F1F2","j":["flag","jm","nation","country","banner","jamaica"]},"flag-jordan":{"a":"Flag: Jordan","b":"1F1EF-1F1F4","j":["flag","jo","nation","country","banner","jordan"]},"flag-japan":{"a":"Flag: Japan","b":"1F1EF-1F1F5","j":["flag","japanese","nation","country","banner","japan"]},"flag-kenya":{"a":"Flag: Kenya","b":"1F1F0-1F1EA","j":["flag","ke","nation","country","banner","kenya"]},"flag-kyrgyzstan":{"a":"Flag: Kyrgyzstan","b":"1F1F0-1F1EC","j":["flag","kg","nation","country","banner","kyrgyzstan"]},"flag-cambodia":{"a":"Flag: Cambodia","b":"1F1F0-1F1ED","j":["flag","kh","nation","country","banner","cambodia"]},"flag-kiribati":{"a":"Flag: Kiribati","b":"1F1F0-1F1EE","j":["flag","ki","nation","country","banner","kiribati"]},"flag-comoros":{"a":"Flag: Comoros","b":"1F1F0-1F1F2","j":["flag","km","nation","country","banner","comoros"]},"flag-st-kitts--nevis":{"a":"Flag: St. Kitts & Nevis","b":"1F1F0-1F1F3","j":["flag","flag_st_kitts_nevis","saint","kitts","nevis","nation","country","banner","st_kitts_nevis"]},"flag-north-korea":{"a":"Flag: North Korea","b":"1F1F0-1F1F5","j":["flag","north","korea","nation","country","banner","north_korea"]},"flag-south-korea":{"a":"Flag: South Korea","b":"1F1F0-1F1F7","j":["flag","south","korea","nation","country","banner","south_korea"]},"flag-kuwait":{"a":"Flag: Kuwait","b":"1F1F0-1F1FC","j":["flag","kw","nation","country","banner","kuwait"]},"flag-cayman-islands":{"a":"Flag: Cayman Islands","b":"1F1F0-1F1FE","j":["flag","cayman","islands","nation","country","banner","cayman_islands"]},"flag-kazakhstan":{"a":"Flag: Kazakhstan","b":"1F1F0-1F1FF","j":["flag","kz","nation","country","banner","kazakhstan"]},"flag-laos":{"a":"Flag: Laos","b":"1F1F1-1F1E6","j":["flag","lao","democratic","republic","nation","country","banner","laos"]},"flag-lebanon":{"a":"Flag: Lebanon","b":"1F1F1-1F1E7","j":["flag","lb","nation","country","banner","lebanon"]},"flag-st-lucia":{"a":"Flag: St. Lucia","b":"1F1F1-1F1E8","j":["flag","saint","lucia","nation","country","banner","st_lucia"]},"flag-liechtenstein":{"a":"Flag: Liechtenstein","b":"1F1F1-1F1EE","j":["flag","li","nation","country","banner","liechtenstein"]},"flag-sri-lanka":{"a":"Flag: Sri Lanka","b":"1F1F1-1F1F0","j":["flag","sri","lanka","nation","country","banner","sri_lanka"]},"flag-liberia":{"a":"Flag: Liberia","b":"1F1F1-1F1F7","j":["flag","lr","nation","country","banner","liberia"]},"flag-lesotho":{"a":"Flag: Lesotho","b":"1F1F1-1F1F8","j":["flag","ls","nation","country","banner","lesotho"]},"flag-lithuania":{"a":"Flag: Lithuania","b":"1F1F1-1F1F9","j":["flag","lt","nation","country","banner","lithuania"]},"flag-luxembourg":{"a":"Flag: Luxembourg","b":"1F1F1-1F1FA","j":["flag","lu","nation","country","banner","luxembourg"]},"flag-latvia":{"a":"Flag: Latvia","b":"1F1F1-1F1FB","j":["flag","lv","nation","country","banner","latvia"]},"flag-libya":{"a":"Flag: Libya","b":"1F1F1-1F1FE","j":["flag","ly","nation","country","banner","libya"]},"flag-morocco":{"a":"Flag: Morocco","b":"1F1F2-1F1E6","j":["flag","ma","nation","country","banner","morocco"]},"flag-monaco":{"a":"Flag: Monaco","b":"1F1F2-1F1E8","j":["flag","mc","nation","country","banner","monaco"]},"flag-moldova":{"a":"Flag: Moldova","b":"1F1F2-1F1E9","j":["flag","moldova","republic","nation","country","banner"]},"flag-montenegro":{"a":"Flag: Montenegro","b":"1F1F2-1F1EA","j":["flag","me","nation","country","banner","montenegro"]},"flag-st-martin":{"a":"Flag: St. Martin","b":"1F1F2-1F1EB","j":["flag"]},"flag-madagascar":{"a":"Flag: Madagascar","b":"1F1F2-1F1EC","j":["flag","mg","nation","country","banner","madagascar"]},"flag-marshall-islands":{"a":"Flag: Marshall Islands","b":"1F1F2-1F1ED","j":["flag","marshall","islands","nation","country","banner","marshall_islands"]},"flag-north-macedonia":{"a":"Flag: North Macedonia","b":"1F1F2-1F1F0","j":["flag","macedonia","nation","country","banner","north_macedonia"]},"flag-mali":{"a":"Flag: Mali","b":"1F1F2-1F1F1","j":["flag","ml","nation","country","banner","mali"]},"flag-myanmar-burma":{"a":"Flag: Myanmar (Burma)","b":"1F1F2-1F1F2","j":["flag","flag_myanmar","mm","nation","country","banner","myanmar"]},"flag-mongolia":{"a":"Flag: Mongolia","b":"1F1F2-1F1F3","j":["flag","mn","nation","country","banner","mongolia"]},"flag-macao-sar-china":{"a":"Flag: Macao Sar China","b":"1F1F2-1F1F4","j":["flag","macao","nation","country","banner","macao_sar_china"]},"flag-northern-mariana-islands":{"a":"Flag: Northern Mariana Islands","b":"1F1F2-1F1F5","j":["flag","northern","mariana","islands","nation","country","banner","northern_mariana_islands"]},"flag-martinique":{"a":"Flag: Martinique","b":"1F1F2-1F1F6","j":["flag","mq","nation","country","banner","martinique"]},"flag-mauritania":{"a":"Flag: Mauritania","b":"1F1F2-1F1F7","j":["flag","mr","nation","country","banner","mauritania"]},"flag-montserrat":{"a":"Flag: Montserrat","b":"1F1F2-1F1F8","j":["flag","ms","nation","country","banner","montserrat"]},"flag-malta":{"a":"Flag: Malta","b":"1F1F2-1F1F9","j":["flag","mt","nation","country","banner","malta"]},"flag-mauritius":{"a":"Flag: Mauritius","b":"1F1F2-1F1FA","j":["flag","mu","nation","country","banner","mauritius"]},"flag-maldives":{"a":"Flag: Maldives","b":"1F1F2-1F1FB","j":["flag","mv","nation","country","banner","maldives"]},"flag-malawi":{"a":"Flag: Malawi","b":"1F1F2-1F1FC","j":["flag","mw","nation","country","banner","malawi"]},"flag-mexico":{"a":"Flag: Mexico","b":"1F1F2-1F1FD","j":["flag","mx","nation","country","banner","mexico"]},"flag-malaysia":{"a":"Flag: Malaysia","b":"1F1F2-1F1FE","j":["flag","my","nation","country","banner","malaysia"]},"flag-mozambique":{"a":"Flag: Mozambique","b":"1F1F2-1F1FF","j":["flag","mz","nation","country","banner","mozambique"]},"flag-namibia":{"a":"Flag: Namibia","b":"1F1F3-1F1E6","j":["flag","na","nation","country","banner","namibia"]},"flag-new-caledonia":{"a":"Flag: New Caledonia","b":"1F1F3-1F1E8","j":["flag","new","caledonia","nation","country","banner","new_caledonia"]},"flag-niger":{"a":"Flag: Niger","b":"1F1F3-1F1EA","j":["flag","ne","nation","country","banner","niger"]},"flag-norfolk-island":{"a":"Flag: Norfolk Island","b":"1F1F3-1F1EB","j":["flag","norfolk","island","nation","country","banner","norfolk_island"]},"flag-nigeria":{"a":"Flag: Nigeria","b":"1F1F3-1F1EC","j":["flag","nation","country","banner","nigeria"]},"flag-nicaragua":{"a":"Flag: Nicaragua","b":"1F1F3-1F1EE","j":["flag","ni","nation","country","banner","nicaragua"]},"flag-netherlands":{"a":"Flag: Netherlands","b":"1F1F3-1F1F1","j":["flag","nl","nation","country","banner","netherlands"]},"flag-norway":{"a":"Flag: Norway","b":"1F1F3-1F1F4","j":["flag","no","nation","country","banner","norway"]},"flag-nepal":{"a":"Flag: Nepal","b":"1F1F3-1F1F5","j":["flag","np","nation","country","banner","nepal"]},"flag-nauru":{"a":"Flag: Nauru","b":"1F1F3-1F1F7","j":["flag","nr","nation","country","banner","nauru"]},"flag-niue":{"a":"Flag: Niue","b":"1F1F3-1F1FA","j":["flag","nu","nation","country","banner","niue"]},"flag-new-zealand":{"a":"Flag: New Zealand","b":"1F1F3-1F1FF","j":["flag","new","zealand","nation","country","banner","new_zealand"]},"flag-oman":{"a":"Flag: Oman","b":"1F1F4-1F1F2","j":["flag","om_symbol","nation","country","banner","oman"]},"flag-panama":{"a":"Flag: Panama","b":"1F1F5-1F1E6","j":["flag","pa","nation","country","banner","panama"]},"flag-peru":{"a":"Flag: Peru","b":"1F1F5-1F1EA","j":["flag","pe","nation","country","banner","peru"]},"flag-french-polynesia":{"a":"Flag: French Polynesia","b":"1F1F5-1F1EB","j":["flag","french","polynesia","nation","country","banner","french_polynesia"]},"flag-papua-new-guinea":{"a":"Flag: Papua New Guinea","b":"1F1F5-1F1EC","j":["flag","papua","new","guinea","nation","country","banner","papua_new_guinea"]},"flag-philippines":{"a":"Flag: Philippines","b":"1F1F5-1F1ED","j":["flag","ph","nation","country","banner","philippines"]},"flag-pakistan":{"a":"Flag: Pakistan","b":"1F1F5-1F1F0","j":["flag","pk","nation","country","banner","pakistan"]},"flag-poland":{"a":"Flag: Poland","b":"1F1F5-1F1F1","j":["flag","pl","nation","country","banner","poland"]},"flag-st-pierre--miquelon":{"a":"Flag: St. Pierre & Miquelon","b":"1F1F5-1F1F2","j":["flag","flag_st_pierre_miquelon","saint","pierre","miquelon","nation","country","banner","st_pierre_miquelon"]},"flag-pitcairn-islands":{"a":"Flag: Pitcairn Islands","b":"1F1F5-1F1F3","j":["flag","pitcairn","nation","country","banner","pitcairn_islands"]},"flag-puerto-rico":{"a":"Flag: Puerto Rico","b":"1F1F5-1F1F7","j":["flag","puerto","rico","nation","country","banner","puerto_rico"]},"flag-palestinian-territories":{"a":"Flag: Palestinian Territories","b":"1F1F5-1F1F8","j":["flag","palestine","palestinian","territories","nation","country","banner","palestinian_territories"]},"flag-portugal":{"a":"Flag: Portugal","b":"1F1F5-1F1F9","j":["flag","pt","nation","country","banner","portugal"]},"flag-palau":{"a":"Flag: Palau","b":"1F1F5-1F1FC","j":["flag","pw","nation","country","banner","palau"]},"flag-paraguay":{"a":"Flag: Paraguay","b":"1F1F5-1F1FE","j":["flag","py","nation","country","banner","paraguay"]},"flag-qatar":{"a":"Flag: Qatar","b":"1F1F6-1F1E6","j":["flag","qa","nation","country","banner","qatar"]},"flag-runion":{"a":"Flag: Réunion","b":"1F1F7-1F1EA","j":["flag","flag_reunion","réunion","nation","country","banner","reunion"]},"flag-romania":{"a":"Flag: Romania","b":"1F1F7-1F1F4","j":["flag","ro","nation","country","banner","romania"]},"flag-serbia":{"a":"Flag: Serbia","b":"1F1F7-1F1F8","j":["flag","rs","nation","country","banner","serbia"]},"flag-russia":{"a":"Flag: Russia","b":"1F1F7-1F1FA","j":["flag","russian","federation","nation","country","banner","russia"]},"flag-rwanda":{"a":"Flag: Rwanda","b":"1F1F7-1F1FC","j":["flag","rw","nation","country","banner","rwanda"]},"flag-saudi-arabia":{"a":"Flag: Saudi Arabia","b":"1F1F8-1F1E6","j":["flag","nation","country","banner","saudi_arabia"]},"flag-solomon-islands":{"a":"Flag: Solomon Islands","b":"1F1F8-1F1E7","j":["flag","solomon","islands","nation","country","banner","solomon_islands"]},"flag-seychelles":{"a":"Flag: Seychelles","b":"1F1F8-1F1E8","j":["flag","sc","nation","country","banner","seychelles"]},"flag-sudan":{"a":"Flag: Sudan","b":"1F1F8-1F1E9","j":["flag","sd","nation","country","banner","sudan"]},"flag-sweden":{"a":"Flag: Sweden","b":"1F1F8-1F1EA","j":["flag","se","nation","country","banner","sweden"]},"flag-singapore":{"a":"Flag: Singapore","b":"1F1F8-1F1EC","j":["flag","sg","nation","country","banner","singapore"]},"flag-st-helena":{"a":"Flag: St. Helena","b":"1F1F8-1F1ED","j":["flag","saint","helena","ascension","tristan","cunha","nation","country","banner","st_helena"]},"flag-slovenia":{"a":"Flag: Slovenia","b":"1F1F8-1F1EE","j":["flag","si","nation","country","banner","slovenia"]},"flag-svalbard--jan-mayen":{"a":"Flag: Svalbard & Jan Mayen","b":"1F1F8-1F1EF","j":["flag","flag_svalbard_jan_mayen"]},"flag-slovakia":{"a":"Flag: Slovakia","b":"1F1F8-1F1F0","j":["flag","sk","nation","country","banner","slovakia"]},"flag-sierra-leone":{"a":"Flag: Sierra Leone","b":"1F1F8-1F1F1","j":["flag","sierra","leone","nation","country","banner","sierra_leone"]},"flag-san-marino":{"a":"Flag: San Marino","b":"1F1F8-1F1F2","j":["flag","san","marino","nation","country","banner","san_marino"]},"flag-senegal":{"a":"Flag: Senegal","b":"1F1F8-1F1F3","j":["flag","sn","nation","country","banner","senegal"]},"flag-somalia":{"a":"Flag: Somalia","b":"1F1F8-1F1F4","j":["flag","so","nation","country","banner","somalia"]},"flag-suriname":{"a":"Flag: Suriname","b":"1F1F8-1F1F7","j":["flag","sr","nation","country","banner","suriname"]},"flag-south-sudan":{"a":"Flag: South Sudan","b":"1F1F8-1F1F8","j":["flag","south","sd","nation","country","banner","south_sudan"]},"flag-so-tom--prncipe":{"a":"Flag: São Tomé & Príncipe","b":"1F1F8-1F1F9","j":["flag","flag_sao_tome_principe","sao","tome","principe","nation","country","banner","sao_tome_principe"]},"flag-el-salvador":{"a":"Flag: El Salvador","b":"1F1F8-1F1FB","j":["flag","el","salvador","nation","country","banner","el_salvador"]},"flag-sint-maarten":{"a":"Flag: Sint Maarten","b":"1F1F8-1F1FD","j":["flag","sint","maarten","dutch","nation","country","banner","sint_maarten"]},"flag-syria":{"a":"Flag: Syria","b":"1F1F8-1F1FE","j":["flag","syrian","arab","republic","nation","country","banner","syria"]},"flag-eswatini":{"a":"Flag: Eswatini","b":"1F1F8-1F1FF","j":["flag","sz","nation","country","banner","eswatini"]},"flag-tristan-da-cunha":{"a":"Flag: Tristan Da Cunha","b":"1F1F9-1F1E6","j":["flag"]},"flag-turks--caicos-islands":{"a":"Flag: Turks & Caicos Islands","b":"1F1F9-1F1E8","j":["flag","flag_turks_caicos_islands","turks","caicos","islands","nation","country","banner","turks_caicos_islands"]},"flag-chad":{"a":"Flag: Chad","b":"1F1F9-1F1E9","j":["flag","td","nation","country","banner","chad"]},"flag-french-southern-territories":{"a":"Flag: French Southern Territories","b":"1F1F9-1F1EB","j":["flag","french","southern","territories","nation","country","banner","french_southern_territories"]},"flag-togo":{"a":"Flag: Togo","b":"1F1F9-1F1EC","j":["flag","tg","nation","country","banner","togo"]},"flag-thailand":{"a":"Flag: Thailand","b":"1F1F9-1F1ED","j":["flag","th","nation","country","banner","thailand"]},"flag-tajikistan":{"a":"Flag: Tajikistan","b":"1F1F9-1F1EF","j":["flag","tj","nation","country","banner","tajikistan"]},"flag-tokelau":{"a":"Flag: Tokelau","b":"1F1F9-1F1F0","j":["flag","tk","nation","country","banner","tokelau"]},"flag-timorleste":{"a":"Flag: Timor-Leste","b":"1F1F9-1F1F1","j":["flag","flag_timor_leste","timor","leste","nation","country","banner","timor_leste"]},"flag-turkmenistan":{"a":"Flag: Turkmenistan","b":"1F1F9-1F1F2","j":["flag","nation","country","banner","turkmenistan"]},"flag-tunisia":{"a":"Flag: Tunisia","b":"1F1F9-1F1F3","j":["flag","tn","nation","country","banner","tunisia"]},"flag-tonga":{"a":"Flag: Tonga","b":"1F1F9-1F1F4","j":["flag","to","nation","country","banner","tonga"]},"flag-turkey":{"a":"Flag: Turkey","b":"1F1F9-1F1F7","j":["flag","turkey","nation","country","banner"]},"flag-trinidad--tobago":{"a":"Flag: Trinidad & Tobago","b":"1F1F9-1F1F9","j":["flag","flag_trinidad_tobago","trinidad","tobago","nation","country","banner","trinidad_tobago"]},"flag-tuvalu":{"a":"Flag: Tuvalu","b":"1F1F9-1F1FB","j":["flag","nation","country","banner","tuvalu"]},"flag-taiwan":{"a":"Flag: Taiwan","b":"1F1F9-1F1FC","j":["flag","tw","nation","country","banner","taiwan"]},"flag-tanzania":{"a":"Flag: Tanzania","b":"1F1F9-1F1FF","j":["flag","tanzania","united","republic","nation","country","banner"]},"flag-ukraine":{"a":"Flag: Ukraine","b":"1F1FA-1F1E6","j":["flag","ua","nation","country","banner","ukraine"]},"flag-uganda":{"a":"Flag: Uganda","b":"1F1FA-1F1EC","j":["flag","ug","nation","country","banner","uganda"]},"flag-us-outlying-islands":{"a":"Flag: U.S. Outlying Islands","b":"1F1FA-1F1F2","j":["flag","flag_u_s_outlying_islands"]},"flag-united-nations":{"a":"Flag: United Nations","b":"1F1FA-1F1F3","j":["flag","un","banner"]},"flag-united-states":{"a":"Flag: United States","b":"1F1FA-1F1F8","j":["flag","united","states","america","nation","country","banner","united_states"]},"flag-uruguay":{"a":"Flag: Uruguay","b":"1F1FA-1F1FE","j":["flag","uy","nation","country","banner","uruguay"]},"flag-uzbekistan":{"a":"Flag: Uzbekistan","b":"1F1FA-1F1FF","j":["flag","uz","nation","country","banner","uzbekistan"]},"flag-vatican-city":{"a":"Flag: Vatican City","b":"1F1FB-1F1E6","j":["flag","vatican","city","nation","country","banner","vatican_city"]},"flag-st-vincent--grenadines":{"a":"Flag: St. Vincent & Grenadines","b":"1F1FB-1F1E8","j":["flag","flag_st_vincent_grenadines","saint","vincent","grenadines","nation","country","banner","st_vincent_grenadines"]},"flag-venezuela":{"a":"Flag: Venezuela","b":"1F1FB-1F1EA","j":["flag","ve","bolivarian","republic","nation","country","banner","venezuela"]},"flag-british-virgin-islands":{"a":"Flag: British Virgin Islands","b":"1F1FB-1F1EC","j":["flag","british","virgin","islands","bvi","nation","country","banner","british_virgin_islands"]},"flag-us-virgin-islands":{"a":"Flag: U.S. Virgin Islands","b":"1F1FB-1F1EE","j":["flag","flag_u_s_virgin_islands","virgin","islands","us","nation","country","banner","u_s_virgin_islands"]},"flag-vietnam":{"a":"Flag: Vietnam","b":"1F1FB-1F1F3","j":["flag","viet","nam","nation","country","banner","vietnam"]},"flag-vanuatu":{"a":"Flag: Vanuatu","b":"1F1FB-1F1FA","j":["flag","vu","nation","country","banner","vanuatu"]},"flag-wallis--futuna":{"a":"Flag: Wallis & Futuna","b":"1F1FC-1F1EB","j":["flag","flag_wallis_futuna","wallis","futuna","nation","country","banner","wallis_futuna"]},"flag-samoa":{"a":"Flag: Samoa","b":"1F1FC-1F1F8","j":["flag","ws","nation","country","banner","samoa"]},"flag-kosovo":{"a":"Flag: Kosovo","b":"1F1FD-1F1F0","j":["flag","xk","nation","country","banner","kosovo"]},"flag-yemen":{"a":"Flag: Yemen","b":"1F1FE-1F1EA","j":["flag","ye","nation","country","banner","yemen"]},"flag-mayotte":{"a":"Flag: Mayotte","b":"1F1FE-1F1F9","j":["flag","yt","nation","country","banner","mayotte"]},"flag-south-africa":{"a":"Flag: South Africa","b":"1F1FF-1F1E6","j":["flag","south","africa","nation","country","banner","south_africa"]},"flag-zambia":{"a":"Flag: Zambia","b":"1F1FF-1F1F2","j":["flag","zm","nation","country","banner","zambia"]},"flag-zimbabwe":{"a":"Flag: Zimbabwe","b":"1F1FF-1F1FC","j":["flag","zw","nation","country","banner","zimbabwe"]},"flag-england":{"a":"Flag: England","b":"1F3F4-E0067-E0062-E0065-E006E-E0067-E007F","j":["flag","english"]},"flag-scotland":{"a":"Flag: Scotland","b":"1F3F4-E0067-E0062-E0073-E0063-E0074-E007F","j":["flag","scottish"]},"flag-wales":{"a":"Flag: Wales","b":"1F3F4-E0067-E0062-E0077-E006C-E0073-E007F","j":["flag","welsh"]}},"aliases":{}} \ No newline at end of file +{"compressed":true,"categories":[{"id":"smileys_&_emotion","name":"Smileys & Emotion","emojis":["grinning-face","grinning-face-with-big-eyes","grinning-face-with-smiling-eyes","beaming-face-with-smiling-eyes","grinning-squinting-face","grinning-face-with-sweat","rolling-on-the-floor-laughing","face-with-tears-of-joy","slightly-smiling-face","upsidedown-face","melting-face","winking-face","smiling-face-with-smiling-eyes","smiling-face-with-halo","smiling-face-with-hearts","smiling-face-with-hearteyes","starstruck","face-blowing-a-kiss","kissing-face","smiling-face","kissing-face-with-closed-eyes","kissing-face-with-smiling-eyes","smiling-face-with-tear","face-savoring-food","face-with-tongue","winking-face-with-tongue","zany-face","squinting-face-with-tongue","moneymouth-face","smiling-face-with-open-hands","face-with-hand-over-mouth","face-with-open-eyes-and-hand-over-mouth","face-with-peeking-eye","shushing-face","thinking-face","saluting-face","zippermouth-face","face-with-raised-eyebrow","neutral-face","expressionless-face","face-without-mouth","dotted-line-face","face-in-clouds","smirking-face","unamused-face","face-with-rolling-eyes","grimacing-face","face-exhaling","lying-face","relieved-face","pensive-face","sleepy-face","drooling-face","sleeping-face","face-with-medical-mask","face-with-thermometer","face-with-headbandage","nauseated-face","face-vomiting","sneezing-face","hot-face","cold-face","woozy-face","face-with-crossedout-eyes","face-with-spiral-eyes","exploding-head","cowboy-hat-face","partying-face","disguised-face","smiling-face-with-sunglasses","nerd-face","face-with-monocle","confused-face","face-with-diagonal-mouth","worried-face","slightly-frowning-face","frowning-face","face-with-open-mouth","hushed-face","astonished-face","flushed-face","pleading-face","face-holding-back-tears","frowning-face-with-open-mouth","anguished-face","fearful-face","anxious-face-with-sweat","sad-but-relieved-face","crying-face","loudly-crying-face","face-screaming-in-fear","confounded-face","persevering-face","disappointed-face","downcast-face-with-sweat","weary-face","tired-face","yawning-face","face-with-steam-from-nose","pouting-face","angry-face","face-with-symbols-on-mouth","smiling-face-with-horns","angry-face-with-horns","skull","skull-and-crossbones","pile-of-poo","clown-face","ogre","goblin","ghost","alien","alien-monster","robot","grinning-cat","grinning-cat-with-smiling-eyes","cat-with-tears-of-joy","smiling-cat-with-hearteyes","cat-with-wry-smile","kissing-cat","weary-cat","crying-cat","pouting-cat","seenoevil-monkey","hearnoevil-monkey","speaknoevil-monkey","kiss-mark","love-letter","heart-with-arrow","heart-with-ribbon","sparkling-heart","growing-heart","beating-heart","revolving-hearts","two-hearts","heart-decoration","heart-exclamation","broken-heart","heart-on-fire","mending-heart","red-heart","orange-heart","yellow-heart","green-heart","blue-heart","purple-heart","brown-heart","black-heart","white-heart","hundred-points","anger-symbol","collision","dizzy","sweat-droplets","dashing-away","hole","bomb","speech-balloon","eye-in-speech-bubble","left-speech-bubble","right-anger-bubble","thought-balloon","zzz"]},{"id":"people_&_body","name":"People & Body","emojis":["waving-hand","raised-back-of-hand","hand-with-fingers-splayed","raised-hand","vulcan-salute","rightwards-hand","leftwards-hand","palm-down-hand","palm-up-hand","ok-hand","pinched-fingers","pinching-hand","victory-hand","crossed-fingers","hand-with-index-finger-and-thumb-crossed","loveyou-gesture","sign-of-the-horns","call-me-hand","backhand-index-pointing-left","backhand-index-pointing-right","backhand-index-pointing-up","middle-finger","backhand-index-pointing-down","index-pointing-up","index-pointing-at-the-viewer","thumbs-up","thumbs-down","raised-fist","oncoming-fist","leftfacing-fist","rightfacing-fist","clapping-hands","raising-hands","heart-hands","open-hands","palms-up-together","handshake","folded-hands","writing-hand","nail-polish","selfie","flexed-biceps","mechanical-arm","mechanical-leg","leg","foot","ear","ear-with-hearing-aid","nose","brain","anatomical-heart","lungs","tooth","bone","eyes","eye","tongue","mouth","biting-lip","baby","child","boy","girl","person","person-blond-hair","man","person-beard","man-beard","woman-beard","man-red-hair","man-curly-hair","man-white-hair","man-bald","woman","woman-red-hair","person-red-hair","woman-curly-hair","person-curly-hair","woman-white-hair","person-white-hair","woman-bald","person-bald","woman-blond-hair","man-blond-hair","older-person","old-man","old-woman","person-frowning","man-frowning","woman-frowning","person-pouting","man-pouting","woman-pouting","person-gesturing-no","man-gesturing-no","woman-gesturing-no","person-gesturing-ok","man-gesturing-ok","woman-gesturing-ok","person-tipping-hand","man-tipping-hand","woman-tipping-hand","person-raising-hand","man-raising-hand","woman-raising-hand","deaf-person","deaf-man","deaf-woman","person-bowing","man-bowing","woman-bowing","person-facepalming","man-facepalming","woman-facepalming","person-shrugging","man-shrugging","woman-shrugging","health-worker","man-health-worker","woman-health-worker","student","man-student","woman-student","teacher","man-teacher","woman-teacher","judge","man-judge","woman-judge","farmer","man-farmer","woman-farmer","cook","man-cook","woman-cook","mechanic","man-mechanic","woman-mechanic","factory-worker","man-factory-worker","woman-factory-worker","office-worker","man-office-worker","woman-office-worker","scientist","man-scientist","woman-scientist","technologist","man-technologist","woman-technologist","singer","man-singer","woman-singer","artist","man-artist","woman-artist","pilot","man-pilot","woman-pilot","astronaut","man-astronaut","woman-astronaut","firefighter","man-firefighter","woman-firefighter","police-officer","man-police-officer","woman-police-officer","detective","man-detective","woman-detective","guard","man-guard","woman-guard","ninja","construction-worker","man-construction-worker","woman-construction-worker","person-with-crown","prince","princess","person-wearing-turban","man-wearing-turban","woman-wearing-turban","person-with-skullcap","woman-with-headscarf","person-in-tuxedo","man-in-tuxedo","woman-in-tuxedo","person-with-veil","man-with-veil","woman-with-veil","pregnant-woman","pregnant-man","pregnant-person","breastfeeding","woman-feeding-baby","man-feeding-baby","person-feeding-baby","baby-angel","santa-claus","mrs-claus","mx-claus","superhero","man-superhero","woman-superhero","supervillain","man-supervillain","woman-supervillain","mage","man-mage","woman-mage","fairy","man-fairy","woman-fairy","vampire","man-vampire","woman-vampire","merperson","merman","mermaid","elf","man-elf","woman-elf","genie","man-genie","woman-genie","zombie","man-zombie","woman-zombie","troll","person-getting-massage","man-getting-massage","woman-getting-massage","person-getting-haircut","man-getting-haircut","woman-getting-haircut","person-walking","man-walking","woman-walking","person-standing","man-standing","woman-standing","person-kneeling","man-kneeling","woman-kneeling","person-with-white-cane","man-with-white-cane","woman-with-white-cane","person-in-motorized-wheelchair","man-in-motorized-wheelchair","woman-in-motorized-wheelchair","person-in-manual-wheelchair","man-in-manual-wheelchair","woman-in-manual-wheelchair","person-running","man-running","woman-running","woman-dancing","man-dancing","person-in-suit-levitating","people-with-bunny-ears","men-with-bunny-ears","women-with-bunny-ears","person-in-steamy-room","man-in-steamy-room","woman-in-steamy-room","person-climbing","man-climbing","woman-climbing","person-fencing","horse-racing","skier","snowboarder","person-golfing","man-golfing","woman-golfing","person-surfing","man-surfing","woman-surfing","person-rowing-boat","man-rowing-boat","woman-rowing-boat","person-swimming","man-swimming","woman-swimming","person-bouncing-ball","man-bouncing-ball","woman-bouncing-ball","person-lifting-weights","man-lifting-weights","woman-lifting-weights","person-biking","man-biking","woman-biking","person-mountain-biking","man-mountain-biking","woman-mountain-biking","person-cartwheeling","man-cartwheeling","woman-cartwheeling","people-wrestling","men-wrestling","women-wrestling","person-playing-water-polo","man-playing-water-polo","woman-playing-water-polo","person-playing-handball","man-playing-handball","woman-playing-handball","person-juggling","man-juggling","woman-juggling","person-in-lotus-position","man-in-lotus-position","woman-in-lotus-position","person-taking-bath","person-in-bed","people-holding-hands","women-holding-hands","woman-and-man-holding-hands","men-holding-hands","kiss","kiss-woman-man","kiss-man-man","kiss-woman-woman","couple-with-heart","couple-with-heart-woman-man","couple-with-heart-man-man","couple-with-heart-woman-woman","family","family-man-woman-boy","family-man-woman-girl","family-man-woman-girl-boy","family-man-woman-boy-boy","family-man-woman-girl-girl","family-man-man-boy","family-man-man-girl","family-man-man-girl-boy","family-man-man-boy-boy","family-man-man-girl-girl","family-woman-woman-boy","family-woman-woman-girl","family-woman-woman-girl-boy","family-woman-woman-boy-boy","family-woman-woman-girl-girl","family-man-boy","family-man-boy-boy","family-man-girl","family-man-girl-boy","family-man-girl-girl","family-woman-boy","family-woman-boy-boy","family-woman-girl","family-woman-girl-boy","family-woman-girl-girl","speaking-head","bust-in-silhouette","busts-in-silhouette","people-hugging","footprints"]},{"id":"animals_&_nature","name":"Animals & Nature","emojis":["monkey-face","monkey","gorilla","orangutan","dog-face","dog","guide-dog","service-dog","poodle","wolf","fox","raccoon","cat-face","cat","black-cat","lion","tiger-face","tiger","leopard","horse-face","horse","unicorn","zebra","deer","bison","cow-face","ox","water-buffalo","cow","pig-face","pig","boar","pig-nose","ram","ewe","goat","camel","twohump-camel","llama","giraffe","elephant","mammoth","rhinoceros","hippopotamus","mouse-face","mouse","rat","hamster","rabbit-face","rabbit","chipmunk","beaver","hedgehog","bat","bear","polar-bear","koala","panda","sloth","otter","skunk","kangaroo","badger","paw-prints","turkey","chicken","rooster","hatching-chick","baby-chick","frontfacing-baby-chick","bird","penguin","dove","eagle","duck","swan","owl","dodo","feather","flamingo","peacock","parrot","frog","crocodile","turtle","lizard","snake","dragon-face","dragon","sauropod","trex","spouting-whale","whale","dolphin","seal","fish","tropical-fish","blowfish","shark","octopus","spiral-shell","coral","snail","butterfly","bug","ant","honeybee","beetle","lady-beetle","cricket","cockroach","spider","spider-web","scorpion","mosquito","fly","worm","microbe","bouquet","cherry-blossom","white-flower","lotus","rosette","rose","wilted-flower","hibiscus","sunflower","blossom","tulip","seedling","potted-plant","evergreen-tree","deciduous-tree","palm-tree","cactus","sheaf-of-rice","herb","shamrock","four-leaf-clover","maple-leaf","fallen-leaf","leaf-fluttering-in-wind","empty-nest","nest-with-eggs"]},{"id":"food_&_drink","name":"Food & Drink","emojis":["grapes","melon","watermelon","tangerine","lemon","banana","pineapple","mango","red-apple","green-apple","pear","peach","cherries","strawberry","blueberries","kiwi-fruit","tomato","olive","coconut","avocado","eggplant","potato","carrot","ear-of-corn","hot-pepper","bell-pepper","cucumber","leafy-green","broccoli","garlic","onion","mushroom","peanuts","beans","chestnut","bread","croissant","baguette-bread","flatbread","pretzel","bagel","pancakes","waffle","cheese-wedge","meat-on-bone","poultry-leg","cut-of-meat","bacon","hamburger","french-fries","pizza","hot-dog","sandwich","taco","burrito","tamale","stuffed-flatbread","falafel","egg","cooking","shallow-pan-of-food","pot-of-food","fondue","bowl-with-spoon","green-salad","popcorn","butter","salt","canned-food","bento-box","rice-cracker","rice-ball","cooked-rice","curry-rice","steaming-bowl","spaghetti","roasted-sweet-potato","oden","sushi","fried-shrimp","fish-cake-with-swirl","moon-cake","dango","dumpling","fortune-cookie","takeout-box","crab","lobster","shrimp","squid","oyster","soft-ice-cream","shaved-ice","ice-cream","doughnut","cookie","birthday-cake","shortcake","cupcake","pie","chocolate-bar","candy","lollipop","custard","honey-pot","baby-bottle","glass-of-milk","hot-beverage","teapot","teacup-without-handle","sake","bottle-with-popping-cork","wine-glass","cocktail-glass","tropical-drink","beer-mug","clinking-beer-mugs","clinking-glasses","tumbler-glass","pouring-liquid","cup-with-straw","bubble-tea","beverage-box","mate","ice","chopsticks","fork-and-knife-with-plate","fork-and-knife","spoon","kitchen-knife","jar","amphora"]},{"id":"travel_&_places","name":"Travel & Places","emojis":["globe-showing-europeafrica","globe-showing-americas","globe-showing-asiaaustralia","globe-with-meridians","world-map","map-of-japan","compass","snowcapped-mountain","mountain","volcano","mount-fuji","camping","beach-with-umbrella","desert","desert-island","national-park","stadium","classical-building","building-construction","brick","rock","wood","hut","houses","derelict-house","house","house-with-garden","office-building","japanese-post-office","post-office","hospital","bank","hotel","love-hotel","convenience-store","school","department-store","factory","japanese-castle","castle","wedding","tokyo-tower","statue-of-liberty","church","mosque","hindu-temple","synagogue","shinto-shrine","kaaba","fountain","tent","foggy","night-with-stars","cityscape","sunrise-over-mountains","sunrise","cityscape-at-dusk","sunset","bridge-at-night","hot-springs","carousel-horse","playground-slide","ferris-wheel","roller-coaster","barber-pole","circus-tent","locomotive","railway-car","highspeed-train","bullet-train","train","metro","light-rail","station","tram","monorail","mountain-railway","tram-car","bus","oncoming-bus","trolleybus","minibus","ambulance","fire-engine","police-car","oncoming-police-car","taxi","oncoming-taxi","automobile","oncoming-automobile","sport-utility-vehicle","pickup-truck","delivery-truck","articulated-lorry","tractor","racing-car","motorcycle","motor-scooter","manual-wheelchair","motorized-wheelchair","auto-rickshaw","bicycle","kick-scooter","skateboard","roller-skate","bus-stop","motorway","railway-track","oil-drum","fuel-pump","wheel","police-car-light","horizontal-traffic-light","vertical-traffic-light","stop-sign","construction","anchor","ring-buoy","sailboat","canoe","speedboat","passenger-ship","ferry","motor-boat","ship","airplane","small-airplane","airplane-departure","airplane-arrival","parachute","seat","helicopter","suspension-railway","mountain-cableway","aerial-tramway","satellite","rocket","flying-saucer","bellhop-bell","luggage","hourglass-done","hourglass-not-done","watch","alarm-clock","stopwatch","timer-clock","mantelpiece-clock","twelve-oclock","twelvethirty","one-oclock","onethirty","two-oclock","twothirty","three-oclock","threethirty","four-oclock","fourthirty","five-oclock","fivethirty","six-oclock","sixthirty","seven-oclock","seventhirty","eight-oclock","eightthirty","nine-oclock","ninethirty","ten-oclock","tenthirty","eleven-oclock","eleventhirty","new-moon","waxing-crescent-moon","first-quarter-moon","waxing-gibbous-moon","full-moon","waning-gibbous-moon","last-quarter-moon","waning-crescent-moon","crescent-moon","new-moon-face","first-quarter-moon-face","last-quarter-moon-face","thermometer","sun","full-moon-face","sun-with-face","ringed-planet","star","glowing-star","shooting-star","milky-way","cloud","sun-behind-cloud","cloud-with-lightning-and-rain","sun-behind-small-cloud","sun-behind-large-cloud","sun-behind-rain-cloud","cloud-with-rain","cloud-with-snow","cloud-with-lightning","tornado","fog","wind-face","cyclone","rainbow","closed-umbrella","umbrella","umbrella-with-rain-drops","umbrella-on-ground","high-voltage","snowflake","snowman","snowman-without-snow","comet","fire","droplet","water-wave"]},{"id":"activities","name":"Activities","emojis":["jackolantern","christmas-tree","fireworks","sparkler","firecracker","sparkles","balloon","party-popper","confetti-ball","tanabata-tree","pine-decoration","japanese-dolls","carp-streamer","wind-chime","moon-viewing-ceremony","red-envelope","ribbon","wrapped-gift","reminder-ribbon","admission-tickets","ticket","military-medal","trophy","sports-medal","1st-place-medal","2nd-place-medal","3rd-place-medal","soccer-ball","baseball","softball","basketball","volleyball","american-football","rugby-football","tennis","flying-disc","bowling","cricket-game","field-hockey","ice-hockey","lacrosse","ping-pong","badminton","boxing-glove","martial-arts-uniform","goal-net","flag-in-hole","ice-skate","fishing-pole","diving-mask","running-shirt","skis","sled","curling-stone","bullseye","yoyo","kite","pool-8-ball","crystal-ball","magic-wand","nazar-amulet","hamsa","video-game","joystick","slot-machine","game-die","puzzle-piece","teddy-bear","piata","mirror-ball","nesting-dolls","spade-suit","heart-suit","diamond-suit","club-suit","chess-pawn","joker","mahjong-red-dragon","flower-playing-cards","performing-arts","framed-picture","artist-palette","thread","sewing-needle","yarn","knot"]},{"id":"objects","name":"Objects","emojis":["glasses","sunglasses","goggles","lab-coat","safety-vest","necktie","tshirt","jeans","scarf","gloves","coat","socks","dress","kimono","sari","onepiece-swimsuit","briefs","shorts","bikini","womans-clothes","purse","handbag","clutch-bag","shopping-bags","backpack","thong-sandal","mans-shoe","running-shoe","hiking-boot","flat-shoe","highheeled-shoe","womans-sandal","ballet-shoes","womans-boot","crown","womans-hat","top-hat","graduation-cap","billed-cap","military-helmet","rescue-workers-helmet","prayer-beads","lipstick","ring","gem-stone","muted-speaker","speaker-low-volume","speaker-medium-volume","speaker-high-volume","loudspeaker","megaphone","postal-horn","bell","bell-with-slash","musical-score","musical-note","musical-notes","studio-microphone","level-slider","control-knobs","microphone","headphone","radio","saxophone","accordion","guitar","musical-keyboard","trumpet","violin","banjo","drum","long-drum","mobile-phone","mobile-phone-with-arrow","telephone","telephone-receiver","pager","fax-machine","battery","low-battery","electric-plug","laptop","desktop-computer","printer","keyboard","computer-mouse","trackball","computer-disk","floppy-disk","optical-disk","dvd","abacus","movie-camera","film-frames","film-projector","clapper-board","television","camera","camera-with-flash","video-camera","videocassette","magnifying-glass-tilted-left","magnifying-glass-tilted-right","candle","light-bulb","flashlight","red-paper-lantern","diya-lamp","notebook-with-decorative-cover","closed-book","open-book","green-book","blue-book","orange-book","books","notebook","ledger","page-with-curl","scroll","page-facing-up","newspaper","rolledup-newspaper","bookmark-tabs","bookmark","label","money-bag","coin","yen-banknote","dollar-banknote","euro-banknote","pound-banknote","money-with-wings","credit-card","receipt","chart-increasing-with-yen","envelope","email","incoming-envelope","envelope-with-arrow","outbox-tray","inbox-tray","package","closed-mailbox-with-raised-flag","closed-mailbox-with-lowered-flag","open-mailbox-with-raised-flag","open-mailbox-with-lowered-flag","postbox","ballot-box-with-ballot","pencil","black-nib","fountain-pen","pen","paintbrush","crayon","memo","briefcase","file-folder","open-file-folder","card-index-dividers","calendar","tearoff-calendar","spiral-notepad","spiral-calendar","card-index","chart-increasing","chart-decreasing","bar-chart","clipboard","pushpin","round-pushpin","paperclip","linked-paperclips","straight-ruler","triangular-ruler","scissors","card-file-box","file-cabinet","wastebasket","locked","unlocked","locked-with-pen","locked-with-key","key","old-key","hammer","axe","pick","hammer-and-pick","hammer-and-wrench","dagger","crossed-swords","water-pistol","boomerang","bow-and-arrow","shield","carpentry-saw","wrench","screwdriver","nut-and-bolt","gear","clamp","balance-scale","white-cane","link","chains","hook","toolbox","magnet","ladder","alembic","test-tube","petri-dish","dna","microscope","telescope","satellite-antenna","syringe","drop-of-blood","pill","adhesive-bandage","crutch","stethoscope","xray","door","elevator","mirror","window","bed","couch-and-lamp","chair","toilet","plunger","shower","bathtub","mouse-trap","razor","lotion-bottle","safety-pin","broom","basket","roll-of-paper","bucket","soap","bubbles","toothbrush","sponge","fire-extinguisher","shopping-cart","cigarette","coffin","headstone","funeral-urn","moai","placard","identification-card"]},{"id":"symbols","name":"Symbols","emojis":["atm-sign","litter-in-bin-sign","potable-water","wheelchair-symbol","mens-room","womens-room","restroom","baby-symbol","water-closet","passport-control","customs","baggage-claim","left-luggage","warning","children-crossing","no-entry","prohibited","no-bicycles","no-smoking","no-littering","nonpotable-water","no-pedestrians","no-mobile-phones","no-one-under-eighteen","radioactive","biohazard","up-arrow","upright-arrow","right-arrow","downright-arrow","down-arrow","downleft-arrow","left-arrow","upleft-arrow","updown-arrow","leftright-arrow","right-arrow-curving-left","left-arrow-curving-right","right-arrow-curving-up","right-arrow-curving-down","clockwise-vertical-arrows","counterclockwise-arrows-button","back-arrow","end-arrow","on-arrow","soon-arrow","top-arrow","place-of-worship","atom-symbol","om","star-of-david","wheel-of-dharma","yin-yang","latin-cross","orthodox-cross","star-and-crescent","peace-symbol","menorah","dotted-sixpointed-star","aries","taurus","gemini","cancer","leo","virgo","libra","scorpio","sagittarius","capricorn","aquarius","pisces","ophiuchus","shuffle-tracks-button","repeat-button","repeat-single-button","play-button","fastforward-button","next-track-button","play-or-pause-button","reverse-button","fast-reverse-button","last-track-button","upwards-button","fast-up-button","downwards-button","fast-down-button","pause-button","stop-button","record-button","eject-button","cinema","dim-button","bright-button","antenna-bars","vibration-mode","mobile-phone-off","female-sign","male-sign","transgender-symbol","multiply","plus","minus","divide","heavy-equals-sign","infinity","double-exclamation-mark","exclamation-question-mark","red-question-mark","white-question-mark","white-exclamation-mark","red-exclamation-mark","wavy-dash","currency-exchange","heavy-dollar-sign","medical-symbol","recycling-symbol","fleurdelis","trident-emblem","name-badge","japanese-symbol-for-beginner","hollow-red-circle","check-mark-button","check-box-with-check","check-mark","cross-mark","cross-mark-button","curly-loop","double-curly-loop","part-alternation-mark","eightspoked-asterisk","eightpointed-star","sparkle","copyright","registered","trade-mark","keycap","keycap","keycap-0","keycap-1","keycap-2","keycap-3","keycap-4","keycap-5","keycap-6","keycap-7","keycap-8","keycap-9","keycap-10","input-latin-uppercase","input-latin-lowercase","input-numbers","input-symbols","input-latin-letters","a-button-blood-type","ab-button-blood-type","b-button-blood-type","cl-button","cool-button","free-button","information","id-button","circled-m","new-button","ng-button","o-button-blood-type","ok-button","p-button","sos-button","up-button","vs-button","japanese-here-button","japanese-service-charge-button","japanese-monthly-amount-button","japanese-not-free-of-charge-button","japanese-reserved-button","japanese-bargain-button","japanese-discount-button","japanese-free-of-charge-button","japanese-prohibited-button","japanese-acceptable-button","japanese-application-button","japanese-passing-grade-button","japanese-vacancy-button","japanese-congratulations-button","japanese-secret-button","japanese-open-for-business-button","japanese-no-vacancy-button","red-circle","orange-circle","yellow-circle","green-circle","blue-circle","purple-circle","brown-circle","black-circle","white-circle","red-square","orange-square","yellow-square","green-square","blue-square","purple-square","brown-square","black-large-square","white-large-square","black-medium-square","white-medium-square","black-mediumsmall-square","white-mediumsmall-square","black-small-square","white-small-square","large-orange-diamond","large-blue-diamond","small-orange-diamond","small-blue-diamond","red-triangle-pointed-up","red-triangle-pointed-down","diamond-with-a-dot","radio-button","white-square-button","black-square-button"]},{"id":"flags","name":"Flags","emojis":["chequered-flag","triangular-flag","crossed-flags","black-flag","white-flag","rainbow-flag","transgender-flag","pirate-flag","flag-ascension-island","flag-andorra","flag-united-arab-emirates","flag-afghanistan","flag-antigua--barbuda","flag-anguilla","flag-albania","flag-armenia","flag-angola","flag-antarctica","flag-argentina","flag-american-samoa","flag-austria","flag-australia","flag-aruba","flag-land-islands","flag-azerbaijan","flag-bosnia--herzegovina","flag-barbados","flag-bangladesh","flag-belgium","flag-burkina-faso","flag-bulgaria","flag-bahrain","flag-burundi","flag-benin","flag-st-barthlemy","flag-bermuda","flag-brunei","flag-bolivia","flag-caribbean-netherlands","flag-brazil","flag-bahamas","flag-bhutan","flag-bouvet-island","flag-botswana","flag-belarus","flag-belize","flag-canada","flag-cocos-keeling-islands","flag-congo--kinshasa","flag-central-african-republic","flag-congo--brazzaville","flag-switzerland","flag-cte-divoire","flag-cook-islands","flag-chile","flag-cameroon","flag-china","flag-colombia","flag-clipperton-island","flag-costa-rica","flag-cuba","flag-cape-verde","flag-curaao","flag-christmas-island","flag-cyprus","flag-czechia","flag-germany","flag-diego-garcia","flag-djibouti","flag-denmark","flag-dominica","flag-dominican-republic","flag-algeria","flag-ceuta--melilla","flag-ecuador","flag-estonia","flag-egypt","flag-western-sahara","flag-eritrea","flag-spain","flag-ethiopia","flag-european-union","flag-finland","flag-fiji","flag-falkland-islands","flag-micronesia","flag-faroe-islands","flag-france","flag-gabon","flag-united-kingdom","flag-grenada","flag-georgia","flag-french-guiana","flag-guernsey","flag-ghana","flag-gibraltar","flag-greenland","flag-gambia","flag-guinea","flag-guadeloupe","flag-equatorial-guinea","flag-greece","flag-south-georgia--south-sandwich-islands","flag-guatemala","flag-guam","flag-guineabissau","flag-guyana","flag-hong-kong-sar-china","flag-heard--mcdonald-islands","flag-honduras","flag-croatia","flag-haiti","flag-hungary","flag-canary-islands","flag-indonesia","flag-ireland","flag-israel","flag-isle-of-man","flag-india","flag-british-indian-ocean-territory","flag-iraq","flag-iran","flag-iceland","flag-italy","flag-jersey","flag-jamaica","flag-jordan","flag-japan","flag-kenya","flag-kyrgyzstan","flag-cambodia","flag-kiribati","flag-comoros","flag-st-kitts--nevis","flag-north-korea","flag-south-korea","flag-kuwait","flag-cayman-islands","flag-kazakhstan","flag-laos","flag-lebanon","flag-st-lucia","flag-liechtenstein","flag-sri-lanka","flag-liberia","flag-lesotho","flag-lithuania","flag-luxembourg","flag-latvia","flag-libya","flag-morocco","flag-monaco","flag-moldova","flag-montenegro","flag-st-martin","flag-madagascar","flag-marshall-islands","flag-north-macedonia","flag-mali","flag-myanmar-burma","flag-mongolia","flag-macao-sar-china","flag-northern-mariana-islands","flag-martinique","flag-mauritania","flag-montserrat","flag-malta","flag-mauritius","flag-maldives","flag-malawi","flag-mexico","flag-malaysia","flag-mozambique","flag-namibia","flag-new-caledonia","flag-niger","flag-norfolk-island","flag-nigeria","flag-nicaragua","flag-netherlands","flag-norway","flag-nepal","flag-nauru","flag-niue","flag-new-zealand","flag-oman","flag-panama","flag-peru","flag-french-polynesia","flag-papua-new-guinea","flag-philippines","flag-pakistan","flag-poland","flag-st-pierre--miquelon","flag-pitcairn-islands","flag-puerto-rico","flag-palestinian-territories","flag-portugal","flag-palau","flag-paraguay","flag-qatar","flag-runion","flag-romania","flag-serbia","flag-russia","flag-rwanda","flag-saudi-arabia","flag-solomon-islands","flag-seychelles","flag-sudan","flag-sweden","flag-singapore","flag-st-helena","flag-slovenia","flag-svalbard--jan-mayen","flag-slovakia","flag-sierra-leone","flag-san-marino","flag-senegal","flag-somalia","flag-suriname","flag-south-sudan","flag-so-tom--prncipe","flag-el-salvador","flag-sint-maarten","flag-syria","flag-eswatini","flag-tristan-da-cunha","flag-turks--caicos-islands","flag-chad","flag-french-southern-territories","flag-togo","flag-thailand","flag-tajikistan","flag-tokelau","flag-timorleste","flag-turkmenistan","flag-tunisia","flag-tonga","flag-turkey","flag-trinidad--tobago","flag-tuvalu","flag-taiwan","flag-tanzania","flag-ukraine","flag-uganda","flag-us-outlying-islands","flag-united-nations","flag-united-states","flag-uruguay","flag-uzbekistan","flag-vatican-city","flag-st-vincent--grenadines","flag-venezuela","flag-british-virgin-islands","flag-us-virgin-islands","flag-vietnam","flag-vanuatu","flag-wallis--futuna","flag-samoa","flag-kosovo","flag-yemen","flag-mayotte","flag-south-africa","flag-zambia","flag-zimbabwe","flag-england","flag-scotland","flag-wales"]}],"emojis":{"grinning-face":{"a":"Grinning Face","b":"1F600","j":["face","grin","smile","happy","joy",":D"]},"grinning-face-with-big-eyes":{"a":"Grinning Face with Big Eyes","b":"1F603","j":["face","mouth","open","smile","happy","joy","haha",":D",":)","funny"]},"grinning-face-with-smiling-eyes":{"a":"Grinning Face with Smiling Eyes","b":"1F604","j":["eye","face","mouth","open","smile","happy","joy","funny","haha","laugh","like",":D",":)"]},"beaming-face-with-smiling-eyes":{"a":"Beaming Face with Smiling Eyes","b":"1F601","j":["eye","face","grin","smile","happy","joy","kawaii"]},"grinning-squinting-face":{"a":"Grinning Squinting Face","b":"1F606","j":["face","laugh","mouth","satisfied","smile","happy","joy","lol","haha","glad","XD"]},"grinning-face-with-sweat":{"a":"Grinning Face with Sweat","b":"1F605","j":["cold","face","open","smile","sweat","hot","happy","laugh","relief"]},"rolling-on-the-floor-laughing":{"a":"Rolling on the Floor Laughing","b":"1F923","j":["face","floor","laugh","rofl","rolling","rotfl","laughing","lol","haha"]},"face-with-tears-of-joy":{"a":"Face with Tears of Joy","b":"1F602","j":["face","joy","laugh","tear","cry","tears","weep","happy","happytears","haha"]},"slightly-smiling-face":{"a":"Slightly Smiling Face","b":"1F642","j":["face","smile"]},"upsidedown-face":{"a":"Upside-Down Face","b":"1F643","j":["face","upside-down","upside_down_face","flipped","silly","smile"]},"melting-face":{"a":"⊛ Melting Face","b":"1FAE0","j":["disappear","dissolve","liquid","melt"]},"winking-face":{"a":"Winking Face","b":"1F609","j":["face","wink","happy","mischievous","secret",";)","smile","eye"]},"smiling-face-with-smiling-eyes":{"a":"Smiling Face with Smiling Eyes","b":"1F60A","j":["blush","eye","face","smile","happy","flushed","crush","embarrassed","shy","joy"]},"smiling-face-with-halo":{"a":"Smiling Face with Halo","b":"1F607","j":["angel","face","fantasy","halo","innocent","heaven"]},"smiling-face-with-hearts":{"a":"Smiling Face with Hearts","b":"1F970","j":["adore","crush","hearts","in love","face","love","like","affection","valentines","infatuation"]},"smiling-face-with-hearteyes":{"a":"Smiling Face with Heart-Eyes","b":"1F60D","j":["eye","face","love","smile","smiling face with heart-eyes","smiling_face_with_heart_eyes","like","affection","valentines","infatuation","crush","heart"]},"starstruck":{"a":"Star-Struck","b":"1F929","j":["eyes","face","grinning","star","star-struck","starry-eyed","star_struck","smile","starry"]},"face-blowing-a-kiss":{"a":"Face Blowing a Kiss","b":"1F618","j":["face","kiss","love","like","affection","valentines","infatuation"]},"kissing-face":{"a":"Kissing Face","b":"1F617","j":["face","kiss","love","like","3","valentines","infatuation"]},"smiling-face":{"a":"Smiling Face","b":"263A","j":["face","outlined","relaxed","smile","blush","massage","happiness"]},"kissing-face-with-closed-eyes":{"a":"Kissing Face with Closed Eyes","b":"1F61A","j":["closed","eye","face","kiss","love","like","affection","valentines","infatuation"]},"kissing-face-with-smiling-eyes":{"a":"Kissing Face with Smiling Eyes","b":"1F619","j":["eye","face","kiss","smile","affection","valentines","infatuation"]},"smiling-face-with-tear":{"a":"Smiling Face with Tear","b":"1F972","j":["grateful","proud","relieved","smiling","tear","touched","sad","cry","pretend"]},"face-savoring-food":{"a":"Face Savoring Food","b":"1F60B","j":["delicious","face","savouring","smile","yum","happy","joy","tongue","silly","yummy","nom"]},"face-with-tongue":{"a":"Face with Tongue","b":"1F61B","j":["face","tongue","prank","childish","playful","mischievous","smile"]},"winking-face-with-tongue":{"a":"Winking Face with Tongue","b":"1F61C","j":["eye","face","joke","tongue","wink","prank","childish","playful","mischievous","smile"]},"zany-face":{"a":"Zany Face","b":"1F92A","j":["eye","goofy","large","small","face","crazy"]},"squinting-face-with-tongue":{"a":"Squinting Face with Tongue","b":"1F61D","j":["eye","face","horrible","taste","tongue","prank","playful","mischievous","smile"]},"moneymouth-face":{"a":"Money-Mouth Face","b":"1F911","j":["face","money","money-mouth face","mouth","money_mouth_face","rich","dollar"]},"smiling-face-with-open-hands":{"a":"Smiling Face with Open Hands","b":"1F917","j":["face","hug","hugging","open hands","smiling face","hugging_face","smile"]},"face-with-hand-over-mouth":{"a":"Face with Hand over Mouth","b":"1F92D","j":["whoops","shock","sudden realization","surprise","face"]},"face-with-open-eyes-and-hand-over-mouth":{"a":"⊛ Face with Open Eyes and Hand over Mouth","b":"1FAE2","j":["amazement","awe","disbelief","embarrass","scared","surprise"]},"face-with-peeking-eye":{"a":"⊛ Face with Peeking Eye","b":"1FAE3","j":["captivated","peep","stare"]},"shushing-face":{"a":"Shushing Face","b":"1F92B","j":["quiet","shush","face","shhh"]},"thinking-face":{"a":"Thinking Face","b":"1F914","j":["face","thinking","hmmm","think","consider"]},"saluting-face":{"a":"⊛ Saluting Face","b":"1FAE1","j":["ok","salute","sunny","troops","yes"]},"zippermouth-face":{"a":"Zipper-Mouth Face","b":"1F910","j":["face","mouth","zipper","zipper-mouth face","zipper_mouth_face","sealed","secret"]},"face-with-raised-eyebrow":{"a":"Face with Raised Eyebrow","b":"1F928","j":["distrust","skeptic","disapproval","disbelief","mild surprise","scepticism","face","surprise"]},"neutral-face":{"a":"Neutral Face","b":"1F610","j":["deadpan","face","meh","neutral","indifference",":|"]},"expressionless-face":{"a":"Expressionless Face","b":"1F611","j":["expressionless","face","inexpressive","meh","unexpressive","indifferent","-_-","deadpan"]},"face-without-mouth":{"a":"Face Without Mouth","b":"1F636","j":["face","mouth","quiet","silent","hellokitty"]},"dotted-line-face":{"a":"⊛ Dotted Line Face","b":"1FAE5","j":["depressed","disappear","hide","introvert","invisible"]},"face-in-clouds":{"a":"Face in Clouds","b":"1F636-200D-1F32B-FE0F","j":["absentminded","face in the fog","head in clouds","shower","steam","dream"]},"smirking-face":{"a":"Smirking Face","b":"1F60F","j":["face","smirk","smile","mean","prank","smug","sarcasm"]},"unamused-face":{"a":"Unamused Face","b":"1F612","j":["face","unamused","unhappy","indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"]},"face-with-rolling-eyes":{"a":"Face with Rolling Eyes","b":"1F644","j":["eyeroll","eyes","face","rolling","frustrated"]},"grimacing-face":{"a":"Grimacing Face","b":"1F62C","j":["face","grimace","teeth"]},"face-exhaling":{"a":"Face Exhaling","b":"1F62E-200D-1F4A8","j":["exhale","gasp","groan","relief","whisper","whistle","relieve","tired","sigh"]},"lying-face":{"a":"Lying Face","b":"1F925","j":["face","lie","pinocchio"]},"relieved-face":{"a":"Relieved Face","b":"1F60C","j":["face","relieved","relaxed","phew","massage","happiness"]},"pensive-face":{"a":"Pensive Face","b":"1F614","j":["dejected","face","pensive","sad","depressed","upset"]},"sleepy-face":{"a":"Sleepy Face","b":"1F62A","j":["face","sleep","tired","rest","nap"]},"drooling-face":{"a":"Drooling Face","b":"1F924","j":["drooling","face"]},"sleeping-face":{"a":"Sleeping Face","b":"1F634","j":["face","sleep","zzz","tired","sleepy","night"]},"face-with-medical-mask":{"a":"Face with Medical Mask","b":"1F637","j":["cold","doctor","face","mask","sick","ill","disease"]},"face-with-thermometer":{"a":"Face with Thermometer","b":"1F912","j":["face","ill","sick","thermometer","temperature","cold","fever"]},"face-with-headbandage":{"a":"Face with Head-Bandage","b":"1F915","j":["bandage","face","face with head-bandage","hurt","injury","face_with_head_bandage","injured","clumsy"]},"nauseated-face":{"a":"Nauseated Face","b":"1F922","j":["face","nauseated","vomit","gross","green","sick","throw up","ill"]},"face-vomiting":{"a":"Face Vomiting","b":"1F92E","j":["puke","sick","vomit","face"]},"sneezing-face":{"a":"Sneezing Face","b":"1F927","j":["face","gesundheit","sneeze","sick","allergy"]},"hot-face":{"a":"Hot Face","b":"1F975","j":["feverish","heat stroke","hot","red-faced","sweating","face","heat","red"]},"cold-face":{"a":"Cold Face","b":"1F976","j":["blue-faced","cold","freezing","frostbite","icicles","face","blue","frozen"]},"woozy-face":{"a":"Woozy Face","b":"1F974","j":["dizzy","intoxicated","tipsy","uneven eyes","wavy mouth","face","wavy"]},"face-with-crossedout-eyes":{"a":"Face with Crossed-out Eyes","b":"1F635","j":["crossed-out eyes","dead","face","face with crossed-out eyes","knocked out","dizzy_face","spent","unconscious","xox","dizzy"]},"face-with-spiral-eyes":{"a":"Face with Spiral Eyes","b":"1F635-200D-1F4AB","j":["dizzy","hypnotized","spiral","trouble","whoa","sick","ill","confused","nauseous","nausea"]},"exploding-head":{"a":"Exploding Head","b":"1F92F","j":["mind blown","shocked","face","mind","blown"]},"cowboy-hat-face":{"a":"Cowboy Hat Face","b":"1F920","j":["cowboy","cowgirl","face","hat"]},"partying-face":{"a":"Partying Face","b":"1F973","j":["celebration","hat","horn","party","face","woohoo"]},"disguised-face":{"a":"Disguised Face","b":"1F978","j":["disguise","face","glasses","incognito","nose","pretent","brows","moustache"]},"smiling-face-with-sunglasses":{"a":"Smiling Face with Sunglasses","b":"1F60E","j":["bright","cool","face","sun","sunglasses","smile","summer","beach","sunglass"]},"nerd-face":{"a":"Nerd Face","b":"1F913","j":["face","geek","nerd","nerdy","dork"]},"face-with-monocle":{"a":"Face with Monocle","b":"1F9D0","j":["stuffy","wealthy","face"]},"confused-face":{"a":"Confused Face","b":"1F615","j":["confused","face","meh","indifference","huh","weird","hmmm",":/"]},"face-with-diagonal-mouth":{"a":"⊛ Face with Diagonal Mouth","b":"1FAE4","j":["disappointed","meh","skeptical","unsure"]},"worried-face":{"a":"Worried Face","b":"1F61F","j":["face","worried","concern","nervous",":("]},"slightly-frowning-face":{"a":"Slightly Frowning Face","b":"1F641","j":["face","frown","frowning","disappointed","sad","upset"]},"frowning-face":{"a":"Frowning Face","b":"2639","j":["face","frown","sad","upset"]},"face-with-open-mouth":{"a":"Face with Open Mouth","b":"1F62E","j":["face","mouth","open","sympathy","surprise","impressed","wow","whoa",":O"]},"hushed-face":{"a":"Hushed Face","b":"1F62F","j":["face","hushed","stunned","surprised","woo","shh"]},"astonished-face":{"a":"Astonished Face","b":"1F632","j":["astonished","face","shocked","totally","xox","surprised","poisoned"]},"flushed-face":{"a":"Flushed Face","b":"1F633","j":["dazed","face","flushed","blush","shy","flattered"]},"pleading-face":{"a":"Pleading Face","b":"1F97A","j":["begging","mercy","puppy eyes","face"]},"face-holding-back-tears":{"a":"⊛ Face Holding Back Tears","b":"1F979","j":["angry","cry","proud","resist","sad"]},"frowning-face-with-open-mouth":{"a":"Frowning Face with Open Mouth","b":"1F626","j":["face","frown","mouth","open","aw","what"]},"anguished-face":{"a":"Anguished Face","b":"1F627","j":["anguished","face","stunned","nervous"]},"fearful-face":{"a":"Fearful Face","b":"1F628","j":["face","fear","fearful","scared","terrified","nervous","oops","huh"]},"anxious-face-with-sweat":{"a":"Anxious Face with Sweat","b":"1F630","j":["blue","cold","face","rushed","sweat","nervous"]},"sad-but-relieved-face":{"a":"Sad but Relieved Face","b":"1F625","j":["disappointed","face","relieved","whew","phew","sweat","nervous"]},"crying-face":{"a":"Crying Face","b":"1F622","j":["cry","face","sad","tear","tears","depressed","upset",":'("]},"loudly-crying-face":{"a":"Loudly Crying Face","b":"1F62D","j":["cry","face","sad","sob","tear","tears","upset","depressed"]},"face-screaming-in-fear":{"a":"Face Screaming in Fear","b":"1F631","j":["face","fear","munch","scared","scream","omg"]},"confounded-face":{"a":"Confounded Face","b":"1F616","j":["confounded","face","confused","sick","unwell","oops",":S"]},"persevering-face":{"a":"Persevering Face","b":"1F623","j":["face","persevere","sick","no","upset","oops"]},"disappointed-face":{"a":"Disappointed Face","b":"1F61E","j":["disappointed","face","sad","upset","depressed",":("]},"downcast-face-with-sweat":{"a":"Downcast Face with Sweat","b":"1F613","j":["cold","face","sweat","hot","sad","tired","exercise"]},"weary-face":{"a":"Weary Face","b":"1F629","j":["face","tired","weary","sleepy","sad","frustrated","upset"]},"tired-face":{"a":"Tired Face","b":"1F62B","j":["face","tired","sick","whine","upset","frustrated"]},"yawning-face":{"a":"Yawning Face","b":"1F971","j":["bored","tired","yawn","sleepy"]},"face-with-steam-from-nose":{"a":"Face with Steam From Nose","b":"1F624","j":["face","triumph","won","gas","phew","proud","pride"]},"pouting-face":{"a":"Pouting Face","b":"1F621","j":["angry","face","mad","pouting","rage","red","hate","despise"]},"angry-face":{"a":"Angry Face","b":"1F620","j":["anger","angry","face","mad","annoyed","frustrated"]},"face-with-symbols-on-mouth":{"a":"Face with Symbols on Mouth","b":"1F92C","j":["swearing","cursing","face","cussing","profanity","expletive"]},"smiling-face-with-horns":{"a":"Smiling Face with Horns","b":"1F608","j":["face","fairy tale","fantasy","horns","smile","devil"]},"angry-face-with-horns":{"a":"Angry Face with Horns","b":"1F47F","j":["demon","devil","face","fantasy","imp","angry","horns"]},"skull":{"a":"Skull","b":"1F480","j":["death","face","fairy tale","monster","dead","skeleton","creepy"]},"skull-and-crossbones":{"a":"Skull and Crossbones","b":"2620","j":["crossbones","death","face","monster","skull","poison","danger","deadly","scary","pirate","evil"]},"pile-of-poo":{"a":"Pile of Poo","b":"1F4A9","j":["dung","face","monster","poo","poop","hankey","shitface","fail","turd","shit"]},"clown-face":{"a":"Clown Face","b":"1F921","j":["clown","face"]},"ogre":{"a":"Ogre","b":"1F479","j":["creature","face","fairy tale","fantasy","monster","troll","red","mask","halloween","scary","creepy","devil","demon","japanese"]},"goblin":{"a":"Goblin","b":"1F47A","j":["creature","face","fairy tale","fantasy","monster","red","evil","mask","scary","creepy","japanese"]},"ghost":{"a":"Ghost","b":"1F47B","j":["creature","face","fairy tale","fantasy","monster","halloween","spooky","scary"]},"alien":{"a":"Alien","b":"1F47D","j":["creature","extraterrestrial","face","fantasy","ufo","UFO","paul","weird","outer_space"]},"alien-monster":{"a":"Alien Monster","b":"1F47E","j":["alien","creature","extraterrestrial","face","monster","ufo","game","arcade","play"]},"robot":{"a":"Robot","b":"1F916","j":["face","monster","computer","machine","bot"]},"grinning-cat":{"a":"Grinning Cat","b":"1F63A","j":["cat","face","grinning","mouth","open","smile","animal","cats","happy"]},"grinning-cat-with-smiling-eyes":{"a":"Grinning Cat with Smiling Eyes","b":"1F638","j":["cat","eye","face","grin","smile","animal","cats"]},"cat-with-tears-of-joy":{"a":"Cat with Tears of Joy","b":"1F639","j":["cat","face","joy","tear","animal","cats","haha","happy","tears"]},"smiling-cat-with-hearteyes":{"a":"Smiling Cat with Heart-Eyes","b":"1F63B","j":["cat","eye","face","heart","love","smile","smiling cat with heart-eyes","smiling_cat_with_heart_eyes","animal","like","affection","cats","valentines"]},"cat-with-wry-smile":{"a":"Cat with Wry Smile","b":"1F63C","j":["cat","face","ironic","smile","wry","animal","cats","smirk"]},"kissing-cat":{"a":"Kissing Cat","b":"1F63D","j":["cat","eye","face","kiss","animal","cats"]},"weary-cat":{"a":"Weary Cat","b":"1F640","j":["cat","face","oh","surprised","weary","animal","cats","munch","scared","scream"]},"crying-cat":{"a":"Crying Cat","b":"1F63F","j":["cat","cry","face","sad","tear","animal","tears","weep","cats","upset"]},"pouting-cat":{"a":"Pouting Cat","b":"1F63E","j":["cat","face","pouting","animal","cats"]},"seenoevil-monkey":{"a":"See-No-Evil Monkey","b":"1F648","j":["evil","face","forbidden","monkey","see","see-no-evil monkey","see_no_evil_monkey","animal","nature","haha"]},"hearnoevil-monkey":{"a":"Hear-No-Evil Monkey","b":"1F649","j":["evil","face","forbidden","hear","hear-no-evil monkey","monkey","hear_no_evil_monkey","animal","nature"]},"speaknoevil-monkey":{"a":"Speak-No-Evil Monkey","b":"1F64A","j":["evil","face","forbidden","monkey","speak","speak-no-evil monkey","speak_no_evil_monkey","animal","nature","omg"]},"kiss-mark":{"a":"Kiss Mark","b":"1F48B","j":["kiss","lips","face","love","like","affection","valentines"]},"love-letter":{"a":"Love Letter","b":"1F48C","j":["heart","letter","love","mail","email","like","affection","envelope","valentines"]},"heart-with-arrow":{"a":"Heart with Arrow","b":"1F498","j":["arrow","cupid","love","like","heart","affection","valentines"]},"heart-with-ribbon":{"a":"Heart with Ribbon","b":"1F49D","j":["ribbon","valentine","love","valentines"]},"sparkling-heart":{"a":"Sparkling Heart","b":"1F496","j":["excited","sparkle","love","like","affection","valentines"]},"growing-heart":{"a":"Growing Heart","b":"1F497","j":["excited","growing","nervous","pulse","like","love","affection","valentines","pink"]},"beating-heart":{"a":"Beating Heart","b":"1F493","j":["beating","heartbeat","pulsating","love","like","affection","valentines","pink","heart"]},"revolving-hearts":{"a":"Revolving Hearts","b":"1F49E","j":["revolving","love","like","affection","valentines"]},"two-hearts":{"a":"Two Hearts","b":"1F495","j":["love","like","affection","valentines","heart"]},"heart-decoration":{"a":"Heart Decoration","b":"1F49F","j":["heart","purple-square","love","like"]},"heart-exclamation":{"a":"Heart Exclamation","b":"2763","j":["exclamation","mark","punctuation","decoration","love"]},"broken-heart":{"a":"Broken Heart","b":"1F494","j":["break","broken","sad","sorry","heart","heartbreak"]},"heart-on-fire":{"a":"Heart on Fire","b":"2764-FE0F-200D-1F525","j":["burn","heart","love","lust","sacred heart","passionate","enthusiastic"]},"mending-heart":{"a":"Mending Heart","b":"2764-FE0F-200D-1FA79","j":["healthier","improving","mending","recovering","recuperating","well","broken heart","bandage","wounded"]},"red-heart":{"a":"Red Heart","b":"2764","j":["heart","love","like","valentines"]},"orange-heart":{"a":"Orange Heart","b":"1F9E1","j":["orange","love","like","affection","valentines"]},"yellow-heart":{"a":"Yellow Heart","b":"1F49B","j":["yellow","love","like","affection","valentines"]},"green-heart":{"a":"Green Heart","b":"1F49A","j":["green","love","like","affection","valentines"]},"blue-heart":{"a":"Blue Heart","b":"1F499","j":["blue","love","like","affection","valentines"]},"purple-heart":{"a":"Purple Heart","b":"1F49C","j":["purple","love","like","affection","valentines"]},"brown-heart":{"a":"Brown Heart","b":"1F90E","j":["brown","heart","coffee"]},"black-heart":{"a":"Black Heart","b":"1F5A4","j":["black","evil","wicked"]},"white-heart":{"a":"White Heart","b":"1F90D","j":["heart","white","pure"]},"hundred-points":{"a":"Hundred Points","b":"1F4AF","j":["100","full","hundred","score","perfect","numbers","century","exam","quiz","test","pass"]},"anger-symbol":{"a":"Anger Symbol","b":"1F4A2","j":["angry","comic","mad"]},"collision":{"a":"Collision","b":"1F4A5","j":["boom","comic","bomb","explode","explosion","blown"]},"dizzy":{"a":"Dizzy","b":"1F4AB","j":["comic","star","sparkle","shoot","magic"]},"sweat-droplets":{"a":"Sweat Droplets","b":"1F4A6","j":["comic","splashing","sweat","water","drip","oops"]},"dashing-away":{"a":"Dashing Away","b":"1F4A8","j":["comic","dash","running","wind","air","fast","shoo","fart","smoke","puff"]},"hole":{"a":"Hole","b":"1F573","j":["embarrassing"]},"bomb":{"a":"Bomb","b":"1F4A3","j":["comic","boom","explode","explosion","terrorism"]},"speech-balloon":{"a":"Speech Balloon","b":"1F4AC","j":["balloon","bubble","comic","dialog","speech","words","message","talk","chatting"]},"eye-in-speech-bubble":{"a":"Eye in Speech Bubble","b":"1F441-FE0F-200D-1F5E8-FE0F","j":["eye","speech bubble","witness","info"]},"left-speech-bubble":{"a":"Left Speech Bubble","b":"1F5E8","j":["dialog","speech","words","message","talk","chatting"]},"right-anger-bubble":{"a":"Right Anger Bubble","b":"1F5EF","j":["angry","balloon","bubble","mad","caption","speech","thinking"]},"thought-balloon":{"a":"Thought Balloon","b":"1F4AD","j":["balloon","bubble","comic","thought","cloud","speech","thinking","dream"]},"zzz":{"a":"Zzz","b":"1F4A4","j":["comic","sleep","sleepy","tired","dream"]},"waving-hand":{"a":"Waving Hand","b":"1F44B","j":["hand","wave","waving","hands","gesture","goodbye","solong","farewell","hello","hi","palm"]},"raised-back-of-hand":{"a":"Raised Back of Hand","b":"1F91A","j":["backhand","raised","fingers"]},"hand-with-fingers-splayed":{"a":"Hand with Fingers Splayed","b":"1F590","j":["finger","hand","splayed","fingers","palm"]},"raised-hand":{"a":"Raised Hand","b":"270B","j":["hand","high 5","high five","fingers","stop","highfive","palm","ban"]},"vulcan-salute":{"a":"Vulcan Salute","b":"1F596","j":["finger","hand","spock","vulcan","fingers","star trek"]},"rightwards-hand":{"a":"⊛ Rightwards Hand","b":"1FAF1","j":["hand","right","rightward"]},"leftwards-hand":{"a":"⊛ Leftwards Hand","b":"1FAF2","j":["hand","left","leftward"]},"palm-down-hand":{"a":"⊛ Palm Down Hand","b":"1FAF3","j":["dismiss","drop","shoo"]},"palm-up-hand":{"a":"⊛ Palm Up Hand","b":"1FAF4","j":["beckon","catch","come","offer"]},"ok-hand":{"a":"Ok Hand","b":"1F44C","j":["hand","OK","fingers","limbs","perfect","ok","okay"]},"pinched-fingers":{"a":"Pinched Fingers","b":"1F90C","j":["fingers","hand gesture","interrogation","pinched","sarcastic","size","tiny","small"]},"pinching-hand":{"a":"Pinching Hand","b":"1F90F","j":["small amount","tiny","small","size"]},"victory-hand":{"a":"Victory Hand","b":"270C","j":["hand","v","victory","fingers","ohyeah","peace","two"]},"crossed-fingers":{"a":"Crossed Fingers","b":"1F91E","j":["cross","finger","hand","luck","good","lucky"]},"hand-with-index-finger-and-thumb-crossed":{"a":"⊛ Hand with Index Finger and Thumb Crossed","b":"1FAF0","j":["expensive","heart","love","money","snap"]},"loveyou-gesture":{"a":"Love-You Gesture","b":"1F91F","j":["hand","ILY","love-you gesture","love_you_gesture","fingers","gesture"]},"sign-of-the-horns":{"a":"Sign of the Horns","b":"1F918","j":["finger","hand","horns","rock-on","fingers","evil_eye","sign_of_horns","rock_on"]},"call-me-hand":{"a":"Call Me Hand","b":"1F919","j":["call","hand","hands","gesture","shaka"]},"backhand-index-pointing-left":{"a":"Backhand Index Pointing Left","b":"1F448","j":["backhand","finger","hand","index","point","direction","fingers","left"]},"backhand-index-pointing-right":{"a":"Backhand Index Pointing Right","b":"1F449","j":["backhand","finger","hand","index","point","fingers","direction","right"]},"backhand-index-pointing-up":{"a":"Backhand Index Pointing Up","b":"1F446","j":["backhand","finger","hand","point","up","fingers","direction"]},"middle-finger":{"a":"Middle Finger","b":"1F595","j":["finger","hand","fingers","rude","middle","flipping"]},"backhand-index-pointing-down":{"a":"Backhand Index Pointing Down","b":"1F447","j":["backhand","down","finger","hand","point","fingers","direction"]},"index-pointing-up":{"a":"Index Pointing Up","b":"261D","j":["finger","hand","index","point","up","fingers","direction"]},"index-pointing-at-the-viewer":{"a":"⊛ Index Pointing at the Viewer","b":"1FAF5","j":["point","you"]},"thumbs-up":{"a":"Thumbs Up","b":"1F44D","j":["+1","hand","thumb","up","thumbsup","yes","awesome","good","agree","accept","cool","like"]},"thumbs-down":{"a":"Thumbs Down","b":"1F44E","j":["-1","down","hand","thumb","thumbsdown","no","dislike"]},"raised-fist":{"a":"Raised Fist","b":"270A","j":["clenched","fist","hand","punch","fingers","grasp"]},"oncoming-fist":{"a":"Oncoming Fist","b":"1F44A","j":["clenched","fist","hand","punch","angry","violence","hit","attack"]},"leftfacing-fist":{"a":"Left-Facing Fist","b":"1F91B","j":["fist","left-facing fist","leftwards","left_facing_fist","hand","fistbump"]},"rightfacing-fist":{"a":"Right-Facing Fist","b":"1F91C","j":["fist","right-facing fist","rightwards","right_facing_fist","hand","fistbump"]},"clapping-hands":{"a":"Clapping Hands","b":"1F44F","j":["clap","hand","hands","praise","applause","congrats","yay"]},"raising-hands":{"a":"Raising Hands","b":"1F64C","j":["celebration","gesture","hand","hooray","raised","yea","hands"]},"heart-hands":{"a":"⊛ Heart Hands","b":"1FAF6","j":["love"]},"open-hands":{"a":"Open Hands","b":"1F450","j":["hand","open","fingers","butterfly","hands"]},"palms-up-together":{"a":"Palms Up Together","b":"1F932","j":["prayer","cupped hands","hands","gesture","cupped"]},"handshake":{"a":"Handshake","b":"1F91D","j":["agreement","hand","meeting","shake"]},"folded-hands":{"a":"Folded Hands","b":"1F64F","j":["ask","hand","high 5","high five","please","pray","thanks","hope","wish","namaste","highfive"]},"writing-hand":{"a":"Writing Hand","b":"270D","j":["hand","write","lower_left_ballpoint_pen","stationery","compose"]},"nail-polish":{"a":"Nail Polish","b":"1F485","j":["care","cosmetics","manicure","nail","polish","beauty","finger","fashion"]},"selfie":{"a":"Selfie","b":"1F933","j":["camera","phone"]},"flexed-biceps":{"a":"Flexed Biceps","b":"1F4AA","j":["biceps","comic","flex","muscle","arm","hand","summer","strong"]},"mechanical-arm":{"a":"Mechanical Arm","b":"1F9BE","j":["accessibility","prosthetic"]},"mechanical-leg":{"a":"Mechanical Leg","b":"1F9BF","j":["accessibility","prosthetic"]},"leg":{"a":"Leg","b":"1F9B5","j":["kick","limb"]},"foot":{"a":"Foot","b":"1F9B6","j":["kick","stomp"]},"ear":{"a":"Ear","b":"1F442","j":["body","face","hear","sound","listen"]},"ear-with-hearing-aid":{"a":"Ear with Hearing Aid","b":"1F9BB","j":["accessibility","hard of hearing"]},"nose":{"a":"Nose","b":"1F443","j":["body","smell","sniff"]},"brain":{"a":"Brain","b":"1F9E0","j":["intelligent","smart"]},"anatomical-heart":{"a":"Anatomical Heart","b":"1FAC0","j":["anatomical","cardiology","heart","organ","pulse","health","heartbeat"]},"lungs":{"a":"Lungs","b":"1FAC1","j":["breath","exhalation","inhalation","organ","respiration","breathe"]},"tooth":{"a":"Tooth","b":"1F9B7","j":["dentist","teeth"]},"bone":{"a":"Bone","b":"1F9B4","j":["skeleton"]},"eyes":{"a":"Eyes","b":"1F440","j":["eye","face","look","watch","stalk","peek","see"]},"eye":{"a":"Eye","b":"1F441","j":["body","face","look","see","watch","stare"]},"tongue":{"a":"Tongue","b":"1F445","j":["body","mouth","playful"]},"mouth":{"a":"Mouth","b":"1F444","j":["lips","kiss"]},"biting-lip":{"a":"⊛ Biting Lip","b":"1FAE6","j":["anxious","fear","flirting","nervous","uncomfortable","worried"]},"baby":{"a":"Baby","b":"1F476","j":["young","child","boy","girl","toddler"]},"child":{"a":"Child","b":"1F9D2","j":["gender-neutral","unspecified gender","young"]},"boy":{"a":"Boy","b":"1F466","j":["young","man","male","guy","teenager"]},"girl":{"a":"Girl","b":"1F467","j":["Virgo","young","zodiac","female","woman","teenager"]},"person":{"a":"Person","b":"1F9D1","j":["adult","gender-neutral","unspecified gender"]},"person-blond-hair":{"a":"Person: Blond Hair","b":"1F471","j":["blond","blond-haired person","hair","person: blond hair","hairstyle"]},"man":{"a":"Man","b":"1F468","j":["adult","mustache","father","dad","guy","classy","sir","moustache"]},"person-beard":{"a":"Person: Beard","b":"1F9D4","j":["beard","person","person: beard","bewhiskered","man_beard"]},"man-beard":{"a":"Man: Beard","b":"1F9D4-200D-2642-FE0F","j":["beard","man","man: beard","facial hair"]},"woman-beard":{"a":"Woman: Beard","b":"1F9D4-200D-2640-FE0F","j":["beard","woman","woman: beard","facial hair"]},"man-red-hair":{"a":"Man: Red Hair","b":"1F468-200D-1F9B0","j":["adult","man","red hair","hairstyle"]},"man-curly-hair":{"a":"Man: Curly Hair","b":"1F468-200D-1F9B1","j":["adult","curly hair","man","hairstyle"]},"man-white-hair":{"a":"Man: White Hair","b":"1F468-200D-1F9B3","j":["adult","man","white hair","old","elder"]},"man-bald":{"a":"Man: Bald","b":"1F468-200D-1F9B2","j":["adult","bald","man","hairless"]},"woman":{"a":"Woman","b":"1F469","j":["adult","female","girls","lady"]},"woman-red-hair":{"a":"Woman: Red Hair","b":"1F469-200D-1F9B0","j":["adult","red hair","woman","hairstyle"]},"person-red-hair":{"a":"Person: Red Hair","b":"1F9D1-200D-1F9B0","j":["adult","gender-neutral","person","red hair","unspecified gender","hairstyle"]},"woman-curly-hair":{"a":"Woman: Curly Hair","b":"1F469-200D-1F9B1","j":["adult","curly hair","woman","hairstyle"]},"person-curly-hair":{"a":"Person: Curly Hair","b":"1F9D1-200D-1F9B1","j":["adult","curly hair","gender-neutral","person","unspecified gender","hairstyle"]},"woman-white-hair":{"a":"Woman: White Hair","b":"1F469-200D-1F9B3","j":["adult","white hair","woman","old","elder"]},"person-white-hair":{"a":"Person: White Hair","b":"1F9D1-200D-1F9B3","j":["adult","gender-neutral","person","unspecified gender","white hair","elder","old"]},"woman-bald":{"a":"Woman: Bald","b":"1F469-200D-1F9B2","j":["adult","bald","woman","hairless"]},"person-bald":{"a":"Person: Bald","b":"1F9D1-200D-1F9B2","j":["adult","bald","gender-neutral","person","unspecified gender","hairless"]},"woman-blond-hair":{"a":"Woman: Blond Hair","b":"1F471-200D-2640-FE0F","j":["blond-haired woman","blonde","hair","woman","woman: blond hair","female","girl","person"]},"man-blond-hair":{"a":"Man: Blond Hair","b":"1F471-200D-2642-FE0F","j":["blond","blond-haired man","hair","man","man: blond hair","male","boy","blonde","guy","person"]},"older-person":{"a":"Older Person","b":"1F9D3","j":["adult","gender-neutral","old","unspecified gender","human","elder","senior"]},"old-man":{"a":"Old Man","b":"1F474","j":["adult","man","old","human","male","men","elder","senior"]},"old-woman":{"a":"Old Woman","b":"1F475","j":["adult","old","woman","human","female","women","lady","elder","senior"]},"person-frowning":{"a":"Person Frowning","b":"1F64D","j":["frown","gesture","worried"]},"man-frowning":{"a":"Man Frowning","b":"1F64D-200D-2642-FE0F","j":["frowning","gesture","man","male","boy","sad","depressed","discouraged","unhappy"]},"woman-frowning":{"a":"Woman Frowning","b":"1F64D-200D-2640-FE0F","j":["frowning","gesture","woman","female","girl","sad","depressed","discouraged","unhappy"]},"person-pouting":{"a":"Person Pouting","b":"1F64E","j":["gesture","pouting","upset"]},"man-pouting":{"a":"Man Pouting","b":"1F64E-200D-2642-FE0F","j":["gesture","man","pouting","male","boy"]},"woman-pouting":{"a":"Woman Pouting","b":"1F64E-200D-2640-FE0F","j":["gesture","pouting","woman","female","girl"]},"person-gesturing-no":{"a":"Person Gesturing No","b":"1F645","j":["forbidden","gesture","hand","person gesturing NO","prohibited","decline"]},"man-gesturing-no":{"a":"Man Gesturing No","b":"1F645-200D-2642-FE0F","j":["forbidden","gesture","hand","man","man gesturing NO","prohibited","male","boy","nope"]},"woman-gesturing-no":{"a":"Woman Gesturing No","b":"1F645-200D-2640-FE0F","j":["forbidden","gesture","hand","prohibited","woman","woman gesturing NO","female","girl","nope"]},"person-gesturing-ok":{"a":"Person Gesturing Ok","b":"1F646","j":["gesture","hand","OK","person gesturing OK","agree"]},"man-gesturing-ok":{"a":"Man Gesturing Ok","b":"1F646-200D-2642-FE0F","j":["gesture","hand","man","man gesturing OK","OK","men","boy","male","blue","human"]},"woman-gesturing-ok":{"a":"Woman Gesturing Ok","b":"1F646-200D-2640-FE0F","j":["gesture","hand","OK","woman","woman gesturing OK","women","girl","female","pink","human"]},"person-tipping-hand":{"a":"Person Tipping Hand","b":"1F481","j":["hand","help","information","sassy","tipping"]},"man-tipping-hand":{"a":"Man Tipping Hand","b":"1F481-200D-2642-FE0F","j":["man","sassy","tipping hand","male","boy","human","information"]},"woman-tipping-hand":{"a":"Woman Tipping Hand","b":"1F481-200D-2640-FE0F","j":["sassy","tipping hand","woman","female","girl","human","information"]},"person-raising-hand":{"a":"Person Raising Hand","b":"1F64B","j":["gesture","hand","happy","raised","question"]},"man-raising-hand":{"a":"Man Raising Hand","b":"1F64B-200D-2642-FE0F","j":["gesture","man","raising hand","male","boy"]},"woman-raising-hand":{"a":"Woman Raising Hand","b":"1F64B-200D-2640-FE0F","j":["gesture","raising hand","woman","female","girl"]},"deaf-person":{"a":"Deaf Person","b":"1F9CF","j":["accessibility","deaf","ear","hear"]},"deaf-man":{"a":"Deaf Man","b":"1F9CF-200D-2642-FE0F","j":["deaf","man","accessibility"]},"deaf-woman":{"a":"Deaf Woman","b":"1F9CF-200D-2640-FE0F","j":["deaf","woman","accessibility"]},"person-bowing":{"a":"Person Bowing","b":"1F647","j":["apology","bow","gesture","sorry","respectiful"]},"man-bowing":{"a":"Man Bowing","b":"1F647-200D-2642-FE0F","j":["apology","bowing","favor","gesture","man","sorry","male","boy"]},"woman-bowing":{"a":"Woman Bowing","b":"1F647-200D-2640-FE0F","j":["apology","bowing","favor","gesture","sorry","woman","female","girl"]},"person-facepalming":{"a":"Person Facepalming","b":"1F926","j":["disbelief","exasperation","face","palm","disappointed"]},"man-facepalming":{"a":"Man Facepalming","b":"1F926-200D-2642-FE0F","j":["disbelief","exasperation","facepalm","man","male","boy"]},"woman-facepalming":{"a":"Woman Facepalming","b":"1F926-200D-2640-FE0F","j":["disbelief","exasperation","facepalm","woman","female","girl"]},"person-shrugging":{"a":"Person Shrugging","b":"1F937","j":["doubt","ignorance","indifference","shrug","regardless"]},"man-shrugging":{"a":"Man Shrugging","b":"1F937-200D-2642-FE0F","j":["doubt","ignorance","indifference","man","shrug","male","boy","confused","indifferent"]},"woman-shrugging":{"a":"Woman Shrugging","b":"1F937-200D-2640-FE0F","j":["doubt","ignorance","indifference","shrug","woman","female","girl","confused","indifferent"]},"health-worker":{"a":"Health Worker","b":"1F9D1-200D-2695-FE0F","j":["doctor","healthcare","nurse","therapist","hospital"]},"man-health-worker":{"a":"Man Health Worker","b":"1F468-200D-2695-FE0F","j":["doctor","healthcare","man","nurse","therapist","human"]},"woman-health-worker":{"a":"Woman Health Worker","b":"1F469-200D-2695-FE0F","j":["doctor","healthcare","nurse","therapist","woman","human"]},"student":{"a":"Student","b":"1F9D1-200D-1F393","j":["graduate","learn"]},"man-student":{"a":"Man Student","b":"1F468-200D-1F393","j":["graduate","man","student","human"]},"woman-student":{"a":"Woman Student","b":"1F469-200D-1F393","j":["graduate","student","woman","human"]},"teacher":{"a":"Teacher","b":"1F9D1-200D-1F3EB","j":["instructor","professor"]},"man-teacher":{"a":"Man Teacher","b":"1F468-200D-1F3EB","j":["instructor","man","professor","teacher","human"]},"woman-teacher":{"a":"Woman Teacher","b":"1F469-200D-1F3EB","j":["instructor","professor","teacher","woman","human"]},"judge":{"a":"Judge","b":"1F9D1-200D-2696-FE0F","j":["justice","scales","law"]},"man-judge":{"a":"Man Judge","b":"1F468-200D-2696-FE0F","j":["judge","justice","man","scales","court","human"]},"woman-judge":{"a":"Woman Judge","b":"1F469-200D-2696-FE0F","j":["judge","justice","scales","woman","court","human"]},"farmer":{"a":"Farmer","b":"1F9D1-200D-1F33E","j":["gardener","rancher","crops"]},"man-farmer":{"a":"Man Farmer","b":"1F468-200D-1F33E","j":["farmer","gardener","man","rancher","human"]},"woman-farmer":{"a":"Woman Farmer","b":"1F469-200D-1F33E","j":["farmer","gardener","rancher","woman","human"]},"cook":{"a":"Cook","b":"1F9D1-200D-1F373","j":["chef","food","kitchen","culinary"]},"man-cook":{"a":"Man Cook","b":"1F468-200D-1F373","j":["chef","cook","man","human"]},"woman-cook":{"a":"Woman Cook","b":"1F469-200D-1F373","j":["chef","cook","woman","human"]},"mechanic":{"a":"Mechanic","b":"1F9D1-200D-1F527","j":["electrician","plumber","tradesperson","worker","technician"]},"man-mechanic":{"a":"Man Mechanic","b":"1F468-200D-1F527","j":["electrician","man","mechanic","plumber","tradesperson","human","wrench"]},"woman-mechanic":{"a":"Woman Mechanic","b":"1F469-200D-1F527","j":["electrician","mechanic","plumber","tradesperson","woman","human","wrench"]},"factory-worker":{"a":"Factory Worker","b":"1F9D1-200D-1F3ED","j":["assembly","factory","industrial","worker","labor"]},"man-factory-worker":{"a":"Man Factory Worker","b":"1F468-200D-1F3ED","j":["assembly","factory","industrial","man","worker","human"]},"woman-factory-worker":{"a":"Woman Factory Worker","b":"1F469-200D-1F3ED","j":["assembly","factory","industrial","woman","worker","human"]},"office-worker":{"a":"Office Worker","b":"1F9D1-200D-1F4BC","j":["architect","business","manager","white-collar"]},"man-office-worker":{"a":"Man Office Worker","b":"1F468-200D-1F4BC","j":["architect","business","man","manager","white-collar","human"]},"woman-office-worker":{"a":"Woman Office Worker","b":"1F469-200D-1F4BC","j":["architect","business","manager","white-collar","woman","human"]},"scientist":{"a":"Scientist","b":"1F9D1-200D-1F52C","j":["biologist","chemist","engineer","physicist","chemistry"]},"man-scientist":{"a":"Man Scientist","b":"1F468-200D-1F52C","j":["biologist","chemist","engineer","man","physicist","scientist","human"]},"woman-scientist":{"a":"Woman Scientist","b":"1F469-200D-1F52C","j":["biologist","chemist","engineer","physicist","scientist","woman","human"]},"technologist":{"a":"Technologist","b":"1F9D1-200D-1F4BB","j":["coder","developer","inventor","software","computer"]},"man-technologist":{"a":"Man Technologist","b":"1F468-200D-1F4BB","j":["coder","developer","inventor","man","software","technologist","engineer","programmer","human","laptop","computer"]},"woman-technologist":{"a":"Woman Technologist","b":"1F469-200D-1F4BB","j":["coder","developer","inventor","software","technologist","woman","engineer","programmer","human","laptop","computer"]},"singer":{"a":"Singer","b":"1F9D1-200D-1F3A4","j":["actor","entertainer","rock","star","song","artist","performer"]},"man-singer":{"a":"Man Singer","b":"1F468-200D-1F3A4","j":["actor","entertainer","man","rock","singer","star","rockstar","human"]},"woman-singer":{"a":"Woman Singer","b":"1F469-200D-1F3A4","j":["actor","entertainer","rock","singer","star","woman","rockstar","human"]},"artist":{"a":"Artist","b":"1F9D1-200D-1F3A8","j":["palette","painting","draw","creativity"]},"man-artist":{"a":"Man Artist","b":"1F468-200D-1F3A8","j":["artist","man","palette","painter","human"]},"woman-artist":{"a":"Woman Artist","b":"1F469-200D-1F3A8","j":["artist","palette","woman","painter","human"]},"pilot":{"a":"Pilot","b":"1F9D1-200D-2708-FE0F","j":["plane","fly","airplane"]},"man-pilot":{"a":"Man Pilot","b":"1F468-200D-2708-FE0F","j":["man","pilot","plane","aviator","human"]},"woman-pilot":{"a":"Woman Pilot","b":"1F469-200D-2708-FE0F","j":["pilot","plane","woman","aviator","human"]},"astronaut":{"a":"Astronaut","b":"1F9D1-200D-1F680","j":["rocket","outerspace"]},"man-astronaut":{"a":"Man Astronaut","b":"1F468-200D-1F680","j":["astronaut","man","rocket","space","human"]},"woman-astronaut":{"a":"Woman Astronaut","b":"1F469-200D-1F680","j":["astronaut","rocket","woman","space","human"]},"firefighter":{"a":"Firefighter","b":"1F9D1-200D-1F692","j":["firetruck","fire"]},"man-firefighter":{"a":"Man Firefighter","b":"1F468-200D-1F692","j":["firefighter","firetruck","man","fireman","human"]},"woman-firefighter":{"a":"Woman Firefighter","b":"1F469-200D-1F692","j":["firefighter","firetruck","woman","fireman","human"]},"police-officer":{"a":"Police Officer","b":"1F46E","j":["cop","officer","police"]},"man-police-officer":{"a":"Man Police Officer","b":"1F46E-200D-2642-FE0F","j":["cop","man","officer","police","law","legal","enforcement","arrest","911"]},"woman-police-officer":{"a":"Woman Police Officer","b":"1F46E-200D-2640-FE0F","j":["cop","officer","police","woman","law","legal","enforcement","arrest","911","female"]},"detective":{"a":"Detective","b":"1F575","j":["sleuth","spy","human"]},"man-detective":{"a":"Man Detective","b":"1F575-FE0F-200D-2642-FE0F","j":["detective","man","sleuth","spy","crime"]},"woman-detective":{"a":"Woman Detective","b":"1F575-FE0F-200D-2640-FE0F","j":["detective","sleuth","spy","woman","human","female"]},"guard":{"a":"Guard","b":"1F482","j":["protect"]},"man-guard":{"a":"Man Guard","b":"1F482-200D-2642-FE0F","j":["guard","man","uk","gb","british","male","guy","royal"]},"woman-guard":{"a":"Woman Guard","b":"1F482-200D-2640-FE0F","j":["guard","woman","uk","gb","british","female","royal"]},"ninja":{"a":"Ninja","b":"1F977","j":["fighter","hidden","stealth","ninjutsu","skills","japanese"]},"construction-worker":{"a":"Construction Worker","b":"1F477","j":["construction","hat","worker","labor","build"]},"man-construction-worker":{"a":"Man Construction Worker","b":"1F477-200D-2642-FE0F","j":["construction","man","worker","male","human","wip","guy","build","labor"]},"woman-construction-worker":{"a":"Woman Construction Worker","b":"1F477-200D-2640-FE0F","j":["construction","woman","worker","female","human","wip","build","labor"]},"person-with-crown":{"a":"⊛ Person with Crown","b":"1FAC5","j":["monarch","noble","regal","royalty"]},"prince":{"a":"Prince","b":"1F934","j":["boy","man","male","crown","royal","king"]},"princess":{"a":"Princess","b":"1F478","j":["fairy tale","fantasy","girl","woman","female","blond","crown","royal","queen"]},"person-wearing-turban":{"a":"Person Wearing Turban","b":"1F473","j":["turban","headdress"]},"man-wearing-turban":{"a":"Man Wearing Turban","b":"1F473-200D-2642-FE0F","j":["man","turban","male","indian","hinduism","arabs"]},"woman-wearing-turban":{"a":"Woman Wearing Turban","b":"1F473-200D-2640-FE0F","j":["turban","woman","female","indian","hinduism","arabs"]},"person-with-skullcap":{"a":"Person with Skullcap","b":"1F472","j":["cap","gua pi mao","hat","person","skullcap","man_with_skullcap","male","boy","chinese"]},"woman-with-headscarf":{"a":"Woman with Headscarf","b":"1F9D5","j":["headscarf","hijab","mantilla","tichel","bandana","head kerchief","female"]},"person-in-tuxedo":{"a":"Person in Tuxedo","b":"1F935","j":["groom","person","tuxedo","man_in_tuxedo","couple","marriage","wedding"]},"man-in-tuxedo":{"a":"Man in Tuxedo","b":"1F935-200D-2642-FE0F","j":["man","tuxedo","formal","fashion"]},"woman-in-tuxedo":{"a":"Woman in Tuxedo","b":"1F935-200D-2640-FE0F","j":["tuxedo","woman","formal","fashion"]},"person-with-veil":{"a":"Person with Veil","b":"1F470","j":["bride","person","veil","wedding","bride_with_veil","couple","marriage","woman"]},"man-with-veil":{"a":"Man with Veil","b":"1F470-200D-2642-FE0F","j":["man","veil","wedding","marriage"]},"woman-with-veil":{"a":"Woman with Veil","b":"1F470-200D-2640-FE0F","j":["veil","woman","wedding","marriage"]},"pregnant-woman":{"a":"Pregnant Woman","b":"1F930","j":["pregnant","woman","baby"]},"pregnant-man":{"a":"⊛ Pregnant Man","b":"1FAC3","j":["belly","bloated","full","pregnant"]},"pregnant-person":{"a":"⊛ Pregnant Person","b":"1FAC4","j":["belly","bloated","full","pregnant"]},"breastfeeding":{"a":"Breast-Feeding","b":"1F931","j":["baby","breast","breast-feeding","nursing","breast_feeding"]},"woman-feeding-baby":{"a":"Woman Feeding Baby","b":"1F469-200D-1F37C","j":["baby","feeding","nursing","woman","birth","food"]},"man-feeding-baby":{"a":"Man Feeding Baby","b":"1F468-200D-1F37C","j":["baby","feeding","man","nursing","birth","food"]},"person-feeding-baby":{"a":"Person Feeding Baby","b":"1F9D1-200D-1F37C","j":["baby","feeding","nursing","person","birth","food"]},"baby-angel":{"a":"Baby Angel","b":"1F47C","j":["angel","baby","face","fairy tale","fantasy","heaven","wings","halo"]},"santa-claus":{"a":"Santa Claus","b":"1F385","j":["celebration","Christmas","claus","father","santa","festival","man","male","xmas","father christmas"]},"mrs-claus":{"a":"Mrs. Claus","b":"1F936","j":["celebration","Christmas","claus","mother","Mrs.","woman","female","xmas","mother christmas"]},"mx-claus":{"a":"Mx Claus","b":"1F9D1-200D-1F384","j":["Claus, christmas","christmas"]},"superhero":{"a":"Superhero","b":"1F9B8","j":["good","hero","heroine","superpower","marvel"]},"man-superhero":{"a":"Man Superhero","b":"1F9B8-200D-2642-FE0F","j":["good","hero","man","superpower","male","superpowers"]},"woman-superhero":{"a":"Woman Superhero","b":"1F9B8-200D-2640-FE0F","j":["good","hero","heroine","superpower","woman","female","superpowers"]},"supervillain":{"a":"Supervillain","b":"1F9B9","j":["criminal","evil","superpower","villain","marvel"]},"man-supervillain":{"a":"Man Supervillain","b":"1F9B9-200D-2642-FE0F","j":["criminal","evil","man","superpower","villain","male","bad","hero","superpowers"]},"woman-supervillain":{"a":"Woman Supervillain","b":"1F9B9-200D-2640-FE0F","j":["criminal","evil","superpower","villain","woman","female","bad","heroine","superpowers"]},"mage":{"a":"Mage","b":"1F9D9","j":["sorcerer","sorceress","witch","wizard","magic"]},"man-mage":{"a":"Man Mage","b":"1F9D9-200D-2642-FE0F","j":["sorcerer","wizard","man","male","mage"]},"woman-mage":{"a":"Woman Mage","b":"1F9D9-200D-2640-FE0F","j":["sorceress","witch","woman","female","mage"]},"fairy":{"a":"Fairy","b":"1F9DA","j":["Oberon","Puck","Titania","wings","magical"]},"man-fairy":{"a":"Man Fairy","b":"1F9DA-200D-2642-FE0F","j":["Oberon","Puck","man","male"]},"woman-fairy":{"a":"Woman Fairy","b":"1F9DA-200D-2640-FE0F","j":["Titania","woman","female"]},"vampire":{"a":"Vampire","b":"1F9DB","j":["Dracula","undead","blood","twilight"]},"man-vampire":{"a":"Man Vampire","b":"1F9DB-200D-2642-FE0F","j":["Dracula","undead","man","male","dracula"]},"woman-vampire":{"a":"Woman Vampire","b":"1F9DB-200D-2640-FE0F","j":["undead","woman","female"]},"merperson":{"a":"Merperson","b":"1F9DC","j":["mermaid","merman","merwoman","sea"]},"merman":{"a":"Merman","b":"1F9DC-200D-2642-FE0F","j":["Triton","man","male","triton"]},"mermaid":{"a":"Mermaid","b":"1F9DC-200D-2640-FE0F","j":["merwoman","woman","female","ariel"]},"elf":{"a":"Elf","b":"1F9DD","j":["magical","LOTR style"]},"man-elf":{"a":"Man Elf","b":"1F9DD-200D-2642-FE0F","j":["magical","man","male"]},"woman-elf":{"a":"Woman Elf","b":"1F9DD-200D-2640-FE0F","j":["magical","woman","female"]},"genie":{"a":"Genie","b":"1F9DE","j":["djinn","(non-human color)","magical","wishes"]},"man-genie":{"a":"Man Genie","b":"1F9DE-200D-2642-FE0F","j":["djinn","man","male"]},"woman-genie":{"a":"Woman Genie","b":"1F9DE-200D-2640-FE0F","j":["djinn","woman","female"]},"zombie":{"a":"Zombie","b":"1F9DF","j":["undead","walking dead","(non-human color)","dead"]},"man-zombie":{"a":"Man Zombie","b":"1F9DF-200D-2642-FE0F","j":["undead","walking dead","man","male","dracula"]},"woman-zombie":{"a":"Woman Zombie","b":"1F9DF-200D-2640-FE0F","j":["undead","walking dead","woman","female"]},"troll":{"a":"⊛ Troll","b":"1F9CC","j":["fairy tale","fantasy","monster"]},"person-getting-massage":{"a":"Person Getting Massage","b":"1F486","j":["face","massage","salon","relax"]},"man-getting-massage":{"a":"Man Getting Massage","b":"1F486-200D-2642-FE0F","j":["face","man","massage","male","boy","head"]},"woman-getting-massage":{"a":"Woman Getting Massage","b":"1F486-200D-2640-FE0F","j":["face","massage","woman","female","girl","head"]},"person-getting-haircut":{"a":"Person Getting Haircut","b":"1F487","j":["barber","beauty","haircut","parlor","hairstyle"]},"man-getting-haircut":{"a":"Man Getting Haircut","b":"1F487-200D-2642-FE0F","j":["haircut","man","male","boy"]},"woman-getting-haircut":{"a":"Woman Getting Haircut","b":"1F487-200D-2640-FE0F","j":["haircut","woman","female","girl"]},"person-walking":{"a":"Person Walking","b":"1F6B6","j":["hike","walk","walking","move"]},"man-walking":{"a":"Man Walking","b":"1F6B6-200D-2642-FE0F","j":["hike","man","walk","human","feet","steps"]},"woman-walking":{"a":"Woman Walking","b":"1F6B6-200D-2640-FE0F","j":["hike","walk","woman","human","feet","steps","female"]},"person-standing":{"a":"Person Standing","b":"1F9CD","j":["stand","standing","still"]},"man-standing":{"a":"Man Standing","b":"1F9CD-200D-2642-FE0F","j":["man","standing","still"]},"woman-standing":{"a":"Woman Standing","b":"1F9CD-200D-2640-FE0F","j":["standing","woman","still"]},"person-kneeling":{"a":"Person Kneeling","b":"1F9CE","j":["kneel","kneeling","pray","respectful"]},"man-kneeling":{"a":"Man Kneeling","b":"1F9CE-200D-2642-FE0F","j":["kneeling","man","pray","respectful"]},"woman-kneeling":{"a":"Woman Kneeling","b":"1F9CE-200D-2640-FE0F","j":["kneeling","woman","respectful","pray"]},"person-with-white-cane":{"a":"Person with White Cane","b":"1F9D1-200D-1F9AF","j":["accessibility","blind","person_with_probing_cane"]},"man-with-white-cane":{"a":"Man with White Cane","b":"1F468-200D-1F9AF","j":["accessibility","blind","man","man_with_probing_cane"]},"woman-with-white-cane":{"a":"Woman with White Cane","b":"1F469-200D-1F9AF","j":["accessibility","blind","woman","woman_with_probing_cane"]},"person-in-motorized-wheelchair":{"a":"Person in Motorized Wheelchair","b":"1F9D1-200D-1F9BC","j":["accessibility","wheelchair","disability"]},"man-in-motorized-wheelchair":{"a":"Man in Motorized Wheelchair","b":"1F468-200D-1F9BC","j":["accessibility","man","wheelchair","disability"]},"woman-in-motorized-wheelchair":{"a":"Woman in Motorized Wheelchair","b":"1F469-200D-1F9BC","j":["accessibility","wheelchair","woman","disability"]},"person-in-manual-wheelchair":{"a":"Person in Manual Wheelchair","b":"1F9D1-200D-1F9BD","j":["accessibility","wheelchair","disability"]},"man-in-manual-wheelchair":{"a":"Man in Manual Wheelchair","b":"1F468-200D-1F9BD","j":["accessibility","man","wheelchair","disability"]},"woman-in-manual-wheelchair":{"a":"Woman in Manual Wheelchair","b":"1F469-200D-1F9BD","j":["accessibility","wheelchair","woman","disability"]},"person-running":{"a":"Person Running","b":"1F3C3","j":["marathon","running","move"]},"man-running":{"a":"Man Running","b":"1F3C3-200D-2642-FE0F","j":["man","marathon","racing","running","walking","exercise","race"]},"woman-running":{"a":"Woman Running","b":"1F3C3-200D-2640-FE0F","j":["marathon","racing","running","woman","walking","exercise","race","female"]},"woman-dancing":{"a":"Woman Dancing","b":"1F483","j":["dance","dancing","woman","female","girl","fun"]},"man-dancing":{"a":"Man Dancing","b":"1F57A","j":["dance","dancing","man","male","boy","fun","dancer"]},"person-in-suit-levitating":{"a":"Person in Suit Levitating","b":"1F574","j":["business","person","suit","man_in_suit_levitating","levitate","hover","jump"]},"people-with-bunny-ears":{"a":"People with Bunny Ears","b":"1F46F","j":["bunny ear","dancer","partying","perform","costume"]},"men-with-bunny-ears":{"a":"Men with Bunny Ears","b":"1F46F-200D-2642-FE0F","j":["bunny ear","dancer","men","partying","male","bunny","boys"]},"women-with-bunny-ears":{"a":"Women with Bunny Ears","b":"1F46F-200D-2640-FE0F","j":["bunny ear","dancer","partying","women","female","bunny","girls"]},"person-in-steamy-room":{"a":"Person in Steamy Room","b":"1F9D6","j":["sauna","steam room","hamam","steambath","relax","spa"]},"man-in-steamy-room":{"a":"Man in Steamy Room","b":"1F9D6-200D-2642-FE0F","j":["sauna","steam room","male","man","spa","steamroom"]},"woman-in-steamy-room":{"a":"Woman in Steamy Room","b":"1F9D6-200D-2640-FE0F","j":["sauna","steam room","female","woman","spa","steamroom"]},"person-climbing":{"a":"Person Climbing","b":"1F9D7","j":["climber","sport"]},"man-climbing":{"a":"Man Climbing","b":"1F9D7-200D-2642-FE0F","j":["climber","sports","hobby","man","male","rock"]},"woman-climbing":{"a":"Woman Climbing","b":"1F9D7-200D-2640-FE0F","j":["climber","sports","hobby","woman","female","rock"]},"person-fencing":{"a":"Person Fencing","b":"1F93A","j":["fencer","fencing","sword","sports"]},"horse-racing":{"a":"Horse Racing","b":"1F3C7","j":["horse","jockey","racehorse","racing","animal","betting","competition","gambling","luck"]},"skier":{"a":"Skier","b":"26F7","j":["ski","snow","sports","winter"]},"snowboarder":{"a":"Snowboarder","b":"1F3C2","j":["ski","snow","snowboard","sports","winter"]},"person-golfing":{"a":"Person Golfing","b":"1F3CC","j":["ball","golf","sports","business"]},"man-golfing":{"a":"Man Golfing","b":"1F3CC-FE0F-200D-2642-FE0F","j":["golf","man","sport"]},"woman-golfing":{"a":"Woman Golfing","b":"1F3CC-FE0F-200D-2640-FE0F","j":["golf","woman","sports","business","female"]},"person-surfing":{"a":"Person Surfing","b":"1F3C4","j":["surfing","sport","sea"]},"man-surfing":{"a":"Man Surfing","b":"1F3C4-200D-2642-FE0F","j":["man","surfing","sports","ocean","sea","summer","beach"]},"woman-surfing":{"a":"Woman Surfing","b":"1F3C4-200D-2640-FE0F","j":["surfing","woman","sports","ocean","sea","summer","beach","female"]},"person-rowing-boat":{"a":"Person Rowing Boat","b":"1F6A3","j":["boat","rowboat","sport","move"]},"man-rowing-boat":{"a":"Man Rowing Boat","b":"1F6A3-200D-2642-FE0F","j":["boat","man","rowboat","sports","hobby","water","ship"]},"woman-rowing-boat":{"a":"Woman Rowing Boat","b":"1F6A3-200D-2640-FE0F","j":["boat","rowboat","woman","sports","hobby","water","ship","female"]},"person-swimming":{"a":"Person Swimming","b":"1F3CA","j":["swim","sport","pool"]},"man-swimming":{"a":"Man Swimming","b":"1F3CA-200D-2642-FE0F","j":["man","swim","sports","exercise","human","athlete","water","summer"]},"woman-swimming":{"a":"Woman Swimming","b":"1F3CA-200D-2640-FE0F","j":["swim","woman","sports","exercise","human","athlete","water","summer","female"]},"person-bouncing-ball":{"a":"Person Bouncing Ball","b":"26F9","j":["ball","sports","human"]},"man-bouncing-ball":{"a":"Man Bouncing Ball","b":"26F9-FE0F-200D-2642-FE0F","j":["ball","man","sport"]},"woman-bouncing-ball":{"a":"Woman Bouncing Ball","b":"26F9-FE0F-200D-2640-FE0F","j":["ball","woman","sports","human","female"]},"person-lifting-weights":{"a":"Person Lifting Weights","b":"1F3CB","j":["lifter","weight","sports","training","exercise"]},"man-lifting-weights":{"a":"Man Lifting Weights","b":"1F3CB-FE0F-200D-2642-FE0F","j":["man","weight lifter","sport"]},"woman-lifting-weights":{"a":"Woman Lifting Weights","b":"1F3CB-FE0F-200D-2640-FE0F","j":["weight lifter","woman","sports","training","exercise","female"]},"person-biking":{"a":"Person Biking","b":"1F6B4","j":["bicycle","biking","cyclist","sport","move"]},"man-biking":{"a":"Man Biking","b":"1F6B4-200D-2642-FE0F","j":["bicycle","biking","cyclist","man","sports","bike","exercise","hipster"]},"woman-biking":{"a":"Woman Biking","b":"1F6B4-200D-2640-FE0F","j":["bicycle","biking","cyclist","woman","sports","bike","exercise","hipster","female"]},"person-mountain-biking":{"a":"Person Mountain Biking","b":"1F6B5","j":["bicycle","bicyclist","bike","cyclist","mountain","sport","move"]},"man-mountain-biking":{"a":"Man Mountain Biking","b":"1F6B5-200D-2642-FE0F","j":["bicycle","bike","cyclist","man","mountain","transportation","sports","human","race"]},"woman-mountain-biking":{"a":"Woman Mountain Biking","b":"1F6B5-200D-2640-FE0F","j":["bicycle","bike","biking","cyclist","mountain","woman","transportation","sports","human","race","female"]},"person-cartwheeling":{"a":"Person Cartwheeling","b":"1F938","j":["cartwheel","gymnastics","sport","gymnastic"]},"man-cartwheeling":{"a":"Man Cartwheeling","b":"1F938-200D-2642-FE0F","j":["cartwheel","gymnastics","man"]},"woman-cartwheeling":{"a":"Woman Cartwheeling","b":"1F938-200D-2640-FE0F","j":["cartwheel","gymnastics","woman"]},"people-wrestling":{"a":"People Wrestling","b":"1F93C","j":["wrestle","wrestler","sport"]},"men-wrestling":{"a":"Men Wrestling","b":"1F93C-200D-2642-FE0F","j":["men","wrestle","sports","wrestlers"]},"women-wrestling":{"a":"Women Wrestling","b":"1F93C-200D-2640-FE0F","j":["women","wrestle","sports","wrestlers"]},"person-playing-water-polo":{"a":"Person Playing Water Polo","b":"1F93D","j":["polo","water","sport"]},"man-playing-water-polo":{"a":"Man Playing Water Polo","b":"1F93D-200D-2642-FE0F","j":["man","water polo","sports","pool"]},"woman-playing-water-polo":{"a":"Woman Playing Water Polo","b":"1F93D-200D-2640-FE0F","j":["water polo","woman","sports","pool"]},"person-playing-handball":{"a":"Person Playing Handball","b":"1F93E","j":["ball","handball","sport"]},"man-playing-handball":{"a":"Man Playing Handball","b":"1F93E-200D-2642-FE0F","j":["handball","man","sports"]},"woman-playing-handball":{"a":"Woman Playing Handball","b":"1F93E-200D-2640-FE0F","j":["handball","woman","sports"]},"person-juggling":{"a":"Person Juggling","b":"1F939","j":["balance","juggle","multitask","skill","performance"]},"man-juggling":{"a":"Man Juggling","b":"1F939-200D-2642-FE0F","j":["juggling","man","multitask","juggle","balance","skill"]},"woman-juggling":{"a":"Woman Juggling","b":"1F939-200D-2640-FE0F","j":["juggling","multitask","woman","juggle","balance","skill"]},"person-in-lotus-position":{"a":"Person in Lotus Position","b":"1F9D8","j":["meditation","yoga","serenity","meditate"]},"man-in-lotus-position":{"a":"Man in Lotus Position","b":"1F9D8-200D-2642-FE0F","j":["meditation","yoga","man","male","serenity","zen","mindfulness"]},"woman-in-lotus-position":{"a":"Woman in Lotus Position","b":"1F9D8-200D-2640-FE0F","j":["meditation","yoga","woman","female","serenity","zen","mindfulness"]},"person-taking-bath":{"a":"Person Taking Bath","b":"1F6C0","j":["bath","bathtub","clean","shower","bathroom"]},"person-in-bed":{"a":"Person in Bed","b":"1F6CC","j":["hotel","sleep","bed","rest"]},"people-holding-hands":{"a":"People Holding Hands","b":"1F9D1-200D-1F91D-200D-1F9D1","j":["couple","hand","hold","holding hands","person","friendship"]},"women-holding-hands":{"a":"Women Holding Hands","b":"1F46D","j":["couple","hand","holding hands","women","pair","friendship","love","like","female","people","human"]},"woman-and-man-holding-hands":{"a":"Woman and Man Holding Hands","b":"1F46B","j":["couple","hand","hold","holding hands","man","woman","pair","people","human","love","date","dating","like","affection","valentines","marriage"]},"men-holding-hands":{"a":"Men Holding Hands","b":"1F46C","j":["couple","Gemini","holding hands","man","men","twins","zodiac","pair","love","like","bromance","friendship","people","human"]},"kiss":{"a":"Kiss","b":"1F48F","j":["couple","pair","valentines","love","like","dating","marriage"]},"kiss-woman-man":{"a":"Kiss: Woman, Man","b":"1F469-200D-2764-FE0F-200D-1F48B-200D-1F468","j":["couple","kiss","man","woman","love"]},"kiss-man-man":{"a":"Kiss: Man, Man","b":"1F468-200D-2764-FE0F-200D-1F48B-200D-1F468","j":["couple","kiss","man","pair","valentines","love","like","dating","marriage"]},"kiss-woman-woman":{"a":"Kiss: Woman, Woman","b":"1F469-200D-2764-FE0F-200D-1F48B-200D-1F469","j":["couple","kiss","woman","pair","valentines","love","like","dating","marriage"]},"couple-with-heart":{"a":"Couple with Heart","b":"1F491","j":["couple","love","pair","like","affection","human","dating","valentines","marriage"]},"couple-with-heart-woman-man":{"a":"Couple with Heart: Woman, Man","b":"1F469-200D-2764-FE0F-200D-1F468","j":["couple","couple with heart","love","man","woman"]},"couple-with-heart-man-man":{"a":"Couple with Heart: Man, Man","b":"1F468-200D-2764-FE0F-200D-1F468","j":["couple","couple with heart","love","man","pair","like","affection","human","dating","valentines","marriage"]},"couple-with-heart-woman-woman":{"a":"Couple with Heart: Woman, Woman","b":"1F469-200D-2764-FE0F-200D-1F469","j":["couple","couple with heart","love","woman","pair","like","affection","human","dating","valentines","marriage"]},"family":{"a":"Family","b":"1F46A","j":["home","parents","child","mom","dad","father","mother","people","human"]},"family-man-woman-boy":{"a":"Family: Man, Woman, Boy","b":"1F468-200D-1F469-200D-1F466","j":["boy","family","man","woman","love"]},"family-man-woman-girl":{"a":"Family: Man, Woman, Girl","b":"1F468-200D-1F469-200D-1F467","j":["family","girl","man","woman","home","parents","people","human","child"]},"family-man-woman-girl-boy":{"a":"Family: Man, Woman, Girl, Boy","b":"1F468-200D-1F469-200D-1F467-200D-1F466","j":["boy","family","girl","man","woman","home","parents","people","human","children"]},"family-man-woman-boy-boy":{"a":"Family: Man, Woman, Boy, Boy","b":"1F468-200D-1F469-200D-1F466-200D-1F466","j":["boy","family","man","woman","home","parents","people","human","children"]},"family-man-woman-girl-girl":{"a":"Family: Man, Woman, Girl, Girl","b":"1F468-200D-1F469-200D-1F467-200D-1F467","j":["family","girl","man","woman","home","parents","people","human","children"]},"family-man-man-boy":{"a":"Family: Man, Man, Boy","b":"1F468-200D-1F468-200D-1F466","j":["boy","family","man","home","parents","people","human","children"]},"family-man-man-girl":{"a":"Family: Man, Man, Girl","b":"1F468-200D-1F468-200D-1F467","j":["family","girl","man","home","parents","people","human","children"]},"family-man-man-girl-boy":{"a":"Family: Man, Man, Girl, Boy","b":"1F468-200D-1F468-200D-1F467-200D-1F466","j":["boy","family","girl","man","home","parents","people","human","children"]},"family-man-man-boy-boy":{"a":"Family: Man, Man, Boy, Boy","b":"1F468-200D-1F468-200D-1F466-200D-1F466","j":["boy","family","man","home","parents","people","human","children"]},"family-man-man-girl-girl":{"a":"Family: Man, Man, Girl, Girl","b":"1F468-200D-1F468-200D-1F467-200D-1F467","j":["family","girl","man","home","parents","people","human","children"]},"family-woman-woman-boy":{"a":"Family: Woman, Woman, Boy","b":"1F469-200D-1F469-200D-1F466","j":["boy","family","woman","home","parents","people","human","children"]},"family-woman-woman-girl":{"a":"Family: Woman, Woman, Girl","b":"1F469-200D-1F469-200D-1F467","j":["family","girl","woman","home","parents","people","human","children"]},"family-woman-woman-girl-boy":{"a":"Family: Woman, Woman, Girl, Boy","b":"1F469-200D-1F469-200D-1F467-200D-1F466","j":["boy","family","girl","woman","home","parents","people","human","children"]},"family-woman-woman-boy-boy":{"a":"Family: Woman, Woman, Boy, Boy","b":"1F469-200D-1F469-200D-1F466-200D-1F466","j":["boy","family","woman","home","parents","people","human","children"]},"family-woman-woman-girl-girl":{"a":"Family: Woman, Woman, Girl, Girl","b":"1F469-200D-1F469-200D-1F467-200D-1F467","j":["family","girl","woman","home","parents","people","human","children"]},"family-man-boy":{"a":"Family: Man, Boy","b":"1F468-200D-1F466","j":["boy","family","man","home","parent","people","human","child"]},"family-man-boy-boy":{"a":"Family: Man, Boy, Boy","b":"1F468-200D-1F466-200D-1F466","j":["boy","family","man","home","parent","people","human","children"]},"family-man-girl":{"a":"Family: Man, Girl","b":"1F468-200D-1F467","j":["family","girl","man","home","parent","people","human","child"]},"family-man-girl-boy":{"a":"Family: Man, Girl, Boy","b":"1F468-200D-1F467-200D-1F466","j":["boy","family","girl","man","home","parent","people","human","children"]},"family-man-girl-girl":{"a":"Family: Man, Girl, Girl","b":"1F468-200D-1F467-200D-1F467","j":["family","girl","man","home","parent","people","human","children"]},"family-woman-boy":{"a":"Family: Woman, Boy","b":"1F469-200D-1F466","j":["boy","family","woman","home","parent","people","human","child"]},"family-woman-boy-boy":{"a":"Family: Woman, Boy, Boy","b":"1F469-200D-1F466-200D-1F466","j":["boy","family","woman","home","parent","people","human","children"]},"family-woman-girl":{"a":"Family: Woman, Girl","b":"1F469-200D-1F467","j":["family","girl","woman","home","parent","people","human","child"]},"family-woman-girl-boy":{"a":"Family: Woman, Girl, Boy","b":"1F469-200D-1F467-200D-1F466","j":["boy","family","girl","woman","home","parent","people","human","children"]},"family-woman-girl-girl":{"a":"Family: Woman, Girl, Girl","b":"1F469-200D-1F467-200D-1F467","j":["family","girl","woman","home","parent","people","human","children"]},"speaking-head":{"a":"Speaking Head","b":"1F5E3","j":["face","head","silhouette","speak","speaking","user","person","human","sing","say","talk"]},"bust-in-silhouette":{"a":"Bust in Silhouette","b":"1F464","j":["bust","silhouette","user","person","human"]},"busts-in-silhouette":{"a":"Busts in Silhouette","b":"1F465","j":["bust","silhouette","user","person","human","group","team"]},"people-hugging":{"a":"People Hugging","b":"1FAC2","j":["goodbye","hello","hug","thanks","care"]},"footprints":{"a":"Footprints","b":"1F463","j":["clothing","footprint","print","feet","tracking","walking","beach"]},"red-hair":{"a":"Red Hair","b":"1F9B0","j":["ginger","red hair","redhead"]},"curly-hair":{"a":"Curly Hair","b":"1F9B1","j":["afro","curly","curly hair","ringlets"]},"white-hair":{"a":"White Hair","b":"1F9B3","j":["gray","hair","old","white"]},"bald":{"a":"Bald","b":"1F9B2","j":["bald","chemotherapy","hairless","no hair","shaven"]},"monkey-face":{"a":"Monkey Face","b":"1F435","j":["face","monkey","animal","nature","circus"]},"monkey":{"a":"Monkey","b":"1F412","j":["animal","nature","banana","circus"]},"gorilla":{"a":"Gorilla","b":"1F98D","j":["animal","nature","circus"]},"orangutan":{"a":"Orangutan","b":"1F9A7","j":["ape","animal"]},"dog-face":{"a":"Dog Face","b":"1F436","j":["dog","face","pet","animal","friend","nature","woof","puppy","faithful"]},"dog":{"a":"Dog","b":"1F415","j":["pet","animal","nature","friend","doge","faithful"]},"guide-dog":{"a":"Guide Dog","b":"1F9AE","j":["accessibility","blind","guide","animal"]},"service-dog":{"a":"Service Dog","b":"1F415-200D-1F9BA","j":["accessibility","assistance","dog","service","blind","animal"]},"poodle":{"a":"Poodle","b":"1F429","j":["dog","animal","101","nature","pet"]},"wolf":{"a":"Wolf","b":"1F43A","j":["face","animal","nature","wild"]},"fox":{"a":"Fox","b":"1F98A","j":["face","animal","nature"]},"raccoon":{"a":"Raccoon","b":"1F99D","j":["curious","sly","animal","nature"]},"cat-face":{"a":"Cat Face","b":"1F431","j":["cat","face","pet","animal","meow","nature","kitten"]},"cat":{"a":"Cat","b":"1F408","j":["pet","animal","meow","cats"]},"black-cat":{"a":"Black Cat","b":"1F408-200D-2B1B","j":["black","cat","unlucky","superstition","luck"]},"lion":{"a":"Lion","b":"1F981","j":["face","Leo","zodiac","animal","nature"]},"tiger-face":{"a":"Tiger Face","b":"1F42F","j":["face","tiger","animal","cat","danger","wild","nature","roar"]},"tiger":{"a":"Tiger","b":"1F405","j":["animal","nature","roar"]},"leopard":{"a":"Leopard","b":"1F406","j":["animal","nature"]},"horse-face":{"a":"Horse Face","b":"1F434","j":["face","horse","animal","brown","nature"]},"horse":{"a":"Horse","b":"1F40E","j":["equestrian","racehorse","racing","animal","gamble","luck"]},"unicorn":{"a":"Unicorn","b":"1F984","j":["face","animal","nature","mystical"]},"zebra":{"a":"Zebra","b":"1F993","j":["stripe","animal","nature","stripes","safari"]},"deer":{"a":"Deer","b":"1F98C","j":["animal","nature","horns","venison"]},"bison":{"a":"Bison","b":"1F9AC","j":["buffalo","herd","wisent","ox"]},"cow-face":{"a":"Cow Face","b":"1F42E","j":["cow","face","beef","ox","animal","nature","moo","milk"]},"ox":{"a":"Ox","b":"1F402","j":["bull","Taurus","zodiac","animal","cow","beef"]},"water-buffalo":{"a":"Water Buffalo","b":"1F403","j":["buffalo","water","animal","nature","ox","cow"]},"cow":{"a":"Cow","b":"1F404","j":["beef","ox","animal","nature","moo","milk"]},"pig-face":{"a":"Pig Face","b":"1F437","j":["face","pig","animal","oink","nature"]},"pig":{"a":"Pig","b":"1F416","j":["sow","animal","nature"]},"boar":{"a":"Boar","b":"1F417","j":["pig","animal","nature"]},"pig-nose":{"a":"Pig Nose","b":"1F43D","j":["face","nose","pig","animal","oink"]},"ram":{"a":"Ram","b":"1F40F","j":["Aries","male","sheep","zodiac","animal","nature"]},"ewe":{"a":"Ewe","b":"1F411","j":["female","sheep","animal","nature","wool","shipit"]},"goat":{"a":"Goat","b":"1F410","j":["Capricorn","zodiac","animal","nature"]},"camel":{"a":"Camel","b":"1F42A","j":["dromedary","hump","animal","hot","desert"]},"twohump-camel":{"a":"Two-Hump Camel","b":"1F42B","j":["bactrian","camel","hump","two-hump camel","two_hump_camel","animal","nature","hot","desert"]},"llama":{"a":"Llama","b":"1F999","j":["alpaca","guanaco","vicuña","wool","animal","nature"]},"giraffe":{"a":"Giraffe","b":"1F992","j":["spots","animal","nature","safari"]},"elephant":{"a":"Elephant","b":"1F418","j":["animal","nature","nose","th","circus"]},"mammoth":{"a":"Mammoth","b":"1F9A3","j":["extinction","large","tusk","woolly","elephant","tusks"]},"rhinoceros":{"a":"Rhinoceros","b":"1F98F","j":["animal","nature","horn"]},"hippopotamus":{"a":"Hippopotamus","b":"1F99B","j":["hippo","animal","nature"]},"mouse-face":{"a":"Mouse Face","b":"1F42D","j":["face","mouse","animal","nature","cheese_wedge","rodent"]},"mouse":{"a":"Mouse","b":"1F401","j":["animal","nature","rodent"]},"rat":{"a":"Rat","b":"1F400","j":["animal","mouse","rodent"]},"hamster":{"a":"Hamster","b":"1F439","j":["face","pet","animal","nature"]},"rabbit-face":{"a":"Rabbit Face","b":"1F430","j":["bunny","face","pet","rabbit","animal","nature","spring","magic"]},"rabbit":{"a":"Rabbit","b":"1F407","j":["bunny","pet","animal","nature","magic","spring"]},"chipmunk":{"a":"Chipmunk","b":"1F43F","j":["squirrel","animal","nature","rodent"]},"beaver":{"a":"Beaver","b":"1F9AB","j":["dam","animal","rodent"]},"hedgehog":{"a":"Hedgehog","b":"1F994","j":["spiny","animal","nature"]},"bat":{"a":"Bat","b":"1F987","j":["vampire","animal","nature","blind"]},"bear":{"a":"Bear","b":"1F43B","j":["face","animal","nature","wild"]},"polar-bear":{"a":"Polar Bear","b":"1F43B-200D-2744-FE0F","j":["arctic","bear","white","animal"]},"koala":{"a":"Koala","b":"1F428","j":["face","marsupial","animal","nature"]},"panda":{"a":"Panda","b":"1F43C","j":["face","animal","nature"]},"sloth":{"a":"Sloth","b":"1F9A5","j":["lazy","slow","animal"]},"otter":{"a":"Otter","b":"1F9A6","j":["fishing","playful","animal"]},"skunk":{"a":"Skunk","b":"1F9A8","j":["stink","animal"]},"kangaroo":{"a":"Kangaroo","b":"1F998","j":["Australia","joey","jump","marsupial","animal","nature","australia","hop"]},"badger":{"a":"Badger","b":"1F9A1","j":["honey badger","pester","animal","nature","honey"]},"paw-prints":{"a":"Paw Prints","b":"1F43E","j":["feet","paw","print","animal","tracking","footprints","dog","cat","pet"]},"turkey":{"a":"Turkey","b":"1F983","j":["bird","animal"]},"chicken":{"a":"Chicken","b":"1F414","j":["bird","animal","cluck","nature"]},"rooster":{"a":"Rooster","b":"1F413","j":["bird","animal","nature","chicken"]},"hatching-chick":{"a":"Hatching Chick","b":"1F423","j":["baby","bird","chick","hatching","animal","chicken","egg","born"]},"baby-chick":{"a":"Baby Chick","b":"1F424","j":["baby","bird","chick","animal","chicken"]},"frontfacing-baby-chick":{"a":"Front-Facing Baby Chick","b":"1F425","j":["baby","bird","chick","front-facing baby chick","front_facing_baby_chick","animal","chicken"]},"bird":{"a":"Bird","b":"1F426","j":["animal","nature","fly","tweet","spring"]},"penguin":{"a":"Penguin","b":"1F427","j":["bird","animal","nature"]},"dove":{"a":"Dove","b":"1F54A","j":["bird","fly","peace","animal"]},"eagle":{"a":"Eagle","b":"1F985","j":["bird","animal","nature"]},"duck":{"a":"Duck","b":"1F986","j":["bird","animal","nature","mallard"]},"swan":{"a":"Swan","b":"1F9A2","j":["bird","cygnet","ugly duckling","animal","nature"]},"owl":{"a":"Owl","b":"1F989","j":["bird","wise","animal","nature","hoot"]},"dodo":{"a":"Dodo","b":"1F9A4","j":["extinction","large","Mauritius","animal","bird"]},"feather":{"a":"Feather","b":"1FAB6","j":["bird","flight","light","plumage","fly"]},"flamingo":{"a":"Flamingo","b":"1F9A9","j":["flamboyant","tropical","animal"]},"peacock":{"a":"Peacock","b":"1F99A","j":["bird","ostentatious","peahen","proud","animal","nature"]},"parrot":{"a":"Parrot","b":"1F99C","j":["bird","pirate","talk","animal","nature"]},"frog":{"a":"Frog","b":"1F438","j":["face","animal","nature","croak","toad"]},"crocodile":{"a":"Crocodile","b":"1F40A","j":["animal","nature","reptile","lizard","alligator"]},"turtle":{"a":"Turtle","b":"1F422","j":["terrapin","tortoise","animal","slow","nature"]},"lizard":{"a":"Lizard","b":"1F98E","j":["reptile","animal","nature"]},"snake":{"a":"Snake","b":"1F40D","j":["bearer","Ophiuchus","serpent","zodiac","animal","evil","nature","hiss","python"]},"dragon-face":{"a":"Dragon Face","b":"1F432","j":["dragon","face","fairy tale","animal","myth","nature","chinese","green"]},"dragon":{"a":"Dragon","b":"1F409","j":["fairy tale","animal","myth","nature","chinese","green"]},"sauropod":{"a":"Sauropod","b":"1F995","j":["brachiosaurus","brontosaurus","diplodocus","animal","nature","dinosaur","extinct"]},"trex":{"a":"T-Rex","b":"1F996","j":["Tyrannosaurus Rex","t_rex","animal","nature","dinosaur","tyrannosaurus","extinct"]},"spouting-whale":{"a":"Spouting Whale","b":"1F433","j":["face","spouting","whale","animal","nature","sea","ocean"]},"whale":{"a":"Whale","b":"1F40B","j":["animal","nature","sea","ocean"]},"dolphin":{"a":"Dolphin","b":"1F42C","j":["flipper","animal","nature","fish","sea","ocean","fins","beach"]},"seal":{"a":"Seal","b":"1F9AD","j":["sea lion","animal","creature","sea"]},"fish":{"a":"Fish","b":"1F41F","j":["Pisces","zodiac","animal","food","nature"]},"tropical-fish":{"a":"Tropical Fish","b":"1F420","j":["fish","tropical","animal","swim","ocean","beach","nemo"]},"blowfish":{"a":"Blowfish","b":"1F421","j":["fish","animal","nature","food","sea","ocean"]},"shark":{"a":"Shark","b":"1F988","j":["fish","animal","nature","sea","ocean","jaws","fins","beach"]},"octopus":{"a":"Octopus","b":"1F419","j":["animal","creature","ocean","sea","nature","beach"]},"spiral-shell":{"a":"Spiral Shell","b":"1F41A","j":["shell","spiral","nature","sea","beach"]},"coral":{"a":"⊛ Coral","b":"1FAB8","j":["ocean","reef"]},"snail":{"a":"Snail","b":"1F40C","j":["slow","animal","shell"]},"butterfly":{"a":"Butterfly","b":"1F98B","j":["insect","pretty","animal","nature","caterpillar"]},"bug":{"a":"Bug","b":"1F41B","j":["insect","animal","nature","worm"]},"ant":{"a":"Ant","b":"1F41C","j":["insect","animal","nature","bug"]},"honeybee":{"a":"Honeybee","b":"1F41D","j":["bee","insect","animal","nature","bug","spring","honey"]},"beetle":{"a":"Beetle","b":"1FAB2","j":["bug","insect"]},"lady-beetle":{"a":"Lady Beetle","b":"1F41E","j":["beetle","insect","ladybird","ladybug","animal","nature"]},"cricket":{"a":"Cricket","b":"1F997","j":["grasshopper","Orthoptera","animal","chirp"]},"cockroach":{"a":"Cockroach","b":"1FAB3","j":["insect","pest","roach","pests"]},"spider":{"a":"Spider","b":"1F577","j":["insect","animal","arachnid"]},"spider-web":{"a":"Spider Web","b":"1F578","j":["spider","web","animal","insect","arachnid","silk"]},"scorpion":{"a":"Scorpion","b":"1F982","j":["scorpio","Scorpio","zodiac","animal","arachnid"]},"mosquito":{"a":"Mosquito","b":"1F99F","j":["disease","fever","malaria","pest","virus","animal","nature","insect"]},"fly":{"a":"Fly","b":"1FAB0","j":["disease","maggot","pest","rotting","insect"]},"worm":{"a":"Worm","b":"1FAB1","j":["annelid","earthworm","parasite","animal"]},"microbe":{"a":"Microbe","b":"1F9A0","j":["amoeba","bacteria","virus","germs"]},"bouquet":{"a":"Bouquet","b":"1F490","j":["flower","flowers","nature","spring"]},"cherry-blossom":{"a":"Cherry Blossom","b":"1F338","j":["blossom","cherry","flower","nature","plant","spring"]},"white-flower":{"a":"White Flower","b":"1F4AE","j":["flower","japanese","spring"]},"lotus":{"a":"⊛ Lotus","b":"1FAB7","j":["Buddhism","flower","Hinduism","India","purity","Vietnam"]},"rosette":{"a":"Rosette","b":"1F3F5","j":["plant","flower","decoration","military"]},"rose":{"a":"Rose","b":"1F339","j":["flower","flowers","valentines","love","spring"]},"wilted-flower":{"a":"Wilted Flower","b":"1F940","j":["flower","wilted","plant","nature"]},"hibiscus":{"a":"Hibiscus","b":"1F33A","j":["flower","plant","vegetable","flowers","beach"]},"sunflower":{"a":"Sunflower","b":"1F33B","j":["flower","sun","nature","plant","fall"]},"blossom":{"a":"Blossom","b":"1F33C","j":["flower","nature","flowers","yellow"]},"tulip":{"a":"Tulip","b":"1F337","j":["flower","flowers","plant","nature","summer","spring"]},"seedling":{"a":"Seedling","b":"1F331","j":["young","plant","nature","grass","lawn","spring"]},"potted-plant":{"a":"Potted Plant","b":"1FAB4","j":["boring","grow","house","nurturing","plant","useless","greenery"]},"evergreen-tree":{"a":"Evergreen Tree","b":"1F332","j":["tree","plant","nature"]},"deciduous-tree":{"a":"Deciduous Tree","b":"1F333","j":["deciduous","shedding","tree","plant","nature"]},"palm-tree":{"a":"Palm Tree","b":"1F334","j":["palm","tree","plant","vegetable","nature","summer","beach","mojito","tropical"]},"cactus":{"a":"Cactus","b":"1F335","j":["plant","vegetable","nature"]},"sheaf-of-rice":{"a":"Sheaf of Rice","b":"1F33E","j":["ear","grain","rice","nature","plant"]},"herb":{"a":"Herb","b":"1F33F","j":["leaf","vegetable","plant","medicine","weed","grass","lawn"]},"shamrock":{"a":"Shamrock","b":"2618","j":["plant","vegetable","nature","irish","clover"]},"four-leaf-clover":{"a":"Four Leaf Clover","b":"1F340","j":["4","clover","four","four-leaf clover","leaf","vegetable","plant","nature","lucky","irish"]},"maple-leaf":{"a":"Maple Leaf","b":"1F341","j":["falling","leaf","maple","nature","plant","vegetable","ca","fall"]},"fallen-leaf":{"a":"Fallen Leaf","b":"1F342","j":["falling","leaf","nature","plant","vegetable","leaves"]},"leaf-fluttering-in-wind":{"a":"Leaf Fluttering in Wind","b":"1F343","j":["blow","flutter","leaf","wind","nature","plant","tree","vegetable","grass","lawn","spring"]},"empty-nest":{"a":"⊛ Empty Nest","b":"1FAB9","j":["nesting"]},"nest-with-eggs":{"a":"⊛ Nest with Eggs","b":"1FABA","j":["nesting"]},"grapes":{"a":"Grapes","b":"1F347","j":["fruit","grape","food","wine"]},"melon":{"a":"Melon","b":"1F348","j":["fruit","nature","food"]},"watermelon":{"a":"Watermelon","b":"1F349","j":["fruit","food","picnic","summer"]},"tangerine":{"a":"Tangerine","b":"1F34A","j":["fruit","orange","food","nature"]},"lemon":{"a":"Lemon","b":"1F34B","j":["citrus","fruit","nature"]},"banana":{"a":"Banana","b":"1F34C","j":["fruit","food","monkey"]},"pineapple":{"a":"Pineapple","b":"1F34D","j":["fruit","nature","food"]},"mango":{"a":"Mango","b":"1F96D","j":["fruit","tropical","food"]},"red-apple":{"a":"Red Apple","b":"1F34E","j":["apple","fruit","red","mac","school"]},"green-apple":{"a":"Green Apple","b":"1F34F","j":["apple","fruit","green","nature"]},"pear":{"a":"Pear","b":"1F350","j":["fruit","nature","food"]},"peach":{"a":"Peach","b":"1F351","j":["fruit","nature","food"]},"cherries":{"a":"Cherries","b":"1F352","j":["berries","cherry","fruit","red","food"]},"strawberry":{"a":"Strawberry","b":"1F353","j":["berry","fruit","food","nature"]},"blueberries":{"a":"Blueberries","b":"1FAD0","j":["berry","bilberry","blue","blueberry","fruit"]},"kiwi-fruit":{"a":"Kiwi Fruit","b":"1F95D","j":["food","fruit","kiwi"]},"tomato":{"a":"Tomato","b":"1F345","j":["fruit","vegetable","nature","food"]},"olive":{"a":"Olive","b":"1FAD2","j":["food","fruit"]},"coconut":{"a":"Coconut","b":"1F965","j":["palm","piña colada","fruit","nature","food"]},"avocado":{"a":"Avocado","b":"1F951","j":["food","fruit"]},"eggplant":{"a":"Eggplant","b":"1F346","j":["aubergine","vegetable","nature","food"]},"potato":{"a":"Potato","b":"1F954","j":["food","vegetable","tuber","vegatable","starch"]},"carrot":{"a":"Carrot","b":"1F955","j":["food","vegetable","orange"]},"ear-of-corn":{"a":"Ear of Corn","b":"1F33D","j":["corn","ear","maize","maze","food","vegetable","plant"]},"hot-pepper":{"a":"Hot Pepper","b":"1F336","j":["hot","pepper","food","spicy","chilli","chili"]},"bell-pepper":{"a":"Bell Pepper","b":"1FAD1","j":["capsicum","pepper","vegetable","fruit","plant"]},"cucumber":{"a":"Cucumber","b":"1F952","j":["food","pickle","vegetable","fruit"]},"leafy-green":{"a":"Leafy Green","b":"1F96C","j":["bok choy","cabbage","kale","lettuce","food","vegetable","plant"]},"broccoli":{"a":"Broccoli","b":"1F966","j":["wild cabbage","fruit","food","vegetable"]},"garlic":{"a":"Garlic","b":"1F9C4","j":["flavoring","food","spice","cook"]},"onion":{"a":"Onion","b":"1F9C5","j":["flavoring","cook","food","spice"]},"mushroom":{"a":"Mushroom","b":"1F344","j":["toadstool","plant","vegetable"]},"peanuts":{"a":"Peanuts","b":"1F95C","j":["food","nut","peanut","vegetable"]},"beans":{"a":"⊛ Beans","b":"1FAD8","j":["food","kidney","legume"]},"chestnut":{"a":"Chestnut","b":"1F330","j":["plant","food","squirrel"]},"bread":{"a":"Bread","b":"1F35E","j":["loaf","food","wheat","breakfast","toast"]},"croissant":{"a":"Croissant","b":"1F950","j":["bread","breakfast","food","french","roll"]},"baguette-bread":{"a":"Baguette Bread","b":"1F956","j":["baguette","bread","food","french"]},"flatbread":{"a":"Flatbread","b":"1FAD3","j":["arepa","lavash","naan","pita","flour","food"]},"pretzel":{"a":"Pretzel","b":"1F968","j":["twisted","convoluted","food","bread"]},"bagel":{"a":"Bagel","b":"1F96F","j":["bakery","breakfast","schmear","food","bread"]},"pancakes":{"a":"Pancakes","b":"1F95E","j":["breakfast","crêpe","food","hotcake","pancake","flapjacks","hotcakes"]},"waffle":{"a":"Waffle","b":"1F9C7","j":["breakfast","indecisive","iron","food"]},"cheese-wedge":{"a":"Cheese Wedge","b":"1F9C0","j":["cheese","food","chadder"]},"meat-on-bone":{"a":"Meat on Bone","b":"1F356","j":["bone","meat","good","food","drumstick"]},"poultry-leg":{"a":"Poultry Leg","b":"1F357","j":["bone","chicken","drumstick","leg","poultry","food","meat","bird","turkey"]},"cut-of-meat":{"a":"Cut of Meat","b":"1F969","j":["chop","lambchop","porkchop","steak","food","cow","meat","cut"]},"bacon":{"a":"Bacon","b":"1F953","j":["breakfast","food","meat","pork","pig"]},"hamburger":{"a":"Hamburger","b":"1F354","j":["burger","meat","fast food","beef","cheeseburger","mcdonalds","burger king"]},"french-fries":{"a":"French Fries","b":"1F35F","j":["french","fries","chips","snack","fast food"]},"pizza":{"a":"Pizza","b":"1F355","j":["cheese","slice","food","party"]},"hot-dog":{"a":"Hot Dog","b":"1F32D","j":["frankfurter","hotdog","sausage","food"]},"sandwich":{"a":"Sandwich","b":"1F96A","j":["bread","food","lunch"]},"taco":{"a":"Taco","b":"1F32E","j":["mexican","food"]},"burrito":{"a":"Burrito","b":"1F32F","j":["mexican","wrap","food"]},"tamale":{"a":"Tamale","b":"1FAD4","j":["mexican","wrapped","food","masa"]},"stuffed-flatbread":{"a":"Stuffed Flatbread","b":"1F959","j":["falafel","flatbread","food","gyro","kebab","stuffed"]},"falafel":{"a":"Falafel","b":"1F9C6","j":["chickpea","meatball","food"]},"egg":{"a":"Egg","b":"1F95A","j":["breakfast","food","chicken"]},"cooking":{"a":"Cooking","b":"1F373","j":["breakfast","egg","frying","pan","food","kitchen"]},"shallow-pan-of-food":{"a":"Shallow Pan of Food","b":"1F958","j":["casserole","food","paella","pan","shallow","cooking"]},"pot-of-food":{"a":"Pot of Food","b":"1F372","j":["pot","stew","food","meat","soup"]},"fondue":{"a":"Fondue","b":"1FAD5","j":["cheese","chocolate","melted","pot","Swiss","food"]},"bowl-with-spoon":{"a":"Bowl with Spoon","b":"1F963","j":["breakfast","cereal","congee","oatmeal","porridge","food"]},"green-salad":{"a":"Green Salad","b":"1F957","j":["food","green","salad","healthy","lettuce"]},"popcorn":{"a":"Popcorn","b":"1F37F","j":["food","movie theater","films","snack"]},"butter":{"a":"Butter","b":"1F9C8","j":["dairy","food","cook"]},"salt":{"a":"Salt","b":"1F9C2","j":["condiment","shaker"]},"canned-food":{"a":"Canned Food","b":"1F96B","j":["can","food","soup"]},"bento-box":{"a":"Bento Box","b":"1F371","j":["bento","box","food","japanese"]},"rice-cracker":{"a":"Rice Cracker","b":"1F358","j":["cracker","rice","food","japanese"]},"rice-ball":{"a":"Rice Ball","b":"1F359","j":["ball","Japanese","rice","food","japanese"]},"cooked-rice":{"a":"Cooked Rice","b":"1F35A","j":["cooked","rice","food","china","asian"]},"curry-rice":{"a":"Curry Rice","b":"1F35B","j":["curry","rice","food","spicy","hot","indian"]},"steaming-bowl":{"a":"Steaming Bowl","b":"1F35C","j":["bowl","noodle","ramen","steaming","food","japanese","chopsticks"]},"spaghetti":{"a":"Spaghetti","b":"1F35D","j":["pasta","food","italian","noodle"]},"roasted-sweet-potato":{"a":"Roasted Sweet Potato","b":"1F360","j":["potato","roasted","sweet","food","nature"]},"oden":{"a":"Oden","b":"1F362","j":["kebab","seafood","skewer","stick","food","japanese"]},"sushi":{"a":"Sushi","b":"1F363","j":["food","fish","japanese","rice"]},"fried-shrimp":{"a":"Fried Shrimp","b":"1F364","j":["fried","prawn","shrimp","tempura","food","animal","appetizer","summer"]},"fish-cake-with-swirl":{"a":"Fish Cake with Swirl","b":"1F365","j":["cake","fish","pastry","swirl","food","japan","sea","beach","narutomaki","pink","kamaboko","surimi","ramen"]},"moon-cake":{"a":"Moon Cake","b":"1F96E","j":["autumn","festival","yuèbǐng","food"]},"dango":{"a":"Dango","b":"1F361","j":["dessert","Japanese","skewer","stick","sweet","food","japanese","barbecue","meat"]},"dumpling":{"a":"Dumpling","b":"1F95F","j":["empanada","gyōza","jiaozi","pierogi","potsticker","food"]},"fortune-cookie":{"a":"Fortune Cookie","b":"1F960","j":["prophecy","food"]},"takeout-box":{"a":"Takeout Box","b":"1F961","j":["oyster pail","food","leftovers"]},"crab":{"a":"Crab","b":"1F980","j":["Cancer","zodiac","animal","crustacean"]},"lobster":{"a":"Lobster","b":"1F99E","j":["bisque","claws","seafood","animal","nature"]},"shrimp":{"a":"Shrimp","b":"1F990","j":["food","shellfish","small","animal","ocean","nature","seafood"]},"squid":{"a":"Squid","b":"1F991","j":["food","molusc","animal","nature","ocean","sea"]},"oyster":{"a":"Oyster","b":"1F9AA","j":["diving","pearl","food"]},"soft-ice-cream":{"a":"Soft Ice Cream","b":"1F366","j":["cream","dessert","ice","icecream","soft","sweet","food","hot","summer"]},"shaved-ice":{"a":"Shaved Ice","b":"1F367","j":["dessert","ice","shaved","sweet","hot","summer"]},"ice-cream":{"a":"Ice Cream","b":"1F368","j":["cream","dessert","ice","sweet","food","hot"]},"doughnut":{"a":"Doughnut","b":"1F369","j":["breakfast","dessert","donut","sweet","food","snack"]},"cookie":{"a":"Cookie","b":"1F36A","j":["dessert","sweet","food","snack","oreo","chocolate"]},"birthday-cake":{"a":"Birthday Cake","b":"1F382","j":["birthday","cake","celebration","dessert","pastry","sweet","food"]},"shortcake":{"a":"Shortcake","b":"1F370","j":["cake","dessert","pastry","slice","sweet","food"]},"cupcake":{"a":"Cupcake","b":"1F9C1","j":["bakery","sweet","food","dessert"]},"pie":{"a":"Pie","b":"1F967","j":["filling","pastry","fruit","meat","food","dessert"]},"chocolate-bar":{"a":"Chocolate Bar","b":"1F36B","j":["bar","chocolate","dessert","sweet","food","snack"]},"candy":{"a":"Candy","b":"1F36C","j":["dessert","sweet","snack","lolly"]},"lollipop":{"a":"Lollipop","b":"1F36D","j":["candy","dessert","sweet","food","snack"]},"custard":{"a":"Custard","b":"1F36E","j":["dessert","pudding","sweet","food"]},"honey-pot":{"a":"Honey Pot","b":"1F36F","j":["honey","honeypot","pot","sweet","bees","kitchen"]},"baby-bottle":{"a":"Baby Bottle","b":"1F37C","j":["baby","bottle","drink","milk","food","container"]},"glass-of-milk":{"a":"Glass of Milk","b":"1F95B","j":["drink","glass","milk","beverage","cow"]},"hot-beverage":{"a":"Hot Beverage","b":"2615","j":["beverage","coffee","drink","hot","steaming","tea","caffeine","latte","espresso"]},"teapot":{"a":"Teapot","b":"1FAD6","j":["drink","pot","tea","hot"]},"teacup-without-handle":{"a":"Teacup Without Handle","b":"1F375","j":["beverage","cup","drink","tea","teacup","bowl","breakfast","green","british"]},"sake":{"a":"Sake","b":"1F376","j":["bar","beverage","bottle","cup","drink","wine","drunk","japanese","alcohol","booze"]},"bottle-with-popping-cork":{"a":"Bottle with Popping Cork","b":"1F37E","j":["bar","bottle","cork","drink","popping","wine","celebration"]},"wine-glass":{"a":"Wine Glass","b":"1F377","j":["bar","beverage","drink","glass","wine","drunk","alcohol","booze"]},"cocktail-glass":{"a":"Cocktail Glass","b":"1F378","j":["bar","cocktail","drink","glass","drunk","alcohol","beverage","booze","mojito"]},"tropical-drink":{"a":"Tropical Drink","b":"1F379","j":["bar","drink","tropical","beverage","cocktail","summer","beach","alcohol","booze","mojito"]},"beer-mug":{"a":"Beer Mug","b":"1F37A","j":["bar","beer","drink","mug","relax","beverage","drunk","party","pub","summer","alcohol","booze"]},"clinking-beer-mugs":{"a":"Clinking Beer Mugs","b":"1F37B","j":["bar","beer","clink","drink","mug","relax","beverage","drunk","party","pub","summer","alcohol","booze"]},"clinking-glasses":{"a":"Clinking Glasses","b":"1F942","j":["celebrate","clink","drink","glass","beverage","party","alcohol","cheers","wine","champagne","toast"]},"tumbler-glass":{"a":"Tumbler Glass","b":"1F943","j":["glass","liquor","shot","tumbler","whisky","drink","beverage","drunk","alcohol","booze","bourbon","scotch"]},"pouring-liquid":{"a":"⊛ Pouring Liquid","b":"1FAD7","j":["drink","empty","glass","spill"]},"cup-with-straw":{"a":"Cup with Straw","b":"1F964","j":["juice","soda","malt","soft drink","water","drink"]},"bubble-tea":{"a":"Bubble Tea","b":"1F9CB","j":["bubble","milk","pearl","tea","taiwan","boba","milk tea","straw"]},"beverage-box":{"a":"Beverage Box","b":"1F9C3","j":["beverage","box","juice","straw","sweet","drink"]},"mate":{"a":"Mate","b":"1F9C9","j":["drink","tea","beverage"]},"ice":{"a":"Ice","b":"1F9CA","j":["cold","ice cube","iceberg","water"]},"chopsticks":{"a":"Chopsticks","b":"1F962","j":["hashi","jeotgarak","kuaizi","food"]},"fork-and-knife-with-plate":{"a":"Fork and Knife with Plate","b":"1F37D","j":["cooking","fork","knife","plate","food","eat","meal","lunch","dinner","restaurant"]},"fork-and-knife":{"a":"Fork and Knife","b":"1F374","j":["cooking","cutlery","fork","knife","kitchen"]},"spoon":{"a":"Spoon","b":"1F944","j":["tableware","cutlery","kitchen"]},"kitchen-knife":{"a":"Kitchen Knife","b":"1F52A","j":["cooking","hocho","knife","tool","weapon","blade","cutlery","kitchen"]},"jar":{"a":"⊛ Jar","b":"1FAD9","j":["condiment","container","empty","sauce","store"]},"amphora":{"a":"Amphora","b":"1F3FA","j":["Aquarius","cooking","drink","jug","zodiac","vase","jar"]},"globe-showing-europeafrica":{"a":"Globe Showing Europe-Africa","b":"1F30D","j":["Africa","earth","Europe","globe","globe showing Europe-Africa","world","globe_showing_europe_africa","international"]},"globe-showing-americas":{"a":"Globe Showing Americas","b":"1F30E","j":["Americas","earth","globe","globe showing Americas","world","USA","international"]},"globe-showing-asiaaustralia":{"a":"Globe Showing Asia-Australia","b":"1F30F","j":["Asia","Australia","earth","globe","globe showing Asia-Australia","world","globe_showing_asia_australia","east","international"]},"globe-with-meridians":{"a":"Globe with Meridians","b":"1F310","j":["earth","globe","meridians","world","international","internet","interweb","i18n"]},"world-map":{"a":"World Map","b":"1F5FA","j":["map","world","location","direction"]},"map-of-japan":{"a":"Map of Japan","b":"1F5FE","j":["Japan","map","map of Japan","nation","country","japanese","asia"]},"compass":{"a":"Compass","b":"1F9ED","j":["magnetic","navigation","orienteering"]},"snowcapped-mountain":{"a":"Snow-Capped Mountain","b":"1F3D4","j":["cold","mountain","snow","snow-capped mountain","snow_capped_mountain","photo","nature","environment","winter"]},"mountain":{"a":"Mountain","b":"26F0","j":["photo","nature","environment"]},"volcano":{"a":"Volcano","b":"1F30B","j":["eruption","mountain","photo","nature","disaster"]},"mount-fuji":{"a":"Mount Fuji","b":"1F5FB","j":["fuji","mountain","photo","nature","japanese"]},"camping":{"a":"Camping","b":"1F3D5","j":["photo","outdoors","tent"]},"beach-with-umbrella":{"a":"Beach with Umbrella","b":"1F3D6","j":["beach","umbrella","weather","summer","sunny","sand","mojito"]},"desert":{"a":"Desert","b":"1F3DC","j":["photo","warm","saharah"]},"desert-island":{"a":"Desert Island","b":"1F3DD","j":["desert","island","photo","tropical","mojito"]},"national-park":{"a":"National Park","b":"1F3DE","j":["park","photo","environment","nature"]},"stadium":{"a":"Stadium","b":"1F3DF","j":["photo","place","sports","concert","venue"]},"classical-building":{"a":"Classical Building","b":"1F3DB","j":["classical","art","culture","history"]},"building-construction":{"a":"Building Construction","b":"1F3D7","j":["construction","wip","working","progress"]},"brick":{"a":"Brick","b":"1F9F1","j":["bricks","clay","mortar","wall"]},"rock":{"a":"Rock","b":"1FAA8","j":["boulder","heavy","solid","stone"]},"wood":{"a":"Wood","b":"1FAB5","j":["log","lumber","timber","nature","trunk"]},"hut":{"a":"Hut","b":"1F6D6","j":["house","roundhouse","yurt","structure"]},"houses":{"a":"Houses","b":"1F3D8","j":["buildings","photo"]},"derelict-house":{"a":"Derelict House","b":"1F3DA","j":["derelict","house","abandon","evict","broken","building"]},"house":{"a":"House","b":"1F3E0","j":["home","building"]},"house-with-garden":{"a":"House with Garden","b":"1F3E1","j":["garden","home","house","plant","nature"]},"office-building":{"a":"Office Building","b":"1F3E2","j":["building","bureau","work"]},"japanese-post-office":{"a":"Japanese Post Office","b":"1F3E3","j":["Japanese","Japanese post office","post","building","envelope","communication"]},"post-office":{"a":"Post Office","b":"1F3E4","j":["European","post","building","email"]},"hospital":{"a":"Hospital","b":"1F3E5","j":["doctor","medicine","building","health","surgery"]},"bank":{"a":"Bank","b":"1F3E6","j":["building","money","sales","cash","business","enterprise"]},"hotel":{"a":"Hotel","b":"1F3E8","j":["building","accomodation","checkin"]},"love-hotel":{"a":"Love Hotel","b":"1F3E9","j":["hotel","love","like","affection","dating"]},"convenience-store":{"a":"Convenience Store","b":"1F3EA","j":["convenience","store","building","shopping","groceries"]},"school":{"a":"School","b":"1F3EB","j":["building","student","education","learn","teach"]},"department-store":{"a":"Department Store","b":"1F3EC","j":["department","store","building","shopping","mall"]},"factory":{"a":"Factory","b":"1F3ED","j":["building","industry","pollution","smoke"]},"japanese-castle":{"a":"Japanese Castle","b":"1F3EF","j":["castle","Japanese","photo","building"]},"castle":{"a":"Castle","b":"1F3F0","j":["European","building","royalty","history"]},"wedding":{"a":"Wedding","b":"1F492","j":["chapel","romance","love","like","affection","couple","marriage","bride","groom"]},"tokyo-tower":{"a":"Tokyo Tower","b":"1F5FC","j":["Tokyo","tower","photo","japanese"]},"statue-of-liberty":{"a":"Statue of Liberty","b":"1F5FD","j":["liberty","statue","american","newyork"]},"church":{"a":"Church","b":"26EA","j":["Christian","cross","religion","building","christ"]},"mosque":{"a":"Mosque","b":"1F54C","j":["islam","Muslim","religion","worship","minaret"]},"hindu-temple":{"a":"Hindu Temple","b":"1F6D5","j":["hindu","temple","religion"]},"synagogue":{"a":"Synagogue","b":"1F54D","j":["Jew","Jewish","religion","temple","judaism","worship","jewish"]},"shinto-shrine":{"a":"Shinto Shrine","b":"26E9","j":["religion","shinto","shrine","temple","japan","kyoto"]},"kaaba":{"a":"Kaaba","b":"1F54B","j":["islam","Muslim","religion","mecca","mosque"]},"fountain":{"a":"Fountain","b":"26F2","j":["photo","summer","water","fresh"]},"tent":{"a":"Tent","b":"26FA","j":["camping","photo","outdoors"]},"foggy":{"a":"Foggy","b":"1F301","j":["fog","photo","mountain"]},"night-with-stars":{"a":"Night with Stars","b":"1F303","j":["night","star","evening","city","downtown"]},"cityscape":{"a":"Cityscape","b":"1F3D9","j":["city","photo","night life","urban"]},"sunrise-over-mountains":{"a":"Sunrise over Mountains","b":"1F304","j":["morning","mountain","sun","sunrise","view","vacation","photo"]},"sunrise":{"a":"Sunrise","b":"1F305","j":["morning","sun","view","vacation","photo"]},"cityscape-at-dusk":{"a":"Cityscape at Dusk","b":"1F306","j":["city","dusk","evening","landscape","sunset","photo","sky","buildings"]},"sunset":{"a":"Sunset","b":"1F307","j":["dusk","sun","photo","good morning","dawn"]},"bridge-at-night":{"a":"Bridge at Night","b":"1F309","j":["bridge","night","photo","sanfrancisco"]},"hot-springs":{"a":"Hot Springs","b":"2668","j":["hot","hotsprings","springs","steaming","bath","warm","relax"]},"carousel-horse":{"a":"Carousel Horse","b":"1F3A0","j":["carousel","horse","photo","carnival"]},"playground-slide":{"a":"⊛ Playground Slide","b":"1F6DD","j":["amusement park","play"]},"ferris-wheel":{"a":"Ferris Wheel","b":"1F3A1","j":["amusement park","ferris","wheel","photo","carnival","londoneye"]},"roller-coaster":{"a":"Roller Coaster","b":"1F3A2","j":["amusement park","coaster","roller","carnival","playground","photo","fun"]},"barber-pole":{"a":"Barber Pole","b":"1F488","j":["barber","haircut","pole","hair","salon","style"]},"circus-tent":{"a":"Circus Tent","b":"1F3AA","j":["circus","tent","festival","carnival","party"]},"locomotive":{"a":"Locomotive","b":"1F682","j":["engine","railway","steam","train","transportation","vehicle"]},"railway-car":{"a":"Railway Car","b":"1F683","j":["car","electric","railway","train","tram","trolleybus","transportation","vehicle"]},"highspeed-train":{"a":"High-Speed Train","b":"1F684","j":["high-speed train","railway","shinkansen","speed","train","high_speed_train","transportation","vehicle"]},"bullet-train":{"a":"Bullet Train","b":"1F685","j":["bullet","railway","shinkansen","speed","train","transportation","vehicle","fast","public","travel"]},"train":{"a":"Train","b":"1F686","j":["railway","transportation","vehicle"]},"metro":{"a":"Metro","b":"1F687","j":["subway","transportation","blue-square","mrt","underground","tube"]},"light-rail":{"a":"Light Rail","b":"1F688","j":["railway","transportation","vehicle"]},"station":{"a":"Station","b":"1F689","j":["railway","train","transportation","vehicle","public"]},"tram":{"a":"Tram","b":"1F68A","j":["trolleybus","transportation","vehicle"]},"monorail":{"a":"Monorail","b":"1F69D","j":["vehicle","transportation"]},"mountain-railway":{"a":"Mountain Railway","b":"1F69E","j":["car","mountain","railway","transportation","vehicle"]},"tram-car":{"a":"Tram Car","b":"1F68B","j":["car","tram","trolleybus","transportation","vehicle","carriage","public","travel"]},"bus":{"a":"Bus","b":"1F68C","j":["vehicle","car","transportation"]},"oncoming-bus":{"a":"Oncoming Bus","b":"1F68D","j":["bus","oncoming","vehicle","transportation"]},"trolleybus":{"a":"Trolleybus","b":"1F68E","j":["bus","tram","trolley","bart","transportation","vehicle"]},"minibus":{"a":"Minibus","b":"1F690","j":["bus","vehicle","car","transportation"]},"ambulance":{"a":"Ambulance","b":"1F691","j":["vehicle","health","911","hospital"]},"fire-engine":{"a":"Fire Engine","b":"1F692","j":["engine","fire","truck","transportation","cars","vehicle"]},"police-car":{"a":"Police Car","b":"1F693","j":["car","patrol","police","vehicle","cars","transportation","law","legal","enforcement"]},"oncoming-police-car":{"a":"Oncoming Police Car","b":"1F694","j":["car","oncoming","police","vehicle","law","legal","enforcement","911"]},"taxi":{"a":"Taxi","b":"1F695","j":["vehicle","uber","cars","transportation"]},"oncoming-taxi":{"a":"Oncoming Taxi","b":"1F696","j":["oncoming","taxi","vehicle","cars","uber"]},"automobile":{"a":"Automobile","b":"1F697","j":["car","red","transportation","vehicle"]},"oncoming-automobile":{"a":"Oncoming Automobile","b":"1F698","j":["automobile","car","oncoming","vehicle","transportation"]},"sport-utility-vehicle":{"a":"Sport Utility Vehicle","b":"1F699","j":["recreational","sport utility","transportation","vehicle"]},"pickup-truck":{"a":"Pickup Truck","b":"1F6FB","j":["pick-up","pickup","truck","car","transportation"]},"delivery-truck":{"a":"Delivery Truck","b":"1F69A","j":["delivery","truck","cars","transportation"]},"articulated-lorry":{"a":"Articulated Lorry","b":"1F69B","j":["lorry","semi","truck","vehicle","cars","transportation","express"]},"tractor":{"a":"Tractor","b":"1F69C","j":["vehicle","car","farming","agriculture"]},"racing-car":{"a":"Racing Car","b":"1F3CE","j":["car","racing","sports","race","fast","formula","f1"]},"motorcycle":{"a":"Motorcycle","b":"1F3CD","j":["racing","race","sports","fast"]},"motor-scooter":{"a":"Motor Scooter","b":"1F6F5","j":["motor","scooter","vehicle","vespa","sasha"]},"manual-wheelchair":{"a":"Manual Wheelchair","b":"1F9BD","j":["accessibility"]},"motorized-wheelchair":{"a":"Motorized Wheelchair","b":"1F9BC","j":["accessibility"]},"auto-rickshaw":{"a":"Auto Rickshaw","b":"1F6FA","j":["tuk tuk","move","transportation"]},"bicycle":{"a":"Bicycle","b":"1F6B2","j":["bike","sports","exercise","hipster"]},"kick-scooter":{"a":"Kick Scooter","b":"1F6F4","j":["kick","scooter","vehicle","razor"]},"skateboard":{"a":"Skateboard","b":"1F6F9","j":["board"]},"roller-skate":{"a":"Roller Skate","b":"1F6FC","j":["roller","skate","footwear","sports"]},"bus-stop":{"a":"Bus Stop","b":"1F68F","j":["bus","stop","transportation","wait"]},"motorway":{"a":"Motorway","b":"1F6E3","j":["highway","road","cupertino","interstate"]},"railway-track":{"a":"Railway Track","b":"1F6E4","j":["railway","train","transportation"]},"oil-drum":{"a":"Oil Drum","b":"1F6E2","j":["drum","oil","barrell"]},"fuel-pump":{"a":"Fuel Pump","b":"26FD","j":["diesel","fuel","fuelpump","gas","pump","station","gas station","petroleum"]},"wheel":{"a":"⊛ Wheel","b":"1F6DE","j":["circle","tire","turn"]},"police-car-light":{"a":"Police Car Light","b":"1F6A8","j":["beacon","car","light","police","revolving","ambulance","911","emergency","alert","error","pinged","law","legal"]},"horizontal-traffic-light":{"a":"Horizontal Traffic Light","b":"1F6A5","j":["light","signal","traffic","transportation"]},"vertical-traffic-light":{"a":"Vertical Traffic Light","b":"1F6A6","j":["light","signal","traffic","transportation","driving"]},"stop-sign":{"a":"Stop Sign","b":"1F6D1","j":["octagonal","sign","stop"]},"construction":{"a":"Construction","b":"1F6A7","j":["barrier","wip","progress","caution","warning"]},"anchor":{"a":"Anchor","b":"2693","j":["ship","tool","ferry","sea","boat"]},"ring-buoy":{"a":"⊛ Ring Buoy","b":"1F6DF","j":["float","life preserver","life saver","rescue","safety"]},"sailboat":{"a":"Sailboat","b":"26F5","j":["boat","resort","sea","yacht","ship","summer","transportation","water","sailing"]},"canoe":{"a":"Canoe","b":"1F6F6","j":["boat","paddle","water","ship"]},"speedboat":{"a":"Speedboat","b":"1F6A4","j":["boat","ship","transportation","vehicle","summer"]},"passenger-ship":{"a":"Passenger Ship","b":"1F6F3","j":["passenger","ship","yacht","cruise","ferry"]},"ferry":{"a":"Ferry","b":"26F4","j":["boat","passenger","ship","yacht"]},"motor-boat":{"a":"Motor Boat","b":"1F6E5","j":["boat","motorboat","ship"]},"ship":{"a":"Ship","b":"1F6A2","j":["boat","passenger","transportation","titanic","deploy"]},"airplane":{"a":"Airplane","b":"2708","j":["aeroplane","vehicle","transportation","flight","fly"]},"small-airplane":{"a":"Small Airplane","b":"1F6E9","j":["aeroplane","airplane","flight","transportation","fly","vehicle"]},"airplane-departure":{"a":"Airplane Departure","b":"1F6EB","j":["aeroplane","airplane","check-in","departure","departures","airport","flight","landing"]},"airplane-arrival":{"a":"Airplane Arrival","b":"1F6EC","j":["aeroplane","airplane","arrivals","arriving","landing","airport","flight","boarding"]},"parachute":{"a":"Parachute","b":"1FA82","j":["hang-glide","parasail","skydive","fly","glide"]},"seat":{"a":"Seat","b":"1F4BA","j":["chair","sit","airplane","transport","bus","flight","fly"]},"helicopter":{"a":"Helicopter","b":"1F681","j":["vehicle","transportation","fly"]},"suspension-railway":{"a":"Suspension Railway","b":"1F69F","j":["railway","suspension","vehicle","transportation"]},"mountain-cableway":{"a":"Mountain Cableway","b":"1F6A0","j":["cable","gondola","mountain","transportation","vehicle","ski"]},"aerial-tramway":{"a":"Aerial Tramway","b":"1F6A1","j":["aerial","cable","car","gondola","tramway","transportation","vehicle","ski"]},"satellite":{"a":"Satellite","b":"1F6F0","j":["space","communication","gps","orbit","spaceflight","NASA","ISS"]},"rocket":{"a":"Rocket","b":"1F680","j":["space","launch","ship","staffmode","NASA","outer space","outer_space","fly"]},"flying-saucer":{"a":"Flying Saucer","b":"1F6F8","j":["UFO","transportation","vehicle","ufo"]},"bellhop-bell":{"a":"Bellhop Bell","b":"1F6CE","j":["bell","bellhop","hotel","service"]},"luggage":{"a":"Luggage","b":"1F9F3","j":["packing","travel"]},"hourglass-done":{"a":"Hourglass Done","b":"231B","j":["sand","timer","time","clock","oldschool","limit","exam","quiz","test"]},"hourglass-not-done":{"a":"Hourglass Not Done","b":"23F3","j":["hourglass","sand","timer","oldschool","time","countdown"]},"watch":{"a":"Watch","b":"231A","j":["clock","time","accessories"]},"alarm-clock":{"a":"Alarm Clock","b":"23F0","j":["alarm","clock","time","wake"]},"stopwatch":{"a":"Stopwatch","b":"23F1","j":["clock","time","deadline"]},"timer-clock":{"a":"Timer Clock","b":"23F2","j":["clock","timer","alarm"]},"mantelpiece-clock":{"a":"Mantelpiece Clock","b":"1F570","j":["clock","time"]},"twelve-oclock":{"a":"Twelve O’Clock","b":"1F55B","j":["00","12","12:00","clock","o’clock","twelve","twelve_o_clock","time","noon","midnight","midday","late","early","schedule"]},"twelvethirty":{"a":"Twelve-Thirty","b":"1F567","j":["12","12:30","clock","thirty","twelve","twelve-thirty","twelve_thirty","time","late","early","schedule"]},"one-oclock":{"a":"One O’Clock","b":"1F550","j":["00","1","1:00","clock","o’clock","one","one_o_clock","time","late","early","schedule"]},"onethirty":{"a":"One-Thirty","b":"1F55C","j":["1","1:30","clock","one","one-thirty","thirty","one_thirty","time","late","early","schedule"]},"two-oclock":{"a":"Two O’Clock","b":"1F551","j":["00","2","2:00","clock","o’clock","two","two_o_clock","time","late","early","schedule"]},"twothirty":{"a":"Two-Thirty","b":"1F55D","j":["2","2:30","clock","thirty","two","two-thirty","two_thirty","time","late","early","schedule"]},"three-oclock":{"a":"Three O’Clock","b":"1F552","j":["00","3","3:00","clock","o’clock","three","three_o_clock","time","late","early","schedule"]},"threethirty":{"a":"Three-Thirty","b":"1F55E","j":["3","3:30","clock","thirty","three","three-thirty","three_thirty","time","late","early","schedule"]},"four-oclock":{"a":"Four O’Clock","b":"1F553","j":["00","4","4:00","clock","four","o’clock","four_o_clock","time","late","early","schedule"]},"fourthirty":{"a":"Four-Thirty","b":"1F55F","j":["4","4:30","clock","four","four-thirty","thirty","four_thirty","time","late","early","schedule"]},"five-oclock":{"a":"Five O’Clock","b":"1F554","j":["00","5","5:00","clock","five","o’clock","five_o_clock","time","late","early","schedule"]},"fivethirty":{"a":"Five-Thirty","b":"1F560","j":["5","5:30","clock","five","five-thirty","thirty","five_thirty","time","late","early","schedule"]},"six-oclock":{"a":"Six O’Clock","b":"1F555","j":["00","6","6:00","clock","o’clock","six","six_o_clock","time","late","early","schedule","dawn","dusk"]},"sixthirty":{"a":"Six-Thirty","b":"1F561","j":["6","6:30","clock","six","six-thirty","thirty","six_thirty","time","late","early","schedule"]},"seven-oclock":{"a":"Seven O’Clock","b":"1F556","j":["00","7","7:00","clock","o’clock","seven","seven_o_clock","time","late","early","schedule"]},"seventhirty":{"a":"Seven-Thirty","b":"1F562","j":["7","7:30","clock","seven","seven-thirty","thirty","seven_thirty","time","late","early","schedule"]},"eight-oclock":{"a":"Eight O’Clock","b":"1F557","j":["00","8","8:00","clock","eight","o’clock","eight_o_clock","time","late","early","schedule"]},"eightthirty":{"a":"Eight-Thirty","b":"1F563","j":["8","8:30","clock","eight","eight-thirty","thirty","eight_thirty","time","late","early","schedule"]},"nine-oclock":{"a":"Nine O’Clock","b":"1F558","j":["00","9","9:00","clock","nine","o’clock","nine_o_clock","time","late","early","schedule"]},"ninethirty":{"a":"Nine-Thirty","b":"1F564","j":["9","9:30","clock","nine","nine-thirty","thirty","nine_thirty","time","late","early","schedule"]},"ten-oclock":{"a":"Ten O’Clock","b":"1F559","j":["00","10","10:00","clock","o’clock","ten","ten_o_clock","time","late","early","schedule"]},"tenthirty":{"a":"Ten-Thirty","b":"1F565","j":["10","10:30","clock","ten","ten-thirty","thirty","ten_thirty","time","late","early","schedule"]},"eleven-oclock":{"a":"Eleven O’Clock","b":"1F55A","j":["00","11","11:00","clock","eleven","o’clock","eleven_o_clock","time","late","early","schedule"]},"eleventhirty":{"a":"Eleven-Thirty","b":"1F566","j":["11","11:30","clock","eleven","eleven-thirty","thirty","eleven_thirty","time","late","early","schedule"]},"new-moon":{"a":"New Moon","b":"1F311","j":["dark","moon","nature","twilight","planet","space","night","evening","sleep"]},"waxing-crescent-moon":{"a":"Waxing Crescent Moon","b":"1F312","j":["crescent","moon","waxing","nature","twilight","planet","space","night","evening","sleep"]},"first-quarter-moon":{"a":"First Quarter Moon","b":"1F313","j":["moon","quarter","nature","twilight","planet","space","night","evening","sleep"]},"waxing-gibbous-moon":{"a":"Waxing Gibbous Moon","b":"1F314","j":["gibbous","moon","waxing","nature","night","sky","gray","twilight","planet","space","evening","sleep"]},"full-moon":{"a":"Full Moon","b":"1F315","j":["full","moon","nature","yellow","twilight","planet","space","night","evening","sleep"]},"waning-gibbous-moon":{"a":"Waning Gibbous Moon","b":"1F316","j":["gibbous","moon","waning","nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"]},"last-quarter-moon":{"a":"Last Quarter Moon","b":"1F317","j":["moon","quarter","nature","twilight","planet","space","night","evening","sleep"]},"waning-crescent-moon":{"a":"Waning Crescent Moon","b":"1F318","j":["crescent","moon","waning","nature","twilight","planet","space","night","evening","sleep"]},"crescent-moon":{"a":"Crescent Moon","b":"1F319","j":["crescent","moon","night","sleep","sky","evening","magic"]},"new-moon-face":{"a":"New Moon Face","b":"1F31A","j":["face","moon","nature","twilight","planet","space","night","evening","sleep"]},"first-quarter-moon-face":{"a":"First Quarter Moon Face","b":"1F31B","j":["face","moon","quarter","nature","twilight","planet","space","night","evening","sleep"]},"last-quarter-moon-face":{"a":"Last Quarter Moon Face","b":"1F31C","j":["face","moon","quarter","nature","twilight","planet","space","night","evening","sleep"]},"thermometer":{"a":"Thermometer","b":"1F321","j":["weather","temperature","hot","cold"]},"sun":{"a":"Sun","b":"2600","j":["bright","rays","sunny","weather","nature","brightness","summer","beach","spring"]},"full-moon-face":{"a":"Full Moon Face","b":"1F31D","j":["bright","face","full","moon","nature","twilight","planet","space","night","evening","sleep"]},"sun-with-face":{"a":"Sun with Face","b":"1F31E","j":["bright","face","sun","nature","morning","sky"]},"ringed-planet":{"a":"Ringed Planet","b":"1FA90","j":["saturn","saturnine","outerspace"]},"star":{"a":"Star","b":"2B50","j":["night","yellow"]},"glowing-star":{"a":"Glowing Star","b":"1F31F","j":["glittery","glow","shining","sparkle","star","night","awesome","good","magic"]},"shooting-star":{"a":"Shooting Star","b":"1F320","j":["falling","shooting","star","night","photo"]},"milky-way":{"a":"Milky Way","b":"1F30C","j":["space","photo","stars"]},"cloud":{"a":"Cloud","b":"2601","j":["weather","sky"]},"sun-behind-cloud":{"a":"Sun Behind Cloud","b":"26C5","j":["cloud","sun","weather","nature","cloudy","morning","fall","spring"]},"cloud-with-lightning-and-rain":{"a":"Cloud with Lightning and Rain","b":"26C8","j":["cloud","rain","thunder","weather","lightning"]},"sun-behind-small-cloud":{"a":"Sun Behind Small Cloud","b":"1F324","j":["cloud","sun","weather"]},"sun-behind-large-cloud":{"a":"Sun Behind Large Cloud","b":"1F325","j":["cloud","sun","weather"]},"sun-behind-rain-cloud":{"a":"Sun Behind Rain Cloud","b":"1F326","j":["cloud","rain","sun","weather"]},"cloud-with-rain":{"a":"Cloud with Rain","b":"1F327","j":["cloud","rain","weather"]},"cloud-with-snow":{"a":"Cloud with Snow","b":"1F328","j":["cloud","cold","snow","weather"]},"cloud-with-lightning":{"a":"Cloud with Lightning","b":"1F329","j":["cloud","lightning","weather","thunder"]},"tornado":{"a":"Tornado","b":"1F32A","j":["cloud","whirlwind","weather","cyclone","twister"]},"fog":{"a":"Fog","b":"1F32B","j":["cloud","weather"]},"wind-face":{"a":"Wind Face","b":"1F32C","j":["blow","cloud","face","wind","gust","air"]},"cyclone":{"a":"Cyclone","b":"1F300","j":["dizzy","hurricane","twister","typhoon","weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado"]},"rainbow":{"a":"Rainbow","b":"1F308","j":["rain","nature","happy","unicorn_face","photo","sky","spring"]},"closed-umbrella":{"a":"Closed Umbrella","b":"1F302","j":["clothing","rain","umbrella","weather","drizzle"]},"umbrella":{"a":"Umbrella","b":"2602","j":["clothing","rain","weather","spring"]},"umbrella-with-rain-drops":{"a":"Umbrella with Rain Drops","b":"2614","j":["clothing","drop","rain","umbrella","rainy","weather","spring"]},"umbrella-on-ground":{"a":"Umbrella on Ground","b":"26F1","j":["rain","sun","umbrella","weather","summer"]},"high-voltage":{"a":"High Voltage","b":"26A1","j":["danger","electric","lightning","voltage","zap","thunder","weather","lightning bolt","fast"]},"snowflake":{"a":"Snowflake","b":"2744","j":["cold","snow","winter","season","weather","christmas","xmas"]},"snowman":{"a":"Snowman","b":"2603","j":["cold","snow","winter","season","weather","christmas","xmas","frozen"]},"snowman-without-snow":{"a":"Snowman Without Snow","b":"26C4","j":["cold","snow","snowman","winter","season","weather","christmas","xmas","frozen","without_snow"]},"comet":{"a":"Comet","b":"2604","j":["space"]},"fire":{"a":"Fire","b":"1F525","j":["flame","tool","hot","cook"]},"droplet":{"a":"Droplet","b":"1F4A7","j":["cold","comic","drop","sweat","water","drip","faucet","spring"]},"water-wave":{"a":"Water Wave","b":"1F30A","j":["ocean","water","wave","sea","nature","tsunami","disaster"]},"jackolantern":{"a":"Jack-O-Lantern","b":"1F383","j":["celebration","halloween","jack","jack-o-lantern","lantern","jack_o_lantern","light","pumpkin","creepy","fall"]},"christmas-tree":{"a":"Christmas Tree","b":"1F384","j":["celebration","Christmas","tree","festival","vacation","december","xmas"]},"fireworks":{"a":"Fireworks","b":"1F386","j":["celebration","photo","festival","carnival","congratulations"]},"sparkler":{"a":"Sparkler","b":"1F387","j":["celebration","fireworks","sparkle","stars","night","shine"]},"firecracker":{"a":"Firecracker","b":"1F9E8","j":["dynamite","explosive","fireworks","boom","explode","explosion"]},"sparkles":{"a":"Sparkles","b":"2728","j":["*","sparkle","star","stars","shine","shiny","cool","awesome","good","magic"]},"balloon":{"a":"Balloon","b":"1F388","j":["celebration","party","birthday","circus"]},"party-popper":{"a":"Party Popper","b":"1F389","j":["celebration","party","popper","tada","congratulations","birthday","magic","circus"]},"confetti-ball":{"a":"Confetti Ball","b":"1F38A","j":["ball","celebration","confetti","festival","party","birthday","circus"]},"tanabata-tree":{"a":"Tanabata Tree","b":"1F38B","j":["banner","celebration","Japanese","tree","plant","nature","branch","summer"]},"pine-decoration":{"a":"Pine Decoration","b":"1F38D","j":["bamboo","celebration","Japanese","pine","plant","nature","vegetable","panda"]},"japanese-dolls":{"a":"Japanese Dolls","b":"1F38E","j":["celebration","doll","festival","Japanese","Japanese dolls","japanese","toy","kimono"]},"carp-streamer":{"a":"Carp Streamer","b":"1F38F","j":["carp","celebration","streamer","fish","japanese","koinobori","banner"]},"wind-chime":{"a":"Wind Chime","b":"1F390","j":["bell","celebration","chime","wind","nature","ding","spring"]},"moon-viewing-ceremony":{"a":"Moon Viewing Ceremony","b":"1F391","j":["celebration","ceremony","moon","photo","japan","asia","tsukimi"]},"red-envelope":{"a":"Red Envelope","b":"1F9E7","j":["gift","good luck","hóngbāo","lai see","money"]},"ribbon":{"a":"Ribbon","b":"1F380","j":["celebration","decoration","pink","girl","bowtie"]},"wrapped-gift":{"a":"Wrapped Gift","b":"1F381","j":["box","celebration","gift","present","wrapped","birthday","christmas","xmas"]},"reminder-ribbon":{"a":"Reminder Ribbon","b":"1F397","j":["celebration","reminder","ribbon","sports","cause","support","awareness"]},"admission-tickets":{"a":"Admission Tickets","b":"1F39F","j":["admission","ticket","sports","concert","entrance"]},"ticket":{"a":"Ticket","b":"1F3AB","j":["admission","event","concert","pass"]},"military-medal":{"a":"Military Medal","b":"1F396","j":["celebration","medal","military","award","winning","army"]},"trophy":{"a":"Trophy","b":"1F3C6","j":["prize","win","award","contest","place","ftw","ceremony"]},"sports-medal":{"a":"Sports Medal","b":"1F3C5","j":["medal","award","winning"]},"1st-place-medal":{"a":"1st Place Medal","b":"1F947","j":["first","gold","medal","award","winning"]},"2nd-place-medal":{"a":"2nd Place Medal","b":"1F948","j":["medal","second","silver","award"]},"3rd-place-medal":{"a":"3rd Place Medal","b":"1F949","j":["bronze","medal","third","award"]},"soccer-ball":{"a":"Soccer Ball","b":"26BD","j":["ball","football","soccer","sports"]},"baseball":{"a":"Baseball","b":"26BE","j":["ball","sports","balls"]},"softball":{"a":"Softball","b":"1F94E","j":["ball","glove","underarm","sports","balls"]},"basketball":{"a":"Basketball","b":"1F3C0","j":["ball","hoop","sports","balls","NBA"]},"volleyball":{"a":"Volleyball","b":"1F3D0","j":["ball","game","sports","balls"]},"american-football":{"a":"American Football","b":"1F3C8","j":["american","ball","football","sports","balls","NFL"]},"rugby-football":{"a":"Rugby Football","b":"1F3C9","j":["ball","football","rugby","sports","team"]},"tennis":{"a":"Tennis","b":"1F3BE","j":["ball","racquet","sports","balls","green"]},"flying-disc":{"a":"Flying Disc","b":"1F94F","j":["ultimate","sports","frisbee"]},"bowling":{"a":"Bowling","b":"1F3B3","j":["ball","game","sports","fun","play"]},"cricket-game":{"a":"Cricket Game","b":"1F3CF","j":["ball","bat","game","sports"]},"field-hockey":{"a":"Field Hockey","b":"1F3D1","j":["ball","field","game","hockey","stick","sports"]},"ice-hockey":{"a":"Ice Hockey","b":"1F3D2","j":["game","hockey","ice","puck","stick","sports"]},"lacrosse":{"a":"Lacrosse","b":"1F94D","j":["ball","goal","stick","sports"]},"ping-pong":{"a":"Ping Pong","b":"1F3D3","j":["ball","bat","game","paddle","table tennis","sports","pingpong"]},"badminton":{"a":"Badminton","b":"1F3F8","j":["birdie","game","racquet","shuttlecock","sports"]},"boxing-glove":{"a":"Boxing Glove","b":"1F94A","j":["boxing","glove","sports","fighting"]},"martial-arts-uniform":{"a":"Martial Arts Uniform","b":"1F94B","j":["judo","karate","martial arts","taekwondo","uniform"]},"goal-net":{"a":"Goal Net","b":"1F945","j":["goal","net","sports"]},"flag-in-hole":{"a":"Flag in Hole","b":"26F3","j":["golf","hole","sports","business","flag","summer"]},"ice-skate":{"a":"Ice Skate","b":"26F8","j":["ice","skate","sports"]},"fishing-pole":{"a":"Fishing Pole","b":"1F3A3","j":["fish","pole","food","hobby","summer"]},"diving-mask":{"a":"Diving Mask","b":"1F93F","j":["diving","scuba","snorkeling","sport","ocean"]},"running-shirt":{"a":"Running Shirt","b":"1F3BD","j":["athletics","running","sash","shirt","play","pageant"]},"skis":{"a":"Skis","b":"1F3BF","j":["ski","snow","sports","winter","cold"]},"sled":{"a":"Sled","b":"1F6F7","j":["sledge","sleigh","luge","toboggan"]},"curling-stone":{"a":"Curling Stone","b":"1F94C","j":["game","rock","sports"]},"bullseye":{"a":"Bullseye","b":"1F3AF","j":["dart","direct hit","game","hit","target","direct_hit","play","bar"]},"yoyo":{"a":"Yo-Yo","b":"1FA80","j":["fluctuate","toy","yo-yo","yo_yo"]},"kite":{"a":"Kite","b":"1FA81","j":["fly","soar","wind"]},"pool-8-ball":{"a":"Pool 8 Ball","b":"1F3B1","j":["8","ball","billiard","eight","game","pool","hobby","luck","magic"]},"crystal-ball":{"a":"Crystal Ball","b":"1F52E","j":["ball","crystal","fairy tale","fantasy","fortune","tool","disco","party","magic","circus","fortune_teller"]},"magic-wand":{"a":"Magic Wand","b":"1FA84","j":["magic","witch","wizard","supernature","power"]},"nazar-amulet":{"a":"Nazar Amulet","b":"1F9FF","j":["bead","charm","evil-eye","nazar","talisman"]},"hamsa":{"a":"⊛ Hamsa","b":"1FAAC","j":["amulet","Fatima","hand","Mary","Miriam","protection"]},"video-game":{"a":"Video Game","b":"1F3AE","j":["controller","game","play","console","PS4"]},"joystick":{"a":"Joystick","b":"1F579","j":["game","video game","play"]},"slot-machine":{"a":"Slot Machine","b":"1F3B0","j":["game","slot","bet","gamble","vegas","fruit machine","luck","casino"]},"game-die":{"a":"Game Die","b":"1F3B2","j":["dice","die","game","random","tabletop","play","luck"]},"puzzle-piece":{"a":"Puzzle Piece","b":"1F9E9","j":["clue","interlocking","jigsaw","piece","puzzle"]},"teddy-bear":{"a":"Teddy Bear","b":"1F9F8","j":["plaything","plush","stuffed","toy"]},"piata":{"a":"Piñata","b":"1FA85","j":["celebration","party","piñata","pinata","mexico","candy"]},"mirror-ball":{"a":"⊛ Mirror Ball","b":"1FAA9","j":["dance","disco","glitter","party"]},"nesting-dolls":{"a":"Nesting Dolls","b":"1FA86","j":["doll","nesting","russia","matryoshka","toy"]},"spade-suit":{"a":"Spade Suit","b":"2660","j":["card","game","poker","cards","suits","magic"]},"heart-suit":{"a":"Heart Suit","b":"2665","j":["card","game","poker","cards","magic","suits"]},"diamond-suit":{"a":"Diamond Suit","b":"2666","j":["card","game","poker","cards","magic","suits"]},"club-suit":{"a":"Club Suit","b":"2663","j":["card","game","poker","cards","magic","suits"]},"chess-pawn":{"a":"Chess Pawn","b":"265F","j":["chess","dupe","expendable"]},"joker":{"a":"Joker","b":"1F0CF","j":["card","game","wildcard","poker","cards","play","magic"]},"mahjong-red-dragon":{"a":"Mahjong Red Dragon","b":"1F004","j":["game","mahjong","red","play","chinese","kanji"]},"flower-playing-cards":{"a":"Flower Playing Cards","b":"1F3B4","j":["card","flower","game","Japanese","playing","sunset","red"]},"performing-arts":{"a":"Performing Arts","b":"1F3AD","j":["art","mask","performing","theater","theatre","acting","drama"]},"framed-picture":{"a":"Framed Picture","b":"1F5BC","j":["art","frame","museum","painting","picture","photography"]},"artist-palette":{"a":"Artist Palette","b":"1F3A8","j":["art","museum","painting","palette","design","paint","draw","colors"]},"thread":{"a":"Thread","b":"1F9F5","j":["needle","sewing","spool","string"]},"sewing-needle":{"a":"Sewing Needle","b":"1FAA1","j":["embroidery","needle","sewing","stitches","sutures","tailoring"]},"yarn":{"a":"Yarn","b":"1F9F6","j":["ball","crochet","knit"]},"knot":{"a":"Knot","b":"1FAA2","j":["rope","tangled","tie","twine","twist","scout"]},"glasses":{"a":"Glasses","b":"1F453","j":["clothing","eye","eyeglasses","eyewear","fashion","accessories","eyesight","nerdy","dork","geek"]},"sunglasses":{"a":"Sunglasses","b":"1F576","j":["dark","eye","eyewear","glasses","face","cool","accessories"]},"goggles":{"a":"Goggles","b":"1F97D","j":["eye protection","swimming","welding","eyes","protection","safety"]},"lab-coat":{"a":"Lab Coat","b":"1F97C","j":["doctor","experiment","scientist","chemist"]},"safety-vest":{"a":"Safety Vest","b":"1F9BA","j":["emergency","safety","vest","protection"]},"necktie":{"a":"Necktie","b":"1F454","j":["clothing","tie","shirt","suitup","formal","fashion","cloth","business"]},"tshirt":{"a":"T-Shirt","b":"1F455","j":["clothing","shirt","t-shirt","t_shirt","fashion","cloth","casual","tee"]},"jeans":{"a":"Jeans","b":"1F456","j":["clothing","pants","trousers","fashion","shopping"]},"scarf":{"a":"Scarf","b":"1F9E3","j":["neck","winter","clothes"]},"gloves":{"a":"Gloves","b":"1F9E4","j":["hand","hands","winter","clothes"]},"coat":{"a":"Coat","b":"1F9E5","j":["jacket"]},"socks":{"a":"Socks","b":"1F9E6","j":["stocking","stockings","clothes"]},"dress":{"a":"Dress","b":"1F457","j":["clothing","clothes","fashion","shopping"]},"kimono":{"a":"Kimono","b":"1F458","j":["clothing","dress","fashion","women","female","japanese"]},"sari":{"a":"Sari","b":"1F97B","j":["clothing","dress"]},"onepiece-swimsuit":{"a":"One-Piece Swimsuit","b":"1FA71","j":["bathing suit","one-piece swimsuit","one_piece_swimsuit","fashion"]},"briefs":{"a":"Briefs","b":"1FA72","j":["bathing suit","one-piece","swimsuit","underwear","clothing"]},"shorts":{"a":"Shorts","b":"1FA73","j":["bathing suit","pants","underwear","clothing"]},"bikini":{"a":"Bikini","b":"1F459","j":["clothing","swim","swimming","female","woman","girl","fashion","beach","summer"]},"womans-clothes":{"a":"Woman’S Clothes","b":"1F45A","j":["clothing","woman","woman’s clothes","woman_s_clothes","fashion","shopping_bags","female"]},"purse":{"a":"Purse","b":"1F45B","j":["clothing","coin","fashion","accessories","money","sales","shopping"]},"handbag":{"a":"Handbag","b":"1F45C","j":["bag","clothing","purse","fashion","accessory","accessories","shopping"]},"clutch-bag":{"a":"Clutch Bag","b":"1F45D","j":["bag","clothing","pouch","accessories","shopping"]},"shopping-bags":{"a":"Shopping Bags","b":"1F6CD","j":["bag","hotel","shopping","mall","buy","purchase"]},"backpack":{"a":"Backpack","b":"1F392","j":["bag","rucksack","satchel","school","student","education"]},"thong-sandal":{"a":"Thong Sandal","b":"1FA74","j":["beach sandals","sandals","thong sandals","thongs","zōri","footwear","summer"]},"mans-shoe":{"a":"Man’S Shoe","b":"1F45E","j":["clothing","man","man’s shoe","shoe","man_s_shoe","fashion","male"]},"running-shoe":{"a":"Running Shoe","b":"1F45F","j":["athletic","clothing","shoe","sneaker","shoes","sports","sneakers"]},"hiking-boot":{"a":"Hiking Boot","b":"1F97E","j":["backpacking","boot","camping","hiking"]},"flat-shoe":{"a":"Flat Shoe","b":"1F97F","j":["ballet flat","slip-on","slipper","ballet"]},"highheeled-shoe":{"a":"High-Heeled Shoe","b":"1F460","j":["clothing","heel","high-heeled shoe","shoe","woman","high_heeled_shoe","fashion","shoes","female","pumps","stiletto"]},"womans-sandal":{"a":"Woman’S Sandal","b":"1F461","j":["clothing","sandal","shoe","woman","woman’s sandal","woman_s_sandal","shoes","fashion","flip flops"]},"ballet-shoes":{"a":"Ballet Shoes","b":"1FA70","j":["ballet","dance"]},"womans-boot":{"a":"Woman’S Boot","b":"1F462","j":["boot","clothing","shoe","woman","woman’s boot","woman_s_boot","shoes","fashion"]},"crown":{"a":"Crown","b":"1F451","j":["clothing","king","queen","kod","leader","royalty","lord"]},"womans-hat":{"a":"Woman’S Hat","b":"1F452","j":["clothing","hat","woman","woman’s hat","woman_s_hat","fashion","accessories","female","lady","spring"]},"top-hat":{"a":"Top Hat","b":"1F3A9","j":["clothing","hat","top","tophat","magic","gentleman","classy","circus"]},"graduation-cap":{"a":"Graduation Cap","b":"1F393","j":["cap","celebration","clothing","graduation","hat","school","college","degree","university","legal","learn","education"]},"billed-cap":{"a":"Billed Cap","b":"1F9E2","j":["baseball cap","cap","baseball"]},"military-helmet":{"a":"Military Helmet","b":"1FA96","j":["army","helmet","military","soldier","warrior","protection"]},"rescue-workers-helmet":{"a":"Rescue Worker’S Helmet","b":"26D1","j":["aid","cross","face","hat","helmet","rescue worker’s helmet","rescue_worker_s_helmet","construction","build"]},"prayer-beads":{"a":"Prayer Beads","b":"1F4FF","j":["beads","clothing","necklace","prayer","religion","dhikr","religious"]},"lipstick":{"a":"Lipstick","b":"1F484","j":["cosmetics","makeup","female","girl","fashion","woman"]},"ring":{"a":"Ring","b":"1F48D","j":["diamond","wedding","propose","marriage","valentines","fashion","jewelry","gem","engagement"]},"gem-stone":{"a":"Gem Stone","b":"1F48E","j":["diamond","gem","jewel","blue","ruby","jewelry"]},"muted-speaker":{"a":"Muted Speaker","b":"1F507","j":["mute","quiet","silent","speaker","sound","volume","silence"]},"speaker-low-volume":{"a":"Speaker Low Volume","b":"1F508","j":["soft","sound","volume","silence","broadcast"]},"speaker-medium-volume":{"a":"Speaker Medium Volume","b":"1F509","j":["medium","volume","speaker","broadcast"]},"speaker-high-volume":{"a":"Speaker High Volume","b":"1F50A","j":["loud","volume","noise","noisy","speaker","broadcast"]},"loudspeaker":{"a":"Loudspeaker","b":"1F4E2","j":["loud","public address","volume","sound"]},"megaphone":{"a":"Megaphone","b":"1F4E3","j":["cheering","sound","speaker","volume"]},"postal-horn":{"a":"Postal Horn","b":"1F4EF","j":["horn","post","postal","instrument","music"]},"bell":{"a":"Bell","b":"1F514","j":["sound","notification","christmas","xmas","chime"]},"bell-with-slash":{"a":"Bell with Slash","b":"1F515","j":["bell","forbidden","mute","quiet","silent","sound","volume"]},"musical-score":{"a":"Musical Score","b":"1F3BC","j":["music","score","treble","clef","compose"]},"musical-note":{"a":"Musical Note","b":"1F3B5","j":["music","note","score","tone","sound"]},"musical-notes":{"a":"Musical Notes","b":"1F3B6","j":["music","note","notes","score"]},"studio-microphone":{"a":"Studio Microphone","b":"1F399","j":["mic","microphone","music","studio","sing","recording","artist","talkshow"]},"level-slider":{"a":"Level Slider","b":"1F39A","j":["level","music","slider","scale"]},"control-knobs":{"a":"Control Knobs","b":"1F39B","j":["control","knobs","music","dial"]},"microphone":{"a":"Microphone","b":"1F3A4","j":["karaoke","mic","sound","music","PA","sing","talkshow"]},"headphone":{"a":"Headphone","b":"1F3A7","j":["earbud","music","score","gadgets"]},"radio":{"a":"Radio","b":"1F4FB","j":["video","communication","music","podcast","program"]},"saxophone":{"a":"Saxophone","b":"1F3B7","j":["instrument","music","sax","jazz","blues"]},"accordion":{"a":"Accordion","b":"1FA97","j":["concertina","squeeze box","music"]},"guitar":{"a":"Guitar","b":"1F3B8","j":["instrument","music"]},"musical-keyboard":{"a":"Musical Keyboard","b":"1F3B9","j":["instrument","keyboard","music","piano","compose"]},"trumpet":{"a":"Trumpet","b":"1F3BA","j":["instrument","music","brass"]},"violin":{"a":"Violin","b":"1F3BB","j":["instrument","music","orchestra","symphony"]},"banjo":{"a":"Banjo","b":"1FA95","j":["music","stringed","instructment"]},"drum":{"a":"Drum","b":"1F941","j":["drumsticks","music","instrument","snare"]},"long-drum":{"a":"Long Drum","b":"1FA98","j":["beat","conga","drum","rhythm","music"]},"mobile-phone":{"a":"Mobile Phone","b":"1F4F1","j":["cell","mobile","phone","telephone","technology","apple","gadgets","dial"]},"mobile-phone-with-arrow":{"a":"Mobile Phone with Arrow","b":"1F4F2","j":["arrow","cell","mobile","phone","receive","iphone","incoming"]},"telephone":{"a":"Telephone","b":"260E","j":["phone","technology","communication","dial"]},"telephone-receiver":{"a":"Telephone Receiver","b":"1F4DE","j":["phone","receiver","telephone","technology","communication","dial"]},"pager":{"a":"Pager","b":"1F4DF","j":["bbcall","oldschool","90s"]},"fax-machine":{"a":"Fax Machine","b":"1F4E0","j":["fax","communication","technology"]},"battery":{"a":"Battery","b":"1F50B","j":["power","energy","sustain"]},"low-battery":{"a":"⊛ Low Battery","b":"1FAAB","j":["electronic","low energy"]},"electric-plug":{"a":"Electric Plug","b":"1F50C","j":["electric","electricity","plug","charger","power"]},"laptop":{"a":"Laptop","b":"1F4BB","j":["computer","pc","personal","technology","screen","display","monitor"]},"desktop-computer":{"a":"Desktop Computer","b":"1F5A5","j":["computer","desktop","technology","computing","screen"]},"printer":{"a":"Printer","b":"1F5A8","j":["computer","paper","ink"]},"keyboard":{"a":"Keyboard","b":"2328","j":["computer","technology","type","input","text"]},"computer-mouse":{"a":"Computer Mouse","b":"1F5B1","j":["computer","click"]},"trackball":{"a":"Trackball","b":"1F5B2","j":["computer","technology","trackpad"]},"computer-disk":{"a":"Computer Disk","b":"1F4BD","j":["computer","disk","minidisk","optical","technology","record","data","90s"]},"floppy-disk":{"a":"Floppy Disk","b":"1F4BE","j":["computer","disk","floppy","oldschool","technology","save","90s","80s"]},"optical-disk":{"a":"Optical Disk","b":"1F4BF","j":["cd","computer","disk","optical","technology","dvd","disc","90s"]},"dvd":{"a":"Dvd","b":"1F4C0","j":["blu-ray","computer","disk","optical","cd","disc"]},"abacus":{"a":"Abacus","b":"1F9EE","j":["calculation"]},"movie-camera":{"a":"Movie Camera","b":"1F3A5","j":["camera","cinema","movie","film","record"]},"film-frames":{"a":"Film Frames","b":"1F39E","j":["cinema","film","frames","movie"]},"film-projector":{"a":"Film Projector","b":"1F4FD","j":["cinema","film","movie","projector","video","tape","record"]},"clapper-board":{"a":"Clapper Board","b":"1F3AC","j":["clapper","movie","film","record"]},"television":{"a":"Television","b":"1F4FA","j":["tv","video","technology","program","oldschool","show"]},"camera":{"a":"Camera","b":"1F4F7","j":["video","gadgets","photography"]},"camera-with-flash":{"a":"Camera with Flash","b":"1F4F8","j":["camera","flash","video","photography","gadgets"]},"video-camera":{"a":"Video Camera","b":"1F4F9","j":["camera","video","film","record"]},"videocassette":{"a":"Videocassette","b":"1F4FC","j":["tape","vhs","video","record","oldschool","90s","80s"]},"magnifying-glass-tilted-left":{"a":"Magnifying Glass Tilted Left","b":"1F50D","j":["glass","magnifying","search","tool","zoom","find","detective"]},"magnifying-glass-tilted-right":{"a":"Magnifying Glass Tilted Right","b":"1F50E","j":["glass","magnifying","search","tool","zoom","find","detective"]},"candle":{"a":"Candle","b":"1F56F","j":["light","fire","wax"]},"light-bulb":{"a":"Light Bulb","b":"1F4A1","j":["bulb","comic","electric","idea","light","electricity"]},"flashlight":{"a":"Flashlight","b":"1F526","j":["electric","light","tool","torch","dark","camping","sight","night"]},"red-paper-lantern":{"a":"Red Paper Lantern","b":"1F3EE","j":["bar","lantern","light","red","paper","halloween","spooky"]},"diya-lamp":{"a":"Diya Lamp","b":"1FA94","j":["diya","lamp","oil","lighting"]},"notebook-with-decorative-cover":{"a":"Notebook with Decorative Cover","b":"1F4D4","j":["book","cover","decorated","notebook","classroom","notes","record","paper","study"]},"closed-book":{"a":"Closed Book","b":"1F4D5","j":["book","closed","read","library","knowledge","textbook","learn"]},"open-book":{"a":"Open Book","b":"1F4D6","j":["book","open","read","library","knowledge","literature","learn","study"]},"green-book":{"a":"Green Book","b":"1F4D7","j":["book","green","read","library","knowledge","study"]},"blue-book":{"a":"Blue Book","b":"1F4D8","j":["blue","book","read","library","knowledge","learn","study"]},"orange-book":{"a":"Orange Book","b":"1F4D9","j":["book","orange","read","library","knowledge","textbook","study"]},"books":{"a":"Books","b":"1F4DA","j":["book","literature","library","study"]},"notebook":{"a":"Notebook","b":"1F4D3","j":["stationery","record","notes","paper","study"]},"ledger":{"a":"Ledger","b":"1F4D2","j":["notebook","notes","paper"]},"page-with-curl":{"a":"Page with Curl","b":"1F4C3","j":["curl","document","page","documents","office","paper"]},"scroll":{"a":"Scroll","b":"1F4DC","j":["paper","documents","ancient","history"]},"page-facing-up":{"a":"Page Facing Up","b":"1F4C4","j":["document","page","documents","office","paper","information"]},"newspaper":{"a":"Newspaper","b":"1F4F0","j":["news","paper","press","headline"]},"rolledup-newspaper":{"a":"Rolled-Up Newspaper","b":"1F5DE","j":["news","newspaper","paper","rolled","rolled-up newspaper","rolled_up_newspaper","press","headline"]},"bookmark-tabs":{"a":"Bookmark Tabs","b":"1F4D1","j":["bookmark","mark","marker","tabs","favorite","save","order","tidy"]},"bookmark":{"a":"Bookmark","b":"1F516","j":["mark","favorite","label","save"]},"label":{"a":"Label","b":"1F3F7","j":["sale","tag"]},"money-bag":{"a":"Money Bag","b":"1F4B0","j":["bag","dollar","money","moneybag","payment","coins","sale"]},"coin":{"a":"Coin","b":"1FA99","j":["gold","metal","money","silver","treasure","currency"]},"yen-banknote":{"a":"Yen Banknote","b":"1F4B4","j":["banknote","bill","currency","money","note","yen","sales","japanese","dollar"]},"dollar-banknote":{"a":"Dollar Banknote","b":"1F4B5","j":["banknote","bill","currency","dollar","money","note","sales"]},"euro-banknote":{"a":"Euro Banknote","b":"1F4B6","j":["banknote","bill","currency","euro","money","note","sales","dollar"]},"pound-banknote":{"a":"Pound Banknote","b":"1F4B7","j":["banknote","bill","currency","money","note","pound","british","sterling","sales","bills","uk","england"]},"money-with-wings":{"a":"Money with Wings","b":"1F4B8","j":["banknote","bill","fly","money","wings","dollar","bills","payment","sale"]},"credit-card":{"a":"Credit Card","b":"1F4B3","j":["card","credit","money","sales","dollar","bill","payment","shopping"]},"receipt":{"a":"Receipt","b":"1F9FE","j":["accounting","bookkeeping","evidence","proof","expenses"]},"chart-increasing-with-yen":{"a":"Chart Increasing with Yen","b":"1F4B9","j":["chart","graph","growth","money","yen","green-square","presentation","stats"]},"envelope":{"a":"Envelope","b":"2709","j":["email","letter","postal","inbox","communication"]},"email":{"a":"E-Mail","b":"1F4E7","j":["e-mail","letter","mail","e_mail","communication","inbox"]},"incoming-envelope":{"a":"Incoming Envelope","b":"1F4E8","j":["e-mail","email","envelope","incoming","letter","receive","inbox"]},"envelope-with-arrow":{"a":"Envelope with Arrow","b":"1F4E9","j":["arrow","e-mail","email","envelope","outgoing","communication"]},"outbox-tray":{"a":"Outbox Tray","b":"1F4E4","j":["box","letter","mail","outbox","sent","tray","inbox","email"]},"inbox-tray":{"a":"Inbox Tray","b":"1F4E5","j":["box","inbox","letter","mail","receive","tray","email","documents"]},"package":{"a":"Package","b":"1F4E6","j":["box","parcel","mail","gift","cardboard","moving"]},"closed-mailbox-with-raised-flag":{"a":"Closed Mailbox with Raised Flag","b":"1F4EB","j":["closed","mail","mailbox","postbox","email","inbox","communication"]},"closed-mailbox-with-lowered-flag":{"a":"Closed Mailbox with Lowered Flag","b":"1F4EA","j":["closed","lowered","mail","mailbox","postbox","email","communication","inbox"]},"open-mailbox-with-raised-flag":{"a":"Open Mailbox with Raised Flag","b":"1F4EC","j":["mail","mailbox","open","postbox","email","inbox","communication"]},"open-mailbox-with-lowered-flag":{"a":"Open Mailbox with Lowered Flag","b":"1F4ED","j":["lowered","mail","mailbox","open","postbox","email","inbox"]},"postbox":{"a":"Postbox","b":"1F4EE","j":["mail","mailbox","email","letter","envelope"]},"ballot-box-with-ballot":{"a":"Ballot Box with Ballot","b":"1F5F3","j":["ballot","box","election","vote"]},"pencil":{"a":"Pencil","b":"270F","j":["stationery","write","paper","writing","school","study"]},"black-nib":{"a":"Black Nib","b":"2712","j":["nib","pen","stationery","writing","write"]},"fountain-pen":{"a":"Fountain Pen","b":"1F58B","j":["fountain","pen","stationery","writing","write"]},"pen":{"a":"Pen","b":"1F58A","j":["ballpoint","stationery","writing","write"]},"paintbrush":{"a":"Paintbrush","b":"1F58C","j":["painting","drawing","creativity","art"]},"crayon":{"a":"Crayon","b":"1F58D","j":["drawing","creativity"]},"memo":{"a":"Memo","b":"1F4DD","j":["pencil","write","documents","stationery","paper","writing","legal","exam","quiz","test","study","compose"]},"briefcase":{"a":"Briefcase","b":"1F4BC","j":["business","documents","work","law","legal","job","career"]},"file-folder":{"a":"File Folder","b":"1F4C1","j":["file","folder","documents","business","office"]},"open-file-folder":{"a":"Open File Folder","b":"1F4C2","j":["file","folder","open","documents","load"]},"card-index-dividers":{"a":"Card Index Dividers","b":"1F5C2","j":["card","dividers","index","organizing","business","stationery"]},"calendar":{"a":"Calendar","b":"1F4C5","j":["date","schedule"]},"tearoff-calendar":{"a":"Tear-off Calendar","b":"1F4C6","j":["calendar","tear-off calendar","tear_off_calendar","schedule","date","planning"]},"spiral-notepad":{"a":"Spiral Notepad","b":"1F5D2","j":["note","pad","spiral","memo","stationery"]},"spiral-calendar":{"a":"Spiral Calendar","b":"1F5D3","j":["calendar","pad","spiral","date","schedule","planning"]},"card-index":{"a":"Card Index","b":"1F4C7","j":["card","index","rolodex","business","stationery"]},"chart-increasing":{"a":"Chart Increasing","b":"1F4C8","j":["chart","graph","growth","trend","upward","presentation","stats","recovery","business","economics","money","sales","good","success"]},"chart-decreasing":{"a":"Chart Decreasing","b":"1F4C9","j":["chart","down","graph","trend","presentation","stats","recession","business","economics","money","sales","bad","failure"]},"bar-chart":{"a":"Bar Chart","b":"1F4CA","j":["bar","chart","graph","presentation","stats"]},"clipboard":{"a":"Clipboard","b":"1F4CB","j":["stationery","documents"]},"pushpin":{"a":"Pushpin","b":"1F4CC","j":["pin","stationery","mark","here"]},"round-pushpin":{"a":"Round Pushpin","b":"1F4CD","j":["pin","pushpin","stationery","location","map","here"]},"paperclip":{"a":"Paperclip","b":"1F4CE","j":["documents","stationery"]},"linked-paperclips":{"a":"Linked Paperclips","b":"1F587","j":["link","paperclip","documents","stationery"]},"straight-ruler":{"a":"Straight Ruler","b":"1F4CF","j":["ruler","straight edge","stationery","calculate","length","math","school","drawing","architect","sketch"]},"triangular-ruler":{"a":"Triangular Ruler","b":"1F4D0","j":["ruler","set","triangle","stationery","math","architect","sketch"]},"scissors":{"a":"Scissors","b":"2702","j":["cutting","tool","stationery","cut"]},"card-file-box":{"a":"Card File Box","b":"1F5C3","j":["box","card","file","business","stationery"]},"file-cabinet":{"a":"File Cabinet","b":"1F5C4","j":["cabinet","file","filing","organizing"]},"wastebasket":{"a":"Wastebasket","b":"1F5D1","j":["bin","trash","rubbish","garbage","toss"]},"locked":{"a":"Locked","b":"1F512","j":["closed","security","password","padlock"]},"unlocked":{"a":"Unlocked","b":"1F513","j":["lock","open","unlock","privacy","security"]},"locked-with-pen":{"a":"Locked with Pen","b":"1F50F","j":["ink","lock","nib","pen","privacy","security","secret"]},"locked-with-key":{"a":"Locked with Key","b":"1F510","j":["closed","key","lock","secure","security","privacy"]},"key":{"a":"Key","b":"1F511","j":["lock","password","door"]},"old-key":{"a":"Old Key","b":"1F5DD","j":["clue","key","lock","old","door","password"]},"hammer":{"a":"Hammer","b":"1F528","j":["tool","tools","build","create"]},"axe":{"a":"Axe","b":"1FA93","j":["chop","hatchet","split","wood","tool","cut"]},"pick":{"a":"Pick","b":"26CF","j":["mining","tool","tools","dig"]},"hammer-and-pick":{"a":"Hammer and Pick","b":"2692","j":["hammer","pick","tool","tools","build","create"]},"hammer-and-wrench":{"a":"Hammer and Wrench","b":"1F6E0","j":["hammer","spanner","tool","wrench","tools","build","create"]},"dagger":{"a":"Dagger","b":"1F5E1","j":["knife","weapon"]},"crossed-swords":{"a":"Crossed Swords","b":"2694","j":["crossed","swords","weapon"]},"water-pistol":{"a":"Water Pistol","b":"1F52B","j":["gun","handgun","pistol","revolver","tool","water","weapon","violence"]},"boomerang":{"a":"Boomerang","b":"1FA83","j":["australia","rebound","repercussion","weapon"]},"bow-and-arrow":{"a":"Bow and Arrow","b":"1F3F9","j":["archer","arrow","bow","Sagittarius","zodiac","sports"]},"shield":{"a":"Shield","b":"1F6E1","j":["weapon","protection","security"]},"carpentry-saw":{"a":"Carpentry Saw","b":"1FA9A","j":["carpenter","lumber","saw","tool","cut","chop"]},"wrench":{"a":"Wrench","b":"1F527","j":["spanner","tool","tools","diy","ikea","fix","maintainer"]},"screwdriver":{"a":"Screwdriver","b":"1FA9B","j":["screw","tool","tools"]},"nut-and-bolt":{"a":"Nut and Bolt","b":"1F529","j":["bolt","nut","tool","handy","tools","fix"]},"gear":{"a":"Gear","b":"2699","j":["cog","cogwheel","tool"]},"clamp":{"a":"Clamp","b":"1F5DC","j":["compress","tool","vice"]},"balance-scale":{"a":"Balance Scale","b":"2696","j":["balance","justice","Libra","scale","zodiac","law","fairness","weight"]},"white-cane":{"a":"White Cane","b":"1F9AF","j":["accessibility","blind","probing_cane"]},"link":{"a":"Link","b":"1F517","j":["rings","url"]},"chains":{"a":"Chains","b":"26D3","j":["chain","lock","arrest"]},"hook":{"a":"Hook","b":"1FA9D","j":["catch","crook","curve","ensnare","selling point","tools"]},"toolbox":{"a":"Toolbox","b":"1F9F0","j":["chest","mechanic","tool","tools","diy","fix","maintainer"]},"magnet":{"a":"Magnet","b":"1F9F2","j":["attraction","horseshoe","magnetic"]},"ladder":{"a":"Ladder","b":"1FA9C","j":["climb","rung","step","tools"]},"alembic":{"a":"Alembic","b":"2697","j":["chemistry","tool","distilling","science","experiment"]},"test-tube":{"a":"Test Tube","b":"1F9EA","j":["chemist","chemistry","experiment","lab","science"]},"petri-dish":{"a":"Petri Dish","b":"1F9EB","j":["bacteria","biologist","biology","culture","lab"]},"dna":{"a":"Dna","b":"1F9EC","j":["biologist","evolution","gene","genetics","life"]},"microscope":{"a":"Microscope","b":"1F52C","j":["science","tool","laboratory","experiment","zoomin","study"]},"telescope":{"a":"Telescope","b":"1F52D","j":["science","tool","stars","space","zoom","astronomy"]},"satellite-antenna":{"a":"Satellite Antenna","b":"1F4E1","j":["antenna","dish","satellite","communication","future","radio","space"]},"syringe":{"a":"Syringe","b":"1F489","j":["medicine","needle","shot","sick","health","hospital","drugs","blood","doctor","nurse"]},"drop-of-blood":{"a":"Drop of Blood","b":"1FA78","j":["bleed","blood donation","injury","medicine","menstruation","period","hurt","harm","wound"]},"pill":{"a":"Pill","b":"1F48A","j":["doctor","medicine","sick","health","pharmacy","drug"]},"adhesive-bandage":{"a":"Adhesive Bandage","b":"1FA79","j":["bandage","heal"]},"crutch":{"a":"⊛ Crutch","b":"1FA7C","j":["cane","disability","hurt","mobility aid","stick"]},"stethoscope":{"a":"Stethoscope","b":"1FA7A","j":["doctor","heart","medicine","health"]},"xray":{"a":"⊛ X-Ray","b":"1FA7B","j":["bones","doctor","medical","skeleton"]},"door":{"a":"Door","b":"1F6AA","j":["house","entry","exit"]},"elevator":{"a":"Elevator","b":"1F6D7","j":["accessibility","hoist","lift"]},"mirror":{"a":"Mirror","b":"1FA9E","j":["reflection","reflector","speculum"]},"window":{"a":"Window","b":"1FA9F","j":["frame","fresh air","opening","transparent","view","scenery"]},"bed":{"a":"Bed","b":"1F6CF","j":["hotel","sleep","rest"]},"couch-and-lamp":{"a":"Couch and Lamp","b":"1F6CB","j":["couch","hotel","lamp","read","chill"]},"chair":{"a":"Chair","b":"1FA91","j":["seat","sit","furniture"]},"toilet":{"a":"Toilet","b":"1F6BD","j":["restroom","wc","washroom","bathroom","potty"]},"plunger":{"a":"Plunger","b":"1FAA0","j":["force cup","plumber","suction","toilet"]},"shower":{"a":"Shower","b":"1F6BF","j":["water","clean","bathroom"]},"bathtub":{"a":"Bathtub","b":"1F6C1","j":["bath","clean","shower","bathroom"]},"mouse-trap":{"a":"Mouse Trap","b":"1FAA4","j":["bait","mousetrap","snare","trap","cheese"]},"razor":{"a":"Razor","b":"1FA92","j":["sharp","shave","cut"]},"lotion-bottle":{"a":"Lotion Bottle","b":"1F9F4","j":["lotion","moisturizer","shampoo","sunscreen"]},"safety-pin":{"a":"Safety Pin","b":"1F9F7","j":["diaper","punk rock"]},"broom":{"a":"Broom","b":"1F9F9","j":["cleaning","sweeping","witch"]},"basket":{"a":"Basket","b":"1F9FA","j":["farming","laundry","picnic"]},"roll-of-paper":{"a":"Roll of Paper","b":"1F9FB","j":["paper towels","toilet paper","roll"]},"bucket":{"a":"Bucket","b":"1FAA3","j":["cask","pail","vat","water","container"]},"soap":{"a":"Soap","b":"1F9FC","j":["bar","bathing","cleaning","lather","soapdish"]},"bubbles":{"a":"⊛ Bubbles","b":"1FAE7","j":["burp","clean","soap","underwater"]},"toothbrush":{"a":"Toothbrush","b":"1FAA5","j":["bathroom","brush","clean","dental","hygiene","teeth"]},"sponge":{"a":"Sponge","b":"1F9FD","j":["absorbing","cleaning","porous"]},"fire-extinguisher":{"a":"Fire Extinguisher","b":"1F9EF","j":["extinguish","fire","quench"]},"shopping-cart":{"a":"Shopping Cart","b":"1F6D2","j":["cart","shopping","trolley"]},"cigarette":{"a":"Cigarette","b":"1F6AC","j":["smoking","kills","tobacco","joint","smoke"]},"coffin":{"a":"Coffin","b":"26B0","j":["death","vampire","dead","die","rip","graveyard","cemetery","casket","funeral","box"]},"headstone":{"a":"Headstone","b":"1FAA6","j":["cemetery","grave","graveyard","tombstone","death","rip"]},"funeral-urn":{"a":"Funeral Urn","b":"26B1","j":["ashes","death","funeral","urn","dead","die","rip"]},"moai":{"a":"Moai","b":"1F5FF","j":["face","moyai","statue","rock","easter island"]},"placard":{"a":"Placard","b":"1FAA7","j":["demonstration","picket","protest","sign","announcement"]},"identification-card":{"a":"⊛ Identification Card","b":"1FAAA","j":["credentials","ID","license","security"]},"atm-sign":{"a":"Atm Sign","b":"1F3E7","j":["atm","ATM sign","automated","bank","teller","money","sales","cash","blue-square","payment"]},"litter-in-bin-sign":{"a":"Litter in Bin Sign","b":"1F6AE","j":["litter","litter bin","blue-square","sign","human","info"]},"potable-water":{"a":"Potable Water","b":"1F6B0","j":["drinking","potable","water","blue-square","liquid","restroom","cleaning","faucet"]},"wheelchair-symbol":{"a":"Wheelchair Symbol","b":"267F","j":["access","blue-square","disabled","accessibility"]},"mens-room":{"a":"Men’S Room","b":"1F6B9","j":["lavatory","man","men’s room","restroom","wc","men_s_room","toilet","blue-square","gender","male"]},"womens-room":{"a":"Women’S Room","b":"1F6BA","j":["lavatory","restroom","wc","woman","women’s room","women_s_room","purple-square","female","toilet","loo","gender"]},"restroom":{"a":"Restroom","b":"1F6BB","j":["lavatory","WC","blue-square","toilet","refresh","wc","gender"]},"baby-symbol":{"a":"Baby Symbol","b":"1F6BC","j":["baby","changing","orange-square","child"]},"water-closet":{"a":"Water Closet","b":"1F6BE","j":["closet","lavatory","restroom","water","wc","toilet","blue-square"]},"passport-control":{"a":"Passport Control","b":"1F6C2","j":["control","passport","custom","blue-square"]},"customs":{"a":"Customs","b":"1F6C3","j":["passport","border","blue-square"]},"baggage-claim":{"a":"Baggage Claim","b":"1F6C4","j":["baggage","claim","blue-square","airport","transport"]},"left-luggage":{"a":"Left Luggage","b":"1F6C5","j":["baggage","locker","luggage","blue-square","travel"]},"warning":{"a":"Warning","b":"26A0","j":["exclamation","wip","alert","error","problem","issue"]},"children-crossing":{"a":"Children Crossing","b":"1F6B8","j":["child","crossing","pedestrian","traffic","school","warning","danger","sign","driving","yellow-diamond"]},"no-entry":{"a":"No Entry","b":"26D4","j":["entry","forbidden","no","not","prohibited","traffic","limit","security","privacy","bad","denied","stop","circle"]},"prohibited":{"a":"Prohibited","b":"1F6AB","j":["entry","forbidden","no","not","forbid","stop","limit","denied","disallow","circle"]},"no-bicycles":{"a":"No Bicycles","b":"1F6B3","j":["bicycle","bike","forbidden","no","prohibited","cyclist","circle"]},"no-smoking":{"a":"No Smoking","b":"1F6AD","j":["forbidden","no","not","prohibited","smoking","cigarette","blue-square","smell","smoke"]},"no-littering":{"a":"No Littering","b":"1F6AF","j":["forbidden","litter","no","not","prohibited","trash","bin","garbage","circle"]},"nonpotable-water":{"a":"Non-Potable Water","b":"1F6B1","j":["non-drinking","non-potable","water","non_potable_water","drink","faucet","tap","circle"]},"no-pedestrians":{"a":"No Pedestrians","b":"1F6B7","j":["forbidden","no","not","pedestrian","prohibited","rules","crossing","walking","circle"]},"no-mobile-phones":{"a":"No Mobile Phones","b":"1F4F5","j":["cell","forbidden","mobile","no","phone","iphone","mute","circle"]},"no-one-under-eighteen":{"a":"No One Under Eighteen","b":"1F51E","j":["18","age restriction","eighteen","prohibited","underage","drink","pub","night","minor","circle"]},"radioactive":{"a":"Radioactive","b":"2622","j":["sign","nuclear","danger"]},"biohazard":{"a":"Biohazard","b":"2623","j":["sign","danger"]},"up-arrow":{"a":"Up Arrow","b":"2B06","j":["arrow","cardinal","direction","north","blue-square","continue","top"]},"upright-arrow":{"a":"Up-Right Arrow","b":"2197","j":["arrow","direction","intercardinal","northeast","up-right arrow","up_right_arrow","blue-square","point","diagonal"]},"right-arrow":{"a":"Right Arrow","b":"27A1","j":["arrow","cardinal","direction","east","blue-square","next"]},"downright-arrow":{"a":"Down-Right Arrow","b":"2198","j":["arrow","direction","down-right arrow","intercardinal","southeast","down_right_arrow","blue-square","diagonal"]},"down-arrow":{"a":"Down Arrow","b":"2B07","j":["arrow","cardinal","direction","down","south","blue-square","bottom"]},"downleft-arrow":{"a":"Down-Left Arrow","b":"2199","j":["arrow","direction","down-left arrow","intercardinal","southwest","down_left_arrow","blue-square","diagonal"]},"left-arrow":{"a":"Left Arrow","b":"2B05","j":["arrow","cardinal","direction","west","blue-square","previous","back"]},"upleft-arrow":{"a":"Up-Left Arrow","b":"2196","j":["arrow","direction","intercardinal","northwest","up-left arrow","up_left_arrow","blue-square","point","diagonal"]},"updown-arrow":{"a":"Up-Down Arrow","b":"2195","j":["arrow","up-down arrow","up_down_arrow","blue-square","direction","way","vertical"]},"leftright-arrow":{"a":"Left-Right Arrow","b":"2194","j":["arrow","left-right arrow","left_right_arrow","shape","direction","horizontal","sideways"]},"right-arrow-curving-left":{"a":"Right Arrow Curving Left","b":"21A9","j":["arrow","back","return","blue-square","undo","enter"]},"left-arrow-curving-right":{"a":"Left Arrow Curving Right","b":"21AA","j":["arrow","blue-square","return","rotate","direction"]},"right-arrow-curving-up":{"a":"Right Arrow Curving Up","b":"2934","j":["arrow","blue-square","direction","top"]},"right-arrow-curving-down":{"a":"Right Arrow Curving Down","b":"2935","j":["arrow","down","blue-square","direction","bottom"]},"clockwise-vertical-arrows":{"a":"Clockwise Vertical Arrows","b":"1F503","j":["arrow","clockwise","reload","sync","cycle","round","repeat"]},"counterclockwise-arrows-button":{"a":"Counterclockwise Arrows Button","b":"1F504","j":["anticlockwise","arrow","counterclockwise","withershins","blue-square","sync","cycle"]},"back-arrow":{"a":"Back Arrow","b":"1F519","j":["arrow","back","BACK arrow","words","return"]},"end-arrow":{"a":"End Arrow","b":"1F51A","j":["arrow","end","END arrow","words"]},"on-arrow":{"a":"On! Arrow","b":"1F51B","j":["arrow","mark","on","ON! arrow","words"]},"soon-arrow":{"a":"Soon Arrow","b":"1F51C","j":["arrow","soon","SOON arrow","words"]},"top-arrow":{"a":"Top Arrow","b":"1F51D","j":["arrow","top","TOP arrow","up","words","blue-square"]},"place-of-worship":{"a":"Place of Worship","b":"1F6D0","j":["religion","worship","church","temple","prayer"]},"atom-symbol":{"a":"Atom Symbol","b":"269B","j":["atheist","atom","science","physics","chemistry"]},"om":{"a":"Om","b":"1F549","j":["Hindu","religion","hinduism","buddhism","sikhism","jainism"]},"star-of-david":{"a":"Star of David","b":"2721","j":["David","Jew","Jewish","religion","star","star of David","judaism"]},"wheel-of-dharma":{"a":"Wheel of Dharma","b":"2638","j":["Buddhist","dharma","religion","wheel","hinduism","buddhism","sikhism","jainism"]},"yin-yang":{"a":"Yin Yang","b":"262F","j":["religion","tao","taoist","yang","yin","balance"]},"latin-cross":{"a":"Latin Cross","b":"271D","j":["Christian","cross","religion","christianity"]},"orthodox-cross":{"a":"Orthodox Cross","b":"2626","j":["Christian","cross","religion","suppedaneum"]},"star-and-crescent":{"a":"Star and Crescent","b":"262A","j":["islam","Muslim","religion"]},"peace-symbol":{"a":"Peace Symbol","b":"262E","j":["peace","hippie"]},"menorah":{"a":"Menorah","b":"1F54E","j":["candelabrum","candlestick","religion","hanukkah","candles","jewish"]},"dotted-sixpointed-star":{"a":"Dotted Six-Pointed Star","b":"1F52F","j":["dotted six-pointed star","fortune","star","dotted_six_pointed_star","purple-square","religion","jewish","hexagram"]},"aries":{"a":"Aries","b":"2648","j":["ram","zodiac","sign","purple-square","astrology"]},"taurus":{"a":"Taurus","b":"2649","j":["bull","ox","zodiac","purple-square","sign","astrology"]},"gemini":{"a":"Gemini","b":"264A","j":["twins","zodiac","sign","purple-square","astrology"]},"cancer":{"a":"Cancer","b":"264B","j":["crab","zodiac","sign","purple-square","astrology"]},"leo":{"a":"Leo","b":"264C","j":["lion","zodiac","sign","purple-square","astrology"]},"virgo":{"a":"Virgo","b":"264D","j":["zodiac","sign","purple-square","astrology"]},"libra":{"a":"Libra","b":"264E","j":["balance","justice","scales","zodiac","sign","purple-square","astrology"]},"scorpio":{"a":"Scorpio","b":"264F","j":["scorpion","scorpius","zodiac","sign","purple-square","astrology"]},"sagittarius":{"a":"Sagittarius","b":"2650","j":["archer","zodiac","sign","purple-square","astrology"]},"capricorn":{"a":"Capricorn","b":"2651","j":["goat","zodiac","sign","purple-square","astrology"]},"aquarius":{"a":"Aquarius","b":"2652","j":["bearer","water","zodiac","sign","purple-square","astrology"]},"pisces":{"a":"Pisces","b":"2653","j":["fish","zodiac","purple-square","sign","astrology"]},"ophiuchus":{"a":"Ophiuchus","b":"26CE","j":["bearer","serpent","snake","zodiac","sign","purple-square","constellation","astrology"]},"shuffle-tracks-button":{"a":"Shuffle Tracks Button","b":"1F500","j":["arrow","crossed","blue-square","shuffle","music","random"]},"repeat-button":{"a":"Repeat Button","b":"1F501","j":["arrow","clockwise","repeat","loop","record"]},"repeat-single-button":{"a":"Repeat Single Button","b":"1F502","j":["arrow","clockwise","once","blue-square","loop"]},"play-button":{"a":"Play Button","b":"25B6","j":["arrow","play","right","triangle","blue-square","direction"]},"fastforward-button":{"a":"Fast-Forward Button","b":"23E9","j":["arrow","double","fast","fast-forward button","forward","fast_forward_button","blue-square","play","speed","continue"]},"next-track-button":{"a":"Next Track Button","b":"23ED","j":["arrow","next scene","next track","triangle","forward","next","blue-square"]},"play-or-pause-button":{"a":"Play or Pause Button","b":"23EF","j":["arrow","pause","play","right","triangle","blue-square"]},"reverse-button":{"a":"Reverse Button","b":"25C0","j":["arrow","left","reverse","triangle","blue-square","direction"]},"fast-reverse-button":{"a":"Fast Reverse Button","b":"23EA","j":["arrow","double","rewind","play","blue-square"]},"last-track-button":{"a":"Last Track Button","b":"23EE","j":["arrow","previous scene","previous track","triangle","backward"]},"upwards-button":{"a":"Upwards Button","b":"1F53C","j":["arrow","button","red","blue-square","triangle","direction","point","forward","top"]},"fast-up-button":{"a":"Fast Up Button","b":"23EB","j":["arrow","double","blue-square","direction","top"]},"downwards-button":{"a":"Downwards Button","b":"1F53D","j":["arrow","button","down","red","blue-square","direction","bottom"]},"fast-down-button":{"a":"Fast Down Button","b":"23EC","j":["arrow","double","down","blue-square","direction","bottom"]},"pause-button":{"a":"Pause Button","b":"23F8","j":["bar","double","pause","vertical","blue-square"]},"stop-button":{"a":"Stop Button","b":"23F9","j":["square","stop","blue-square"]},"record-button":{"a":"Record Button","b":"23FA","j":["circle","record","blue-square"]},"eject-button":{"a":"Eject Button","b":"23CF","j":["eject","blue-square"]},"cinema":{"a":"Cinema","b":"1F3A6","j":["camera","film","movie","blue-square","record","curtain","stage","theater"]},"dim-button":{"a":"Dim Button","b":"1F505","j":["brightness","dim","low","sun","afternoon","warm","summer"]},"bright-button":{"a":"Bright Button","b":"1F506","j":["bright","brightness","sun","light"]},"antenna-bars":{"a":"Antenna Bars","b":"1F4F6","j":["antenna","bar","cell","mobile","phone","blue-square","reception","internet","connection","wifi","bluetooth","bars"]},"vibration-mode":{"a":"Vibration Mode","b":"1F4F3","j":["cell","mobile","mode","phone","telephone","vibration","orange-square"]},"mobile-phone-off":{"a":"Mobile Phone off","b":"1F4F4","j":["cell","mobile","off","phone","telephone","mute","orange-square","silence","quiet"]},"female-sign":{"a":"Female Sign","b":"2640","j":["woman","women","lady","girl"]},"male-sign":{"a":"Male Sign","b":"2642","j":["man","boy","men"]},"transgender-symbol":{"a":"Transgender Symbol","b":"26A7","j":["transgender","lgbtq"]},"multiply":{"a":"Multiply","b":"2716","j":["×","cancel","multiplication","sign","x","multiplication_sign","math","calculation"]},"plus":{"a":"Plus","b":"2795","j":["+","math","sign","plus_sign","calculation","addition","more","increase"]},"minus":{"a":"Minus","b":"2796","j":["-","−","math","sign","minus_sign","calculation","subtract","less"]},"divide":{"a":"Divide","b":"2797","j":["÷","division","math","sign","division_sign","calculation"]},"heavy-equals-sign":{"a":"⊛ Heavy Equals Sign","b":"1F7F0","j":["equality","math"]},"infinity":{"a":"Infinity","b":"267E","j":["forever","unbounded","universal"]},"double-exclamation-mark":{"a":"Double Exclamation Mark","b":"203C","j":["!","!!","bangbang","exclamation","mark","surprise"]},"exclamation-question-mark":{"a":"Exclamation Question Mark","b":"2049","j":["!","!?","?","exclamation","interrobang","mark","punctuation","question","wat","surprise"]},"red-question-mark":{"a":"Red Question Mark","b":"2753","j":["?","mark","punctuation","question","question_mark","doubt","confused"]},"white-question-mark":{"a":"White Question Mark","b":"2754","j":["?","mark","outlined","punctuation","question","doubts","gray","huh","confused"]},"white-exclamation-mark":{"a":"White Exclamation Mark","b":"2755","j":["!","exclamation","mark","outlined","punctuation","surprise","gray","wow","warning"]},"red-exclamation-mark":{"a":"Red Exclamation Mark","b":"2757","j":["!","exclamation","mark","punctuation","exclamation_mark","heavy_exclamation_mark","danger","surprise","wow","warning"]},"wavy-dash":{"a":"Wavy Dash","b":"3030","j":["dash","punctuation","wavy","draw","line","moustache","mustache","squiggle","scribble"]},"currency-exchange":{"a":"Currency Exchange","b":"1F4B1","j":["bank","currency","exchange","money","sales","dollar","travel"]},"heavy-dollar-sign":{"a":"Heavy Dollar Sign","b":"1F4B2","j":["currency","dollar","money","sales","payment","buck"]},"medical-symbol":{"a":"Medical Symbol","b":"2695","j":["aesculapius","medicine","staff","health","hospital"]},"recycling-symbol":{"a":"Recycling Symbol","b":"267B","j":["recycle","arrow","environment","garbage","trash"]},"fleurdelis":{"a":"Fleur-De-Lis","b":"269C","j":["fleur-de-lis","fleur_de_lis","decorative","scout"]},"trident-emblem":{"a":"Trident Emblem","b":"1F531","j":["anchor","emblem","ship","tool","trident","weapon","spear"]},"name-badge":{"a":"Name Badge","b":"1F4DB","j":["badge","name","fire","forbid"]},"japanese-symbol-for-beginner":{"a":"Japanese Symbol for Beginner","b":"1F530","j":["beginner","chevron","Japanese","Japanese symbol for beginner","leaf","badge","shield"]},"hollow-red-circle":{"a":"Hollow Red Circle","b":"2B55","j":["circle","large","o","red","round"]},"check-mark-button":{"a":"Check Mark Button","b":"2705","j":["✓","button","check","mark","green-square","ok","agree","vote","election","answer","tick"]},"check-box-with-check":{"a":"Check Box with Check","b":"2611","j":["✓","box","check","ok","agree","confirm","black-square","vote","election","yes","tick"]},"check-mark":{"a":"Check Mark","b":"2714","j":["✓","check","mark","ok","nike","answer","yes","tick"]},"cross-mark":{"a":"Cross Mark","b":"274C","j":["×","cancel","cross","mark","multiplication","multiply","x","no","delete","remove","red"]},"cross-mark-button":{"a":"Cross Mark Button","b":"274E","j":["×","mark","square","x","green-square","no","deny"]},"curly-loop":{"a":"Curly Loop","b":"27B0","j":["curl","loop","scribble","draw","shape","squiggle"]},"double-curly-loop":{"a":"Double Curly Loop","b":"27BF","j":["curl","double","loop","tape","cassette"]},"part-alternation-mark":{"a":"Part Alternation Mark","b":"303D","j":["mark","part","graph","presentation","stats","business","economics","bad"]},"eightspoked-asterisk":{"a":"Eight-Spoked Asterisk","b":"2733","j":["*","asterisk","eight-spoked asterisk","eight_spoked_asterisk","star","sparkle","green-square"]},"eightpointed-star":{"a":"Eight-Pointed Star","b":"2734","j":["*","eight-pointed star","star","eight_pointed_star","orange-square","shape","polygon"]},"sparkle":{"a":"Sparkle","b":"2747","j":["*","stars","green-square","awesome","good","fireworks"]},"copyright":{"a":"Copyright","b":"00A9","j":["c","ip","license","circle","law","legal"]},"registered":{"a":"Registered","b":"00AE","j":["r","alphabet","circle"]},"trade-mark":{"a":"Trade Mark","b":"2122","j":["mark","tm","trademark","brand","law","legal"]},"keycap":{"a":"Keycap: *","b":"002A-FE0F-20E3","j":["keycap_","star"]},"keycap-0":{"a":"Keycap: 0","b":"0030-FE0F-20E3","j":["keycap","0","numbers","blue-square","null"]},"keycap-1":{"a":"Keycap: 1","b":"0031-FE0F-20E3","j":["keycap","blue-square","numbers","1"]},"keycap-2":{"a":"Keycap: 2","b":"0032-FE0F-20E3","j":["keycap","numbers","2","prime","blue-square"]},"keycap-3":{"a":"Keycap: 3","b":"0033-FE0F-20E3","j":["keycap","3","numbers","prime","blue-square"]},"keycap-4":{"a":"Keycap: 4","b":"0034-FE0F-20E3","j":["keycap","4","numbers","blue-square"]},"keycap-5":{"a":"Keycap: 5","b":"0035-FE0F-20E3","j":["keycap","5","numbers","blue-square","prime"]},"keycap-6":{"a":"Keycap: 6","b":"0036-FE0F-20E3","j":["keycap","6","numbers","blue-square"]},"keycap-7":{"a":"Keycap: 7","b":"0037-FE0F-20E3","j":["keycap","7","numbers","blue-square","prime"]},"keycap-8":{"a":"Keycap: 8","b":"0038-FE0F-20E3","j":["keycap","8","blue-square","numbers"]},"keycap-9":{"a":"Keycap: 9","b":"0039-FE0F-20E3","j":["keycap","blue-square","numbers","9"]},"keycap-10":{"a":"Keycap: 10","b":"1F51F","j":["keycap","numbers","10","blue-square"]},"input-latin-uppercase":{"a":"Input Latin Uppercase","b":"1F520","j":["ABCD","input","latin","letters","uppercase","alphabet","words","blue-square"]},"input-latin-lowercase":{"a":"Input Latin Lowercase","b":"1F521","j":["abcd","input","latin","letters","lowercase","blue-square","alphabet"]},"input-numbers":{"a":"Input Numbers","b":"1F522","j":["1234","input","numbers","blue-square"]},"input-symbols":{"a":"Input Symbols","b":"1F523","j":["〒♪&%","input","blue-square","music","note","ampersand","percent","glyphs","characters"]},"input-latin-letters":{"a":"Input Latin Letters","b":"1F524","j":["abc","alphabet","input","latin","letters","blue-square"]},"a-button-blood-type":{"a":"A Button (Blood Type)","b":"1F170","j":["a","A button (blood type)","blood type","a_button","red-square","alphabet","letter"]},"ab-button-blood-type":{"a":"Ab Button (Blood Type)","b":"1F18E","j":["ab","AB button (blood type)","blood type","ab_button","red-square","alphabet"]},"b-button-blood-type":{"a":"B Button (Blood Type)","b":"1F171","j":["b","B button (blood type)","blood type","b_button","red-square","alphabet","letter"]},"cl-button":{"a":"Cl Button","b":"1F191","j":["cl","CL button","alphabet","words","red-square"]},"cool-button":{"a":"Cool Button","b":"1F192","j":["cool","COOL button","words","blue-square"]},"free-button":{"a":"Free Button","b":"1F193","j":["free","FREE button","blue-square","words"]},"information":{"a":"Information","b":"2139","j":["i","blue-square","alphabet","letter"]},"id-button":{"a":"Id Button","b":"1F194","j":["id","ID button","identity","purple-square","words"]},"circled-m":{"a":"Circled M","b":"24C2","j":["circle","circled M","m","alphabet","blue-circle","letter"]},"new-button":{"a":"New Button","b":"1F195","j":["new","NEW button","blue-square","words","start"]},"ng-button":{"a":"Ng Button","b":"1F196","j":["ng","NG button","blue-square","words","shape","icon"]},"o-button-blood-type":{"a":"O Button (Blood Type)","b":"1F17E","j":["blood type","o","O button (blood type)","o_button","alphabet","red-square","letter"]},"ok-button":{"a":"Ok Button","b":"1F197","j":["OK","OK button","good","agree","yes","blue-square"]},"p-button":{"a":"P Button","b":"1F17F","j":["P button","parking","cars","blue-square","alphabet","letter"]},"sos-button":{"a":"Sos Button","b":"1F198","j":["help","sos","SOS button","red-square","words","emergency","911"]},"up-button":{"a":"Up! Button","b":"1F199","j":["mark","up","UP! button","blue-square","above","high"]},"vs-button":{"a":"Vs Button","b":"1F19A","j":["versus","vs","VS button","words","orange-square"]},"japanese-here-button":{"a":"Japanese “Here” Button","b":"1F201","j":["“here”","Japanese","Japanese “here” button","katakana","ココ","blue-square","here","japanese","destination"]},"japanese-service-charge-button":{"a":"Japanese “Service Charge” Button","b":"1F202","j":["“service charge”","Japanese","Japanese “service charge” button","katakana","サ","japanese","blue-square"]},"japanese-monthly-amount-button":{"a":"Japanese “Monthly Amount” Button","b":"1F237","j":["“monthly amount”","ideograph","Japanese","Japanese “monthly amount” button","月","chinese","month","moon","japanese","orange-square","kanji"]},"japanese-not-free-of-charge-button":{"a":"Japanese “Not Free of Charge” Button","b":"1F236","j":["“not free of charge”","ideograph","Japanese","Japanese “not free of charge” button","有","orange-square","chinese","have","kanji"]},"japanese-reserved-button":{"a":"Japanese “Reserved” Button","b":"1F22F","j":["“reserved”","ideograph","Japanese","Japanese “reserved” button","指","chinese","point","green-square","kanji"]},"japanese-bargain-button":{"a":"Japanese “Bargain” Button","b":"1F250","j":["“bargain”","ideograph","Japanese","Japanese “bargain” button","得","chinese","kanji","obtain","get","circle"]},"japanese-discount-button":{"a":"Japanese “Discount” Button","b":"1F239","j":["“discount”","ideograph","Japanese","Japanese “discount” button","割","cut","divide","chinese","kanji","pink-square"]},"japanese-free-of-charge-button":{"a":"Japanese “Free of Charge” Button","b":"1F21A","j":["“free of charge”","ideograph","Japanese","Japanese “free of charge” button","無","nothing","chinese","kanji","japanese","orange-square"]},"japanese-prohibited-button":{"a":"Japanese “Prohibited” Button","b":"1F232","j":["“prohibited”","ideograph","Japanese","Japanese “prohibited” button","禁","kanji","japanese","chinese","forbidden","limit","restricted","red-square"]},"japanese-acceptable-button":{"a":"Japanese “Acceptable” Button","b":"1F251","j":["“acceptable”","ideograph","Japanese","Japanese “acceptable” button","可","ok","good","chinese","kanji","agree","yes","orange-circle"]},"japanese-application-button":{"a":"Japanese “Application” Button","b":"1F238","j":["“application”","ideograph","Japanese","Japanese “application” button","申","chinese","japanese","kanji","orange-square"]},"japanese-passing-grade-button":{"a":"Japanese “Passing Grade” Button","b":"1F234","j":["“passing grade”","ideograph","Japanese","Japanese “passing grade” button","合","japanese","chinese","join","kanji","red-square"]},"japanese-vacancy-button":{"a":"Japanese “Vacancy” Button","b":"1F233","j":["“vacancy”","ideograph","Japanese","Japanese “vacancy” button","空","kanji","japanese","chinese","empty","sky","blue-square"]},"japanese-congratulations-button":{"a":"Japanese “Congratulations” Button","b":"3297","j":["“congratulations”","ideograph","Japanese","Japanese “congratulations” button","祝","chinese","kanji","japanese","red-circle"]},"japanese-secret-button":{"a":"Japanese “Secret” Button","b":"3299","j":["“secret”","ideograph","Japanese","Japanese “secret” button","秘","privacy","chinese","sshh","kanji","red-circle"]},"japanese-open-for-business-button":{"a":"Japanese “Open for Business” Button","b":"1F23A","j":["“open for business”","ideograph","Japanese","Japanese “open for business” button","営","japanese","opening hours","orange-square"]},"japanese-no-vacancy-button":{"a":"Japanese “No Vacancy” Button","b":"1F235","j":["“no vacancy”","ideograph","Japanese","Japanese “no vacancy” button","満","full","chinese","japanese","red-square","kanji"]},"red-circle":{"a":"Red Circle","b":"1F534","j":["circle","geometric","red","shape","error","danger"]},"orange-circle":{"a":"Orange Circle","b":"1F7E0","j":["circle","orange","round"]},"yellow-circle":{"a":"Yellow Circle","b":"1F7E1","j":["circle","yellow","round"]},"green-circle":{"a":"Green Circle","b":"1F7E2","j":["circle","green","round"]},"blue-circle":{"a":"Blue Circle","b":"1F535","j":["blue","circle","geometric","shape","icon","button"]},"purple-circle":{"a":"Purple Circle","b":"1F7E3","j":["circle","purple","round"]},"brown-circle":{"a":"Brown Circle","b":"1F7E4","j":["brown","circle","round"]},"black-circle":{"a":"Black Circle","b":"26AB","j":["circle","geometric","shape","button","round"]},"white-circle":{"a":"White Circle","b":"26AA","j":["circle","geometric","shape","round"]},"red-square":{"a":"Red Square","b":"1F7E5","j":["red","square"]},"orange-square":{"a":"Orange Square","b":"1F7E7","j":["orange","square"]},"yellow-square":{"a":"Yellow Square","b":"1F7E8","j":["square","yellow"]},"green-square":{"a":"Green Square","b":"1F7E9","j":["green","square"]},"blue-square":{"a":"Blue Square","b":"1F7E6","j":["blue","square"]},"purple-square":{"a":"Purple Square","b":"1F7EA","j":["purple","square"]},"brown-square":{"a":"Brown Square","b":"1F7EB","j":["brown","square"]},"black-large-square":{"a":"Black Large Square","b":"2B1B","j":["geometric","square","shape","icon","button"]},"white-large-square":{"a":"White Large Square","b":"2B1C","j":["geometric","square","shape","icon","stone","button"]},"black-medium-square":{"a":"Black Medium Square","b":"25FC","j":["geometric","square","shape","button","icon"]},"white-medium-square":{"a":"White Medium Square","b":"25FB","j":["geometric","square","shape","stone","icon"]},"black-mediumsmall-square":{"a":"Black Medium-Small Square","b":"25FE","j":["black medium-small square","geometric","square","black_medium_small_square","icon","shape","button"]},"white-mediumsmall-square":{"a":"White Medium-Small Square","b":"25FD","j":["geometric","square","white medium-small square","white_medium_small_square","shape","stone","icon","button"]},"black-small-square":{"a":"Black Small Square","b":"25AA","j":["geometric","square","shape","icon"]},"white-small-square":{"a":"White Small Square","b":"25AB","j":["geometric","square","shape","icon"]},"large-orange-diamond":{"a":"Large Orange Diamond","b":"1F536","j":["diamond","geometric","orange","shape","jewel","gem"]},"large-blue-diamond":{"a":"Large Blue Diamond","b":"1F537","j":["blue","diamond","geometric","shape","jewel","gem"]},"small-orange-diamond":{"a":"Small Orange Diamond","b":"1F538","j":["diamond","geometric","orange","shape","jewel","gem"]},"small-blue-diamond":{"a":"Small Blue Diamond","b":"1F539","j":["blue","diamond","geometric","shape","jewel","gem"]},"red-triangle-pointed-up":{"a":"Red Triangle Pointed Up","b":"1F53A","j":["geometric","red","shape","direction","up","top"]},"red-triangle-pointed-down":{"a":"Red Triangle Pointed Down","b":"1F53B","j":["down","geometric","red","shape","direction","bottom"]},"diamond-with-a-dot":{"a":"Diamond with a Dot","b":"1F4A0","j":["comic","diamond","geometric","inside","jewel","blue","gem","crystal","fancy"]},"radio-button":{"a":"Radio Button","b":"1F518","j":["button","geometric","radio","input","old","music","circle"]},"white-square-button":{"a":"White Square Button","b":"1F533","j":["button","geometric","outlined","square","shape","input"]},"black-square-button":{"a":"Black Square Button","b":"1F532","j":["button","geometric","square","shape","input","frame"]},"chequered-flag":{"a":"Chequered Flag","b":"1F3C1","j":["checkered","chequered","racing","contest","finishline","race","gokart"]},"triangular-flag":{"a":"Triangular Flag","b":"1F6A9","j":["post","mark","milestone","place"]},"crossed-flags":{"a":"Crossed Flags","b":"1F38C","j":["celebration","cross","crossed","Japanese","japanese","nation","country","border"]},"black-flag":{"a":"Black Flag","b":"1F3F4","j":["waving","pirate"]},"white-flag":{"a":"White Flag","b":"1F3F3","j":["waving","losing","loser","lost","surrender","give up","fail"]},"rainbow-flag":{"a":"Rainbow Flag","b":"1F3F3-FE0F-200D-1F308","j":["pride","rainbow","flag","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"]},"transgender-flag":{"a":"Transgender Flag","b":"1F3F3-FE0F-200D-26A7-FE0F","j":["flag","light blue","pink","transgender","white","lgbtq"]},"pirate-flag":{"a":"Pirate Flag","b":"1F3F4-200D-2620-FE0F","j":["Jolly Roger","pirate","plunder","treasure","skull","crossbones","flag","banner"]},"flag-ascension-island":{"a":"Flag: Ascension Island","b":"1F1E6-1F1E8","j":["flag"]},"flag-andorra":{"a":"Flag: Andorra","b":"1F1E6-1F1E9","j":["flag","ad","nation","country","banner","andorra"]},"flag-united-arab-emirates":{"a":"Flag: United Arab Emirates","b":"1F1E6-1F1EA","j":["flag","united","arab","emirates","nation","country","banner","united_arab_emirates"]},"flag-afghanistan":{"a":"Flag: Afghanistan","b":"1F1E6-1F1EB","j":["flag","af","nation","country","banner","afghanistan"]},"flag-antigua--barbuda":{"a":"Flag: Antigua & Barbuda","b":"1F1E6-1F1EC","j":["flag","flag_antigua_barbuda","antigua","barbuda","nation","country","banner","antigua_barbuda"]},"flag-anguilla":{"a":"Flag: Anguilla","b":"1F1E6-1F1EE","j":["flag","ai","nation","country","banner","anguilla"]},"flag-albania":{"a":"Flag: Albania","b":"1F1E6-1F1F1","j":["flag","al","nation","country","banner","albania"]},"flag-armenia":{"a":"Flag: Armenia","b":"1F1E6-1F1F2","j":["flag","am","nation","country","banner","armenia"]},"flag-angola":{"a":"Flag: Angola","b":"1F1E6-1F1F4","j":["flag","ao","nation","country","banner","angola"]},"flag-antarctica":{"a":"Flag: Antarctica","b":"1F1E6-1F1F6","j":["flag","aq","nation","country","banner","antarctica"]},"flag-argentina":{"a":"Flag: Argentina","b":"1F1E6-1F1F7","j":["flag","ar","nation","country","banner","argentina"]},"flag-american-samoa":{"a":"Flag: American Samoa","b":"1F1E6-1F1F8","j":["flag","american","ws","nation","country","banner","american_samoa"]},"flag-austria":{"a":"Flag: Austria","b":"1F1E6-1F1F9","j":["flag","at","nation","country","banner","austria"]},"flag-australia":{"a":"Flag: Australia","b":"1F1E6-1F1FA","j":["flag","au","nation","country","banner","australia"]},"flag-aruba":{"a":"Flag: Aruba","b":"1F1E6-1F1FC","j":["flag","aw","nation","country","banner","aruba"]},"flag-land-islands":{"a":"Flag: Åland Islands","b":"1F1E6-1F1FD","j":["flag","flag_aland_islands","Åland","islands","nation","country","banner","aland_islands"]},"flag-azerbaijan":{"a":"Flag: Azerbaijan","b":"1F1E6-1F1FF","j":["flag","az","nation","country","banner","azerbaijan"]},"flag-bosnia--herzegovina":{"a":"Flag: Bosnia & Herzegovina","b":"1F1E7-1F1E6","j":["flag","flag_bosnia_herzegovina","bosnia","herzegovina","nation","country","banner","bosnia_herzegovina"]},"flag-barbados":{"a":"Flag: Barbados","b":"1F1E7-1F1E7","j":["flag","bb","nation","country","banner","barbados"]},"flag-bangladesh":{"a":"Flag: Bangladesh","b":"1F1E7-1F1E9","j":["flag","bd","nation","country","banner","bangladesh"]},"flag-belgium":{"a":"Flag: Belgium","b":"1F1E7-1F1EA","j":["flag","be","nation","country","banner","belgium"]},"flag-burkina-faso":{"a":"Flag: Burkina Faso","b":"1F1E7-1F1EB","j":["flag","burkina","faso","nation","country","banner","burkina_faso"]},"flag-bulgaria":{"a":"Flag: Bulgaria","b":"1F1E7-1F1EC","j":["flag","bg","nation","country","banner","bulgaria"]},"flag-bahrain":{"a":"Flag: Bahrain","b":"1F1E7-1F1ED","j":["flag","bh","nation","country","banner","bahrain"]},"flag-burundi":{"a":"Flag: Burundi","b":"1F1E7-1F1EE","j":["flag","bi","nation","country","banner","burundi"]},"flag-benin":{"a":"Flag: Benin","b":"1F1E7-1F1EF","j":["flag","bj","nation","country","banner","benin"]},"flag-st-barthlemy":{"a":"Flag: St. Barthélemy","b":"1F1E7-1F1F1","j":["flag","flag_st_barthelemy","saint","barthélemy","nation","country","banner","st_barthelemy"]},"flag-bermuda":{"a":"Flag: Bermuda","b":"1F1E7-1F1F2","j":["flag","bm","nation","country","banner","bermuda"]},"flag-brunei":{"a":"Flag: Brunei","b":"1F1E7-1F1F3","j":["flag","bn","darussalam","nation","country","banner","brunei"]},"flag-bolivia":{"a":"Flag: Bolivia","b":"1F1E7-1F1F4","j":["flag","bo","nation","country","banner","bolivia"]},"flag-caribbean-netherlands":{"a":"Flag: Caribbean Netherlands","b":"1F1E7-1F1F6","j":["flag","bonaire","nation","country","banner","caribbean_netherlands"]},"flag-brazil":{"a":"Flag: Brazil","b":"1F1E7-1F1F7","j":["flag","br","nation","country","banner","brazil"]},"flag-bahamas":{"a":"Flag: Bahamas","b":"1F1E7-1F1F8","j":["flag","bs","nation","country","banner","bahamas"]},"flag-bhutan":{"a":"Flag: Bhutan","b":"1F1E7-1F1F9","j":["flag","bt","nation","country","banner","bhutan"]},"flag-bouvet-island":{"a":"Flag: Bouvet Island","b":"1F1E7-1F1FB","j":["flag","norway"]},"flag-botswana":{"a":"Flag: Botswana","b":"1F1E7-1F1FC","j":["flag","bw","nation","country","banner","botswana"]},"flag-belarus":{"a":"Flag: Belarus","b":"1F1E7-1F1FE","j":["flag","by","nation","country","banner","belarus"]},"flag-belize":{"a":"Flag: Belize","b":"1F1E7-1F1FF","j":["flag","bz","nation","country","banner","belize"]},"flag-canada":{"a":"Flag: Canada","b":"1F1E8-1F1E6","j":["flag","ca","nation","country","banner","canada"]},"flag-cocos-keeling-islands":{"a":"Flag: Cocos (Keeling) Islands","b":"1F1E8-1F1E8","j":["flag","flag_cocos_islands","cocos","keeling","islands","nation","country","banner","cocos_islands"]},"flag-congo--kinshasa":{"a":"Flag: Congo - Kinshasa","b":"1F1E8-1F1E9","j":["flag","flag_congo_kinshasa","congo","democratic","republic","nation","country","banner","congo_kinshasa"]},"flag-central-african-republic":{"a":"Flag: Central African Republic","b":"1F1E8-1F1EB","j":["flag","central","african","republic","nation","country","banner","central_african_republic"]},"flag-congo--brazzaville":{"a":"Flag: Congo - Brazzaville","b":"1F1E8-1F1EC","j":["flag","flag_congo_brazzaville","congo","nation","country","banner","congo_brazzaville"]},"flag-switzerland":{"a":"Flag: Switzerland","b":"1F1E8-1F1ED","j":["flag","ch","nation","country","banner","switzerland"]},"flag-cte-divoire":{"a":"Flag: Côte D’Ivoire","b":"1F1E8-1F1EE","j":["flag","flag_cote_d_ivoire","ivory","coast","nation","country","banner","cote_d_ivoire"]},"flag-cook-islands":{"a":"Flag: Cook Islands","b":"1F1E8-1F1F0","j":["flag","cook","islands","nation","country","banner","cook_islands"]},"flag-chile":{"a":"Flag: Chile","b":"1F1E8-1F1F1","j":["flag","nation","country","banner","chile"]},"flag-cameroon":{"a":"Flag: Cameroon","b":"1F1E8-1F1F2","j":["flag","cm","nation","country","banner","cameroon"]},"flag-china":{"a":"Flag: China","b":"1F1E8-1F1F3","j":["flag","china","chinese","prc","country","nation","banner"]},"flag-colombia":{"a":"Flag: Colombia","b":"1F1E8-1F1F4","j":["flag","co","nation","country","banner","colombia"]},"flag-clipperton-island":{"a":"Flag: Clipperton Island","b":"1F1E8-1F1F5","j":["flag"]},"flag-costa-rica":{"a":"Flag: Costa Rica","b":"1F1E8-1F1F7","j":["flag","costa","rica","nation","country","banner","costa_rica"]},"flag-cuba":{"a":"Flag: Cuba","b":"1F1E8-1F1FA","j":["flag","cu","nation","country","banner","cuba"]},"flag-cape-verde":{"a":"Flag: Cape Verde","b":"1F1E8-1F1FB","j":["flag","cabo","verde","nation","country","banner","cape_verde"]},"flag-curaao":{"a":"Flag: Curaçao","b":"1F1E8-1F1FC","j":["flag","flag_curacao","curaçao","nation","country","banner","curacao"]},"flag-christmas-island":{"a":"Flag: Christmas Island","b":"1F1E8-1F1FD","j":["flag","christmas","island","nation","country","banner","christmas_island"]},"flag-cyprus":{"a":"Flag: Cyprus","b":"1F1E8-1F1FE","j":["flag","cy","nation","country","banner","cyprus"]},"flag-czechia":{"a":"Flag: Czechia","b":"1F1E8-1F1FF","j":["flag","cz","nation","country","banner","czechia"]},"flag-germany":{"a":"Flag: Germany","b":"1F1E9-1F1EA","j":["flag","german","nation","country","banner","germany"]},"flag-diego-garcia":{"a":"Flag: Diego Garcia","b":"1F1E9-1F1EC","j":["flag"]},"flag-djibouti":{"a":"Flag: Djibouti","b":"1F1E9-1F1EF","j":["flag","dj","nation","country","banner","djibouti"]},"flag-denmark":{"a":"Flag: Denmark","b":"1F1E9-1F1F0","j":["flag","dk","nation","country","banner","denmark"]},"flag-dominica":{"a":"Flag: Dominica","b":"1F1E9-1F1F2","j":["flag","dm","nation","country","banner","dominica"]},"flag-dominican-republic":{"a":"Flag: Dominican Republic","b":"1F1E9-1F1F4","j":["flag","dominican","republic","nation","country","banner","dominican_republic"]},"flag-algeria":{"a":"Flag: Algeria","b":"1F1E9-1F1FF","j":["flag","dz","nation","country","banner","algeria"]},"flag-ceuta--melilla":{"a":"Flag: Ceuta & Melilla","b":"1F1EA-1F1E6","j":["flag","flag_ceuta_melilla"]},"flag-ecuador":{"a":"Flag: Ecuador","b":"1F1EA-1F1E8","j":["flag","ec","nation","country","banner","ecuador"]},"flag-estonia":{"a":"Flag: Estonia","b":"1F1EA-1F1EA","j":["flag","ee","nation","country","banner","estonia"]},"flag-egypt":{"a":"Flag: Egypt","b":"1F1EA-1F1EC","j":["flag","eg","nation","country","banner","egypt"]},"flag-western-sahara":{"a":"Flag: Western Sahara","b":"1F1EA-1F1ED","j":["flag","western","sahara","nation","country","banner","western_sahara"]},"flag-eritrea":{"a":"Flag: Eritrea","b":"1F1EA-1F1F7","j":["flag","er","nation","country","banner","eritrea"]},"flag-spain":{"a":"Flag: Spain","b":"1F1EA-1F1F8","j":["flag","spain","nation","country","banner"]},"flag-ethiopia":{"a":"Flag: Ethiopia","b":"1F1EA-1F1F9","j":["flag","et","nation","country","banner","ethiopia"]},"flag-european-union":{"a":"Flag: European Union","b":"1F1EA-1F1FA","j":["flag","european","union","banner"]},"flag-finland":{"a":"Flag: Finland","b":"1F1EB-1F1EE","j":["flag","fi","nation","country","banner","finland"]},"flag-fiji":{"a":"Flag: Fiji","b":"1F1EB-1F1EF","j":["flag","fj","nation","country","banner","fiji"]},"flag-falkland-islands":{"a":"Flag: Falkland Islands","b":"1F1EB-1F1F0","j":["flag","falkland","islands","malvinas","nation","country","banner","falkland_islands"]},"flag-micronesia":{"a":"Flag: Micronesia","b":"1F1EB-1F1F2","j":["flag","micronesia","federated","states","nation","country","banner"]},"flag-faroe-islands":{"a":"Flag: Faroe Islands","b":"1F1EB-1F1F4","j":["flag","faroe","islands","nation","country","banner","faroe_islands"]},"flag-france":{"a":"Flag: France","b":"1F1EB-1F1F7","j":["flag","banner","nation","france","french","country"]},"flag-gabon":{"a":"Flag: Gabon","b":"1F1EC-1F1E6","j":["flag","ga","nation","country","banner","gabon"]},"flag-united-kingdom":{"a":"Flag: United Kingdom","b":"1F1EC-1F1E7","j":["flag","united","kingdom","great","britain","northern","ireland","nation","country","banner","british","UK","english","england","union jack","united_kingdom"]},"flag-grenada":{"a":"Flag: Grenada","b":"1F1EC-1F1E9","j":["flag","gd","nation","country","banner","grenada"]},"flag-georgia":{"a":"Flag: Georgia","b":"1F1EC-1F1EA","j":["flag","ge","nation","country","banner","georgia"]},"flag-french-guiana":{"a":"Flag: French Guiana","b":"1F1EC-1F1EB","j":["flag","french","guiana","nation","country","banner","french_guiana"]},"flag-guernsey":{"a":"Flag: Guernsey","b":"1F1EC-1F1EC","j":["flag","gg","nation","country","banner","guernsey"]},"flag-ghana":{"a":"Flag: Ghana","b":"1F1EC-1F1ED","j":["flag","gh","nation","country","banner","ghana"]},"flag-gibraltar":{"a":"Flag: Gibraltar","b":"1F1EC-1F1EE","j":["flag","gi","nation","country","banner","gibraltar"]},"flag-greenland":{"a":"Flag: Greenland","b":"1F1EC-1F1F1","j":["flag","gl","nation","country","banner","greenland"]},"flag-gambia":{"a":"Flag: Gambia","b":"1F1EC-1F1F2","j":["flag","gm","nation","country","banner","gambia"]},"flag-guinea":{"a":"Flag: Guinea","b":"1F1EC-1F1F3","j":["flag","gn","nation","country","banner","guinea"]},"flag-guadeloupe":{"a":"Flag: Guadeloupe","b":"1F1EC-1F1F5","j":["flag","gp","nation","country","banner","guadeloupe"]},"flag-equatorial-guinea":{"a":"Flag: Equatorial Guinea","b":"1F1EC-1F1F6","j":["flag","equatorial","gn","nation","country","banner","equatorial_guinea"]},"flag-greece":{"a":"Flag: Greece","b":"1F1EC-1F1F7","j":["flag","gr","nation","country","banner","greece"]},"flag-south-georgia--south-sandwich-islands":{"a":"Flag: South Georgia & South Sandwich Islands","b":"1F1EC-1F1F8","j":["flag","flag_south_georgia_south_sandwich_islands","south","georgia","sandwich","islands","nation","country","banner","south_georgia_south_sandwich_islands"]},"flag-guatemala":{"a":"Flag: Guatemala","b":"1F1EC-1F1F9","j":["flag","gt","nation","country","banner","guatemala"]},"flag-guam":{"a":"Flag: Guam","b":"1F1EC-1F1FA","j":["flag","gu","nation","country","banner","guam"]},"flag-guineabissau":{"a":"Flag: Guinea-Bissau","b":"1F1EC-1F1FC","j":["flag","flag_guinea_bissau","gw","bissau","nation","country","banner","guinea_bissau"]},"flag-guyana":{"a":"Flag: Guyana","b":"1F1EC-1F1FE","j":["flag","gy","nation","country","banner","guyana"]},"flag-hong-kong-sar-china":{"a":"Flag: Hong Kong Sar China","b":"1F1ED-1F1F0","j":["flag","hong","kong","nation","country","banner","hong_kong_sar_china"]},"flag-heard--mcdonald-islands":{"a":"Flag: Heard & Mcdonald Islands","b":"1F1ED-1F1F2","j":["flag","flag_heard_mcdonald_islands"]},"flag-honduras":{"a":"Flag: Honduras","b":"1F1ED-1F1F3","j":["flag","hn","nation","country","banner","honduras"]},"flag-croatia":{"a":"Flag: Croatia","b":"1F1ED-1F1F7","j":["flag","hr","nation","country","banner","croatia"]},"flag-haiti":{"a":"Flag: Haiti","b":"1F1ED-1F1F9","j":["flag","ht","nation","country","banner","haiti"]},"flag-hungary":{"a":"Flag: Hungary","b":"1F1ED-1F1FA","j":["flag","hu","nation","country","banner","hungary"]},"flag-canary-islands":{"a":"Flag: Canary Islands","b":"1F1EE-1F1E8","j":["flag","canary","islands","nation","country","banner","canary_islands"]},"flag-indonesia":{"a":"Flag: Indonesia","b":"1F1EE-1F1E9","j":["flag","nation","country","banner","indonesia"]},"flag-ireland":{"a":"Flag: Ireland","b":"1F1EE-1F1EA","j":["flag","ie","nation","country","banner","ireland"]},"flag-israel":{"a":"Flag: Israel","b":"1F1EE-1F1F1","j":["flag","il","nation","country","banner","israel"]},"flag-isle-of-man":{"a":"Flag: Isle of Man","b":"1F1EE-1F1F2","j":["flag","isle","man","nation","country","banner","isle_of_man"]},"flag-india":{"a":"Flag: India","b":"1F1EE-1F1F3","j":["flag","in","nation","country","banner","india"]},"flag-british-indian-ocean-territory":{"a":"Flag: British Indian Ocean Territory","b":"1F1EE-1F1F4","j":["flag","british","indian","ocean","territory","nation","country","banner","british_indian_ocean_territory"]},"flag-iraq":{"a":"Flag: Iraq","b":"1F1EE-1F1F6","j":["flag","iq","nation","country","banner","iraq"]},"flag-iran":{"a":"Flag: Iran","b":"1F1EE-1F1F7","j":["flag","iran","islamic","republic","nation","country","banner"]},"flag-iceland":{"a":"Flag: Iceland","b":"1F1EE-1F1F8","j":["flag","is","nation","country","banner","iceland"]},"flag-italy":{"a":"Flag: Italy","b":"1F1EE-1F1F9","j":["flag","italy","nation","country","banner"]},"flag-jersey":{"a":"Flag: Jersey","b":"1F1EF-1F1EA","j":["flag","je","nation","country","banner","jersey"]},"flag-jamaica":{"a":"Flag: Jamaica","b":"1F1EF-1F1F2","j":["flag","jm","nation","country","banner","jamaica"]},"flag-jordan":{"a":"Flag: Jordan","b":"1F1EF-1F1F4","j":["flag","jo","nation","country","banner","jordan"]},"flag-japan":{"a":"Flag: Japan","b":"1F1EF-1F1F5","j":["flag","japanese","nation","country","banner","japan"]},"flag-kenya":{"a":"Flag: Kenya","b":"1F1F0-1F1EA","j":["flag","ke","nation","country","banner","kenya"]},"flag-kyrgyzstan":{"a":"Flag: Kyrgyzstan","b":"1F1F0-1F1EC","j":["flag","kg","nation","country","banner","kyrgyzstan"]},"flag-cambodia":{"a":"Flag: Cambodia","b":"1F1F0-1F1ED","j":["flag","kh","nation","country","banner","cambodia"]},"flag-kiribati":{"a":"Flag: Kiribati","b":"1F1F0-1F1EE","j":["flag","ki","nation","country","banner","kiribati"]},"flag-comoros":{"a":"Flag: Comoros","b":"1F1F0-1F1F2","j":["flag","km","nation","country","banner","comoros"]},"flag-st-kitts--nevis":{"a":"Flag: St. Kitts & Nevis","b":"1F1F0-1F1F3","j":["flag","flag_st_kitts_nevis","saint","kitts","nevis","nation","country","banner","st_kitts_nevis"]},"flag-north-korea":{"a":"Flag: North Korea","b":"1F1F0-1F1F5","j":["flag","north","korea","nation","country","banner","north_korea"]},"flag-south-korea":{"a":"Flag: South Korea","b":"1F1F0-1F1F7","j":["flag","south","korea","nation","country","banner","south_korea"]},"flag-kuwait":{"a":"Flag: Kuwait","b":"1F1F0-1F1FC","j":["flag","kw","nation","country","banner","kuwait"]},"flag-cayman-islands":{"a":"Flag: Cayman Islands","b":"1F1F0-1F1FE","j":["flag","cayman","islands","nation","country","banner","cayman_islands"]},"flag-kazakhstan":{"a":"Flag: Kazakhstan","b":"1F1F0-1F1FF","j":["flag","kz","nation","country","banner","kazakhstan"]},"flag-laos":{"a":"Flag: Laos","b":"1F1F1-1F1E6","j":["flag","lao","democratic","republic","nation","country","banner","laos"]},"flag-lebanon":{"a":"Flag: Lebanon","b":"1F1F1-1F1E7","j":["flag","lb","nation","country","banner","lebanon"]},"flag-st-lucia":{"a":"Flag: St. Lucia","b":"1F1F1-1F1E8","j":["flag","saint","lucia","nation","country","banner","st_lucia"]},"flag-liechtenstein":{"a":"Flag: Liechtenstein","b":"1F1F1-1F1EE","j":["flag","li","nation","country","banner","liechtenstein"]},"flag-sri-lanka":{"a":"Flag: Sri Lanka","b":"1F1F1-1F1F0","j":["flag","sri","lanka","nation","country","banner","sri_lanka"]},"flag-liberia":{"a":"Flag: Liberia","b":"1F1F1-1F1F7","j":["flag","lr","nation","country","banner","liberia"]},"flag-lesotho":{"a":"Flag: Lesotho","b":"1F1F1-1F1F8","j":["flag","ls","nation","country","banner","lesotho"]},"flag-lithuania":{"a":"Flag: Lithuania","b":"1F1F1-1F1F9","j":["flag","lt","nation","country","banner","lithuania"]},"flag-luxembourg":{"a":"Flag: Luxembourg","b":"1F1F1-1F1FA","j":["flag","lu","nation","country","banner","luxembourg"]},"flag-latvia":{"a":"Flag: Latvia","b":"1F1F1-1F1FB","j":["flag","lv","nation","country","banner","latvia"]},"flag-libya":{"a":"Flag: Libya","b":"1F1F1-1F1FE","j":["flag","ly","nation","country","banner","libya"]},"flag-morocco":{"a":"Flag: Morocco","b":"1F1F2-1F1E6","j":["flag","ma","nation","country","banner","morocco"]},"flag-monaco":{"a":"Flag: Monaco","b":"1F1F2-1F1E8","j":["flag","mc","nation","country","banner","monaco"]},"flag-moldova":{"a":"Flag: Moldova","b":"1F1F2-1F1E9","j":["flag","moldova","republic","nation","country","banner"]},"flag-montenegro":{"a":"Flag: Montenegro","b":"1F1F2-1F1EA","j":["flag","me","nation","country","banner","montenegro"]},"flag-st-martin":{"a":"Flag: St. Martin","b":"1F1F2-1F1EB","j":["flag"]},"flag-madagascar":{"a":"Flag: Madagascar","b":"1F1F2-1F1EC","j":["flag","mg","nation","country","banner","madagascar"]},"flag-marshall-islands":{"a":"Flag: Marshall Islands","b":"1F1F2-1F1ED","j":["flag","marshall","islands","nation","country","banner","marshall_islands"]},"flag-north-macedonia":{"a":"Flag: North Macedonia","b":"1F1F2-1F1F0","j":["flag","macedonia","nation","country","banner","north_macedonia"]},"flag-mali":{"a":"Flag: Mali","b":"1F1F2-1F1F1","j":["flag","ml","nation","country","banner","mali"]},"flag-myanmar-burma":{"a":"Flag: Myanmar (Burma)","b":"1F1F2-1F1F2","j":["flag","flag_myanmar","mm","nation","country","banner","myanmar"]},"flag-mongolia":{"a":"Flag: Mongolia","b":"1F1F2-1F1F3","j":["flag","mn","nation","country","banner","mongolia"]},"flag-macao-sar-china":{"a":"Flag: Macao Sar China","b":"1F1F2-1F1F4","j":["flag","macao","nation","country","banner","macao_sar_china"]},"flag-northern-mariana-islands":{"a":"Flag: Northern Mariana Islands","b":"1F1F2-1F1F5","j":["flag","northern","mariana","islands","nation","country","banner","northern_mariana_islands"]},"flag-martinique":{"a":"Flag: Martinique","b":"1F1F2-1F1F6","j":["flag","mq","nation","country","banner","martinique"]},"flag-mauritania":{"a":"Flag: Mauritania","b":"1F1F2-1F1F7","j":["flag","mr","nation","country","banner","mauritania"]},"flag-montserrat":{"a":"Flag: Montserrat","b":"1F1F2-1F1F8","j":["flag","ms","nation","country","banner","montserrat"]},"flag-malta":{"a":"Flag: Malta","b":"1F1F2-1F1F9","j":["flag","mt","nation","country","banner","malta"]},"flag-mauritius":{"a":"Flag: Mauritius","b":"1F1F2-1F1FA","j":["flag","mu","nation","country","banner","mauritius"]},"flag-maldives":{"a":"Flag: Maldives","b":"1F1F2-1F1FB","j":["flag","mv","nation","country","banner","maldives"]},"flag-malawi":{"a":"Flag: Malawi","b":"1F1F2-1F1FC","j":["flag","mw","nation","country","banner","malawi"]},"flag-mexico":{"a":"Flag: Mexico","b":"1F1F2-1F1FD","j":["flag","mx","nation","country","banner","mexico"]},"flag-malaysia":{"a":"Flag: Malaysia","b":"1F1F2-1F1FE","j":["flag","my","nation","country","banner","malaysia"]},"flag-mozambique":{"a":"Flag: Mozambique","b":"1F1F2-1F1FF","j":["flag","mz","nation","country","banner","mozambique"]},"flag-namibia":{"a":"Flag: Namibia","b":"1F1F3-1F1E6","j":["flag","na","nation","country","banner","namibia"]},"flag-new-caledonia":{"a":"Flag: New Caledonia","b":"1F1F3-1F1E8","j":["flag","new","caledonia","nation","country","banner","new_caledonia"]},"flag-niger":{"a":"Flag: Niger","b":"1F1F3-1F1EA","j":["flag","ne","nation","country","banner","niger"]},"flag-norfolk-island":{"a":"Flag: Norfolk Island","b":"1F1F3-1F1EB","j":["flag","norfolk","island","nation","country","banner","norfolk_island"]},"flag-nigeria":{"a":"Flag: Nigeria","b":"1F1F3-1F1EC","j":["flag","nation","country","banner","nigeria"]},"flag-nicaragua":{"a":"Flag: Nicaragua","b":"1F1F3-1F1EE","j":["flag","ni","nation","country","banner","nicaragua"]},"flag-netherlands":{"a":"Flag: Netherlands","b":"1F1F3-1F1F1","j":["flag","nl","nation","country","banner","netherlands"]},"flag-norway":{"a":"Flag: Norway","b":"1F1F3-1F1F4","j":["flag","no","nation","country","banner","norway"]},"flag-nepal":{"a":"Flag: Nepal","b":"1F1F3-1F1F5","j":["flag","np","nation","country","banner","nepal"]},"flag-nauru":{"a":"Flag: Nauru","b":"1F1F3-1F1F7","j":["flag","nr","nation","country","banner","nauru"]},"flag-niue":{"a":"Flag: Niue","b":"1F1F3-1F1FA","j":["flag","nu","nation","country","banner","niue"]},"flag-new-zealand":{"a":"Flag: New Zealand","b":"1F1F3-1F1FF","j":["flag","new","zealand","nation","country","banner","new_zealand"]},"flag-oman":{"a":"Flag: Oman","b":"1F1F4-1F1F2","j":["flag","om_symbol","nation","country","banner","oman"]},"flag-panama":{"a":"Flag: Panama","b":"1F1F5-1F1E6","j":["flag","pa","nation","country","banner","panama"]},"flag-peru":{"a":"Flag: Peru","b":"1F1F5-1F1EA","j":["flag","pe","nation","country","banner","peru"]},"flag-french-polynesia":{"a":"Flag: French Polynesia","b":"1F1F5-1F1EB","j":["flag","french","polynesia","nation","country","banner","french_polynesia"]},"flag-papua-new-guinea":{"a":"Flag: Papua New Guinea","b":"1F1F5-1F1EC","j":["flag","papua","new","guinea","nation","country","banner","papua_new_guinea"]},"flag-philippines":{"a":"Flag: Philippines","b":"1F1F5-1F1ED","j":["flag","ph","nation","country","banner","philippines"]},"flag-pakistan":{"a":"Flag: Pakistan","b":"1F1F5-1F1F0","j":["flag","pk","nation","country","banner","pakistan"]},"flag-poland":{"a":"Flag: Poland","b":"1F1F5-1F1F1","j":["flag","pl","nation","country","banner","poland"]},"flag-st-pierre--miquelon":{"a":"Flag: St. Pierre & Miquelon","b":"1F1F5-1F1F2","j":["flag","flag_st_pierre_miquelon","saint","pierre","miquelon","nation","country","banner","st_pierre_miquelon"]},"flag-pitcairn-islands":{"a":"Flag: Pitcairn Islands","b":"1F1F5-1F1F3","j":["flag","pitcairn","nation","country","banner","pitcairn_islands"]},"flag-puerto-rico":{"a":"Flag: Puerto Rico","b":"1F1F5-1F1F7","j":["flag","puerto","rico","nation","country","banner","puerto_rico"]},"flag-palestinian-territories":{"a":"Flag: Palestinian Territories","b":"1F1F5-1F1F8","j":["flag","palestine","palestinian","territories","nation","country","banner","palestinian_territories"]},"flag-portugal":{"a":"Flag: Portugal","b":"1F1F5-1F1F9","j":["flag","pt","nation","country","banner","portugal"]},"flag-palau":{"a":"Flag: Palau","b":"1F1F5-1F1FC","j":["flag","pw","nation","country","banner","palau"]},"flag-paraguay":{"a":"Flag: Paraguay","b":"1F1F5-1F1FE","j":["flag","py","nation","country","banner","paraguay"]},"flag-qatar":{"a":"Flag: Qatar","b":"1F1F6-1F1E6","j":["flag","qa","nation","country","banner","qatar"]},"flag-runion":{"a":"Flag: Réunion","b":"1F1F7-1F1EA","j":["flag","flag_reunion","réunion","nation","country","banner","reunion"]},"flag-romania":{"a":"Flag: Romania","b":"1F1F7-1F1F4","j":["flag","ro","nation","country","banner","romania"]},"flag-serbia":{"a":"Flag: Serbia","b":"1F1F7-1F1F8","j":["flag","rs","nation","country","banner","serbia"]},"flag-russia":{"a":"Flag: Russia","b":"1F1F7-1F1FA","j":["flag","russian","federation","nation","country","banner","russia"]},"flag-rwanda":{"a":"Flag: Rwanda","b":"1F1F7-1F1FC","j":["flag","rw","nation","country","banner","rwanda"]},"flag-saudi-arabia":{"a":"Flag: Saudi Arabia","b":"1F1F8-1F1E6","j":["flag","nation","country","banner","saudi_arabia"]},"flag-solomon-islands":{"a":"Flag: Solomon Islands","b":"1F1F8-1F1E7","j":["flag","solomon","islands","nation","country","banner","solomon_islands"]},"flag-seychelles":{"a":"Flag: Seychelles","b":"1F1F8-1F1E8","j":["flag","sc","nation","country","banner","seychelles"]},"flag-sudan":{"a":"Flag: Sudan","b":"1F1F8-1F1E9","j":["flag","sd","nation","country","banner","sudan"]},"flag-sweden":{"a":"Flag: Sweden","b":"1F1F8-1F1EA","j":["flag","se","nation","country","banner","sweden"]},"flag-singapore":{"a":"Flag: Singapore","b":"1F1F8-1F1EC","j":["flag","sg","nation","country","banner","singapore"]},"flag-st-helena":{"a":"Flag: St. Helena","b":"1F1F8-1F1ED","j":["flag","saint","helena","ascension","tristan","cunha","nation","country","banner","st_helena"]},"flag-slovenia":{"a":"Flag: Slovenia","b":"1F1F8-1F1EE","j":["flag","si","nation","country","banner","slovenia"]},"flag-svalbard--jan-mayen":{"a":"Flag: Svalbard & Jan Mayen","b":"1F1F8-1F1EF","j":["flag","flag_svalbard_jan_mayen"]},"flag-slovakia":{"a":"Flag: Slovakia","b":"1F1F8-1F1F0","j":["flag","sk","nation","country","banner","slovakia"]},"flag-sierra-leone":{"a":"Flag: Sierra Leone","b":"1F1F8-1F1F1","j":["flag","sierra","leone","nation","country","banner","sierra_leone"]},"flag-san-marino":{"a":"Flag: San Marino","b":"1F1F8-1F1F2","j":["flag","san","marino","nation","country","banner","san_marino"]},"flag-senegal":{"a":"Flag: Senegal","b":"1F1F8-1F1F3","j":["flag","sn","nation","country","banner","senegal"]},"flag-somalia":{"a":"Flag: Somalia","b":"1F1F8-1F1F4","j":["flag","so","nation","country","banner","somalia"]},"flag-suriname":{"a":"Flag: Suriname","b":"1F1F8-1F1F7","j":["flag","sr","nation","country","banner","suriname"]},"flag-south-sudan":{"a":"Flag: South Sudan","b":"1F1F8-1F1F8","j":["flag","south","sd","nation","country","banner","south_sudan"]},"flag-so-tom--prncipe":{"a":"Flag: São Tomé & Príncipe","b":"1F1F8-1F1F9","j":["flag","flag_sao_tome_principe","sao","tome","principe","nation","country","banner","sao_tome_principe"]},"flag-el-salvador":{"a":"Flag: El Salvador","b":"1F1F8-1F1FB","j":["flag","el","salvador","nation","country","banner","el_salvador"]},"flag-sint-maarten":{"a":"Flag: Sint Maarten","b":"1F1F8-1F1FD","j":["flag","sint","maarten","dutch","nation","country","banner","sint_maarten"]},"flag-syria":{"a":"Flag: Syria","b":"1F1F8-1F1FE","j":["flag","syrian","arab","republic","nation","country","banner","syria"]},"flag-eswatini":{"a":"Flag: Eswatini","b":"1F1F8-1F1FF","j":["flag","sz","nation","country","banner","eswatini"]},"flag-tristan-da-cunha":{"a":"Flag: Tristan Da Cunha","b":"1F1F9-1F1E6","j":["flag"]},"flag-turks--caicos-islands":{"a":"Flag: Turks & Caicos Islands","b":"1F1F9-1F1E8","j":["flag","flag_turks_caicos_islands","turks","caicos","islands","nation","country","banner","turks_caicos_islands"]},"flag-chad":{"a":"Flag: Chad","b":"1F1F9-1F1E9","j":["flag","td","nation","country","banner","chad"]},"flag-french-southern-territories":{"a":"Flag: French Southern Territories","b":"1F1F9-1F1EB","j":["flag","french","southern","territories","nation","country","banner","french_southern_territories"]},"flag-togo":{"a":"Flag: Togo","b":"1F1F9-1F1EC","j":["flag","tg","nation","country","banner","togo"]},"flag-thailand":{"a":"Flag: Thailand","b":"1F1F9-1F1ED","j":["flag","th","nation","country","banner","thailand"]},"flag-tajikistan":{"a":"Flag: Tajikistan","b":"1F1F9-1F1EF","j":["flag","tj","nation","country","banner","tajikistan"]},"flag-tokelau":{"a":"Flag: Tokelau","b":"1F1F9-1F1F0","j":["flag","tk","nation","country","banner","tokelau"]},"flag-timorleste":{"a":"Flag: Timor-Leste","b":"1F1F9-1F1F1","j":["flag","flag_timor_leste","timor","leste","nation","country","banner","timor_leste"]},"flag-turkmenistan":{"a":"Flag: Turkmenistan","b":"1F1F9-1F1F2","j":["flag","nation","country","banner","turkmenistan"]},"flag-tunisia":{"a":"Flag: Tunisia","b":"1F1F9-1F1F3","j":["flag","tn","nation","country","banner","tunisia"]},"flag-tonga":{"a":"Flag: Tonga","b":"1F1F9-1F1F4","j":["flag","to","nation","country","banner","tonga"]},"flag-turkey":{"a":"Flag: Turkey","b":"1F1F9-1F1F7","j":["flag","turkey","nation","country","banner"]},"flag-trinidad--tobago":{"a":"Flag: Trinidad & Tobago","b":"1F1F9-1F1F9","j":["flag","flag_trinidad_tobago","trinidad","tobago","nation","country","banner","trinidad_tobago"]},"flag-tuvalu":{"a":"Flag: Tuvalu","b":"1F1F9-1F1FB","j":["flag","nation","country","banner","tuvalu"]},"flag-taiwan":{"a":"Flag: Taiwan","b":"1F1F9-1F1FC","j":["flag","tw","nation","country","banner","taiwan"]},"flag-tanzania":{"a":"Flag: Tanzania","b":"1F1F9-1F1FF","j":["flag","tanzania","united","republic","nation","country","banner"]},"flag-ukraine":{"a":"Flag: Ukraine","b":"1F1FA-1F1E6","j":["flag","ua","nation","country","banner","ukraine"]},"flag-uganda":{"a":"Flag: Uganda","b":"1F1FA-1F1EC","j":["flag","ug","nation","country","banner","uganda"]},"flag-us-outlying-islands":{"a":"Flag: U.S. Outlying Islands","b":"1F1FA-1F1F2","j":["flag","flag_u_s_outlying_islands"]},"flag-united-nations":{"a":"Flag: United Nations","b":"1F1FA-1F1F3","j":["flag","un","banner"]},"flag-united-states":{"a":"Flag: United States","b":"1F1FA-1F1F8","j":["flag","united","states","america","nation","country","banner","united_states"]},"flag-uruguay":{"a":"Flag: Uruguay","b":"1F1FA-1F1FE","j":["flag","uy","nation","country","banner","uruguay"]},"flag-uzbekistan":{"a":"Flag: Uzbekistan","b":"1F1FA-1F1FF","j":["flag","uz","nation","country","banner","uzbekistan"]},"flag-vatican-city":{"a":"Flag: Vatican City","b":"1F1FB-1F1E6","j":["flag","vatican","city","nation","country","banner","vatican_city"]},"flag-st-vincent--grenadines":{"a":"Flag: St. Vincent & Grenadines","b":"1F1FB-1F1E8","j":["flag","flag_st_vincent_grenadines","saint","vincent","grenadines","nation","country","banner","st_vincent_grenadines"]},"flag-venezuela":{"a":"Flag: Venezuela","b":"1F1FB-1F1EA","j":["flag","ve","bolivarian","republic","nation","country","banner","venezuela"]},"flag-british-virgin-islands":{"a":"Flag: British Virgin Islands","b":"1F1FB-1F1EC","j":["flag","british","virgin","islands","bvi","nation","country","banner","british_virgin_islands"]},"flag-us-virgin-islands":{"a":"Flag: U.S. Virgin Islands","b":"1F1FB-1F1EE","j":["flag","flag_u_s_virgin_islands","virgin","islands","us","nation","country","banner","u_s_virgin_islands"]},"flag-vietnam":{"a":"Flag: Vietnam","b":"1F1FB-1F1F3","j":["flag","viet","nam","nation","country","banner","vietnam"]},"flag-vanuatu":{"a":"Flag: Vanuatu","b":"1F1FB-1F1FA","j":["flag","vu","nation","country","banner","vanuatu"]},"flag-wallis--futuna":{"a":"Flag: Wallis & Futuna","b":"1F1FC-1F1EB","j":["flag","flag_wallis_futuna","wallis","futuna","nation","country","banner","wallis_futuna"]},"flag-samoa":{"a":"Flag: Samoa","b":"1F1FC-1F1F8","j":["flag","ws","nation","country","banner","samoa"]},"flag-kosovo":{"a":"Flag: Kosovo","b":"1F1FD-1F1F0","j":["flag","xk","nation","country","banner","kosovo"]},"flag-yemen":{"a":"Flag: Yemen","b":"1F1FE-1F1EA","j":["flag","ye","nation","country","banner","yemen"]},"flag-mayotte":{"a":"Flag: Mayotte","b":"1F1FE-1F1F9","j":["flag","yt","nation","country","banner","mayotte"]},"flag-south-africa":{"a":"Flag: South Africa","b":"1F1FF-1F1E6","j":["flag","south","africa","nation","country","banner","south_africa"]},"flag-zambia":{"a":"Flag: Zambia","b":"1F1FF-1F1F2","j":["flag","zm","nation","country","banner","zambia"]},"flag-zimbabwe":{"a":"Flag: Zimbabwe","b":"1F1FF-1F1FC","j":["flag","zw","nation","country","banner","zimbabwe"]},"flag-england":{"a":"Flag: England","b":"1F3F4-E0067-E0062-E0065-E006E-E0067-E007F","j":["flag","english"]},"flag-scotland":{"a":"Flag: Scotland","b":"1F3F4-E0067-E0062-E0073-E0063-E0074-E007F","j":["flag","scottish"]},"flag-wales":{"a":"Flag: Wales","b":"1F3F4-E0067-E0062-E0077-E006C-E0073-E007F","j":["flag","welsh"]}},"aliases":{}} \ No newline at end of file From c89a107ca69ab02c1b4c020f9e50b4ffd84f21be Mon Sep 17 00:00:00 2001 From: bmarty Date: Mon, 14 Feb 2022 00:05:49 +0000 Subject: [PATCH 081/302] Sync analytics plan --- .../plan/{Screen.kt => MobileScreen.kt} | 271 ++++++------------ .../app/features/analytics/plan/WebScreen.kt | 241 ++++++++++++++++ 2 files changed, 333 insertions(+), 179 deletions(-) rename vector/src/main/java/im/vector/app/features/analytics/plan/{Screen.kt => MobileScreen.kt} (67%) create mode 100644 vector/src/main/java/im/vector/app/features/analytics/plan/WebScreen.kt diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/MobileScreen.kt similarity index 67% rename from vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt rename to vector/src/main/java/im/vector/app/features/analytics/plan/MobileScreen.kt index 710ae8f6f2..758a0540bf 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/MobileScreen.kt @@ -22,9 +22,9 @@ import im.vector.app.features.analytics.itf.VectorAnalyticsScreen // https://github.com/matrix-org/matrix-analytics-events/ /** - * Triggered when the user changed screen + * Triggered when the user changed screen on Element Android/iOS */ -data class Screen( +data class MobileScreen( /** * How long the screen was displayed for in milliseconds. */ @@ -33,6 +33,11 @@ data class Screen( ) : VectorAnalyticsScreen { enum class ScreenName { + /** + * The screen that displays the user's breadcrumbs. + */ + Breadcrumbs, + /** * The screen shown to create a new (non-direct) room. */ @@ -43,6 +48,16 @@ data class Screen( */ DeactivateAccount, + /** + * The tab on mobile that displays the dialpad. + */ + Dialpad, + + /** + * The Favourites tab on mobile that lists your favourite people/rooms. + */ + Favourites, + /** * The form for the forgot password use case */ @@ -54,11 +69,15 @@ data class Screen( Group, /** - * The Home tab on iOS | possibly the same on Android? | Home page on - * Web + * The Home tab on iOS | possibly the same on Android? */ Home, + /** + * The screen shown to share a link to download the app. + */ + InviteFriends, + /** * The screen that displays the login flow (when the user already has an * account). @@ -66,100 +85,14 @@ data class Screen( Login, /** - * The screen that displays the user's breadcrumbs. + * Legacy: The screen that shows all groups/communities you have joined. */ - MobileBreadcrumbs, - - /** - * The tab on mobile that displays the dialpad. - */ - MobileDialpad, - - /** - * The Favourites tab on mobile that lists your favourite people/rooms. - */ - MobileFavourites, - - /** - * The screen shown to share a link to download the app. - */ - MobileInviteFriends, + MyGroups, /** * The People tab on mobile that lists all the DM rooms you have joined. */ - MobilePeople, - - /** - * The Rooms tab on mobile that lists all the (non-direct) rooms you've - * joined. - */ - MobileRooms, - - /** - * The Files tab shown in the global search screen on Mobile. - */ - MobileSearchFiles, - - /** - * The Messages tab shown in the global search screen on Mobile. - */ - MobileSearchMessages, - - /** - * The People tab shown in the global search screen on Mobile. - */ - MobileSearchPeople, - - /** - * The Rooms tab shown in the global search screen on Mobile. - */ - MobileSearchRooms, - - /** - * The global settings screen shown in the app. - */ - MobileSettings, - - /** - * The settings screen to change the default notification options. - */ - MobileSettingsDefaultNotifications, - - /** - * The settings screen to manage notification mentions and keywords. - */ - MobileSettingsMentionsAndKeywords, - - /** - * The global security settings screen. - */ - MobileSettingsSecurity, - - /** - * The sidebar shown on mobile with spaces, settings etc. - */ - MobileSidebar, - - /** - * Screen that displays the list of members of a space - */ - MobileSpaceMembers, - - /** - * The bottom sheet that list all space options - */ - MobileSpaceMenu, - - /** - * The screen shown to select which room directory you'd like to use. - */ - MobileSwitchDirectory, - - /** - * Legacy: The screen that shows all groups/communities you have joined. - */ - MyGroups, + People, /** * The screen that displays the registration flow (when the user wants @@ -216,107 +149,87 @@ data class Screen( */ RoomUploads, + /** + * The Rooms tab on mobile that lists all the (non-direct) rooms you've + * joined. + */ + Rooms, + + /** + * The Files tab shown in the global search screen on Mobile. + */ + SearchFiles, + + /** + * The Messages tab shown in the global search screen on Mobile. + */ + SearchMessages, + + /** + * The People tab shown in the global search screen on Mobile. + */ + SearchPeople, + + /** + * The Rooms tab shown in the global search screen on Mobile. + */ + SearchRooms, + + /** + * The global settings screen shown in the app. + */ + Settings, + + /** + * The settings screen to change the default notification options. + */ + SettingsDefaultNotifications, + + /** + * The settings screen to manage notification mentions and keywords. + */ + SettingsMentionsAndKeywords, + + /** + * The global security settings screen. + */ + SettingsSecurity, + + /** + * The sidebar shown on mobile with spaces, settings etc. + */ + Sidebar, + /** * Screen that displays the list of rooms and spaces of a space */ SpaceExploreRooms, + /** + * Screen that displays the list of members of a space + */ + SpaceMembers, + + /** + * The bottom sheet that list all space options + */ + SpaceMenu, + /** * The screen shown to create a new direct room. */ StartChat, + /** + * The screen shown to select which room directory you'd like to use. + */ + SwitchDirectory, + /** * A screen that shows information about a room member. */ User, - /** - * Element Web showing flow to trust this new device with cross-signing. - */ - WebCompleteSecurity, - - /** - * Element Web showing flow to setup SSSS / cross-signing on this - * account. - */ - WebE2ESetup, - - /** - * Element Web loading spinner. - */ - WebLoading, - - /** - * Element Web device has been soft logged out by the server. - */ - WebSoftLogout, - - /** - * Legacy: Element Web User Settings Flair Tab. - */ - WebUserSettingFlair, - - /** - * Element Web User Settings Mjolnir (labs) Tab. - */ - WebUserSettingMjolnir, - - /** - * Element Web User Settings Appearance Tab. - */ - WebUserSettingsAppearance, - - /** - * Element Web User Settings General Tab. - */ - WebUserSettingsGeneral, - - /** - * Element Web User Settings Help & About Tab. - */ - WebUserSettingsHelpAbout, - - /** - * Element Web User Settings Ignored Users Tab. - */ - WebUserSettingsIgnoredUsers, - - /** - * Element Web User Settings Keyboard Tab. - */ - WebUserSettingsKeyboard, - - /** - * Element Web User Settings Labs Tab. - */ - WebUserSettingsLabs, - - /** - * Element Web User Settings Notifications Tab. - */ - WebUserSettingsNotifications, - - /** - * Element Web User Settings Preferences Tab. - */ - WebUserSettingsPreferences, - - /** - * Element Web User Settings Security & Privacy Tab. - */ - WebUserSettingsSecurityPrivacy, - - /** - * Element Web User Settings Sidebar Tab. - */ - WebUserSettingsSidebar, - - /** - * Element Web User Settings Voice & Video Tab. - */ - WebUserSettingsVoiceVideo, - /** * The splash screen. */ diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/WebScreen.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/WebScreen.kt new file mode 100644 index 0000000000..b43d6d1b87 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/WebScreen.kt @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2021 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.analytics.plan + +import im.vector.app.features.analytics.itf.VectorAnalyticsEvent + +// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT +// https://github.com/matrix-org/matrix-analytics-events/ + +/** + * Triggered when the user changed screen on Element Web/Desktop + */ +data class WebScreen( + val $current_url: $current_url, + /** + * How long the screen took to load, if applicable. + */ + val durationMs: Int? = null, +) : VectorAnalyticsEvent { + + enum class $current_url { + /** + * Screen showing flow to trust this new device with cross-signing. + */ + CompleteSecurity, + + /** + * The screen shown to create a new (non-direct) room. + */ + CreateRoom, + + /** + * The confirmation screen shown before deactivating an account. + */ + DeactivateAccount, + + /** + * Screen showing flow to setup SSSS / cross-signing on this account. + */ + E2ESetup, + + /** + * The form for the forgot password use case + */ + ForgotPassword, + + /** + * Legacy: The screen that shows information about a specific group. + */ + Group, + + /** + * Home page. + */ + Home, + + /** + * Screen showing loading spinner. + */ + Loading, + + /** + * The screen that displays the login flow (when the user already has an + * account). + */ + Login, + + /** + * Legacy: The screen that shows all groups/communities you have joined. + */ + MyGroups, + + /** + * The screen that displays the registration flow (when the user wants + * to create an account) + */ + Register, + + /** + * The screen that displays the messages and events received in a room. + */ + Room, + + /** + * The screen shown when tapping the name of a room from the Room + * screen. + */ + RoomDetails, + + /** + * The screen that lists public rooms for you to discover. + */ + RoomDirectory, + + /** + * The screen that lists all the user's rooms and let them filter the + * rooms. + */ + RoomFilter, + + /** + * The screen that displays the list of members that are part of a room. + */ + RoomMembers, + + /** + * The notifications settings screen shown from the Room Details screen. + */ + RoomNotifications, + + /** + * The screen that allows you to search for messages/files in a specific + * room. + */ + RoomSearch, + + /** + * The settings screen shown from the Room Details screen. + */ + RoomSettings, + + /** + * The screen that allows you to see all of the files sent in a specific + * room. + */ + RoomUploads, + + /** + * Screen showing device has been soft logged out by the server. + */ + SoftLogout, + + /** + * Screen that displays the list of rooms and spaces of a space + */ + SpaceExploreRooms, + + /** + * The screen shown to create a new direct room. + */ + StartChat, + + /** + * A screen that shows information about a room member. + */ + User, + + /** + * Legacy: screen showing User Settings Flair Tab. + */ + UserSettingFlair, + + /** + * Screen showing User Settings Mjolnir (labs) Tab. + */ + UserSettingMjolnir, + + /** + * Screen showing User Settings Appearance Tab. + */ + UserSettingsAppearance, + + /** + * Screen showing User Settings General Tab. + */ + UserSettingsGeneral, + + /** + * Screen showing User Settings Help & About Tab. + */ + UserSettingsHelpAbout, + + /** + * Screen showing User Settings Ignored Users Tab. + */ + UserSettingsIgnoredUsers, + + /** + * Screen showing User Settings Keyboard Tab. + */ + UserSettingsKeyboard, + + /** + * Screen showing User Settings Labs Tab. + */ + UserSettingsLabs, + + /** + * Screen showing User Settings Notifications Tab. + */ + UserSettingsNotifications, + + /** + * Screen showing User Settings Preferences Tab. + */ + UserSettingsPreferences, + + /** + * Screen showing User Settings Security & Privacy Tab. + */ + UserSettingsSecurityPrivacy, + + /** + * Screen showing User Settings Sidebar Tab. + */ + UserSettingsSidebar, + + /** + * Screen showing User Settings Voice & Video Tab. + */ + UserSettingsVoiceVideo, + + /** + * The splash screen. + */ + Welcome, + } + + override fun getName() = "$pageview" + + override fun getProperties(): Map? { + return mutableMapOf().apply { + put("$current_url", $current_url.name) + durationMs?.let { put("durationMs", it) } + }.takeIf { it.isNotEmpty() } + } +} From 62d9c81420a1210a438b446a32819ef7910fe713 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 14 Feb 2022 11:38:53 +0000 Subject: [PATCH 082/302] adding UI docs section for contributing to the sanity tests - explaining the robot pattern and giving examples --- docs/ui-tests.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/docs/ui-tests.md b/docs/ui-tests.md index 6ebb52abe8..05eb50f525 100644 --- a/docs/ui-tests.md +++ b/docs/ui-tests.md @@ -104,3 +104,76 @@ fun initAccount() { existingSession = createAccountAndSync(matrix, userName, password, true) } ``` + +### Contributing to the UiAllScreensSanityTest + +The `UiAllScreensSanityTest` makes use of the Robot pattern in order to model pages, components and interactions. +Each Robot aims to return the UI back to its original state after the interaction, allowing for a reusable and consistent DSL. + +```kotlin +// launches and closes settings after executing the block +elementRobot.settings { + // whilst in the settings, launches and closes the advanced settings sub screen + advancedSettings { + // crawls all the pages within the advanced settings + crawl() + } +} + +// enables developer mode by navigating to the settings, enabling the toggle and then returning to the starting point to execute the block +// on block completion the Robot disables developer mode by navigating back to the settings and finally returning to the original starting point +elementRobot.withDeveloperMode { + // the same starting point as the example above + settings { + advancedSettings { crawlDeveloperOptions() } + } +} +``` + +The Robots used in the example above... + +```kotlin +class ElementRobot { + fun settings(block: SettingsRobot.() -> Unit) { + // double check we're where we think we are + waitUntilViewVisible(withId(R.id.bottomNavigationView)) + + // navigate to the settings + openDrawer() + clickOn(R.id.homeDrawerHeaderSettingsView) + + // execute the robot with the context of the settings screen + block(SettingsRobot()) + + // close the settings and ensure we're back at the starting point + pressBack() + waitUntilViewVisible(withId(R.id.bottomNavigationView)) + } + + fun withDeveloperMode(block: ElementRobot.() -> Unit) { + settings { toggleDeveloperMode() } + block() + settings { toggleDeveloperMode() } + } +} + +class SettingsRobot { + fun toggleDeveloperMode() { + advancedSettings { + toggleDeveloperMode() + } + } + + fun advancedSettings(block: SettingsAdvancedRobot.() -> Unit) { + clickOn(R.string.settings_advanced_settings) + block(SettingsAdvancedRobot()) + pressBack() + } +} + +class SettingsAdvancedRobot { + fun toggleDeveloperMode() { + clickOn(R.string.settings_developer_mode_summary) + } +} +``` \ No newline at end of file From 4519dec7eb2d95c5dc8a16419a5ec9b737973673 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 14 Feb 2022 12:05:44 +0000 Subject: [PATCH 083/302] scheduling a refresh of the homeserver capabilities on introduction of new fields --- .../database/migration/MigrateSessionTo025.kt | 2 ++ .../sdk/internal/extensions/RealmExtensions.kt | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo025.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo025.kt index 35267d2a16..237b016ac2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo025.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo025.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.database.migration import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields +import org.matrix.android.sdk.internal.extensions.forceRefreshOfHomeServerCapabilities import org.matrix.android.sdk.internal.util.database.RealmMigrator class MigrateSessionTo025(realm: DynamicRealm) : RealmMigrator(realm, 25) { @@ -27,5 +28,6 @@ class MigrateSessionTo025(realm: DynamicRealm) : RealmMigrator(realm, 25) { ?.addField(HomeServerCapabilitiesEntityFields.CAN_CHANGE_DISPLAY_NAME, Boolean::class.java) ?.addField(HomeServerCapabilitiesEntityFields.CAN_CHANGE_AVATAR, Boolean::class.java) ?.addField(HomeServerCapabilitiesEntityFields.CAN_CHANGE3PID, Boolean::class.java) + ?.forceRefreshOfHomeServerCapabilities() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/RealmExtensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/RealmExtensions.kt index e52e32e16a..28b9f64188 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/RealmExtensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/RealmExtensions.kt @@ -18,6 +18,8 @@ package org.matrix.android.sdk.internal.extensions import io.realm.RealmList import io.realm.RealmObject +import io.realm.RealmObjectSchema +import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields internal fun RealmObject.assertIsManaged() { check(isManaged) { "${javaClass.simpleName} entity should be managed to use this function" } @@ -31,3 +33,12 @@ internal fun RealmList.clearWith(delete: (T) -> Unit) { first()?.let { delete.invoke(it) } } } + +/** + * Schedule a refresh of the HomeServers capabilities + */ +internal fun RealmObjectSchema?.forceRefreshOfHomeServerCapabilities(): RealmObjectSchema? { + return this?.transform { obj -> + obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0) + } +} From fed549f647259fa3c4d09bb1b095a9be690bc454 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 14 Feb 2022 12:05:53 +0000 Subject: [PATCH 084/302] reusing refresh extension --- .../sdk/internal/database/migration/MigrateSessionTo003.kt | 7 ++----- .../sdk/internal/database/migration/MigrateSessionTo016.kt | 6 ++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo003.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo003.kt index ab848d129a..bc0b79d7e6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo003.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo003.kt @@ -17,7 +17,7 @@ package org.matrix.android.sdk.internal.database.migration import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields +import org.matrix.android.sdk.internal.extensions.forceRefreshOfHomeServerCapabilities import org.matrix.android.sdk.internal.util.database.RealmMigrator class MigrateSessionTo003(realm: DynamicRealm) : RealmMigrator(realm, 3) { @@ -25,9 +25,6 @@ class MigrateSessionTo003(realm: DynamicRealm) : RealmMigrator(realm, 3) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("HomeServerCapabilitiesEntity") ?.addField("preferredJitsiDomain", String::class.java) - ?.transform { obj -> - // Schedule a refresh of the capabilities - obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0) - } + ?.forceRefreshOfHomeServerCapabilities() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo016.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo016.kt index e6b3d4a463..b2fa54a05c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo016.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo016.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.database.migration import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields +import org.matrix.android.sdk.internal.extensions.forceRefreshOfHomeServerCapabilities import org.matrix.android.sdk.internal.util.database.RealmMigrator class MigrateSessionTo016(realm: DynamicRealm) : RealmMigrator(realm, 16) { @@ -25,9 +26,6 @@ class MigrateSessionTo016(realm: DynamicRealm) : RealmMigrator(realm, 16) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("HomeServerCapabilitiesEntity") ?.addField(HomeServerCapabilitiesEntityFields.ROOM_VERSIONS_JSON, String::class.java) - ?.transform { obj -> - // Schedule a refresh of the capabilities - obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0) - } + ?.forceRefreshOfHomeServerCapabilities() } } From 674aea97a8db26f63bf2c72ab68412368e1d6d2e Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 14 Feb 2022 12:30:47 +0000 Subject: [PATCH 085/302] injecting the room name provider as we're within hilts scope --- vector/src/main/java/im/vector/app/core/di/SingletonModule.kt | 4 ++-- .../features/room/VectorRoomDisplayNameFallbackProvider.kt | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt index 2629d2056b..7db88b801b 100644 --- a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt @@ -110,10 +110,10 @@ object VectorStaticModule { } @Provides - fun providesMatrixConfiguration(context: Context): MatrixConfiguration { + fun providesMatrixConfiguration(vectorRoomDisplayNameFallbackProvider: VectorRoomDisplayNameFallbackProvider): MatrixConfiguration { return MatrixConfiguration( applicationFlavor = BuildConfig.FLAVOR_DESCRIPTION, - roomDisplayNameFallbackProvider = VectorRoomDisplayNameFallbackProvider(context) + roomDisplayNameFallbackProvider = vectorRoomDisplayNameFallbackProvider ) } diff --git a/vector/src/main/java/im/vector/app/features/room/VectorRoomDisplayNameFallbackProvider.kt b/vector/src/main/java/im/vector/app/features/room/VectorRoomDisplayNameFallbackProvider.kt index 33e63434ce..0be2a21ef4 100644 --- a/vector/src/main/java/im/vector/app/features/room/VectorRoomDisplayNameFallbackProvider.kt +++ b/vector/src/main/java/im/vector/app/features/room/VectorRoomDisplayNameFallbackProvider.kt @@ -19,8 +19,9 @@ package im.vector.app.features.room import android.content.Context import im.vector.app.R import org.matrix.android.sdk.api.RoomDisplayNameFallbackProvider +import javax.inject.Inject -class VectorRoomDisplayNameFallbackProvider( +class VectorRoomDisplayNameFallbackProvider @Inject constructor( private val context: Context ) : RoomDisplayNameFallbackProvider { From fd2d9287e7b536ac259f950ad66ecfb11ef029f8 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 14 Feb 2022 12:46:07 +0000 Subject: [PATCH 086/302] creating separate creator for the matrix instance to avoid ambiguous non singleton/duplicated singleton usages - also documents the static methods --- .../java/org/matrix/android/sdk/api/Matrix.kt | 16 ++++++++++++++++ .../im/vector/app/core/utils/TestMatrixHelper.kt | 3 +-- .../im/vector/app/core/di/SingletonModule.kt | 3 +-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt index 901ba75d16..a121b8a85d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt @@ -99,12 +99,28 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo private lateinit var instance: Matrix private val isInit = AtomicBoolean(false) + /** + * Creates a new instance of Matrix, it's recommend to manage this instance as a singleton. + * To make use of the built in singleton use Matrix.initialise() and/or Matrix.getInstance(context) instead + **/ + fun createInstance(context: Context, matrixConfiguration: MatrixConfiguration): Matrix { + return Matrix(context.applicationContext, matrixConfiguration) + } + + /** + * Initializes a singleton instance of Matrix for the given MatrixConfiguration + * This instance will be returned by Matrix.getInstance(context) + */ fun initialize(context: Context, matrixConfiguration: MatrixConfiguration) { if (isInit.compareAndSet(false, true)) { instance = Matrix(context.applicationContext, matrixConfiguration) } } + /** + * Either provides an already initialized singleton Matrix instance or queries the application context for a MatrixConfiguration.Provider + * to lazily create and store the instance. + */ fun getInstance(context: Context): Matrix { if (isInit.compareAndSet(false, true)) { val appContext = context.applicationContext diff --git a/vector/src/androidTest/java/im/vector/app/core/utils/TestMatrixHelper.kt b/vector/src/androidTest/java/im/vector/app/core/utils/TestMatrixHelper.kt index fab41a68bb..322f5fa23d 100644 --- a/vector/src/androidTest/java/im/vector/app/core/utils/TestMatrixHelper.kt +++ b/vector/src/androidTest/java/im/vector/app/core/utils/TestMatrixHelper.kt @@ -26,6 +26,5 @@ fun getMatrixInstance(): Matrix { val configuration = MatrixConfiguration( roomDisplayNameFallbackProvider = VectorRoomDisplayNameFallbackProvider(context) ) - Matrix.initialize(context, configuration) - return Matrix.getInstance(context) + return Matrix.createInstance(context, configuration) } diff --git a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt index 7db88b801b..b4bee417b4 100644 --- a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt @@ -120,8 +120,7 @@ object VectorStaticModule { @Provides @Singleton fun providesMatrix(context: Context, configuration: MatrixConfiguration): Matrix { - Matrix.initialize(context, configuration) - return Matrix.getInstance(context) + return Matrix.createInstance(context, configuration) } @Provides From 2f7f86b8bb04c1426dfb962b2ab01db85d4cd06f Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 14 Feb 2022 13:41:27 +0000 Subject: [PATCH 087/302] Update matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt Co-authored-by: Benoit Marty --- .../src/main/java/org/matrix/android/sdk/api/Matrix.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt index a121b8a85d..7dd19c2744 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt @@ -100,7 +100,7 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo private val isInit = AtomicBoolean(false) /** - * Creates a new instance of Matrix, it's recommend to manage this instance as a singleton. + * Creates a new instance of Matrix, it's recommended to manage this instance as a singleton. * To make use of the built in singleton use Matrix.initialise() and/or Matrix.getInstance(context) instead **/ fun createInstance(context: Context, matrixConfiguration: MatrixConfiguration): Matrix { From 2eb417ab050c27b454a867c7379570727710d745 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 14 Feb 2022 13:41:40 +0000 Subject: [PATCH 088/302] Update matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt Co-authored-by: Benoit Marty --- .../src/main/java/org/matrix/android/sdk/api/Matrix.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt index 7dd19c2744..b2f81891a7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt @@ -101,7 +101,7 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo /** * Creates a new instance of Matrix, it's recommended to manage this instance as a singleton. - * To make use of the built in singleton use Matrix.initialise() and/or Matrix.getInstance(context) instead + * To make use of the built in singleton use Matrix.initialize() and/or Matrix.getInstance(context) instead **/ fun createInstance(context: Context, matrixConfiguration: MatrixConfiguration): Matrix { return Matrix(context.applicationContext, matrixConfiguration) From 88ecfa367891a0a26dafb4948a2fc19d78c5cba3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 14 Feb 2022 16:40:11 +0100 Subject: [PATCH 089/302] Fix compilation issue, Screen has been renamed to MobileScreen Also manually delete WebScreen, which does not compile. Will have to fix that upstream. --- .../app/core/platform/VectorBaseActivity.kt | 4 +- .../VectorBaseBottomSheetDialogFragment.kt | 4 +- .../app/core/platform/VectorBaseFragment.kt | 4 +- .../app/features/analytics/plan/WebScreen.kt | 241 ------------------ .../features/analytics/screen/ScreenEvent.kt | 8 +- .../features/call/dialpad/DialPadFragment.kt | 4 +- .../createdirect/CreateDirectRoomActivity.kt | 4 +- .../vector/app/features/home/HomeActivity.kt | 6 +- .../app/features/home/HomeDrawerFragment.kt | 4 +- .../home/room/detail/RoomDetailActivity.kt | 4 +- .../home/room/detail/TimelineFragment.kt | 4 +- .../room/filtered/FilteredRoomsActivity.kt | 4 +- .../home/room/list/RoomListFragment.kt | 6 +- .../app/features/login/LoginActivity.kt | 6 +- .../login/LoginResetPasswordFragment.kt | 4 +- .../app/features/login/LoginSplashFragment.kt | 4 +- .../roomdirectory/RoomDirectoryActivity.kt | 4 +- .../createroom/CreateRoomActivity.kt | 4 +- .../picker/RoomDirectoryPickerFragment.kt | 4 +- .../RoomMemberProfileFragment.kt | 4 +- .../roomprofile/RoomProfileFragment.kt | 4 +- .../uploads/RoomUploadsFragment.kt | 4 +- .../settings/VectorSettingsBaseFragment.kt | 4 +- .../settings/VectorSettingsRootFragment.kt | 4 +- .../VectorSettingsSecurityPrivacyFragment.kt | 4 +- .../deactivation/DeactivateAccountFragment.kt | 4 +- ...gsDefaultNotificationPreferenceFragment.kt | 4 +- ...dMentionsNotificationPreferenceFragment.kt | 4 +- 28 files changed, 59 insertions(+), 300 deletions(-) delete mode 100644 vector/src/main/java/im/vector/app/features/analytics/plan/WebScreen.kt diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index 8164df9c55..5767acd44b 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -67,7 +67,7 @@ import im.vector.app.core.utils.toast import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs import im.vector.app.features.analytics.AnalyticsTracker -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.screen.ScreenEvent import im.vector.app.features.configuration.VectorConfiguration import im.vector.app.features.consent.ConsentNotGivenHelper @@ -97,7 +97,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver * Analytics * ========================================================================================== */ - protected var analyticsScreenName: Screen.ScreenName? = null + protected var analyticsScreenName: MobileScreen.ScreenName? = null private var screenEvent: ScreenEvent? = null protected lateinit var analyticsTracker: AnalyticsTracker diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt index 7e6a429274..869a12e871 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -38,7 +38,7 @@ import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.core.extensions.toMvRxBundle import im.vector.app.core.utils.DimensionConverter import im.vector.app.features.analytics.AnalyticsTracker -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.screen.ScreenEvent import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -53,7 +53,7 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomShe * Analytics * ========================================================================================== */ - protected var analyticsScreenName: Screen.ScreenName? = null + protected var analyticsScreenName: MobileScreen.ScreenName? = null private var screenEvent: ScreenEvent? = null protected lateinit var analyticsTracker: AnalyticsTracker diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index 8a1b9051cc..6bd62707f2 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -44,7 +44,7 @@ import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.core.extensions.toMvRxBundle import im.vector.app.core.utils.ToolbarConfig import im.vector.app.features.analytics.AnalyticsTracker -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.screen.ScreenEvent import im.vector.app.features.navigation.Navigator import im.vector.lib.ui.styles.dialogs.MaterialProgressDialog @@ -58,7 +58,7 @@ abstract class VectorBaseFragment : Fragment(), MavericksView * Analytics * ========================================================================================== */ - protected var analyticsScreenName: Screen.ScreenName? = null + protected var analyticsScreenName: MobileScreen.ScreenName? = null private var screenEvent: ScreenEvent? = null protected lateinit var analyticsTracker: AnalyticsTracker diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/WebScreen.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/WebScreen.kt deleted file mode 100644 index b43d6d1b87..0000000000 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/WebScreen.kt +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2021 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.analytics.plan - -import im.vector.app.features.analytics.itf.VectorAnalyticsEvent - -// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT -// https://github.com/matrix-org/matrix-analytics-events/ - -/** - * Triggered when the user changed screen on Element Web/Desktop - */ -data class WebScreen( - val $current_url: $current_url, - /** - * How long the screen took to load, if applicable. - */ - val durationMs: Int? = null, -) : VectorAnalyticsEvent { - - enum class $current_url { - /** - * Screen showing flow to trust this new device with cross-signing. - */ - CompleteSecurity, - - /** - * The screen shown to create a new (non-direct) room. - */ - CreateRoom, - - /** - * The confirmation screen shown before deactivating an account. - */ - DeactivateAccount, - - /** - * Screen showing flow to setup SSSS / cross-signing on this account. - */ - E2ESetup, - - /** - * The form for the forgot password use case - */ - ForgotPassword, - - /** - * Legacy: The screen that shows information about a specific group. - */ - Group, - - /** - * Home page. - */ - Home, - - /** - * Screen showing loading spinner. - */ - Loading, - - /** - * The screen that displays the login flow (when the user already has an - * account). - */ - Login, - - /** - * Legacy: The screen that shows all groups/communities you have joined. - */ - MyGroups, - - /** - * The screen that displays the registration flow (when the user wants - * to create an account) - */ - Register, - - /** - * The screen that displays the messages and events received in a room. - */ - Room, - - /** - * The screen shown when tapping the name of a room from the Room - * screen. - */ - RoomDetails, - - /** - * The screen that lists public rooms for you to discover. - */ - RoomDirectory, - - /** - * The screen that lists all the user's rooms and let them filter the - * rooms. - */ - RoomFilter, - - /** - * The screen that displays the list of members that are part of a room. - */ - RoomMembers, - - /** - * The notifications settings screen shown from the Room Details screen. - */ - RoomNotifications, - - /** - * The screen that allows you to search for messages/files in a specific - * room. - */ - RoomSearch, - - /** - * The settings screen shown from the Room Details screen. - */ - RoomSettings, - - /** - * The screen that allows you to see all of the files sent in a specific - * room. - */ - RoomUploads, - - /** - * Screen showing device has been soft logged out by the server. - */ - SoftLogout, - - /** - * Screen that displays the list of rooms and spaces of a space - */ - SpaceExploreRooms, - - /** - * The screen shown to create a new direct room. - */ - StartChat, - - /** - * A screen that shows information about a room member. - */ - User, - - /** - * Legacy: screen showing User Settings Flair Tab. - */ - UserSettingFlair, - - /** - * Screen showing User Settings Mjolnir (labs) Tab. - */ - UserSettingMjolnir, - - /** - * Screen showing User Settings Appearance Tab. - */ - UserSettingsAppearance, - - /** - * Screen showing User Settings General Tab. - */ - UserSettingsGeneral, - - /** - * Screen showing User Settings Help & About Tab. - */ - UserSettingsHelpAbout, - - /** - * Screen showing User Settings Ignored Users Tab. - */ - UserSettingsIgnoredUsers, - - /** - * Screen showing User Settings Keyboard Tab. - */ - UserSettingsKeyboard, - - /** - * Screen showing User Settings Labs Tab. - */ - UserSettingsLabs, - - /** - * Screen showing User Settings Notifications Tab. - */ - UserSettingsNotifications, - - /** - * Screen showing User Settings Preferences Tab. - */ - UserSettingsPreferences, - - /** - * Screen showing User Settings Security & Privacy Tab. - */ - UserSettingsSecurityPrivacy, - - /** - * Screen showing User Settings Sidebar Tab. - */ - UserSettingsSidebar, - - /** - * Screen showing User Settings Voice & Video Tab. - */ - UserSettingsVoiceVideo, - - /** - * The splash screen. - */ - Welcome, - } - - override fun getName() = "$pageview" - - override fun getProperties(): Map? { - return mutableMapOf().apply { - put("$current_url", $current_url.name) - durationMs?.let { put("durationMs", it) } - }.takeIf { it.isNotEmpty() } - } -} diff --git a/vector/src/main/java/im/vector/app/features/analytics/screen/ScreenEvent.kt b/vector/src/main/java/im/vector/app/features/analytics/screen/ScreenEvent.kt index 8e0513f25a..1ad4a1fa32 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/screen/ScreenEvent.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/screen/ScreenEvent.kt @@ -18,13 +18,13 @@ package im.vector.app.features.analytics.screen import android.os.SystemClock import im.vector.app.features.analytics.AnalyticsTracker -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import timber.log.Timber /** * Track a screen display. Unique usage. */ -class ScreenEvent(val screenName: Screen.ScreenName) { +class ScreenEvent(val screenName: MobileScreen.ScreenName) { private val startTime = SystemClock.elapsedRealtime() // Protection to avoid multiple sending @@ -34,14 +34,14 @@ class ScreenEvent(val screenName: Screen.ScreenName) { * @param screenNameOverride can be used to override the screen name passed in constructor parameter */ fun send(analyticsTracker: AnalyticsTracker, - screenNameOverride: Screen.ScreenName? = null) { + screenNameOverride: MobileScreen.ScreenName? = null) { if (isSent) { Timber.w("Event $screenName Already sent!") return } isSent = true analyticsTracker.screen( - Screen( + MobileScreen( screenName = screenNameOverride ?: screenName, durationMs = (SystemClock.elapsedRealtime() - startTime).toInt() ) diff --git a/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt b/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt index 5fc866a4dd..b33ce25f55 100644 --- a/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt +++ b/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt @@ -40,7 +40,7 @@ import com.android.dialer.dialpadview.DigitsEditText import im.vector.app.R import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.features.analytics.AnalyticsTracker -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.screen.ScreenEvent import im.vector.app.features.themes.ThemeUtils @@ -69,7 +69,7 @@ class DialPadFragment : Fragment(), TextWatcher { private var screenEvent: ScreenEvent? = null override fun onResume() { super.onResume() - screenEvent = ScreenEvent(Screen.ScreenName.MobileDialpad) + screenEvent = ScreenEvent(MobileScreen.ScreenName.Dialpad) } override fun onPause() { diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt index 2d93bab6a3..a6b34eda25 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt @@ -43,7 +43,7 @@ import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO import im.vector.app.core.utils.checkPermissions import im.vector.app.core.utils.onPermissionDeniedSnackbar import im.vector.app.core.utils.registerForPermissionsResult -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.contactsbook.ContactsBookFragment import im.vector.app.features.qrcode.QrCodeScannerEvents import im.vector.app.features.qrcode.QrCodeScannerFragment @@ -71,7 +71,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.StartChat + analyticsScreenName = MobileScreen.ScreenName.StartChat views.toolbar.visibility = View.GONE sharedActionViewModel = viewModelProvider.get(UserListSharedActionViewModel::class.java) 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 6b6be63480..f6b32973a0 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 @@ -48,7 +48,7 @@ import im.vector.app.databinding.ActivityHomeBinding import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs import im.vector.app.features.analytics.accountdata.AnalyticsAccountDataViewModel -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.screen.ScreenEvent import im.vector.app.features.disclaimer.showDisclaimerDialog import im.vector.app.features.matrixto.MatrixToBottomSheet @@ -165,7 +165,7 @@ class HomeActivity : private val drawerListener = object : DrawerLayout.SimpleDrawerListener() { private var drawerScreenEvent: ScreenEvent? = null override fun onDrawerOpened(drawerView: View) { - drawerScreenEvent = ScreenEvent(Screen.ScreenName.MobileSidebar) + drawerScreenEvent = ScreenEvent(MobileScreen.ScreenName.Sidebar) } override fun onDrawerClosed(drawerView: View) { @@ -184,7 +184,7 @@ class HomeActivity : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.Home + analyticsScreenName = MobileScreen.ScreenName.Home supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false) FcmHelper.ensureFcmTokenIsRetrieved(this, pushManager, vectorPreferences.areNotificationEnabledForDevice()) sharedActionViewModel = viewModelProvider.get(HomeSharedActionViewModel::class.java) diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt index 9af06ef801..1aee0257f4 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt @@ -30,7 +30,7 @@ import im.vector.app.core.extensions.replaceChildFragment import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.startSharePlainTextIntent import im.vector.app.databinding.FragmentHomeDrawerBinding -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorSettingsActivity import im.vector.app.features.spaces.SpaceListFragment @@ -98,7 +98,7 @@ class HomeDrawerFragment @Inject constructor( views.homeDrawerInviteFriendButton.debouncedClicks { session.permalinkService().createPermalink(sharedActionViewModel.session.myUserId)?.let { permalink -> - analyticsTracker.screen(Screen(screenName = Screen.ScreenName.MobileInviteFriends)) + analyticsTracker.screen(MobileScreen(screenName = MobileScreen.ScreenName.InviteFriends)) val text = getString(R.string.invite_friends_text, permalink) startSharePlainTextIntent( diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index ae24052aa2..f5bf086e96 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -35,7 +35,7 @@ import im.vector.app.core.extensions.keepScreenOn import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityRoomDetailBinding -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.screen.ScreenEvent import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsFragment import im.vector.app.features.home.room.detail.arguments.TimelineArgs @@ -160,7 +160,7 @@ class RoomDetailActivity : private val drawerListener = object : DrawerLayout.SimpleDrawerListener() { private var drawerScreenEvent: ScreenEvent? = null override fun onDrawerOpened(drawerView: View) { - drawerScreenEvent = ScreenEvent(Screen.ScreenName.MobileBreadcrumbs) + drawerScreenEvent = ScreenEvent(MobileScreen.ScreenName.Breadcrumbs) } override fun onDrawerClosed(drawerView: View) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 92319fabdc..ff392eaf1b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -120,7 +120,7 @@ import im.vector.app.core.utils.toast import im.vector.app.databinding.DialogReportContentBinding import im.vector.app.databinding.FragmentTimelineBinding import im.vector.app.features.analytics.plan.Composer -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.attachments.AttachmentTypeSelectorView import im.vector.app.features.attachments.AttachmentsHelper import im.vector.app.features.attachments.ContactAttachment @@ -342,7 +342,7 @@ class TimelineFragment @Inject constructor( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.Room + analyticsScreenName = MobileScreen.ScreenName.Room setFragmentResultListener(MigrateRoomBottomSheet.REQUEST_KEY) { _, bundle -> bundle.getString(MigrateRoomBottomSheet.BUNDLE_KEY_REPLACEMENT_ROOM)?.let { replacementRoomId -> timelineViewModel.handle(RoomDetailAction.RoomUpgradeSuccess(replacementRoomId)) diff --git a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt index 0e16b4b0df..cf7c4a0e80 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt @@ -24,7 +24,7 @@ import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityFilteredRoomsBinding -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.home.room.list.RoomListFragment import im.vector.app.features.home.room.list.RoomListParams @@ -43,7 +43,7 @@ class FilteredRoomsActivity : VectorBaseActivity() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.RoomFilter + analyticsScreenName = MobileScreen.ScreenName.RoomFilter setupToolbar(views.filteredRoomsToolbar) .allowBack() if (isFirstCreation()) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index b6481c9cbb..b023c26590 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -42,7 +42,7 @@ import im.vector.app.core.platform.StateView import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.UserPreferencesProvider import im.vector.app.databinding.FragmentRoomListBinding -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.home.room.filtered.FilteredRoomFooterItem import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet @@ -104,8 +104,8 @@ class RoomListFragment @Inject constructor( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) analyticsScreenName = when (roomListParams.displayMode) { - RoomListDisplayMode.PEOPLE -> Screen.ScreenName.MobilePeople - RoomListDisplayMode.ROOMS -> Screen.ScreenName.MobileRooms + RoomListDisplayMode.PEOPLE -> MobileScreen.ScreenName.People + RoomListDisplayMode.ROOMS -> MobileScreen.ScreenName.Rooms else -> null } } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt index edc77d73f6..bf596fc6aa 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt @@ -38,7 +38,7 @@ import im.vector.app.core.extensions.addFragmentToBackstack import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityLoginBinding -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.home.HomeActivity import im.vector.app.features.login.terms.LoginTermsFragment import im.vector.app.features.login.terms.LoginTermsFragmentArgument @@ -81,7 +81,7 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA override fun getCoordinatorLayout() = views.coordinatorLayout override fun initUiAndData() { - analyticsScreenName = Screen.ScreenName.Login + analyticsScreenName = MobileScreen.ScreenName.Login if (isFirstCreation()) { addFirstFragment() @@ -203,7 +203,7 @@ open class LoginActivity : VectorBaseActivity(), UnlockedA if (loginViewState.isUserLogged()) { if (loginViewState.signMode == SignMode.SignUp) { // change the screen name - analyticsScreenName = Screen.ScreenName.Register + analyticsScreenName = MobileScreen.ScreenName.Register } val intent = HomeActivity.newIntent( this, diff --git a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt index 0328d09427..d121245532 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt @@ -31,7 +31,7 @@ import im.vector.app.core.extensions.hidePassword import im.vector.app.core.extensions.isEmail import im.vector.app.core.extensions.toReducedUrl import im.vector.app.databinding.FragmentLoginResetPasswordBinding -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map @@ -48,7 +48,7 @@ class LoginResetPasswordFragment @Inject constructor() : AbstractLoginFragment(), Matri override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.RoomDirectory + analyticsScreenName = MobileScreen.ScreenName.RoomDirectory sharedActionViewModel = viewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) if (isFirstCreation()) { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt index 339c819a65..e4c350b88e 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt @@ -26,7 +26,7 @@ import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.roomdirectory.RoomDirectorySharedAction import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel import kotlinx.coroutines.flow.launchIn @@ -57,7 +57,7 @@ class CreateRoomActivity : VectorBaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.CreateRoom + analyticsScreenName = MobileScreen.ScreenName.CreateRoom sharedActionViewModel = viewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) sharedActionViewModel .stream() diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt index 48610dda7b..cb71f93a0e 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt @@ -29,7 +29,7 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentRoomDirectoryPickerBinding -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.roomdirectory.RoomDirectoryAction import im.vector.app.features.roomdirectory.RoomDirectoryData import im.vector.app.features.roomdirectory.RoomDirectoryServer @@ -54,7 +54,7 @@ class RoomDirectoryPickerFragment @Inject constructor(private val roomDirectoryP override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.MobileSwitchDirectory + analyticsScreenName = MobileScreen.ScreenName.SwitchDirectory } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt index c68bfca973..fcebe9adbb 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt @@ -47,7 +47,7 @@ import im.vector.app.databinding.DialogBaseEditTextBinding import im.vector.app.databinding.DialogShareQrCodeBinding import im.vector.app.databinding.FragmentMatrixProfileBinding import im.vector.app.databinding.ViewStubRoomMemberProfileHeaderBinding -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.crypto.verification.VerificationBottomSheet import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer @@ -91,7 +91,7 @@ class RoomMemberProfileFragment @Inject constructor( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.User + analyticsScreenName = MobileScreen.ScreenName.User } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index 8acf53088d..251b99e318 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -44,7 +44,7 @@ import im.vector.app.core.utils.copyToClipboard import im.vector.app.core.utils.startSharePlainTextIntent import im.vector.app.databinding.FragmentMatrixProfileBinding import im.vector.app.databinding.ViewStubRoomProfileHeaderBinding -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.RoomDetailPendingAction import im.vector.app.features.home.room.detail.RoomDetailPendingActionStore @@ -89,7 +89,7 @@ class RoomProfileFragment @Inject constructor( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.RoomSettings + analyticsScreenName = MobileScreen.ScreenName.RoomSettings setFragmentResultListener(MigrateRoomBottomSheet.REQUEST_KEY) { _, bundle -> bundle.getString(MigrateRoomBottomSheet.BUNDLE_KEY_REPLACEMENT_ROOM)?.let { replacementRoomId -> roomDetailPendingActionStore.data = RoomDetailPendingAction.OpenRoom(replacementRoomId, closeCurrentRoom = true) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt index 3c1a763072..a0adf42d5b 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt @@ -34,7 +34,7 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.saveMedia import im.vector.app.core.utils.shareMedia import im.vector.app.databinding.FragmentRoomUploadsBinding -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.notifications.NotificationUtils import im.vector.app.features.roomprofile.RoomProfileArgs @@ -57,7 +57,7 @@ class RoomUploadsFragment @Inject constructor( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.RoomUploads + analyticsScreenName = MobileScreen.ScreenName.RoomUploads } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt index 7cefd20269..4185fde663 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt @@ -30,7 +30,7 @@ import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.toast import im.vector.app.features.analytics.AnalyticsTracker -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.screen.ScreenEvent import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -43,7 +43,7 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), Maverick * Analytics * ========================================================================================== */ - protected var analyticsScreenName: Screen.ScreenName? = null + protected var analyticsScreenName: MobileScreen.ScreenName? = null private var screenEvent: ScreenEvent? = null protected lateinit var analyticsTracker: AnalyticsTracker diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt index cd76efac58..51011e29a2 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt @@ -19,7 +19,7 @@ package im.vector.app.features.settings import android.os.Bundle import im.vector.app.R import im.vector.app.core.preference.VectorPreference -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import javax.inject.Inject class VectorSettingsRootFragment @Inject constructor() : VectorSettingsBaseFragment() { @@ -29,7 +29,7 @@ class VectorSettingsRootFragment @Inject constructor() : VectorSettingsBaseFragm override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.MobileSettings + analyticsScreenName = MobileScreen.ScreenName.Settings } override fun bindPref() { diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index e4e287e83a..ef87d908ea 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -51,7 +51,7 @@ import im.vector.app.core.utils.copyToClipboard import im.vector.app.core.utils.openFileSelection import im.vector.app.core.utils.toast import im.vector.app.databinding.DialogImportE2eKeysBinding -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewActions import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewModel import im.vector.app.features.analytics.ui.consent.AnalyticsConsentViewState @@ -94,7 +94,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.MobileSettingsSecurity + analyticsScreenName = MobileScreen.ScreenName.SettingsSecurity } // cryptography diff --git a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt index 867526c009..631c375e62 100644 --- a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt @@ -31,7 +31,7 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentDeactivateAccountBinding import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs -import im.vector.app.features.analytics.plan.Screen +import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.auth.ReAuthActivity import im.vector.app.features.settings.VectorSettingsActivity import org.matrix.android.sdk.api.auth.data.LoginFlowTypes @@ -66,7 +66,7 @@ class DeactivateAccountFragment @Inject constructor() : VectorBaseFragment Date: Mon, 14 Feb 2022 15:53:34 +0000 Subject: [PATCH 090/302] providing more alternatives when Matrix.getInstance fails --- .../src/main/java/org/matrix/android/sdk/api/Matrix.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt index a121b8a85d..7df1912b0c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt @@ -129,7 +129,8 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo instance = Matrix(appContext, matrixConfiguration) } else { throw IllegalStateException("Matrix is not initialized properly." + - " You should call Matrix.initialize or let your application implements MatrixConfiguration.Provider.") + " If you want to manage your own Matrix instance use Matrix.createInstance" + + " otherwise you should call Matrix.initialize or let your application implement MatrixConfiguration.Provider.") } } return instance From 95df3e7e2b4ee249995eb9b3e90fb188dc5d6aa2 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 14 Feb 2022 16:04:47 +0000 Subject: [PATCH 091/302] deprecating the Matrix.initialize and Matrix.getInstance entry points in favour of clients controlling their own instances --- changelog.d/5185.sdk | 2 +- .../src/main/java/org/matrix/android/sdk/api/Matrix.kt | 2 ++ .../main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/changelog.d/5185.sdk b/changelog.d/5185.sdk index 14071c2961..9eda2e7c9b 100644 --- a/changelog.d/5185.sdk +++ b/changelog.d/5185.sdk @@ -1 +1 @@ -Avoids using Matrix.getInstance() within the SyncService and instead relies on the SDK client to provide the matrix instance \ No newline at end of file +Deprecates Matrix.initialize and Matrix.getInstance in favour of the client providing its own singleton instance via Matrix.createInstance \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt index 7df1912b0c..269a885d0f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt @@ -111,6 +111,7 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo * Initializes a singleton instance of Matrix for the given MatrixConfiguration * This instance will be returned by Matrix.getInstance(context) */ + @Deprecated("Use Matrix.createInstance and manage the instance manually") fun initialize(context: Context, matrixConfiguration: MatrixConfiguration) { if (isInit.compareAndSet(false, true)) { instance = Matrix(context.applicationContext, matrixConfiguration) @@ -121,6 +122,7 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo * Either provides an already initialized singleton Matrix instance or queries the application context for a MatrixConfiguration.Provider * to lazily create and store the instance. */ + @Deprecated("Use Matrix.createInstance and manage the instance manually") fun getInstance(context: Context): Matrix { if (isInit.compareAndSet(false, true)) { val appContext = context.applicationContext 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 306ed45500..c87f21d7ac 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 @@ -66,6 +66,7 @@ data class MatrixConfiguration( /** * Can be implemented by your Application class. */ + @Deprecated("Use Matrix.createInstance and manage the instance manually instead of Matrix.getInstance") interface Provider { fun providesMatrixConfiguration(): MatrixConfiguration } From ffd2a762aff34dd9c069131e5db16db8c7652963 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 14 Feb 2022 17:07:52 +0100 Subject: [PATCH 092/302] Let the Activity that created the result intent deserialize it. --- .../vector/app/features/call/VectorCallActivity.kt | 11 ++++------- .../features/call/transfer/CallTransferActivity.kt | 12 +++++++++--- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt index 6575949552..23c7b79914 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt @@ -55,7 +55,6 @@ import im.vector.app.databinding.ActivityCallBinding import im.vector.app.features.call.dialpad.CallDialPadBottomSheet import im.vector.app.features.call.dialpad.DialPadFragment import im.vector.app.features.call.transfer.CallTransferActivity -import im.vector.app.features.call.transfer.CallTransferResult import im.vector.app.features.call.utils.EglUtils import im.vector.app.features.call.webrtc.WebRtcCall import im.vector.app.features.call.webrtc.WebRtcCallManager @@ -525,22 +524,20 @@ class VectorCallActivity : VectorBaseActivity(), CallContro val callId = withState(callViewModel) { it.callId } navigator.openCallTransfer(this, callTransferActivityResultLauncher, callId) } - is VectorCallViewEvents.FailToTransfer -> showSnackbar(getString(R.string.call_transfer_failure)) + is VectorCallViewEvents.FailToTransfer -> showSnackbar(getString(R.string.call_transfer_failure)) null -> { } } } private val callTransferActivityResultLauncher = registerStartForActivityResult { activityResult -> - when (activityResult.resultCode) { Activity.RESULT_CANCELED -> { callViewModel.handle(VectorCallViewActions.CallTransferSelectionCancelled) } - Activity.RESULT_OK -> { - activityResult.data?.extras?.getParcelable(CallTransferActivity.EXTRA_TRANSFER_RESULT)?.also { - callViewModel.handle(VectorCallViewActions.CallTransferSelectionResult(it)) - } + Activity.RESULT_OK -> { + CallTransferActivity.getCallTransferResult(activityResult.data) + ?.let { callViewModel.handle(VectorCallViewActions.CallTransferSelectionResult(it)) } } } } diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt index d4b77c7739..d8eede6a55 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt @@ -26,6 +26,7 @@ import com.google.android.material.tabs.TabLayoutMediator import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.error.ErrorFormatter +import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityCallTransferBinding import kotlinx.parcelize.Parcelize @@ -55,8 +56,8 @@ class CallTransferActivity : VectorBaseActivity() { callTransferViewModel.observeViewEvents { when (it) { - is CallTransferViewEvents.Complete -> handleComplete() - } + is CallTransferViewEvents.Complete -> handleComplete() + }.exhaustive } sectionsPagerAdapter = CallTransferPagerAdapter(this) @@ -104,11 +105,16 @@ class CallTransferActivity : VectorBaseActivity() { } companion object { - const val EXTRA_TRANSFER_RESULT = "EXTRA_TRANSFER_RESULT" + private const val EXTRA_TRANSFER_RESULT = "EXTRA_TRANSFER_RESULT" + fun newIntent(context: Context, callId: String): Intent { return Intent(context, CallTransferActivity::class.java).also { it.putExtra(Mavericks.KEY_ARG, CallTransferArgs(callId)) } } + + fun getCallTransferResult(intent: Intent?): CallTransferResult? { + return intent?.extras?.getParcelable(EXTRA_TRANSFER_RESULT) + } } } From 5b851f1cb77a25326c849ea24282609c7ac8dec1 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 14 Feb 2022 16:33:25 +0000 Subject: [PATCH 093/302] suppressing deprecated warning on an unused method --- .../src/main/java/org/matrix/android/sdk/api/Matrix.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt index 43f8dbd656..5fedff53f0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt @@ -122,6 +122,7 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo * Either provides an already initialized singleton Matrix instance or queries the application context for a MatrixConfiguration.Provider * to lazily create and store the instance. */ + @Suppress("deprecation") // suppressing warning as this method is unused but is still provided for SDK clients @Deprecated("Use Matrix.createInstance and manage the instance manually") fun getInstance(context: Context): Matrix { if (isInit.compareAndSet(false, true)) { From 580ecc9c44c05d16187ad6700c28b24b5a6e7bca Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 15 Feb 2022 12:19:39 +0000 Subject: [PATCH 094/302] adding lateinit user property factory for use when calling the initial identify tracking - this will allow us send the pending onboarding properties once consent is given --- .../impl/LateInitUserPropertiesFactory.kt | 36 +++++++++ .../impl/LateInitUserPropertiesFactoryTest.kt | 73 +++++++++++++++++++ .../test/fakes/FakeActiveSessionDataSource.kt | 30 ++++++++ .../im/vector/app/test/fakes/FakeSession.kt | 16 ++++ .../vector/app/test/fakes/FakeVectorStore.kt | 34 +++++++++ 5 files changed, 189 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/analytics/impl/LateInitUserPropertiesFactory.kt create mode 100644 vector/src/test/java/im/vector/app/features/analytics/impl/LateInitUserPropertiesFactoryTest.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeActiveSessionDataSource.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeVectorStore.kt diff --git a/vector/src/main/java/im/vector/app/features/analytics/impl/LateInitUserPropertiesFactory.kt b/vector/src/main/java/im/vector/app/features/analytics/impl/LateInitUserPropertiesFactory.kt new file mode 100644 index 0000000000..d961ceaadc --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/analytics/impl/LateInitUserPropertiesFactory.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 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.analytics.impl + +import android.content.Context +import im.vector.app.ActiveSessionDataSource +import im.vector.app.core.extensions.vectorStore +import im.vector.app.features.analytics.extensions.toTrackingValue +import im.vector.app.features.analytics.plan.UserProperties +import javax.inject.Inject + +class LateInitUserPropertiesFactory @Inject constructor( + private val activeSessionDataSource: ActiveSessionDataSource, + private val context: Context, +) { + suspend fun createUserProperties(): UserProperties? { + val useCase = activeSessionDataSource.currentValue?.orNull()?.vectorStore(context)?.readUseCase() + return useCase?.let { + UserProperties(ftueUseCaseSelection = it.toTrackingValue()) + } + } +} diff --git a/vector/src/test/java/im/vector/app/features/analytics/impl/LateInitUserPropertiesFactoryTest.kt b/vector/src/test/java/im/vector/app/features/analytics/impl/LateInitUserPropertiesFactoryTest.kt new file mode 100644 index 0000000000..c2fa50f789 --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/analytics/impl/LateInitUserPropertiesFactoryTest.kt @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022 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.analytics.impl + +import im.vector.app.features.analytics.plan.UserProperties +import im.vector.app.features.onboarding.FtueUseCase +import im.vector.app.test.fakes.FakeActiveSessionDataSource +import im.vector.app.test.fakes.FakeContext +import im.vector.app.test.fakes.FakeSession +import im.vector.app.test.fakes.FakeVectorStore +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runBlockingTest +import org.amshove.kluent.shouldBeEqualTo +import org.junit.Test + +@ExperimentalCoroutinesApi +class LateInitUserPropertiesFactoryTest { + + private val fakeActiveSessionDataSource = FakeActiveSessionDataSource() + private val fakeVectorStore = FakeVectorStore() + private val fakeContext = FakeContext() + private val fakeSession = FakeSession().also { + it.givenVectorStore(fakeVectorStore.instance) + } + + private val lateInitUserProperties = LateInitUserPropertiesFactory( + fakeActiveSessionDataSource.instance, + fakeContext.instance + ) + + @Test + fun `given no active session when creating properties then returns null`() = runBlockingTest { + val result = lateInitUserProperties.createUserProperties() + + result shouldBeEqualTo null + } + + @Test + fun `given no use case set on an active session when creating properties then returns null`() = runBlockingTest { + fakeVectorStore.givenUseCase(null) + fakeSession.givenVectorStore(fakeVectorStore.instance) + fakeActiveSessionDataSource.setActiveSession(fakeSession) + + val result = lateInitUserProperties.createUserProperties() + + result shouldBeEqualTo null + } + + @Test + fun `given use case set on an active session when creating properties then includes the use case`() = runBlockingTest { + fakeVectorStore.givenUseCase(FtueUseCase.TEAMS) + fakeActiveSessionDataSource.setActiveSession(fakeSession) + val result = lateInitUserProperties.createUserProperties() + + result shouldBeEqualTo UserProperties( + ftueUseCaseSelection = UserProperties.FtueUseCaseSelection.WorkMessaging + ) + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeActiveSessionDataSource.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeActiveSessionDataSource.kt new file mode 100644 index 0000000000..4dab6daf3b --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeActiveSessionDataSource.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 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.test.fakes + +import arrow.core.Option +import im.vector.app.ActiveSessionDataSource +import org.matrix.android.sdk.api.session.Session + +class FakeActiveSessionDataSource { + + val instance = ActiveSessionDataSource() + + fun setActiveSession(session: Session) { + instance.post(Option.just(session)) + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt index 91403b3b2c..a23c43b986 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt @@ -16,8 +16,12 @@ package im.vector.app.test.fakes +import im.vector.app.core.extensions.vectorStore +import im.vector.app.features.session.VectorSessionStore import im.vector.app.test.testCoroutineDispatchers +import io.mockk.coEvery import io.mockk.mockk +import io.mockk.mockkStatic import org.matrix.android.sdk.api.session.Session class FakeSession( @@ -25,7 +29,19 @@ class FakeSession( val fakeSharedSecretStorageService: FakeSharedSecretStorageService = FakeSharedSecretStorageService() ) : Session by mockk(relaxed = true) { + init { + mockkStatic("im.vector.app.core.extensions.SessionKt") + } + override fun cryptoService() = fakeCryptoService override val sharedSecretStorageService = fakeSharedSecretStorageService override val coroutineDispatchers = testCoroutineDispatchers + + fun givenVectorStore(vectorSessionStore: VectorSessionStore) { + coEvery { + this@FakeSession.vectorStore(any()) + } coAnswers { + vectorSessionStore + } + } } diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeVectorStore.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeVectorStore.kt new file mode 100644 index 0000000000..22a4a5f6cf --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeVectorStore.kt @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 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.test.fakes + +import im.vector.app.features.onboarding.FtueUseCase +import im.vector.app.features.session.VectorSessionStore +import io.mockk.coEvery +import io.mockk.mockk + +class FakeVectorStore { + val instance = mockk() + + fun givenUseCase(useCase: FtueUseCase?) { + coEvery { + instance.readUseCase() + } coAnswers { + useCase + } + } +} From f1f8f518052af3259f2d611cee15945f069287cb Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 15 Feb 2022 12:26:08 +0000 Subject: [PATCH 095/302] lifting the global scope to a provide to allow for unit testing the analytics impl --- .../im/vector/app/core/di/NamedGlobalScope.kt | 23 +++++++++++++++++++ .../im/vector/app/core/di/SingletonModule.kt | 8 +++++++ .../analytics/impl/DefaultVectorAnalytics.kt | 12 +++++----- 3 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/di/NamedGlobalScope.kt diff --git a/vector/src/main/java/im/vector/app/core/di/NamedGlobalScope.kt b/vector/src/main/java/im/vector/app/core/di/NamedGlobalScope.kt new file mode 100644 index 0000000000..cc1ac829a1 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/di/NamedGlobalScope.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 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.core.di + +import javax.inject.Qualifier + +@Qualifier +@Retention(AnnotationRetention.RUNTIME) +annotation class NamedGlobalScope diff --git a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt index 0e19cd4388..94d8df3692 100644 --- a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt @@ -46,6 +46,7 @@ import im.vector.app.features.ui.SharedPreferencesUiStateRepository import im.vector.app.features.ui.UiStateRepository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.SupervisorJob import org.matrix.android.sdk.api.Matrix import org.matrix.android.sdk.api.auth.AuthenticationService @@ -147,4 +148,11 @@ object VectorStaticModule { fun providesCoroutineDispatchers(): CoroutineDispatchers { return CoroutineDispatchers(io = Dispatchers.IO, computation = Dispatchers.Default) } + + @Suppress("EXPERIMENTAL_API_USAGE") + @Provides + @NamedGlobalScope + fun providesGlobalScope(): CoroutineScope { + return GlobalScope + } } diff --git a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt index 6dbf412d83..3694ef7e09 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt @@ -22,13 +22,14 @@ import com.posthog.android.PostHog import com.posthog.android.Properties import im.vector.app.BuildConfig import im.vector.app.config.analyticsConfig +import im.vector.app.core.di.NamedGlobalScope import im.vector.app.features.analytics.VectorAnalytics import im.vector.app.features.analytics.itf.VectorAnalyticsEvent import im.vector.app.features.analytics.itf.VectorAnalyticsScreen import im.vector.app.features.analytics.log.analyticsTag import im.vector.app.features.analytics.plan.UserProperties import im.vector.app.features.analytics.store.AnalyticsStore -import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -42,7 +43,8 @@ private val IGNORED_OPTIONS: Options? = null @Singleton class DefaultVectorAnalytics @Inject constructor( private val context: Context, - private val analyticsStore: AnalyticsStore + private val analyticsStore: AnalyticsStore, + @NamedGlobalScope private val globalScope: CoroutineScope ) : VectorAnalytics { private var posthog: PostHog? = null @@ -88,7 +90,6 @@ class DefaultVectorAnalytics @Inject constructor( createAnalyticsClient() } - @Suppress("EXPERIMENTAL_API_USAGE") private fun observeAnalyticsId() { getAnalyticsId() .onEach { id -> @@ -96,7 +97,7 @@ class DefaultVectorAnalytics @Inject constructor( analyticsId = id identifyPostHog() } - .launchIn(GlobalScope) + .launchIn(globalScope) } private fun identifyPostHog() { @@ -110,7 +111,6 @@ class DefaultVectorAnalytics @Inject constructor( } } - @Suppress("EXPERIMENTAL_API_USAGE") private fun observeUserConsent() { getUserConsent() .onEach { consent -> @@ -118,7 +118,7 @@ class DefaultVectorAnalytics @Inject constructor( userConsent = consent optOutPostHog() } - .launchIn(GlobalScope) + .launchIn(globalScope) } private fun optOutPostHog() { From 837caabcec07ec31cb2efeed5b1f57da94bb7310 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 15 Feb 2022 12:51:21 +0000 Subject: [PATCH 096/302] providing the posthog creation and analytics config via hilt in order to make the analytics impl testable --- .../im/vector/app/core/di/SingletonModule.kt | 7 +++ .../analytics/impl/DefaultVectorAnalytics.kt | 33 ++---------- .../features/analytics/impl/PostHogFactory.kt | 52 +++++++++++++++++++ 3 files changed, 64 insertions(+), 28 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/analytics/impl/PostHogFactory.kt diff --git a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt index 94d8df3692..56ae63a682 100644 --- a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt @@ -28,11 +28,13 @@ import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import im.vector.app.EmojiCompatWrapper import im.vector.app.EmojiSpanify +import im.vector.app.config.analyticsConfig import im.vector.app.core.dispatchers.CoroutineDispatchers import im.vector.app.core.error.DefaultErrorFormatter import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.time.Clock import im.vector.app.core.time.DefaultClock +import im.vector.app.features.analytics.AnalyticsConfig import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.VectorAnalytics import im.vector.app.features.analytics.impl.DefaultVectorAnalytics @@ -155,4 +157,9 @@ object VectorStaticModule { fun providesGlobalScope(): CoroutineScope { return GlobalScope } + + @Provides + fun providesAnalyticsConfig(): AnalyticsConfig { + return analyticsConfig + } } diff --git a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt index 3694ef7e09..2cbdbf5b5f 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt @@ -16,13 +16,11 @@ package im.vector.app.features.analytics.impl -import android.content.Context import com.posthog.android.Options import com.posthog.android.PostHog import com.posthog.android.Properties -import im.vector.app.BuildConfig -import im.vector.app.config.analyticsConfig import im.vector.app.core.di.NamedGlobalScope +import im.vector.app.features.analytics.AnalyticsConfig import im.vector.app.features.analytics.VectorAnalytics import im.vector.app.features.analytics.itf.VectorAnalyticsEvent import im.vector.app.features.analytics.itf.VectorAnalyticsScreen @@ -42,8 +40,9 @@ private val IGNORED_OPTIONS: Options? = null @Singleton class DefaultVectorAnalytics @Inject constructor( - private val context: Context, + private val postHogFactory: PostHogFactory, private val analyticsStore: AnalyticsStore, + private val analyticsConfig: AnalyticsConfig, @NamedGlobalScope private val globalScope: CoroutineScope ) : VectorAnalytics { private var posthog: PostHog? = null @@ -85,9 +84,9 @@ class DefaultVectorAnalytics @Inject constructor( } override fun init() { + createAnalyticsClient() observeUserConsent() observeAnalyticsId() - createAnalyticsClient() } private fun observeAnalyticsId() { @@ -133,34 +132,12 @@ class DefaultVectorAnalytics @Inject constructor( return } - posthog = PostHog.Builder(context, analyticsConfig.postHogApiKey, analyticsConfig.postHogHost) - // Record certain application events automatically! (off/false by default) - // .captureApplicationLifecycleEvents() - // Record screen views automatically! (off/false by default) - // .recordScreenViews() - // Capture deep links as part of the screen call. (off by default) - // .captureDeepLinks() - // Maximum number of events to keep in queue before flushing (default 20) - // .flushQueueSize(20) - // Max delay before flushing the queue (30 seconds) - // .flushInterval(30, TimeUnit.SECONDS) - // Enable or disable collection of ANDROID_ID (true) - .collectDeviceId(false) - .logLevel(getLogLevel()) - .build() + posthog = postHogFactory.createPosthog() optOutPostHog() identifyPostHog() } - private fun getLogLevel(): PostHog.LogLevel { - return if (BuildConfig.DEBUG) { - PostHog.LogLevel.DEBUG - } else { - PostHog.LogLevel.INFO - } - } - override fun capture(event: VectorAnalyticsEvent) { Timber.tag(analyticsTag.value).d("capture($event)") posthog diff --git a/vector/src/main/java/im/vector/app/features/analytics/impl/PostHogFactory.kt b/vector/src/main/java/im/vector/app/features/analytics/impl/PostHogFactory.kt new file mode 100644 index 0000000000..029732f76c --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/analytics/impl/PostHogFactory.kt @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 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.analytics.impl + +import android.content.Context +import com.posthog.android.PostHog +import im.vector.app.BuildConfig +import im.vector.app.config.analyticsConfig +import javax.inject.Inject + +class PostHogFactory @Inject constructor(private val context: Context) { + + fun createPosthog(): PostHog { + return PostHog.Builder(context, analyticsConfig.postHogApiKey, analyticsConfig.postHogHost) + // Record certain application events automatically! (off/false by default) + // .captureApplicationLifecycleEvents() + // Record screen views automatically! (off/false by default) + // .recordScreenViews() + // Capture deep links as part of the screen call. (off by default) + // .captureDeepLinks() + // Maximum number of events to keep in queue before flushing (default 20) + // .flushQueueSize(20) + // Max delay before flushing the queue (30 seconds) + // .flushInterval(30, TimeUnit.SECONDS) + // Enable or disable collection of ANDROID_ID (true) + .collectDeviceId(false) + .logLevel(getLogLevel()) + .build() + } + + private fun getLogLevel(): PostHog.LogLevel { + return if (BuildConfig.DEBUG) { + PostHog.LogLevel.DEBUG + } else { + PostHog.LogLevel.INFO + } + } +} From e36e67c54cbc82e3cd15c5117a7c91a374176bcc Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 15 Feb 2022 14:23:26 +0000 Subject: [PATCH 097/302] adding unit tests around the analytics impl --- .../analytics/impl/DefaultVectorAnalytics.kt | 4 + .../impl/DefaultVectorAnalyticsTest.kt | 144 ++++++++++++++++++ .../app/test/fakes/FakeAnalyticsStore.kt | 58 +++++++ .../im/vector/app/test/fakes/FakePostHog.kt | 75 +++++++++ .../app/test/fakes/FakePostHogFactory.kt | 28 ++++ .../test/fixtures/AnalyticsConfigFixture.kt | 33 ++++ 6 files changed, 342 insertions(+) create mode 100644 vector/src/test/java/im/vector/app/features/analytics/impl/DefaultVectorAnalyticsTest.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeAnalyticsStore.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakePostHog.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakePostHogFactory.kt create mode 100644 vector/src/test/java/im/vector/app/test/fixtures/AnalyticsConfigFixture.kt diff --git a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt index 2cbdbf5b5f..37649d7c39 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt @@ -113,6 +113,7 @@ class DefaultVectorAnalytics @Inject constructor( private fun observeUserConsent() { getUserConsent() .onEach { consent -> + println("!!!, got consent: $consent") Timber.tag(analyticsTag.value).d("User consent updated to $consent") userConsent = consent optOutPostHog() @@ -147,6 +148,9 @@ class DefaultVectorAnalytics @Inject constructor( override fun screen(screen: VectorAnalyticsScreen) { Timber.tag(analyticsTag.value).d("screen($screen)") + + println("userconsnet: $userConsent") + posthog ?.takeIf { userConsent == true } ?.screen(screen.getName(), screen.getProperties()?.toPostHogProperties()) diff --git a/vector/src/test/java/im/vector/app/features/analytics/impl/DefaultVectorAnalyticsTest.kt b/vector/src/test/java/im/vector/app/features/analytics/impl/DefaultVectorAnalyticsTest.kt new file mode 100644 index 0000000000..2680979d7e --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/analytics/impl/DefaultVectorAnalyticsTest.kt @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2022 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.analytics.impl + +import com.posthog.android.Properties +import im.vector.app.features.analytics.itf.VectorAnalyticsEvent +import im.vector.app.features.analytics.itf.VectorAnalyticsScreen +import im.vector.app.test.fakes.FakeAnalyticsStore +import im.vector.app.test.fakes.FakePostHog +import im.vector.app.test.fakes.FakePostHogFactory +import im.vector.app.test.fixtures.AnalyticsConfigFixture.anAnalyticsConfig +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runBlockingTest +import org.junit.Before +import org.junit.Test + +private const val AN_ANALYTICS_ID = "analytics-id" +private val A_SCREEN_EVENT = object : VectorAnalyticsScreen { + override fun getName() = "a-screen-event-name" + override fun getProperties() = mapOf("property-name" to "property-value") +} +private val AN_EVENT = object : VectorAnalyticsEvent { + override fun getName() = "an-event-name" + override fun getProperties() = mapOf("property-name" to "property-value") +} + +@OptIn(ExperimentalCoroutinesApi::class) +class DefaultVectorAnalyticsTest { + + private val fakePostHog = FakePostHog() + private val fakeAnalyticsStore = FakeAnalyticsStore() + + private val defaultVectorAnalytics = DefaultVectorAnalytics( + postHogFactory = FakePostHogFactory(fakePostHog.instance).instance, + analyticsStore = fakeAnalyticsStore.instance, + globalScope = CoroutineScope(Dispatchers.Unconfined), + analyticsConfig = anAnalyticsConfig(isEnabled = true) + ) + + @Before + fun setUp() { + defaultVectorAnalytics.init() + } + + @Test + fun `when setting user consent then updates analytics store`() = runBlockingTest { + defaultVectorAnalytics.setUserConsent(true) + + fakeAnalyticsStore.verifyConsentUpdated(updatedValue = true) + } + + @Test + fun `when consenting to analytics then updates posthog opt out to false`() = runBlockingTest { + fakeAnalyticsStore.givenUserContent(consent = true) + + fakePostHog.verifyOptOutStatus(optedOut = false) + } + + @Test + fun `when revoking consent to analytics then updates posthog opt out to true`() = runBlockingTest { + fakeAnalyticsStore.givenUserContent(consent = false) + + fakePostHog.verifyOptOutStatus(optedOut = true) + } + + @Test + fun `when setting the analytics id then updates analytics store`() = runBlockingTest { + defaultVectorAnalytics.setAnalyticsId(AN_ANALYTICS_ID) + + fakeAnalyticsStore.verifyAnalyticsIdUpdated(updatedValue = AN_ANALYTICS_ID) + } + + @Test + fun `when valid analytics id updates then identify`() = runBlockingTest { + fakeAnalyticsStore.givenAnalyticsId(AN_ANALYTICS_ID) + + fakePostHog.verifyIdentifies(AN_ANALYTICS_ID) + } + + @Test + fun `when signing out analytics id updates then resets`() = runBlockingTest { + fakeAnalyticsStore.allowSettingAnalyticsIdToCallBackingFlow() + + defaultVectorAnalytics.onSignOut() + + fakePostHog.verifyReset() + } + + @Test + fun `given user consent when tracking screen events then submits to posthog`() = runBlockingTest { + fakeAnalyticsStore.givenUserContent(consent = true) + + defaultVectorAnalytics.screen(A_SCREEN_EVENT) + + fakePostHog.verifyScreenTracked(A_SCREEN_EVENT.getName(), Properties().also { + it.putAll(A_SCREEN_EVENT.getProperties()) + }) + } + + @Test + fun `given user has not consented when tracking screen events then does not track`() = runBlockingTest { + fakeAnalyticsStore.givenUserContent(consent = false) + + defaultVectorAnalytics.screen(A_SCREEN_EVENT) + + fakePostHog.verifyNoScreenTracking() + } + + @Test + fun `given user consent when tracking events then submits to posthog`() = runBlockingTest { + fakeAnalyticsStore.givenUserContent(consent = true) + + defaultVectorAnalytics.capture(AN_EVENT) + + fakePostHog.verifyEventTracked(AN_EVENT.getName(), Properties().also { + it.putAll(AN_EVENT.getProperties()) + }) + } + + @Test + fun `given user has not consented when tracking events then does not track`() = runBlockingTest { + fakeAnalyticsStore.givenUserContent(consent = false) + + defaultVectorAnalytics.capture(AN_EVENT) + + fakePostHog.verifyNoEventTracking() + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeAnalyticsStore.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeAnalyticsStore.kt new file mode 100644 index 0000000000..6304da8d37 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeAnalyticsStore.kt @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022 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.test.fakes + +import im.vector.app.features.analytics.store.AnalyticsStore +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.runBlocking + +class FakeAnalyticsStore { + + private val _consentFlow = MutableSharedFlow() + private val _idFlow = MutableSharedFlow() + + val instance = mockk(relaxed = true) { + every { userConsentFlow } returns _consentFlow + every { analyticsIdFlow } returns _idFlow + } + + fun allowSettingAnalyticsIdToCallBackingFlow() { + coEvery { instance.setAnalyticsId(any()) } answers { + runBlocking { _idFlow.emit(firstArg()) } + } + } + + fun verifyConsentUpdated(updatedValue: Boolean) { + coVerify { instance.setUserConsent(updatedValue) } + } + + suspend fun givenUserContent(consent: Boolean) { + _consentFlow.emit(consent) + } + + fun verifyAnalyticsIdUpdated(updatedValue: String) { + coVerify { instance.setAnalyticsId(updatedValue) } + } + + suspend fun givenAnalyticsId(id: String) { + _idFlow.emit(id) + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakePostHog.kt b/vector/src/test/java/im/vector/app/test/fakes/FakePostHog.kt new file mode 100644 index 0000000000..631e09aada --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakePostHog.kt @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2022 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.test.fakes + +import android.os.Looper +import com.posthog.android.PostHog +import com.posthog.android.Properties +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.verify + +class FakePostHog { + + init { + // workaround to avoid PostHog.HANDLER failing + mockkStatic(Looper::class) + val looper = mockk { + every { thread } returns Thread.currentThread() + } + every { Looper.getMainLooper() } returns looper + } + + val instance = mockk(relaxed = true) + + fun verifyOptOutStatus(optedOut: Boolean) { + verify { instance.optOut(optedOut) } + } + + fun verifyIdentifies(analyticsId: String) { + verify { instance.identify(analyticsId) } + } + + fun verifyReset() { + verify { instance.reset() } + } + + fun verifyScreenTracked(name: String, properties: Properties) { + verify { instance.screen(name, properties) } + } + + fun verifyNoScreenTracking() { + verify(exactly = 0) { + instance.screen(any()) + instance.screen(any(), any()) + instance.screen(any(), any(), any()) + } + } + + fun verifyEventTracked(name: String, properties: Properties) { + verify { instance.capture(name, properties) } + } + + fun verifyNoEventTracking() { + verify(exactly = 0) { + instance.capture(any()) + instance.capture(any(), any()) + instance.capture(any(), any(), any()) + } + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakePostHogFactory.kt b/vector/src/test/java/im/vector/app/test/fakes/FakePostHogFactory.kt new file mode 100644 index 0000000000..1d18c97d32 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakePostHogFactory.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 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.test.fakes + +import com.posthog.android.PostHog +import im.vector.app.features.analytics.impl.PostHogFactory +import io.mockk.every +import io.mockk.mockk + +class FakePostHogFactory(postHog: PostHog) { + val instance = mockk().also { + every { it.createPosthog() } returns postHog + } +} diff --git a/vector/src/test/java/im/vector/app/test/fixtures/AnalyticsConfigFixture.kt b/vector/src/test/java/im/vector/app/test/fixtures/AnalyticsConfigFixture.kt new file mode 100644 index 0000000000..5fbcdd98d1 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fixtures/AnalyticsConfigFixture.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 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.test.fixtures + +import im.vector.app.features.analytics.AnalyticsConfig + +object AnalyticsConfigFixture { + fun anAnalyticsConfig( + isEnabled: Boolean = false, + postHogHost: String = "http://posthog.url", + postHogApiKey: String = "api-key", + policyLink: String = "http://policy.link" + ) = object : AnalyticsConfig { + override val isEnabled: Boolean = isEnabled + override val postHogHost = postHogHost + override val postHogApiKey = postHogApiKey + override val policyLink = policyLink + } +} From 3236d87323c63b76b46c96e8697a780548c9ea47 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 15 Feb 2022 15:39:05 +0000 Subject: [PATCH 098/302] inlining posthog creation and removing eager optout and identify calls as the backing values are null which means they aren't actually being called --- .../analytics/impl/DefaultVectorAnalytics.kt | 42 +++++++------------ 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt index 37649d7c39..1ccdbd8bbc 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt @@ -40,17 +40,29 @@ private val IGNORED_OPTIONS: Options? = null @Singleton class DefaultVectorAnalytics @Inject constructor( - private val postHogFactory: PostHogFactory, + postHogFactory: PostHogFactory, + analyticsConfig: AnalyticsConfig, private val analyticsStore: AnalyticsStore, - private val analyticsConfig: AnalyticsConfig, @NamedGlobalScope private val globalScope: CoroutineScope ) : VectorAnalytics { - private var posthog: PostHog? = null + + private val posthog: PostHog? = when { + analyticsConfig.isEnabled -> postHogFactory.createPosthog() + else -> { + Timber.tag(analyticsTag.value).w("Analytics is disabled") + null + } + } // Cache for the store values private var userConsent: Boolean? = null private var analyticsId: String? = null + override fun init() { + observeUserConsent() + observeAnalyticsId() + } + override fun getUserConsent(): Flow { return analyticsStore.userConsentFlow } @@ -83,12 +95,6 @@ class DefaultVectorAnalytics @Inject constructor( setAnalyticsId("") } - override fun init() { - createAnalyticsClient() - observeUserConsent() - observeAnalyticsId() - } - private fun observeAnalyticsId() { getAnalyticsId() .onEach { id -> @@ -113,7 +119,6 @@ class DefaultVectorAnalytics @Inject constructor( private fun observeUserConsent() { getUserConsent() .onEach { consent -> - println("!!!, got consent: $consent") Timber.tag(analyticsTag.value).d("User consent updated to $consent") userConsent = consent optOutPostHog() @@ -125,20 +130,6 @@ class DefaultVectorAnalytics @Inject constructor( userConsent?.let { posthog?.optOut(!it) } } - private fun createAnalyticsClient() { - Timber.tag(analyticsTag.value).d("createAnalyticsClient()") - - if (analyticsConfig.isEnabled.not()) { - Timber.tag(analyticsTag.value).w("Analytics is disabled") - return - } - - posthog = postHogFactory.createPosthog() - - optOutPostHog() - identifyPostHog() - } - override fun capture(event: VectorAnalyticsEvent) { Timber.tag(analyticsTag.value).d("capture($event)") posthog @@ -148,9 +139,6 @@ class DefaultVectorAnalytics @Inject constructor( override fun screen(screen: VectorAnalyticsScreen) { Timber.tag(analyticsTag.value).d("screen($screen)") - - println("userconsnet: $userConsent") - posthog ?.takeIf { userConsent == true } ?.screen(screen.getName(), screen.getProperties()?.toPostHogProperties()) From d99a2f8d14d4c19d2c53c22b9f019d945744c9df Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 15 Feb 2022 16:03:21 +0000 Subject: [PATCH 099/302] creating and passing stored user properties on post hog initialisation - this allows information captured during the onboarding to be sent once the user has opt'd in --- .../analytics/impl/DefaultVectorAnalytics.kt | 5 +- .../impl/DefaultVectorAnalyticsTest.kt | 47 ++++++++++++------- .../FakeLateInitUserPropertiesFactory.kt | 31 ++++++++++++ .../im/vector/app/test/fakes/FakePostHog.kt | 14 ++++-- .../test/fixtures/UserPropertiesFixture.kt | 26 ++++++++++ .../test/fixtures/VectorAnalyticsFixture.kt | 36 ++++++++++++++ 6 files changed, 135 insertions(+), 24 deletions(-) create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeLateInitUserPropertiesFactory.kt create mode 100644 vector/src/test/java/im/vector/app/test/fixtures/UserPropertiesFixture.kt create mode 100644 vector/src/test/java/im/vector/app/test/fixtures/VectorAnalyticsFixture.kt diff --git a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt index 1ccdbd8bbc..7b653ef44b 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt @@ -43,6 +43,7 @@ class DefaultVectorAnalytics @Inject constructor( postHogFactory: PostHogFactory, analyticsConfig: AnalyticsConfig, private val analyticsStore: AnalyticsStore, + private val lateInitUserPropertiesFactory: LateInitUserPropertiesFactory, @NamedGlobalScope private val globalScope: CoroutineScope ) : VectorAnalytics { @@ -105,14 +106,14 @@ class DefaultVectorAnalytics @Inject constructor( .launchIn(globalScope) } - private fun identifyPostHog() { + private suspend fun identifyPostHog() { val id = analyticsId ?: return if (id.isEmpty()) { Timber.tag(analyticsTag.value).d("reset") posthog?.reset() } else { Timber.tag(analyticsTag.value).d("identify") - posthog?.identify(id) + posthog?.identify(id, lateInitUserPropertiesFactory.createUserProperties()?.getProperties()?.toPostHogUserProperties(), IGNORED_OPTIONS) } } diff --git a/vector/src/test/java/im/vector/app/features/analytics/impl/DefaultVectorAnalyticsTest.kt b/vector/src/test/java/im/vector/app/features/analytics/impl/DefaultVectorAnalyticsTest.kt index 2680979d7e..b17c1a8bba 100644 --- a/vector/src/test/java/im/vector/app/features/analytics/impl/DefaultVectorAnalyticsTest.kt +++ b/vector/src/test/java/im/vector/app/features/analytics/impl/DefaultVectorAnalyticsTest.kt @@ -20,9 +20,13 @@ import com.posthog.android.Properties import im.vector.app.features.analytics.itf.VectorAnalyticsEvent import im.vector.app.features.analytics.itf.VectorAnalyticsScreen import im.vector.app.test.fakes.FakeAnalyticsStore +import im.vector.app.test.fakes.FakeLateInitUserPropertiesFactory import im.vector.app.test.fakes.FakePostHog import im.vector.app.test.fakes.FakePostHogFactory import im.vector.app.test.fixtures.AnalyticsConfigFixture.anAnalyticsConfig +import im.vector.app.test.fixtures.aUserProperties +import im.vector.app.test.fixtures.aVectorAnalyticsEvent +import im.vector.app.test.fixtures.aVectorAnalyticsScreen import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -31,26 +35,23 @@ import org.junit.Before import org.junit.Test private const val AN_ANALYTICS_ID = "analytics-id" -private val A_SCREEN_EVENT = object : VectorAnalyticsScreen { - override fun getName() = "a-screen-event-name" - override fun getProperties() = mapOf("property-name" to "property-value") -} -private val AN_EVENT = object : VectorAnalyticsEvent { - override fun getName() = "an-event-name" - override fun getProperties() = mapOf("property-name" to "property-value") -} +private val A_SCREEN_EVENT = aVectorAnalyticsScreen() +private val AN_EVENT = aVectorAnalyticsEvent() +private val A_LATE_INIT_USER_PROPERTIES = aUserProperties() @OptIn(ExperimentalCoroutinesApi::class) class DefaultVectorAnalyticsTest { private val fakePostHog = FakePostHog() private val fakeAnalyticsStore = FakeAnalyticsStore() + private val fakeLateInitUserPropertiesFactory = FakeLateInitUserPropertiesFactory() private val defaultVectorAnalytics = DefaultVectorAnalytics( postHogFactory = FakePostHogFactory(fakePostHog.instance).instance, analyticsStore = fakeAnalyticsStore.instance, globalScope = CoroutineScope(Dispatchers.Unconfined), - analyticsConfig = anAnalyticsConfig(isEnabled = true) + analyticsConfig = anAnalyticsConfig(isEnabled = true), + lateInitUserPropertiesFactory = fakeLateInitUserPropertiesFactory.instance ) @Before @@ -87,14 +88,16 @@ class DefaultVectorAnalyticsTest { } @Test - fun `when valid analytics id updates then identify`() = runBlockingTest { + fun `given lateinit user properties when valid analytics id updates then identify with lateinit properties`() = runBlockingTest { + fakeLateInitUserPropertiesFactory.givenCreatesProperties(A_LATE_INIT_USER_PROPERTIES) + fakeAnalyticsStore.givenAnalyticsId(AN_ANALYTICS_ID) - fakePostHog.verifyIdentifies(AN_ANALYTICS_ID) + fakePostHog.verifyIdentifies(AN_ANALYTICS_ID, A_LATE_INIT_USER_PROPERTIES) } @Test - fun `when signing out analytics id updates then resets`() = runBlockingTest { + fun `when signing out then resets posthog`() = runBlockingTest { fakeAnalyticsStore.allowSettingAnalyticsIdToCallBackingFlow() defaultVectorAnalytics.onSignOut() @@ -108,9 +111,7 @@ class DefaultVectorAnalyticsTest { defaultVectorAnalytics.screen(A_SCREEN_EVENT) - fakePostHog.verifyScreenTracked(A_SCREEN_EVENT.getName(), Properties().also { - it.putAll(A_SCREEN_EVENT.getProperties()) - }) + fakePostHog.verifyScreenTracked(A_SCREEN_EVENT.getName(), A_SCREEN_EVENT.toPostHogProperties()) } @Test @@ -128,9 +129,7 @@ class DefaultVectorAnalyticsTest { defaultVectorAnalytics.capture(AN_EVENT) - fakePostHog.verifyEventTracked(AN_EVENT.getName(), Properties().also { - it.putAll(AN_EVENT.getProperties()) - }) + fakePostHog.verifyEventTracked(AN_EVENT.getName(), AN_EVENT.toPostHogProperties()) } @Test @@ -142,3 +141,15 @@ class DefaultVectorAnalyticsTest { fakePostHog.verifyNoEventTracking() } } + +private fun VectorAnalyticsScreen.toPostHogProperties(): Properties? { + return getProperties()?.let { properties -> + Properties().also { it.putAll(properties) } + } +} + +private fun VectorAnalyticsEvent.toPostHogProperties(): Properties? { + return getProperties()?.let { properties -> + Properties().also { it.putAll(properties) } + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeLateInitUserPropertiesFactory.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeLateInitUserPropertiesFactory.kt new file mode 100644 index 0000000000..9b442ece73 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeLateInitUserPropertiesFactory.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 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.test.fakes + +import im.vector.app.features.analytics.impl.LateInitUserPropertiesFactory +import im.vector.app.features.analytics.plan.UserProperties +import io.mockk.coEvery +import io.mockk.mockk + +class FakeLateInitUserPropertiesFactory { + + val instance = mockk() + + fun givenCreatesProperties(userProperties: UserProperties?) { + coEvery { instance.createUserProperties() } returns userProperties + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakePostHog.kt b/vector/src/test/java/im/vector/app/test/fakes/FakePostHog.kt index 631e09aada..e14f809e66 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakePostHog.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakePostHog.kt @@ -19,6 +19,7 @@ package im.vector.app.test.fakes import android.os.Looper import com.posthog.android.PostHog import com.posthog.android.Properties +import im.vector.app.features.analytics.plan.UserProperties import io.mockk.every import io.mockk.mockk import io.mockk.mockkStatic @@ -41,15 +42,20 @@ class FakePostHog { verify { instance.optOut(optedOut) } } - fun verifyIdentifies(analyticsId: String) { - verify { instance.identify(analyticsId) } + fun verifyIdentifies(analyticsId: String, userProperties: UserProperties?) { + verify { + val postHogProperties = userProperties?.getProperties() + ?.let { rawProperties -> Properties().also { it.putAll(rawProperties) } } + ?.takeIf { it.isNotEmpty() } + instance.identify(analyticsId, postHogProperties, null) + } } fun verifyReset() { verify { instance.reset() } } - fun verifyScreenTracked(name: String, properties: Properties) { + fun verifyScreenTracked(name: String, properties: Properties?) { verify { instance.screen(name, properties) } } @@ -61,7 +67,7 @@ class FakePostHog { } } - fun verifyEventTracked(name: String, properties: Properties) { + fun verifyEventTracked(name: String, properties: Properties?) { verify { instance.capture(name, properties) } } diff --git a/vector/src/test/java/im/vector/app/test/fixtures/UserPropertiesFixture.kt b/vector/src/test/java/im/vector/app/test/fixtures/UserPropertiesFixture.kt new file mode 100644 index 0000000000..5a911e2bc9 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fixtures/UserPropertiesFixture.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 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.test.fixtures + +import im.vector.app.features.analytics.plan.UserProperties +import im.vector.app.features.analytics.plan.UserProperties.FtueUseCaseSelection + +fun aUserProperties( + ftueUseCase: FtueUseCaseSelection? = FtueUseCaseSelection.Skip +) = UserProperties( + ftueUseCaseSelection = ftueUseCase +) diff --git a/vector/src/test/java/im/vector/app/test/fixtures/VectorAnalyticsFixture.kt b/vector/src/test/java/im/vector/app/test/fixtures/VectorAnalyticsFixture.kt new file mode 100644 index 0000000000..95590b0a44 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fixtures/VectorAnalyticsFixture.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 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.test.fixtures + +import im.vector.app.features.analytics.itf.VectorAnalyticsEvent +import im.vector.app.features.analytics.itf.VectorAnalyticsScreen + +fun aVectorAnalyticsScreen( + name: String = "a-screen-name", + properties: Map? = null +) = object : VectorAnalyticsScreen { + override fun getName() = name + override fun getProperties() = properties +} + +fun aVectorAnalyticsEvent( + name: String = "an-event-name", + properties: Map? = null +) = object : VectorAnalyticsEvent { + override fun getName() = name + override fun getProperties() = properties +} From 3c226002a03f8c472fd2b955cd614f08f818d070 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 15 Feb 2022 16:24:22 +0000 Subject: [PATCH 100/302] adding changelog entry --- changelog.d/5234.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5234.bugfix diff --git a/changelog.d/5234.bugfix b/changelog.d/5234.bugfix new file mode 100644 index 0000000000..2b5d4dee37 --- /dev/null +++ b/changelog.d/5234.bugfix @@ -0,0 +1 @@ +Analytics: Fixes missing use case identity values from within the onboarding flow \ No newline at end of file From 29088acdb324c447951dacbac8d619077cf15a5a Mon Sep 17 00:00:00 2001 From: NIkita Fedrunov Date: Wed, 2 Feb 2022 11:29:27 +0100 Subject: [PATCH 101/302] Code review fixes --- .../java/im/vector/app/EspressoExt.kt | 1 + .../vector/app/ui/UiAllScreensSanityTest.kt | 147 ++++++------ .../im/vector/app/ui/robot/ElementRobot.kt | 1 + .../java/im/vector/app/ui/robot/SpaceRobot.kt | 214 ------------------ .../app/ui/robot/space/SpaceCreateRobot.kt | 102 +++++++++ .../app/ui/robot/space/SpaceMenuRobot.kt | 116 ++++++++++ .../vector/app/ui/robot/space/SpaceRobot.kt | 38 ++++ .../app/ui/robot/space/SpaceSettingsRobot.kt | 68 ++++++ 8 files changed, 401 insertions(+), 286 deletions(-) delete mode 100644 vector/src/androidTest/java/im/vector/app/ui/robot/SpaceRobot.kt create mode 100644 vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceCreateRobot.kt create mode 100644 vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceMenuRobot.kt create mode 100644 vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceRobot.kt create mode 100644 vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceSettingsRobot.kt diff --git a/vector/src/androidTest/java/im/vector/app/EspressoExt.kt b/vector/src/androidTest/java/im/vector/app/EspressoExt.kt index 59ad122f36..1c3799f81d 100644 --- a/vector/src/androidTest/java/im/vector/app/EspressoExt.kt +++ b/vector/src/androidTest/java/im/vector/app/EspressoExt.kt @@ -195,6 +195,7 @@ fun activityIdlingResource(activityClass: Class<*>): IdlingResource { println("*** [$name] onActivityLifecycleChanged callback: $callback") callback?.onTransitionToIdle() } + else -> {} } } } diff --git a/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt b/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt index 8d1f93bc1a..1f47f3a798 100644 --- a/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt +++ b/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt @@ -20,13 +20,9 @@ import androidx.test.espresso.IdlingPolicies import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest -import com.adevinta.android.barista.interaction.BaristaDrawerInteractions.openDrawer -import im.vector.app.R import im.vector.app.espresso.tools.ScreenshotFailureRule import im.vector.app.features.MainActivity -import im.vector.app.getString import im.vector.app.ui.robot.ElementRobot -import im.vector.app.ui.robot.withDeveloperMode import org.junit.Rule import org.junit.Test import org.junit.rules.RuleChain @@ -56,88 +52,95 @@ class UiAllScreensSanityTest { fun allScreensTest() { IdlingPolicies.setMasterPolicyTimeout(120, TimeUnit.SECONDS) - elementRobot.onboarding { - crawl() - } +// elementRobot.onboarding { +// crawl() +// } // Create an account - val userId = "UiTest_" + UUID.randomUUID().toString() - elementRobot.signUp(userId) +// val userId = "UiTest_" + UUID.randomUUID().toString() +// elementRobot.signUp(userId) - elementRobot.settings { - general { crawl() } - notifications { crawl() } - preferences { crawl() } - voiceAndVideo() - ignoredUsers() - // TODO Test analytics - securityAndPrivacy { crawl() } - labs() - advancedSettings { crawl() } - // TODO Rework this part (Legals, etc.) - // helpAndAbout { crawl() } - } +// elementRobot.settings { +// general { crawl() } +// notifications { crawl() } +// preferences { crawl() } +// voiceAndVideo() +// ignoredUsers() +// // TODO Test analytics +// securityAndPrivacy { crawl() } +// labs() +// advancedSettings { crawl() } +// // TODO Rework this part (Legals, etc.) +// // helpAndAbout { crawl() } +// } - elementRobot.newDirectMessage { - verifyQrCodeButton() - verifyInviteFriendsButton() - } +// elementRobot.newDirectMessage { +// verifyQrCodeButton() +// verifyInviteFriendsButton() +// } - elementRobot.newRoom { - createNewRoom { - crawl() - createRoom { - val message = "Hello world!" - postMessage(message) - crawl() - crawlMessage(message) - openSettings { crawl() } - } - } - } +// elementRobot.newRoom { +// createNewRoom { +// crawl() +// createRoom { +// val message = "Hello world!" +// postMessage(message) +// crawl() +// crawlMessage(message) +// openSettings { crawl() } +// } +// } +// } elementRobot.space { - openDrawer() - createSpace() - openDrawer() - openSpaceMenu() - invitePeople() - openSpaceMenu() - spaceMembers() - spaceSettings() - exploreRooms() - addRoom() - openSpaceMenu() - addSpace() - openSpaceMenu() - leaveSpace() - } - - elementRobot.withDeveloperMode { - settings { - advancedSettings { crawlDeveloperOptions() } + createSpace { + crawl() } - roomList { - openRoom(getString(R.string.room_displayname_empty_room)) { - val message = "Test view source" - postMessage(message) - openMessageMenu(message) { - viewSource() - } + val spaceName = UUID.randomUUID().toString() + createSpace { + createPublicSpace(spaceName) + } + + spaceMenu(spaceName) { + spaceMembers() + spaceSettings { + crawl() } + exploreRooms() + + invitePeople().also { openMenu(spaceName) } + addRoom().also { openMenu(spaceName) } + addSpace().also { openMenu(spaceName) } + + leaveSpace() } } - elementRobot.roomList { - verifyCreatedRoom() - } +// elementRobot.withDeveloperMode { +// settings { +// advancedSettings { crawlDeveloperOptions() } +// } +// roomList { +// openRoom(getString(R.string.room_displayname_empty_room)) { +// val message = "Test view source" +// postMessage(message) +// openMessageMenu(message) { +// viewSource() +// } +// } +// } +// } - elementRobot.signout(expectSignOutWarning = true) +// elementRobot.roomList { +// verifyCreatedRoom() +// } + +// elementRobot.signout(expectSignOutWarning = true) // Login again on the same account - elementRobot.login(userId) - elementRobot.dismissVerificationIfPresent() - // TODO Deactivate account instead of logout? - elementRobot.signout(expectSignOutWarning = false) +// elementRobot.login(userId) +// elementRobot.dismissVerificationIfPresent() +// TODO Deactivate account instead of logout? +// elementRobot.signout(expectSignOutWarning = false) } } diff --git a/vector/src/androidTest/java/im/vector/app/ui/robot/ElementRobot.kt b/vector/src/androidTest/java/im/vector/app/ui/robot/ElementRobot.kt index 4363f69fb9..023ee6ad99 100644 --- a/vector/src/androidTest/java/im/vector/app/ui/robot/ElementRobot.kt +++ b/vector/src/androidTest/java/im/vector/app/ui/robot/ElementRobot.kt @@ -35,6 +35,7 @@ import im.vector.app.features.home.HomeActivity import im.vector.app.features.onboarding.OnboardingActivity import im.vector.app.initialSyncIdlingResource import im.vector.app.ui.robot.settings.SettingsRobot +import im.vector.app.ui.robot.space.SpaceRobot import im.vector.app.withIdlingResource import timber.log.Timber diff --git a/vector/src/androidTest/java/im/vector/app/ui/robot/SpaceRobot.kt b/vector/src/androidTest/java/im/vector/app/ui/robot/SpaceRobot.kt deleted file mode 100644 index 154582f2ad..0000000000 --- a/vector/src/androidTest/java/im/vector/app/ui/robot/SpaceRobot.kt +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2021 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.ui.robot - -import androidx.recyclerview.widget.RecyclerView -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.Espresso.pressBack -import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.action.ViewActions.replaceText -import androidx.test.espresso.contrib.RecyclerViewActions -import androidx.test.espresso.matcher.ViewMatchers -import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility -import androidx.test.espresso.matcher.ViewMatchers.withHint -import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.espresso.matcher.ViewMatchers.withText -import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn -import com.adevinta.android.barista.internal.viewaction.ClickChildAction.clickChildWithId -import im.vector.app.EspressoHelper -import im.vector.app.R -import im.vector.app.espresso.tools.waitUntilActivityVisible -import im.vector.app.espresso.tools.waitUntilDialogVisible -import im.vector.app.espresso.tools.waitUntilViewVisible -import im.vector.app.features.home.HomeActivity -import im.vector.app.features.invite.InviteUsersToRoomActivity -import im.vector.app.features.roomprofile.RoomProfileActivity -import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleActivity -import im.vector.app.features.spaces.SpaceCreationActivity -import im.vector.app.features.spaces.SpaceExploreActivity -import im.vector.app.features.spaces.leave.SpaceLeaveAdvancedActivity -import im.vector.app.features.spaces.manage.SpaceManageActivity -import org.hamcrest.Matchers.allOf -import java.util.UUID - -class SpaceRobot { - - fun createSpace() { - clickOn(R.string.add_space) - waitUntilActivityVisible { - waitUntilViewVisible(withId(R.id.privateButton)) - } - crawlCreate() - - onView(withId(R.id.roomList)) - .perform( - RecyclerViewActions.actionOnItem( - ViewMatchers.hasDescendant(withText(R.string.room_displayname_empty_room)), - click() - ).atPosition(0) - ) - clickOn(R.id.spaceAddRoomSaveItem) - waitUntilActivityVisible { - waitUntilViewVisible(withId(R.id.roomListContainer)) - } - } - - private fun crawlCreate() { - //public - clickOn(R.id.publicButton) - waitUntilViewVisible(withId(R.id.recyclerView)) - onView(withHint(R.string.create_room_name_hint)).perform(replaceText(UUID.randomUUID().toString())) - clickOn(R.id.nextButton) - waitUntilViewVisible(withId(R.id.recyclerView)) - pressBack() - pressBack() - - //private - clickOn(R.id.privateButton) - waitUntilViewVisible(withId(R.id.recyclerView)) - clickOn(R.id.nextButton) - - waitUntilViewVisible(withId(R.id.teammatesButton)) - //me and teammates - clickOn(R.id.teammatesButton) - waitUntilViewVisible(withId(R.id.recyclerView)) - clickOn(R.id.nextButton) - pressBack() - pressBack() - - //just me - waitUntilViewVisible(withId(R.id.justMeButton)) - clickOn(R.id.justMeButton) - waitUntilActivityVisible { - waitUntilViewVisible(withId(R.id.roomList)) - } - } - - fun openSpaceMenu() { - waitUntilViewVisible(withId(R.id.groupListView)) - onView(withId(R.id.groupListView)) - .perform( - RecyclerViewActions.actionOnItem( - ViewMatchers.hasDescendant(allOf(withId(R.id.groupTmpLeave), withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))), - clickChildWithId(R.id.groupTmpLeave) - ).atPosition(0) - ) - waitUntilDialogVisible(withId(R.id.spaceNameView)) - } - - fun invitePeople() { - clickOn(R.id.invitePeople) - waitUntilDialogVisible(withId(R.id.inviteByMxidButton)) - clickOn(R.id.inviteByMxidButton) - waitUntilActivityVisible { - waitUntilViewVisible(withId(R.id.userListRecyclerView)) - } - EspressoHelper.getCurrentActivity()!!.finish() - //close invite dialog - pressBack() - } - - fun spaceMembers() { - clickOn(R.id.showMemberList) - waitUntilActivityVisible { - waitUntilViewVisible(withId(R.id.roomSettingsRecyclerView)) - } - pressBack() - } - - fun spaceSettings() { - clickOn(R.id.spaceSettings) - waitUntilActivityVisible() { - waitUntilViewVisible(withId(R.id.roomSettingsRecyclerView)) - } - crawlSettings() - } - - private fun crawlSettings() { - onView(withId(R.id.roomSettingsRecyclerView)) - .perform( - RecyclerViewActions.actionOnItem( - ViewMatchers.hasDescendant(withText(R.string.room_settings_space_access_title)), - click() - ) - ) - - waitUntilActivityVisible() { - waitUntilViewVisible(withId(R.id.genericRecyclerView)) - } - - pressBack() - - onView(withId(R.id.roomSettingsRecyclerView)) - .perform( - RecyclerViewActions.actionOnItem( - ViewMatchers.hasDescendant(withText(R.string.space_settings_manage_rooms)), - click() - ) - ) - - waitUntilViewVisible(withId(R.id.roomList)) - pressBack() - - onView(withId(R.id.roomSettingsRecyclerView)) - .perform( - RecyclerViewActions.actionOnItem( - ViewMatchers.hasDescendant(withText(R.string.space_settings_permissions_title)), - click() - ) - ) - - waitUntilViewVisible(withId(R.id.roomSettingsRecyclerView)) - pressBack() - pressBack() - } - - fun exploreRooms() { - clickOn(R.id.exploreRooms) - waitUntilActivityVisible { - waitUntilViewVisible(withId(R.id.spaceDirectoryList)) - } - pressBack() - } - - fun addRoom() { - clickOn(R.id.addRooms) - waitUntilActivityVisible { - waitUntilViewVisible(withId(R.id.roomList)) - } - pressBack() - } - - fun addSpace() { - clickOn(R.id.addSpaces) - waitUntilActivityVisible { - waitUntilViewVisible(withId(R.id.roomList)) - } - pressBack() - } - - fun leaveSpace() { - clickOn(R.id.leaveSpace) - waitUntilDialogVisible(withId(R.id.leaveButton)) - clickOn(R.id.leave_selected) - waitUntilActivityVisible { - waitUntilViewVisible(withId(R.id.roomList)) - } - clickOn(R.id.spaceLeaveButton) - waitUntilViewVisible(withId(R.id.groupListView)) - } -} diff --git a/vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceCreateRobot.kt b/vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceCreateRobot.kt new file mode 100644 index 0000000000..082adcb173 --- /dev/null +++ b/vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceCreateRobot.kt @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2022 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.ui.robot.space + +import androidx.recyclerview.widget.RecyclerView +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.Espresso.pressBack +import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.contrib.RecyclerViewActions +import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText +import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn +import im.vector.app.R +import im.vector.app.espresso.tools.waitUntilActivityVisible +import im.vector.app.espresso.tools.waitUntilDialogVisible +import im.vector.app.espresso.tools.waitUntilViewVisible +import im.vector.app.features.home.HomeActivity +import im.vector.app.features.home.room.detail.RoomDetailActivity +import im.vector.app.features.spaces.manage.SpaceManageActivity +import java.util.UUID + +class SpaceCreateRobot { + + fun crawl() { + // public + clickOn(R.id.publicButton) + waitUntilViewVisible(withId(R.id.recyclerView)) + onView(ViewMatchers.withHint(R.string.create_room_name_hint)).perform(ViewActions.replaceText(UUID.randomUUID().toString())) + clickOn(R.id.nextButton) + waitUntilViewVisible(withId(R.id.recyclerView)) + pressBack() + pressBack() + + // private + clickOn(R.id.privateButton) + waitUntilViewVisible(withId(R.id.recyclerView)) + clickOn(R.id.nextButton) + + waitUntilViewVisible(withId(R.id.teammatesButton)) + // me and teammates + clickOn(R.id.teammatesButton) + waitUntilViewVisible(withId(R.id.recyclerView)) + clickOn(R.id.nextButton) + pressBack() + pressBack() + + // just me + waitUntilViewVisible(withId(R.id.justMeButton)) + clickOn(R.id.justMeButton) + waitUntilActivityVisible { + waitUntilViewVisible(withId(R.id.roomList)) + } + + onView(withId(R.id.roomList)) + .perform( + RecyclerViewActions.actionOnItem( + ViewMatchers.hasDescendant(withText(R.string.room_displayname_empty_room)), + click() + ).atPosition(0) + ) + clickOn(R.id.spaceAddRoomSaveItem) + waitUntilActivityVisible { + waitUntilViewVisible(withId(R.id.roomListContainer)) + } + } + + fun createPublicSpace(spaceName: String) { + clickOn(R.id.publicButton) + waitUntilViewVisible(withId(R.id.recyclerView)) + onView(ViewMatchers.withHint(R.string.create_room_name_hint)).perform(ViewActions.replaceText(spaceName)) + clickOn(R.id.nextButton) + waitUntilViewVisible(withId(R.id.recyclerView)) + clickOn(R.id.nextButton) + waitUntilActivityVisible { + waitUntilDialogVisible(withId(R.id.inviteByMxidButton)) + } + // close invite dialog + pressBack() + + waitUntilViewVisible(withId(R.id.timelineRecyclerView)) + // close room + pressBack() + + waitUntilViewVisible(withId(R.id.roomListContainer)) + } +} diff --git a/vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceMenuRobot.kt b/vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceMenuRobot.kt new file mode 100644 index 0000000000..74389fa723 --- /dev/null +++ b/vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceMenuRobot.kt @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2022 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.ui.robot.space + +import androidx.recyclerview.widget.RecyclerView +import androidx.test.espresso.Espresso +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.contrib.RecyclerViewActions +import androidx.test.espresso.matcher.ViewMatchers +import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn +import com.adevinta.android.barista.internal.viewaction.ClickChildAction +import im.vector.app.R +import im.vector.app.espresso.tools.waitUntilActivityVisible +import im.vector.app.espresso.tools.waitUntilDialogVisible +import im.vector.app.espresso.tools.waitUntilViewVisible +import im.vector.app.features.invite.InviteUsersToRoomActivity +import im.vector.app.features.roomprofile.RoomProfileActivity +import im.vector.app.features.spaces.SpaceExploreActivity +import im.vector.app.features.spaces.leave.SpaceLeaveAdvancedActivity +import im.vector.app.features.spaces.manage.SpaceManageActivity +import org.hamcrest.Matchers + +class SpaceMenuRobot { + + fun openMenu(spaceName: String) { + waitUntilViewVisible(ViewMatchers.withId(R.id.groupListView)) + onView(ViewMatchers.withId(R.id.groupListView)) + .perform( + RecyclerViewActions.actionOnItem( + ViewMatchers.hasDescendant(Matchers.allOf(ViewMatchers.withId(R.id.groupNameView), ViewMatchers.withText(spaceName))), + ClickChildAction.clickChildWithId(R.id.groupTmpLeave) + ).atPosition(0) + ) + waitUntilDialogVisible(ViewMatchers.withId(R.id.spaceNameView)) + } + + fun invitePeople() = apply { + clickOn(R.id.invitePeople) + waitUntilDialogVisible(ViewMatchers.withId(R.id.inviteByMxidButton)) + clickOn(R.id.inviteByMxidButton) + waitUntilActivityVisible { + waitUntilViewVisible(ViewMatchers.withId(R.id.userListRecyclerView)) + } + // close keyboard + Espresso.pressBack() + // close invite view + Espresso.pressBack() + + Espresso.pressBack() + } + + fun spaceMembers() { + clickOn(R.id.showMemberList) + waitUntilActivityVisible { + waitUntilViewVisible(ViewMatchers.withId(R.id.roomSettingsRecyclerView)) + } + Espresso.pressBack() + } + + fun spaceSettings(block: SpaceSettingsRobot.() -> Unit) { + clickOn(R.id.spaceSettings) + waitUntilActivityVisible { + waitUntilViewVisible(ViewMatchers.withId(R.id.roomSettingsRecyclerView)) + } + block(SpaceSettingsRobot()) + } + + fun exploreRooms() { + clickOn(R.id.exploreRooms) + waitUntilActivityVisible { + waitUntilViewVisible(ViewMatchers.withId(R.id.spaceDirectoryList)) + } + Espresso.pressBack() + } + + fun addRoom() = apply { + clickOn(R.id.addRooms) + waitUntilActivityVisible { + waitUntilViewVisible(ViewMatchers.withId(R.id.roomList)) + } + Espresso.pressBack() + } + + fun addSpace() = apply { + clickOn(R.id.addSpaces) + waitUntilActivityVisible { + waitUntilViewVisible(ViewMatchers.withId(R.id.roomList)) + } + Espresso.pressBack() + } + + fun leaveSpace() { + clickOn(R.id.leaveSpace) + waitUntilDialogVisible(ViewMatchers.withId(R.id.leaveButton)) + clickOn(R.id.leave_selected) + waitUntilActivityVisible { + waitUntilViewVisible(ViewMatchers.withId(R.id.roomList)) + } + clickOn(R.id.spaceLeaveButton) + waitUntilViewVisible(ViewMatchers.withId(R.id.groupListView)) + } +} diff --git a/vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceRobot.kt b/vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceRobot.kt new file mode 100644 index 0000000000..ffb3c24051 --- /dev/null +++ b/vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceRobot.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 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.ui.robot.space + +import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn +import com.adevinta.android.barista.interaction.BaristaDrawerInteractions.openDrawer +import im.vector.app.R + +class SpaceRobot { + + fun createSpace(block: SpaceCreateRobot.() -> Unit) { + openDrawer() + clickOn(R.string.add_space) + block(SpaceCreateRobot()) + } + + fun spaceMenu(spaceName: String, block: SpaceMenuRobot.() -> Unit) { + openDrawer() + with(SpaceMenuRobot()) { + openMenu(spaceName) + block() + } + } +} diff --git a/vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceSettingsRobot.kt b/vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceSettingsRobot.kt new file mode 100644 index 0000000000..dcd003da98 --- /dev/null +++ b/vector/src/androidTest/java/im/vector/app/ui/robot/space/SpaceSettingsRobot.kt @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 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.ui.robot.space + +import androidx.recyclerview.widget.RecyclerView +import androidx.test.espresso.Espresso +import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.contrib.RecyclerViewActions +import androidx.test.espresso.matcher.ViewMatchers +import im.vector.app.R +import im.vector.app.espresso.tools.waitUntilActivityVisible +import im.vector.app.espresso.tools.waitUntilViewVisible +import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleActivity + +class SpaceSettingsRobot { + fun crawl() { + Espresso.onView(ViewMatchers.withId(R.id.roomSettingsRecyclerView)) + .perform( + RecyclerViewActions.actionOnItem( + ViewMatchers.hasDescendant(ViewMatchers.withText(R.string.room_settings_space_access_title)), + ViewActions.click() + ) + ) + + waitUntilActivityVisible { + waitUntilViewVisible(ViewMatchers.withId(R.id.genericRecyclerView)) + } + + Espresso.pressBack() + + Espresso.onView(ViewMatchers.withId(R.id.roomSettingsRecyclerView)) + .perform( + RecyclerViewActions.actionOnItem( + ViewMatchers.hasDescendant(ViewMatchers.withText(R.string.space_settings_manage_rooms)), + ViewActions.click() + ) + ) + + waitUntilViewVisible(ViewMatchers.withId(R.id.roomList)) + Espresso.pressBack() + + Espresso.onView(ViewMatchers.withId(R.id.roomSettingsRecyclerView)) + .perform( + RecyclerViewActions.actionOnItem( + ViewMatchers.hasDescendant(ViewMatchers.withText(R.string.space_settings_permissions_title)), + ViewActions.click() + ) + ) + + waitUntilViewVisible(ViewMatchers.withId(R.id.roomSettingsRecyclerView)) + Espresso.pressBack() + Espresso.pressBack() + } +} From 343b8bf08daaa8784998d50a4bdfcecee4ed820b Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 16 Feb 2022 12:29:08 +0000 Subject: [PATCH 102/302] Incrementing schema version - fixes pre-release launch crash (#5245) * updating the schema version to 25 to reflect the latest migration * adding changelog entry --- changelog.d/5243.bugfix | 1 + .../android/sdk/internal/database/RealmSessionStoreMigration.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/5243.bugfix diff --git a/changelog.d/5243.bugfix b/changelog.d/5243.bugfix new file mode 100644 index 0000000000..eb323c1ca4 --- /dev/null +++ b/changelog.d/5243.bugfix @@ -0,0 +1 @@ +Increments database schema to take advantage of homeserver capabilities entity migration (fixes crash in pre-release builds) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt index 4bf352c06c..12e60da114 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt @@ -57,7 +57,7 @@ internal class RealmSessionStoreMigration @Inject constructor( override fun equals(other: Any?) = other is RealmSessionStoreMigration override fun hashCode() = 1000 - val schemaVersion = 24L + val schemaVersion = 25L override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { Timber.d("Migrating Realm Session from $oldVersion to $newVersion") From 0a04ff9aa60f584e27fc6bcb6d6a54fa354c1dd6 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Wed, 16 Feb 2022 13:46:06 +0100 Subject: [PATCH 103/302] Adding changelog entry --- changelog.d/2782.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/2782.misc diff --git a/changelog.d/2782.misc b/changelog.d/2782.misc new file mode 100644 index 0000000000..6c340219d5 --- /dev/null +++ b/changelog.d/2782.misc @@ -0,0 +1 @@ +Collapse ACL events From 4641153df0f1a82851526f7aeec86e6de3d3a5b6 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Wed, 16 Feb 2022 16:01:31 +0100 Subject: [PATCH 104/302] Making ACL multiple successive events as collapsable --- .../factory/MergedHeaderItemFactory.kt | 49 +++++++++++-------- .../helper/TimelineDisplayableEvents.kt | 3 +- ...entsItem.kt => DefaultMergedEventsItem.kt} | 6 ++- vector/src/main/res/values/strings.xml | 4 ++ 4 files changed, 39 insertions(+), 23 deletions(-) rename vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/{MergedMembershipEventsItem.kt => DefaultMergedEventsItem.kt} (91%) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt index 99a026a0cf..bf7e93982e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt @@ -16,6 +16,7 @@ package im.vector.app.features.home.room.detail.timeline.factory +import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.extensions.prevOrNull import im.vector.app.features.home.AvatarRenderer @@ -26,8 +27,8 @@ import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventVisi import im.vector.app.features.home.room.detail.timeline.helper.canBeMerged import im.vector.app.features.home.room.detail.timeline.helper.isRoomConfiguration import im.vector.app.features.home.room.detail.timeline.item.BasedMergedItem -import im.vector.app.features.home.room.detail.timeline.item.MergedMembershipEventsItem -import im.vector.app.features.home.room.detail.timeline.item.MergedMembershipEventsItem_ +import im.vector.app.features.home.room.detail.timeline.item.DefaultMergedEventsItem +import im.vector.app.features.home.room.detail.timeline.item.DefaultMergedEventsItem_ import im.vector.app.features.home.room.detail.timeline.item.MergedRoomCreationItem import im.vector.app.features.home.room.detail.timeline.item.MergedRoomCreationItem_ import im.vector.app.features.home.room.detail.timeline.tools.createLinkMovementMethod @@ -82,7 +83,7 @@ class MergedHeaderItemFactory @Inject constructor(private val activeSessionHolde event: TimelineEvent, eventIdToHighlight: String?, requestModelBuild: () -> Unit, - callback: TimelineEventController.Callback?): MergedMembershipEventsItem_? { + callback: TimelineEventController.Callback?): DefaultMergedEventsItem_? { val mergedEvents = timelineEventVisibilityHelper.prevSameTypeEvents( items, currentPosition, @@ -122,23 +123,31 @@ class MergedHeaderItemFactory @Inject constructor(private val activeSessionHolde collapsedEventIds.removeAll(mergedEventIds) } val mergeId = mergedEventIds.joinToString(separator = "_") { it.toString() } - val attributes = MergedMembershipEventsItem.Attributes( - isCollapsed = isCollapsed, - mergeData = mergedData, - avatarRenderer = avatarRenderer, - onCollapsedStateChanged = { - mergeItemCollapseStates[event.localId] = it - requestModelBuild() - } - ) - MergedMembershipEventsItem_() - .id(mergeId) - .leftGuideline(avatarSizeProvider.leftGuideline) - .highlighted(isCollapsed && highlighted) - .attributes(attributes) - .also { - it.setOnVisibilityStateChanged(MergedTimelineEventVisibilityStateChangedListener(callback, mergedEvents)) - } + val summaryTitleResId = when(event.root.getClearType()) { + EventType.STATE_ROOM_MEMBER -> R.plurals.membership_changes + EventType.STATE_ROOM_SERVER_ACL -> R.plurals.notice_room_server_acl_changes + else -> null + } + summaryTitleResId?.let { summaryTitle -> + val attributes = DefaultMergedEventsItem.Attributes( + summaryTitleResId = summaryTitle, + isCollapsed = isCollapsed, + mergeData = mergedData, + avatarRenderer = avatarRenderer, + onCollapsedStateChanged = { + mergeItemCollapseStates[event.localId] = it + requestModelBuild() + } + ) + DefaultMergedEventsItem_() + .id(mergeId) + .leftGuideline(avatarSizeProvider.leftGuideline) + .highlighted(isCollapsed && highlighted) + .attributes(attributes) + .also { + it.setOnVisibilityStateChanged(MergedTimelineEventVisibilityStateChangedListener(callback, mergedEvents)) + } + } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt index bcccbc9f7c..53a9fbbaea 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt @@ -56,7 +56,8 @@ object TimelineDisplayableEvents { } fun TimelineEvent.canBeMerged(): Boolean { - return root.getClearType() == EventType.STATE_ROOM_MEMBER + return root.getClearType() == EventType.STATE_ROOM_MEMBER || + root.getClearType() == EventType.STATE_ROOM_SERVER_ACL } fun TimelineEvent.isRoomConfiguration(roomCreatorUserId: String?): Boolean { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedMembershipEventsItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/DefaultMergedEventsItem.kt similarity index 91% rename from vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedMembershipEventsItem.kt rename to vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/DefaultMergedEventsItem.kt index e19dc33fff..65675efca9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedMembershipEventsItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/DefaultMergedEventsItem.kt @@ -20,6 +20,7 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView +import androidx.annotation.PluralsRes import androidx.core.view.children import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass @@ -27,7 +28,7 @@ import im.vector.app.R import im.vector.app.features.home.AvatarRenderer @EpoxyModelClass(layout = R.layout.item_timeline_event_base_noinfo) -abstract class MergedMembershipEventsItem : BasedMergedItem() { +abstract class DefaultMergedEventsItem : BasedMergedItem() { override fun getViewStubId() = STUB_ID @@ -37,7 +38,7 @@ abstract class MergedMembershipEventsItem : BasedMergedItem, override val avatarRenderer: AvatarRenderer, diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index c155b6bb75..7387688dfe 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -81,6 +81,10 @@ %s changed the server ACLs for this room. You changed the server ACLs for this room. + + %d server ACLs change + %d server ACLs changes + • Servers matching %s are now banned. • Servers matching %s were removed from the ban list. • Servers matching %s are now allowed. From bc45c0ce509f764f9844c37e78b6df6310e5ae37 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Wed, 16 Feb 2022 16:09:10 +0100 Subject: [PATCH 105/302] Fix code formatting --- .../room/detail/timeline/factory/MergedHeaderItemFactory.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt index bf7e93982e..0b8c2eb572 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt @@ -123,10 +123,10 @@ class MergedHeaderItemFactory @Inject constructor(private val activeSessionHolde collapsedEventIds.removeAll(mergedEventIds) } val mergeId = mergedEventIds.joinToString(separator = "_") { it.toString() } - val summaryTitleResId = when(event.root.getClearType()) { - EventType.STATE_ROOM_MEMBER -> R.plurals.membership_changes + val summaryTitleResId = when (event.root.getClearType()) { + EventType.STATE_ROOM_MEMBER -> R.plurals.membership_changes EventType.STATE_ROOM_SERVER_ACL -> R.plurals.notice_room_server_acl_changes - else -> null + else -> null } summaryTitleResId?.let { summaryTitle -> val attributes = DefaultMergedEventsItem.Attributes( From 4fe3b409d245636d90f4b35bb5d472b7855e7a4b Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 17 Feb 2022 10:27:59 +0100 Subject: [PATCH 106/302] Replacing the search icon by a filter icon --- changelog.d/4643.misc | 1 + vector/src/main/res/menu/home.xml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changelog.d/4643.misc diff --git a/changelog.d/4643.misc b/changelog.d/4643.misc new file mode 100644 index 0000000000..9092e77942 --- /dev/null +++ b/changelog.d/4643.misc @@ -0,0 +1 @@ +Replacing search icon by filter icon diff --git a/vector/src/main/res/menu/home.xml b/vector/src/main/res/menu/home.xml index 93947a5a7f..f15c31b4e9 100644 --- a/vector/src/main/res/menu/home.xml +++ b/vector/src/main/res/menu/home.xml @@ -31,9 +31,9 @@ - \ No newline at end of file + From b346a732430653244b508032adb7b9fd23cea677 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 17 Feb 2022 11:03:04 +0100 Subject: [PATCH 107/302] Adding more details in changelog --- changelog.d/4643.misc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/4643.misc b/changelog.d/4643.misc index 9092e77942..3d86baa1a2 100644 --- a/changelog.d/4643.misc +++ b/changelog.d/4643.misc @@ -1 +1 @@ -Replacing search icon by filter icon +Home screen: Replacing search icon by filter icon in the top right menu From 2d38786d02cadb670627ede6e8759d06769e1db2 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Mon, 7 Feb 2022 13:51:10 +0100 Subject: [PATCH 108/302] Adding TODOs --- .../android/sdk/api/session/room/model/PowerLevelsContent.kt | 1 + .../vector/app/features/autocomplete/AutocompleteMatrixItem.kt | 1 + .../autocomplete/member/AutocompleteMemberPresenter.kt | 3 +++ 3 files changed, 5 insertions(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PowerLevelsContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PowerLevelsContent.kt index 5c46db7166..371fb922e6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PowerLevelsContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PowerLevelsContent.kt @@ -100,6 +100,7 @@ data class PowerLevelsContent( } } + // TODO use this to check if user can notify everyone => compare user role to room permission setting companion object { /** * Key to use for content.notifications and get the level required to trigger an @room notification. Defaults to 50 if unspecified. diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt index dba2661927..54d809d948 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt @@ -30,6 +30,7 @@ import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.util.MatrixItem +// TODO create a new item for sections @EpoxyModelClass(layout = R.layout.item_autocomplete_matrix_item) abstract class AutocompleteMatrixItem : VectorEpoxyModel() { diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt index 4976cb39b9..6624a15916 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt @@ -72,6 +72,9 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, .asSequence() .sortedBy { it.displayName } .disambiguate() + // TODO check if user can notify everyone => compare user role to room permission setting + // TODO if user can notify everyone, add entry "@room" + // TODO add header sections to separate members and notification controller.setData(members.toList()) } } From 1d1dc8b1fdfda9ec682446277bbc535da1c131de Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Wed, 9 Feb 2022 14:59:09 +0100 Subject: [PATCH 109/302] Adding changelog entry --- changelog.d/5123.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5123.misc diff --git a/changelog.d/5123.misc b/changelog.d/5123.misc new file mode 100644 index 0000000000..790910e493 --- /dev/null +++ b/changelog.d/5123.misc @@ -0,0 +1 @@ +Add completion for @room as per element web From 38fdfb27e4bb495f0f99ad5ec50c0d81f7917bfe Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 10 Feb 2022 14:20:47 +0100 Subject: [PATCH 110/302] Creating sealed wrapper class for member items --- .../matrix/android/sdk/api/util/MatrixItem.kt | 1 + .../autocomplete/AutocompleteMatrixItem.kt | 2 +- .../member/AutocompleteMemberController.kt | 37 +++++++++++++------ .../member/AutocompleteMemberItem.kt | 26 +++++++++++++ .../member/AutocompleteMemberPresenter.kt | 10 ++--- .../home/room/detail/AutoCompleter.kt | 14 ++++--- .../app/features/html/PillsPostProcessor.kt | 1 + 7 files changed, 69 insertions(+), 22 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberItem.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt index 3396c4a6c9..31dcd007a2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt @@ -27,6 +27,7 @@ import org.matrix.android.sdk.api.session.room.sender.SenderInfo import org.matrix.android.sdk.api.session.user.model.User import java.util.Locale +// TODO how to represent the notify everyone @room item? EveryoneItem ?? sealed class MatrixItem( open val id: String, open val displayName: String?, diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt index 54d809d948..d0e2c81b56 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt @@ -30,7 +30,7 @@ import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.util.MatrixItem -// TODO create a new item for sections +// TODO create a new item for sections: AutocompleteSection @EpoxyModelClass(layout = R.layout.item_autocomplete_matrix_item) abstract class AutocompleteMatrixItem : VectorEpoxyModel() { diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt index 9b4bd78504..5bbd4a3996 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt @@ -20,28 +20,43 @@ import com.airbnb.epoxy.TypedEpoxyController import im.vector.app.features.autocomplete.AutocompleteClickListener import im.vector.app.features.autocomplete.autocompleteMatrixItem import im.vector.app.features.home.AvatarRenderer -import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject -class AutocompleteMemberController @Inject constructor() : TypedEpoxyController>() { +class AutocompleteMemberController @Inject constructor() : TypedEpoxyController>() { - var listener: AutocompleteClickListener? = null + var listener: AutocompleteClickListener? = null @Inject lateinit var avatarRenderer: AvatarRenderer - override fun buildModels(data: List?) { + override fun buildModels(data: List?) { if (data.isNullOrEmpty()) { return } - val host = this - data.forEach { user -> - autocompleteMatrixItem { - id(user.userId) - matrixItem(user.toMatrixItem()) - avatarRenderer(host.avatarRenderer) - clickListener { host.listener?.onItemClick(user) } + data.forEach { item -> + when (item) { + is AutocompleteMemberItem.RoomMember -> buildRoomMemberItem(item) + is AutocompleteMemberItem.Everyone -> buildEveryoneItem(item) } } } + + /////////////////////////////////////////////////////////////////////////// + // HELPER METHODS + /////////////////////////////////////////////////////////////////////////// + + private fun buildRoomMemberItem(roomMember: AutocompleteMemberItem.RoomMember) { + autocompleteMatrixItem { + roomMember.roomMemberSummary.let { user -> + id(user.userId) + matrixItem(user.toMatrixItem()) + avatarRenderer(this@AutocompleteMemberController.avatarRenderer) + clickListener { this@AutocompleteMemberController.listener?.onItemClick(roomMember) } + } + } + } + + private fun buildEveryoneItem(everyone: AutocompleteMemberItem.Everyone) { + // TODO + } } diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberItem.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberItem.kt new file mode 100644 index 0000000000..fa9693895f --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberItem.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 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.autocomplete.member + +import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary +import org.matrix.android.sdk.api.session.room.model.RoomSummary + +sealed class AutocompleteMemberItem { + // TODO add section class + data class RoomMember(val roomMemberSummary: RoomMemberSummary) : AutocompleteMemberItem() + data class Everyone(val roomSummary: RoomSummary) : AutocompleteMemberItem() +} diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt index 6624a15916..bb7d41cc46 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt @@ -33,7 +33,7 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, @Assisted val roomId: String, session: Session, private val controller: AutocompleteMemberController -) : RecyclerViewPresenter(context), AutocompleteClickListener { +) : RecyclerViewPresenter(context), AutocompleteClickListener { private val room by lazy { session.getRoom(roomId)!! } @@ -54,7 +54,7 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, return controller.adapter } - override fun onItemClick(t: RoomMemberSummary) { + override fun onItemClick(t: AutocompleteMemberItem) { dispatchClick(t) } @@ -72,10 +72,10 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, .asSequence() .sortedBy { it.displayName } .disambiguate() - // TODO check if user can notify everyone => compare user role to room permission setting - // TODO if user can notify everyone, add entry "@room" + // TODO check if user can notify everyone => compare user role to room permission setting: PowerLevelsContent + // TODO if user can notify everyone, add entry AutocompleteMemberItem.Everyone // TODO add header sections to separate members and notification - controller.setData(members.toList()) + controller.setData(members.map { AutocompleteMemberItem.RoomMember(it) }.toList()) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt index 9f85d4015b..88e49f7062 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt @@ -33,6 +33,7 @@ import im.vector.app.features.autocomplete.command.AutocompleteCommandPresenter import im.vector.app.features.autocomplete.command.CommandAutocompletePolicy import im.vector.app.features.autocomplete.emoji.AutocompleteEmojiPresenter import im.vector.app.features.autocomplete.group.AutocompleteGroupPresenter +import im.vector.app.features.autocomplete.member.AutocompleteMemberItem import im.vector.app.features.autocomplete.member.AutocompleteMemberPresenter import im.vector.app.features.autocomplete.room.AutocompleteRoomPresenter import im.vector.app.features.command.Command @@ -41,7 +42,6 @@ import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.html.PillImageSpan import im.vector.app.features.themes.ThemeUtils import org.matrix.android.sdk.api.session.group.model.GroupSummary -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.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem @@ -125,14 +125,18 @@ class AutoCompleter @AssistedInject constructor( private fun setupMembers(backgroundDrawable: ColorDrawable, editText: EditText) { autocompleteMemberPresenter = autocompleteMemberPresenterFactory.create(roomId) - Autocomplete.on(editText) + Autocomplete.on(editText) .with(CharPolicy('@', true)) .with(autocompleteMemberPresenter) .with(ELEVATION) .with(backgroundDrawable) - .with(object : AutocompleteCallback { - override fun onPopupItemClicked(editable: Editable, item: RoomMemberSummary): Boolean { - insertMatrixItem(editText, editable, "@", item.toMatrixItem()) + .with(object : AutocompleteCallback { + override fun onPopupItemClicked(editable: Editable, item: AutocompleteMemberItem): Boolean { + when (item) { + is AutocompleteMemberItem.RoomMember -> + insertMatrixItem(editText, editable, "@", item.roomMemberSummary.toMatrixItem()) + is AutocompleteMemberItem.Everyone -> Unit // TODO + } return true } diff --git a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt index f8a2ee5137..8376d25065 100644 --- a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt @@ -59,6 +59,7 @@ class PillsPostProcessor @AssistedInject constructor(@Assisted private val roomI } private fun LinkSpan.createPillSpan(roomId: String?): PillImageSpan? { + // TODO handle @room text to create associated chip val permalinkData = PermalinkParser.parse(url) val matrixItem = when (permalinkData) { is PermalinkData.UserLink -> { From d8e28d7be95da206a0fabae58ab52e828ae38a35 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 10 Feb 2022 17:22:29 +0100 Subject: [PATCH 111/302] Adding autocomplete for @room (missing correct first letter of avatar) --- .../matrix/android/sdk/api/util/MatrixItem.kt | 43 +++++++++++++------ .../member/AutocompleteMemberController.kt | 37 ++++++++++++++-- .../member/AutocompleteMemberPresenter.kt | 21 +++++++-- .../home/room/detail/AutoCompleter.kt | 5 ++- vector/src/main/res/values/strings.xml | 3 ++ 5 files changed, 87 insertions(+), 22 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt index 31dcd007a2..9ad1e42513 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt @@ -27,7 +27,6 @@ import org.matrix.android.sdk.api.session.room.sender.SenderInfo import org.matrix.android.sdk.api.session.user.model.User import java.util.Locale -// TODO how to represent the notify everyone @room item? EveryoneItem ?? sealed class MatrixItem( open val id: String, open val displayName: String?, @@ -36,7 +35,18 @@ sealed class MatrixItem( data class UserItem(override val id: String, override val displayName: String? = null, override val avatarUrl: String? = null) : - MatrixItem(id, displayName?.removeSuffix(ircPattern), avatarUrl) { + MatrixItem(id, displayName?.removeSuffix(IRC_PATTERN), avatarUrl) { + init { + if (BuildConfig.DEBUG) checkId() + } + + override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) + } + + data class EveryoneInRoomItem(override val id: String, + override val displayName: String? = null, + override val avatarUrl: String? = null) : + MatrixItem(id, displayName, avatarUrl) { init { if (BuildConfig.DEBUG) checkId() } @@ -47,7 +57,7 @@ sealed class MatrixItem( data class EventItem(override val id: String, override val displayName: String? = null, override val avatarUrl: String? = null) : - MatrixItem(id, displayName, avatarUrl) { + MatrixItem(id, displayName, avatarUrl) { init { if (BuildConfig.DEBUG) checkId() } @@ -58,7 +68,7 @@ sealed class MatrixItem( data class RoomItem(override val id: String, override val displayName: String? = null, override val avatarUrl: String? = null) : - MatrixItem(id, displayName, avatarUrl) { + MatrixItem(id, displayName, avatarUrl) { init { if (BuildConfig.DEBUG) checkId() } @@ -69,7 +79,7 @@ sealed class MatrixItem( data class SpaceItem(override val id: String, override val displayName: String? = null, override val avatarUrl: String? = null) : - MatrixItem(id, displayName, avatarUrl) { + MatrixItem(id, displayName, avatarUrl) { init { if (BuildConfig.DEBUG) checkId() } @@ -80,7 +90,7 @@ sealed class MatrixItem( data class RoomAliasItem(override val id: String, override val displayName: String? = null, override val avatarUrl: String? = null) : - MatrixItem(id, displayName, avatarUrl) { + MatrixItem(id, displayName, avatarUrl) { init { if (BuildConfig.DEBUG) checkId() } @@ -91,7 +101,7 @@ sealed class MatrixItem( data class GroupItem(override val id: String, override val displayName: String? = null, override val avatarUrl: String? = null) : - MatrixItem(id, displayName, avatarUrl) { + MatrixItem(id, displayName, avatarUrl) { init { if (BuildConfig.DEBUG) checkId() } @@ -110,16 +120,18 @@ sealed class MatrixItem( /** * Return the prefix as defined in the matrix spec (and not extracted from the id) */ - fun getIdPrefix() = when (this) { - is UserItem -> '@' - is EventItem -> '$' + private fun getIdPrefix() = when (this) { + is UserItem -> '@' + is EventItem -> '$' is SpaceItem, - is RoomItem -> '!' - is RoomAliasItem -> '#' - is GroupItem -> '+' + is RoomItem, + is EveryoneInRoomItem -> '!' + is RoomAliasItem -> '#' + is GroupItem -> '+' } fun firstLetterOfDisplayName(): String { + // TODO retrieve first letter of room name when EveryoneInRoomItem return (displayName?.takeIf { it.isNotBlank() } ?: id) .let { dn -> var startIndex = 0 @@ -152,7 +164,8 @@ sealed class MatrixItem( } companion object { - private const val ircPattern = " (IRC)" + private const val IRC_PATTERN = " (IRC)" + const val NOTIFY_EVERYONE = "@room" } } @@ -172,6 +185,8 @@ fun RoomSummary.toMatrixItem() = if (roomType == RoomType.SPACE) { fun RoomSummary.toRoomAliasMatrixItem() = MatrixItem.RoomAliasItem(canonicalAlias ?: roomId, displayName, avatarUrl) +fun RoomSummary.toEveryoneInRoomMatrixItem() = MatrixItem.EveryoneInRoomItem(roomId, MatrixItem.NOTIFY_EVERYONE, avatarUrl) + // If no name is available, use room alias as Riot-Web does fun PublicRoom.toMatrixItem() = MatrixItem.RoomItem(roomId, name ?: getPrimaryAlias() ?: "", avatarUrl) diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt index 5bbd4a3996..0684067ba8 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt @@ -16,19 +16,35 @@ package im.vector.app.features.autocomplete.member +import android.content.Context import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.R import im.vector.app.features.autocomplete.AutocompleteClickListener import im.vector.app.features.autocomplete.autocompleteMatrixItem import im.vector.app.features.home.AvatarRenderer +import org.matrix.android.sdk.api.util.toEveryoneInRoomMatrixItem import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject -class AutocompleteMemberController @Inject constructor() : TypedEpoxyController>() { +class AutocompleteMemberController @Inject constructor(private val context: Context) + : TypedEpoxyController>() { + + /////////////////////////////////////////////////////////////////////////// + // FIELDS + /////////////////////////////////////////////////////////////////////////// var listener: AutocompleteClickListener? = null + /////////////////////////////////////////////////////////////////////////// + // DEPENDENCIES + /////////////////////////////////////////////////////////////////////////// + @Inject lateinit var avatarRenderer: AvatarRenderer + /////////////////////////////////////////////////////////////////////////// + // SPECIALIZATION + /////////////////////////////////////////////////////////////////////////// + override fun buildModels(data: List?) { if (data.isNullOrEmpty()) { return @@ -46,17 +62,30 @@ class AutocompleteMemberController @Inject constructor() : TypedEpoxyController< /////////////////////////////////////////////////////////////////////////// private fun buildRoomMemberItem(roomMember: AutocompleteMemberItem.RoomMember) { + val host = this autocompleteMatrixItem { roomMember.roomMemberSummary.let { user -> id(user.userId) matrixItem(user.toMatrixItem()) - avatarRenderer(this@AutocompleteMemberController.avatarRenderer) - clickListener { this@AutocompleteMemberController.listener?.onItemClick(roomMember) } + avatarRenderer(host.avatarRenderer) + clickListener { host.listener?.onItemClick(roomMember) } } } } private fun buildEveryoneItem(everyone: AutocompleteMemberItem.Everyone) { - // TODO + val host = this + + autocompleteMatrixItem { + everyone.roomSummary.let { room -> + id(room.roomId) + matrixItem(room.toEveryoneInRoomMatrixItem()) + subName(host.context.getString(R.string.room_message_notify_everyone)) + // TODO fix usage of first letter of room name when avatarUrl is empty + // TODO test avatar with a room which has a picture + avatarRenderer(host.avatarRenderer) + clickListener { host.listener?.onItemClick(everyone) } + } + } } } diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt index bb7d41cc46..5640632ec2 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt @@ -28,6 +28,7 @@ import org.matrix.android.sdk.api.session.Session 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.RoomMemberSummary +import org.matrix.android.sdk.api.util.MatrixItem class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, @Assisted val roomId: String, @@ -68,14 +69,28 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, memberships = listOf(Membership.JOIN) excludeSelf = true } + val members = room.getRoomMembers(queryParams) .asSequence() .sortedBy { it.displayName } .disambiguate() + .map { AutocompleteMemberItem.RoomMember(it) } + .toList() + // TODO check if user can notify everyone => compare user role to room permission setting: PowerLevelsContent - // TODO if user can notify everyone, add entry AutocompleteMemberItem.Everyone - // TODO add header sections to separate members and notification - controller.setData(members.map { AutocompleteMemberItem.RoomMember(it) }.toList()) + val everyone = room.roomSummary() + ?.takeIf { query.isNullOrBlank() || MatrixItem.NOTIFY_EVERYONE.startsWith("@$query") } + ?.let { + AutocompleteMemberItem.Everyone(it) + } + + val items = mutableListOf().apply { + // TODO add header sections + addAll(members) + everyone?.let { add(it) } + } + + controller.setData(items) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt index 88e49f7062..4bd38095a9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt @@ -44,6 +44,7 @@ import im.vector.app.features.themes.ThemeUtils import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.util.MatrixItem +import org.matrix.android.sdk.api.util.toEveryoneInRoomMatrixItem import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.api.util.toRoomAliasMatrixItem @@ -135,7 +136,8 @@ class AutoCompleter @AssistedInject constructor( when (item) { is AutocompleteMemberItem.RoomMember -> insertMatrixItem(editText, editable, "@", item.roomMemberSummary.toMatrixItem()) - is AutocompleteMemberItem.Everyone -> Unit // TODO + is AutocompleteMemberItem.Everyone -> + insertMatrixItem(editText, editable, "@", item.roomSummary.toEveryoneInRoomMatrixItem()) } return true } @@ -253,6 +255,7 @@ class AutoCompleter @AssistedInject constructor( } companion object { + // TODO add consts for string trigger for autocomplete private const val ELEVATION = 6f } } diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index c155b6bb75..69a1c53d1c 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -3782,4 +3782,7 @@ Show less "%1$d more" + Notify the whole room + Users + Room notification From 38317e6033966d4ad6a248ae69d9fe3f4091f7d5 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 10 Feb 2022 17:30:28 +0100 Subject: [PATCH 112/302] Using const for char triggers --- .../home/room/detail/AutoCompleter.kt | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt index 4bd38095a9..550f89dd70 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt @@ -107,7 +107,7 @@ class AutoCompleter @AssistedInject constructor( Autocomplete.on(editText) .with(commandAutocompletePolicy) .with(autocompleteCommandPresenter) - .with(ELEVATION) + .with(ELEVATION_DP) .with(backgroundDrawable) .with(object : AutocompleteCallback { override fun onPopupItemClicked(editable: Editable, item: Command): Boolean { @@ -127,17 +127,17 @@ class AutoCompleter @AssistedInject constructor( private fun setupMembers(backgroundDrawable: ColorDrawable, editText: EditText) { autocompleteMemberPresenter = autocompleteMemberPresenterFactory.create(roomId) Autocomplete.on(editText) - .with(CharPolicy('@', true)) + .with(CharPolicy(TRIGGER_AUTO_COMPLETE_MEMBERS, true)) .with(autocompleteMemberPresenter) - .with(ELEVATION) + .with(ELEVATION_DP) .with(backgroundDrawable) .with(object : AutocompleteCallback { override fun onPopupItemClicked(editable: Editable, item: AutocompleteMemberItem): Boolean { when (item) { is AutocompleteMemberItem.RoomMember -> - insertMatrixItem(editText, editable, "@", item.roomMemberSummary.toMatrixItem()) + insertMatrixItem(editText, editable, TRIGGER_AUTO_COMPLETE_MEMBERS, item.roomMemberSummary.toMatrixItem()) is AutocompleteMemberItem.Everyone -> - insertMatrixItem(editText, editable, "@", item.roomSummary.toEveryoneInRoomMatrixItem()) + insertMatrixItem(editText, editable, TRIGGER_AUTO_COMPLETE_MEMBERS, item.roomSummary.toEveryoneInRoomMatrixItem()) } return true } @@ -150,13 +150,13 @@ class AutoCompleter @AssistedInject constructor( private fun setupRooms(backgroundDrawable: ColorDrawable, editText: EditText) { Autocomplete.on(editText) - .with(CharPolicy('#', true)) + .with(CharPolicy(TRIGGER_AUTO_COMPLETE_ROOMS, true)) .with(autocompleteRoomPresenter) - .with(ELEVATION) + .with(ELEVATION_DP) .with(backgroundDrawable) .with(object : AutocompleteCallback { override fun onPopupItemClicked(editable: Editable, item: RoomSummary): Boolean { - insertMatrixItem(editText, editable, "#", item.toRoomAliasMatrixItem()) + insertMatrixItem(editText, editable, TRIGGER_AUTO_COMPLETE_ROOMS, item.toRoomAliasMatrixItem()) return true } @@ -168,13 +168,13 @@ class AutoCompleter @AssistedInject constructor( private fun setupGroups(backgroundDrawable: ColorDrawable, editText: EditText) { Autocomplete.on(editText) - .with(CharPolicy('+', true)) + .with(CharPolicy(TRIGGER_AUTO_COMPLETE_GROUPS, true)) .with(autocompleteGroupPresenter) - .with(ELEVATION) + .with(ELEVATION_DP) .with(backgroundDrawable) .with(object : AutocompleteCallback { override fun onPopupItemClicked(editable: Editable, item: GroupSummary): Boolean { - insertMatrixItem(editText, editable, "+", item.toMatrixItem()) + insertMatrixItem(editText, editable, TRIGGER_AUTO_COMPLETE_GROUPS, item.toMatrixItem()) return true } @@ -186,9 +186,9 @@ class AutoCompleter @AssistedInject constructor( private fun setupEmojis(backgroundDrawable: Drawable, editText: EditText) { Autocomplete.on(editText) - .with(CharPolicy(':', false)) + .with(CharPolicy(TRIGGER_AUTO_COMPLETE_EMOJIS, false)) .with(autocompleteEmojiPresenter) - .with(ELEVATION) + .with(ELEVATION_DP) .with(backgroundDrawable) .with(object : AutocompleteCallback { override fun onPopupItemClicked(editable: Editable, item: String): Boolean { @@ -216,7 +216,7 @@ class AutoCompleter @AssistedInject constructor( .build() } - private fun insertMatrixItem(editText: EditText, editable: Editable, firstChar: String, matrixItem: MatrixItem) { + private fun insertMatrixItem(editText: EditText, editable: Editable, firstChar: Char, matrixItem: MatrixItem) { // Detect last firstChar and remove it var startIndex = editable.lastIndexOf(firstChar) if (startIndex == -1) { @@ -234,7 +234,7 @@ class AutoCompleter @AssistedInject constructor( // Adding trailing space " " or ": " if the user started mention someone val displayNameSuffix = - if (firstChar == "@" && startIndex == 0) { + if (firstChar == TRIGGER_AUTO_COMPLETE_MEMBERS && startIndex == 0) { ": " } else { " " @@ -255,7 +255,10 @@ class AutoCompleter @AssistedInject constructor( } companion object { - // TODO add consts for string trigger for autocomplete - private const val ELEVATION = 6f + private const val ELEVATION_DP = 6f + private const val TRIGGER_AUTO_COMPLETE_MEMBERS = '@' + private const val TRIGGER_AUTO_COMPLETE_ROOMS = '#' + private const val TRIGGER_AUTO_COMPLETE_GROUPS = '+' + private const val TRIGGER_AUTO_COMPLETE_EMOJIS = ':' } } From 82ac302843b01c80723462b8ed63d1c9ab44c985 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 10 Feb 2022 17:50:48 +0100 Subject: [PATCH 113/302] Fixing avatar name when there is no room picture --- .../org/matrix/android/sdk/api/util/MatrixItem.kt | 11 ++++++++--- .../member/AutocompleteMemberController.kt | 2 -- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt index 9ad1e42513..1f3a94b2ad 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt @@ -45,7 +45,8 @@ sealed class MatrixItem( data class EveryoneInRoomItem(override val id: String, override val displayName: String? = null, - override val avatarUrl: String? = null) : + override val avatarUrl: String? = null, + val roomDisplayName: String? = null) : MatrixItem(id, displayName, avatarUrl) { init { if (BuildConfig.DEBUG) checkId() @@ -131,7 +132,11 @@ sealed class MatrixItem( } fun firstLetterOfDisplayName(): String { - // TODO retrieve first letter of room name when EveryoneInRoomItem + val displayName = when (this) { + // use the room display name for the notify everyone item + is EveryoneInRoomItem -> roomDisplayName + else -> displayName + } return (displayName?.takeIf { it.isNotBlank() } ?: id) .let { dn -> var startIndex = 0 @@ -185,7 +190,7 @@ fun RoomSummary.toMatrixItem() = if (roomType == RoomType.SPACE) { fun RoomSummary.toRoomAliasMatrixItem() = MatrixItem.RoomAliasItem(canonicalAlias ?: roomId, displayName, avatarUrl) -fun RoomSummary.toEveryoneInRoomMatrixItem() = MatrixItem.EveryoneInRoomItem(roomId, MatrixItem.NOTIFY_EVERYONE, avatarUrl) +fun RoomSummary.toEveryoneInRoomMatrixItem() = MatrixItem.EveryoneInRoomItem(roomId, MatrixItem.NOTIFY_EVERYONE, avatarUrl, displayName) // If no name is available, use room alias as Riot-Web does fun PublicRoom.toMatrixItem() = MatrixItem.RoomItem(roomId, name ?: getPrimaryAlias() ?: "", avatarUrl) diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt index 0684067ba8..2132cc2f1d 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt @@ -81,8 +81,6 @@ class AutocompleteMemberController @Inject constructor(private val context: Cont id(room.roomId) matrixItem(room.toEveryoneInRoomMatrixItem()) subName(host.context.getString(R.string.room_message_notify_everyone)) - // TODO fix usage of first letter of room name when avatarUrl is empty - // TODO test avatar with a room which has a picture avatarRenderer(host.avatarRenderer) clickListener { host.listener?.onItemClick(everyone) } } From d214ef34dfb43d071f0c869341986a8cae122f73 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 10 Feb 2022 17:59:59 +0100 Subject: [PATCH 114/302] Updating changelog entry name --- changelog.d/5123.misc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/5123.misc b/changelog.d/5123.misc index 790910e493..cb1a7adf08 100644 --- a/changelog.d/5123.misc +++ b/changelog.d/5123.misc @@ -1 +1 @@ -Add completion for @room as per element web +Add completion for @room to notify everyone in a room From 2beff8d4cd4a266b8e54009de89deab43feac661 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Fri, 11 Feb 2022 11:03:20 +0100 Subject: [PATCH 115/302] adding headers to separate sections --- .../autocomplete/AutocompleteHeaderItem.kt | 39 +++++++++++++++ .../autocomplete/AutocompleteMatrixItem.kt | 1 - .../member/AutocompleteMemberController.kt | 9 ++++ .../member/AutocompleteMemberItem.kt | 2 +- .../member/AutocompleteMemberPresenter.kt | 49 +++++++++++++++++-- .../home/room/detail/AutoCompleter.kt | 12 +++-- .../layout/item_autocomplete_header_item.xml | 21 ++++++++ 7 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteHeaderItem.kt create mode 100644 vector/src/main/res/layout/item_autocomplete_header_item.xml diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteHeaderItem.kt b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteHeaderItem.kt new file mode 100644 index 0000000000..f287104415 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteHeaderItem.kt @@ -0,0 +1,39 @@ +/* + * 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.autocomplete + +import android.widget.TextView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.app.R +import im.vector.app.core.epoxy.VectorEpoxyHolder +import im.vector.app.core.epoxy.VectorEpoxyModel + +@EpoxyModelClass(layout = R.layout.item_autocomplete_header_item) +abstract class AutocompleteHeaderItem : VectorEpoxyModel() { + + @EpoxyAttribute var title: String? = null + + override fun bind(holder: Holder) { + super.bind(holder) + holder.titleView.text = title + } + + class Holder : VectorEpoxyHolder() { + val titleView by bind(R.id.headerItemAutocompleteTitle) + } +} diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt index d0e2c81b56..dba2661927 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/AutocompleteMatrixItem.kt @@ -30,7 +30,6 @@ import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.util.MatrixItem -// TODO create a new item for sections: AutocompleteSection @EpoxyModelClass(layout = R.layout.item_autocomplete_matrix_item) abstract class AutocompleteMatrixItem : VectorEpoxyModel() { diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt index 2132cc2f1d..ce515ad6ad 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt @@ -20,6 +20,7 @@ import android.content.Context import com.airbnb.epoxy.TypedEpoxyController import im.vector.app.R import im.vector.app.features.autocomplete.AutocompleteClickListener +import im.vector.app.features.autocomplete.autocompleteHeaderItem import im.vector.app.features.autocomplete.autocompleteMatrixItem import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.util.toEveryoneInRoomMatrixItem @@ -51,6 +52,7 @@ class AutocompleteMemberController @Inject constructor(private val context: Cont } data.forEach { item -> when (item) { + is AutocompleteMemberItem.Header -> buildHeaderItem(item) is AutocompleteMemberItem.RoomMember -> buildRoomMemberItem(item) is AutocompleteMemberItem.Everyone -> buildEveryoneItem(item) } @@ -61,6 +63,13 @@ class AutocompleteMemberController @Inject constructor(private val context: Cont // HELPER METHODS /////////////////////////////////////////////////////////////////////////// + private fun buildHeaderItem(header: AutocompleteMemberItem.Header) { + autocompleteHeaderItem { + id(header.id) + title(header.title) + } + } + private fun buildRoomMemberItem(roomMember: AutocompleteMemberItem.RoomMember) { val host = this autocompleteMatrixItem { diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberItem.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberItem.kt index fa9693895f..77c5069938 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberItem.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberItem.kt @@ -20,7 +20,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary sealed class AutocompleteMemberItem { - // TODO add section class + data class Header(val id: String, val title: String) : AutocompleteMemberItem() data class RoomMember(val roomMemberSummary: RoomMemberSummary) : AutocompleteMemberItem() data class Everyone(val roomSummary: RoomSummary) : AutocompleteMemberItem() } diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt index 5640632ec2..3830742adc 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt @@ -21,6 +21,7 @@ import androidx.recyclerview.widget.RecyclerView import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import im.vector.app.R import im.vector.app.features.autocomplete.AutocompleteClickListener import im.vector.app.features.autocomplete.RecyclerViewPresenter import org.matrix.android.sdk.api.query.QueryStringValue @@ -36,12 +37,24 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, private val controller: AutocompleteMemberController ) : RecyclerViewPresenter(context), AutocompleteClickListener { + /////////////////////////////////////////////////////////////////////////// + // FIELDS + /////////////////////////////////////////////////////////////////////////// + private val room by lazy { session.getRoom(roomId)!! } + /////////////////////////////////////////////////////////////////////////// + // INIT + /////////////////////////////////////////////////////////////////////////// + init { controller.listener = this } + /////////////////////////////////////////////////////////////////////////// + // PUBLIC API + /////////////////////////////////////////////////////////////////////////// + fun clear() { controller.listener = null } @@ -51,6 +64,10 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, fun create(roomId: String): AutocompleteMemberPresenter } + /////////////////////////////////////////////////////////////////////////// + // SPECIALIZATION + /////////////////////////////////////////////////////////////////////////// + override fun instantiateAdapter(): RecyclerView.Adapter<*> { return controller.adapter } @@ -70,6 +87,10 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, excludeSelf = true } + val membersHeader = AutocompleteMemberItem.Header( + ID_HEADER_MEMBERS, + context.getString(R.string.room_message_autocomplete_users) + ) val members = room.getRoomMembers(queryParams) .asSequence() .sortedBy { it.displayName } @@ -81,17 +102,35 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, val everyone = room.roomSummary() ?.takeIf { query.isNullOrBlank() || MatrixItem.NOTIFY_EVERYONE.startsWith("@$query") } ?.let { - AutocompleteMemberItem.Everyone(it) - } + AutocompleteMemberItem.Everyone(it) + } val items = mutableListOf().apply { - // TODO add header sections - addAll(members) - everyone?.let { add(it) } + if(members.isNotEmpty()) { + add(membersHeader) + addAll(members) + } + everyone?.let { + val everyoneHeader = AutocompleteMemberItem.Header( + ID_HEADER_EVERYONE, + context.getString(R.string.room_message_autocomplete_notification) + ) + add(everyoneHeader) + add(it) + } } controller.setData(items) } + + /////////////////////////////////////////////////////////////////////////// + // CONST + /////////////////////////////////////////////////////////////////////////// + + companion object { + private const val ID_HEADER_MEMBERS = "ID_HEADER_MEMBERS" + private const val ID_HEADER_EVERYONE = "ID_HEADER_EVERYONE" + } } private fun Sequence.disambiguate(): Sequence { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt index 550f89dd70..38548377aa 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt @@ -133,13 +133,17 @@ class AutoCompleter @AssistedInject constructor( .with(backgroundDrawable) .with(object : AutocompleteCallback { override fun onPopupItemClicked(editable: Editable, item: AutocompleteMemberItem): Boolean { - when (item) { - is AutocompleteMemberItem.RoomMember -> + return when (item) { + is AutocompleteMemberItem.Header -> false // do nothing header is not clickable + is AutocompleteMemberItem.RoomMember -> { insertMatrixItem(editText, editable, TRIGGER_AUTO_COMPLETE_MEMBERS, item.roomMemberSummary.toMatrixItem()) - is AutocompleteMemberItem.Everyone -> + true + } + is AutocompleteMemberItem.Everyone -> { insertMatrixItem(editText, editable, TRIGGER_AUTO_COMPLETE_MEMBERS, item.roomSummary.toEveryoneInRoomMatrixItem()) + true + } } - return true } override fun onPopupVisibilityChanged(shown: Boolean) { diff --git a/vector/src/main/res/layout/item_autocomplete_header_item.xml b/vector/src/main/res/layout/item_autocomplete_header_item.xml new file mode 100644 index 0000000000..f842129e0c --- /dev/null +++ b/vector/src/main/res/layout/item_autocomplete_header_item.xml @@ -0,0 +1,21 @@ + + + + + + From fb2401d0b1339da03ee3149544d79e4040c9a3fc Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Fri, 11 Feb 2022 17:29:33 +0100 Subject: [PATCH 116/302] Fixing parsing of outcoming messages for @room chip (missing incoming messages) --- .../matrix/android/sdk/api/util/MatrixItem.kt | 5 +- .../session/room/send/pills/TextPillsUtils.kt | 3 + .../home/room/detail/AutoCompleter.kt | 2 +- .../timeline/factory/MessageItemFactory.kt | 1 + .../app/features/html/PillsPostProcessor.kt | 111 +++++++++++++----- 5 files changed, 89 insertions(+), 33 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt index 1f3a94b2ad..b665ef7116 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt @@ -43,8 +43,9 @@ sealed class MatrixItem( override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) } + // TODO is it correct to represent it by a Matrix Item ? => to confirm data class EveryoneInRoomItem(override val id: String, - override val displayName: String? = null, + override val displayName: String = NOTIFY_EVERYONE, override val avatarUrl: String? = null, val roomDisplayName: String? = null) : MatrixItem(id, displayName, avatarUrl) { @@ -190,7 +191,7 @@ fun RoomSummary.toMatrixItem() = if (roomType == RoomType.SPACE) { fun RoomSummary.toRoomAliasMatrixItem() = MatrixItem.RoomAliasItem(canonicalAlias ?: roomId, displayName, avatarUrl) -fun RoomSummary.toEveryoneInRoomMatrixItem() = MatrixItem.EveryoneInRoomItem(roomId, MatrixItem.NOTIFY_EVERYONE, avatarUrl, displayName) +fun RoomSummary.toEveryoneInRoomMatrixItem() = MatrixItem.EveryoneInRoomItem(id = roomId, avatarUrl = avatarUrl, roomDisplayName = displayName) // If no name is available, use room alias as Riot-Web does fun PublicRoom.toMatrixItem() = MatrixItem.RoomItem(roomId, name ?: getPrimaryAlias() ?: "", avatarUrl) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/pills/TextPillsUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/pills/TextPillsUtils.kt index 33cb0db243..ccbfbfcded 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/pills/TextPillsUtils.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/pills/TextPillsUtils.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.send.pills import android.text.SpannableString import org.matrix.android.sdk.api.session.room.send.MatrixItemSpan +import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.internal.session.displayname.DisplayNameResolver import java.util.Collections import javax.inject.Inject @@ -51,6 +52,8 @@ internal class TextPillsUtils @Inject constructor( val pills = spannableString ?.getSpans(0, text.length, MatrixItemSpan::class.java) ?.map { MentionLinkSpec(it, spannableString.getSpanStart(it), spannableString.getSpanEnd(it)) } + // we use the raw text for @room notification instead of a link + ?.filterNot { it.span.matrixItem is MatrixItem.EveryoneInRoomItem } ?.toMutableList() ?.takeIf { it.isNotEmpty() } ?: return null diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt index 38548377aa..be5f9c0bb4 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/AutoCompleter.kt @@ -238,7 +238,7 @@ class AutoCompleter @AssistedInject constructor( // Adding trailing space " " or ": " if the user started mention someone val displayNameSuffix = - if (firstChar == TRIGGER_AUTO_COMPLETE_MEMBERS && startIndex == 0) { + if (matrixItem is MatrixItem.UserItem) { ": " } else { " " diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 0c836748c8..9ab532e5be 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -549,6 +549,7 @@ class MessageItemFactory @Inject constructor( highlight: Boolean, callback: TimelineEventController.Callback?, attributes: AbsMessageItem.Attributes): MessageTextItem? { + // TODO process body to add pills for @room texts: create a dedicated renderer with PillsPostProcessor ? val bindingOptions = spanUtils.getBindingOptions(body) val linkifiedBody = body.linkify(callback) diff --git a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt index 8376d25065..b2dc190c6f 100644 --- a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt @@ -36,58 +36,109 @@ class PillsPostProcessor @AssistedInject constructor(@Assisted private val roomI private val context: Context, private val avatarRenderer: AvatarRenderer, private val sessionHolder: ActiveSessionHolder) : - EventHtmlRenderer.PostProcessor { + EventHtmlRenderer.PostProcessor { @AssistedFactory interface Factory { fun create(roomId: String?): PillsPostProcessor } + /////////////////////////////////////////////////////////////////////////// + // SPECIALIZATION + /////////////////////////////////////////////////////////////////////////// + override fun afterRender(renderedText: Spannable) { addPillSpans(renderedText, roomId) } + /////////////////////////////////////////////////////////////////////////// + // HELPER METHODS + /////////////////////////////////////////////////////////////////////////// + private fun addPillSpans(renderedText: Spannable, roomId: String?) { + addLinkSpans(renderedText, roomId) + roomId?.let { id -> addRawTextSpans(renderedText, id) } + } + + private fun addPillSpan( + renderedText: Spannable, + pillSpan: PillImageSpan, + startSpan: Int, + endSpan: Int + ) { + renderedText.setSpan(pillSpan, startSpan, endSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + } + + private fun addLinkSpans(renderedText: Spannable, roomId: String?) { // We let markdown handle links and then we add PillImageSpan if needed. val linkSpans = renderedText.getSpans(0, renderedText.length, LinkSpan::class.java) linkSpans.forEach { linkSpan -> val pillSpan = linkSpan.createPillSpan(roomId) ?: return@forEach val startSpan = renderedText.getSpanStart(linkSpan) val endSpan = renderedText.getSpanEnd(linkSpan) - renderedText.setSpan(pillSpan, startSpan, endSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + addPillSpan(renderedText, pillSpan, startSpan, endSpan) } } + // TODO move this into another PostProcessor when there is no html + private fun addRawTextSpans(renderedText: Spannable, roomId: String) { + if (renderedText.contains(MatrixItem.NOTIFY_EVERYONE)) { + addNotifyEveryoneSpans(renderedText, roomId) + } + } + + private fun addNotifyEveryoneSpans(renderedText: Spannable, roomId: String) { + val room: RoomSummary? = sessionHolder.getSafeActiveSession()?.getRoomSummary(roomId) + val matrixItem = MatrixItem.EveryoneInRoomItem( + id = roomId, + avatarUrl = room?.avatarUrl, + roomDisplayName = room?.displayName + ) + val pillSpan = createPillImageSpan(matrixItem) + + // search for notify everyone text + var foundIndex = renderedText.indexOf(MatrixItem.NOTIFY_EVERYONE, 0) + while (foundIndex >= 0) { + val endSpan = foundIndex + MatrixItem.NOTIFY_EVERYONE.length + addPillSpan(renderedText, pillSpan, foundIndex, endSpan) + foundIndex = renderedText.indexOf(MatrixItem.NOTIFY_EVERYONE, endSpan) + } + } + + private fun createPillImageSpan(matrixItem: MatrixItem) = + PillImageSpan(GlideApp.with(context), avatarRenderer, context, matrixItem) + private fun LinkSpan.createPillSpan(roomId: String?): PillImageSpan? { - // TODO handle @room text to create associated chip - val permalinkData = PermalinkParser.parse(url) - val matrixItem = when (permalinkData) { - is PermalinkData.UserLink -> { - if (roomId == null) { - sessionHolder.getSafeActiveSession()?.getUser(permalinkData.userId)?.toMatrixItem() - } else { - sessionHolder.getSafeActiveSession()?.getRoomMember(permalinkData.userId, roomId)?.toMatrixItem() - } - } - is PermalinkData.RoomLink -> { - if (permalinkData.eventId == null) { - val room: RoomSummary? = sessionHolder.getSafeActiveSession()?.getRoomSummary(permalinkData.roomIdOrAlias) - if (permalinkData.isRoomAlias) { - MatrixItem.RoomAliasItem(permalinkData.roomIdOrAlias, room?.displayName, room?.avatarUrl) - } else { - MatrixItem.RoomItem(permalinkData.roomIdOrAlias, room?.displayName, room?.avatarUrl) - } - } else { - // Exclude event link (used in reply events, we do not want to pill the "in reply to") - null - } - } - is PermalinkData.GroupLink -> { - val group = sessionHolder.getSafeActiveSession()?.getGroupSummary(permalinkData.groupId) - MatrixItem.GroupItem(permalinkData.groupId, group?.displayName, group?.avatarUrl) - } + val matrixItem = when (val permalinkData = PermalinkParser.parse(url)) { + is PermalinkData.UserLink -> permalinkData.toMatrixItem(roomId) + is PermalinkData.RoomLink -> permalinkData.toMatrixItem() + is PermalinkData.GroupLink -> permalinkData.toMatrixItem() else -> null } ?: return null - return PillImageSpan(GlideApp.with(context), avatarRenderer, context, matrixItem) + return createPillImageSpan(matrixItem) + } + + private fun PermalinkData.UserLink.toMatrixItem(roomId: String?): MatrixItem? = + if (roomId == null) { + sessionHolder.getSafeActiveSession()?.getUser(userId)?.toMatrixItem() + } else { + sessionHolder.getSafeActiveSession()?.getRoomMember(userId, roomId)?.toMatrixItem() + } + + private fun PermalinkData.RoomLink.toMatrixItem(): MatrixItem? = + if (eventId == null) { + val room: RoomSummary? = sessionHolder.getSafeActiveSession()?.getRoomSummary(roomIdOrAlias) + when { + isRoomAlias -> MatrixItem.RoomAliasItem(roomIdOrAlias, room?.displayName, room?.avatarUrl) + else -> MatrixItem.RoomItem(roomIdOrAlias, room?.displayName, room?.avatarUrl) + } + } else { + // Exclude event link (used in reply events, we do not want to pill the "in reply to") + null + } + + private fun PermalinkData.GroupLink.toMatrixItem(): MatrixItem? { + val group = sessionHolder.getSafeActiveSession()?.getGroupSummary(groupId) + return MatrixItem.GroupItem(groupId, group?.displayName, group?.avatarUrl) } } From 07a59e63a6e664183f80645cd0ede0e3561395c0 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Mon, 14 Feb 2022 12:28:18 +0100 Subject: [PATCH 117/302] Create chips for incoming messages --- .../timeline/factory/MessageItemFactory.kt | 12 ++- .../timeline/render/EventTextRenderer.kt | 95 +++++++++++++++++++ .../app/features/html/PillsPostProcessor.kt | 26 ----- 3 files changed, 104 insertions(+), 29 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 9ab532e5be..aa1758dd6c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -61,6 +61,7 @@ import im.vector.app.features.home.room.detail.timeline.item.RedactedMessageItem import im.vector.app.features.home.room.detail.timeline.item.RedactedMessageItem_ import im.vector.app.features.home.room.detail.timeline.item.VerificationRequestItem import im.vector.app.features.home.room.detail.timeline.item.VerificationRequestItem_ +import im.vector.app.features.home.room.detail.timeline.render.EventTextRenderer import im.vector.app.features.home.room.detail.timeline.tools.createLinkMovementMethod import im.vector.app.features.home.room.detail.timeline.tools.linkify import im.vector.app.features.html.EventHtmlRenderer @@ -112,6 +113,7 @@ class MessageItemFactory @Inject constructor( private val timelineMediaSizeProvider: TimelineMediaSizeProvider, private val htmlRenderer: Lazy, private val htmlCompressor: VectorHtmlCompressor, + private val textRendererFactory: EventTextRenderer.Factory, private val stringProvider: StringProvider, private val imageContentRenderer: ImageContentRenderer, private val messageInformationDataFactory: MessageInformationDataFactory, @@ -138,6 +140,10 @@ class MessageItemFactory @Inject constructor( pillsPostProcessorFactory.create(roomId) } + private val textRenderer by lazy { + textRendererFactory.create(roomId) + } + fun create(params: TimelineItemFactoryParams): VectorEpoxyModel<*>? { val event = params.event val highlight = params.isHighlighted @@ -549,9 +555,9 @@ class MessageItemFactory @Inject constructor( highlight: Boolean, callback: TimelineEventController.Callback?, attributes: AbsMessageItem.Attributes): MessageTextItem? { - // TODO process body to add pills for @room texts: create a dedicated renderer with PillsPostProcessor ? - val bindingOptions = spanUtils.getBindingOptions(body) - val linkifiedBody = body.linkify(callback) + val renderedBody = textRenderer.render(body) + val bindingOptions = spanUtils.getBindingOptions(renderedBody) + val linkifiedBody = renderedBody.linkify(callback) return MessageTextItem_() .message( diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt new file mode 100644 index 0000000000..29761e0d68 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2022 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.home.room.detail.timeline.render + +import android.content.Context +import android.text.Spannable +import android.text.SpannableStringBuilder +import android.text.Spanned +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import im.vector.app.core.di.ActiveSessionHolder +import im.vector.app.core.glide.GlideApp +import im.vector.app.features.home.AvatarRenderer +import im.vector.app.features.html.PillImageSpan +import org.matrix.android.sdk.api.session.room.model.RoomSummary +import org.matrix.android.sdk.api.util.MatrixItem +import timber.log.Timber + +class EventTextRenderer @AssistedInject constructor(@Assisted private val roomId: String?, + private val context: Context, + private val avatarRenderer: AvatarRenderer, + private val sessionHolder: ActiveSessionHolder) { + + /////////////////////////////////////////////////////////////////////////// + // PUBLIC API + /////////////////////////////////////////////////////////////////////////// + + @AssistedFactory + interface Factory { + fun create(roomId: String?): EventTextRenderer + } + + /** + * @param text the text you want to render + */ + fun render(text: CharSequence): CharSequence { + return if (roomId != null && text.contains(MatrixItem.NOTIFY_EVERYONE)) { + SpannableStringBuilder(text).apply { + addNotifyEveryoneSpans(this, roomId) + } + } else { + text + } + } + + /////////////////////////////////////////////////////////////////////////// + // HELPER METHODS + /////////////////////////////////////////////////////////////////////////// + + private fun addNotifyEveryoneSpans(text: Spannable, roomId: String) { + val room: RoomSummary? = sessionHolder.getSafeActiveSession()?.getRoomSummary(roomId) + val matrixItem = MatrixItem.EveryoneInRoomItem( + id = roomId, + avatarUrl = room?.avatarUrl, + roomDisplayName = room?.displayName + ) + + // search for notify everyone text + var foundIndex = text.indexOf(MatrixItem.NOTIFY_EVERYONE, 0) + while (foundIndex >= 0) { + val endSpan = foundIndex + MatrixItem.NOTIFY_EVERYONE.length + //text.setSpan(ForegroundColorSpan(Color.RED), foundIndex, endSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + addPillSpan(text, createPillImageSpan(matrixItem), foundIndex, endSpan) + Timber.e("set span for text $text from index $foundIndex to $endSpan") + foundIndex = text.indexOf(MatrixItem.NOTIFY_EVERYONE, endSpan) + } + } + + private fun createPillImageSpan(matrixItem: MatrixItem) = + PillImageSpan(GlideApp.with(context), avatarRenderer, context, matrixItem) + + private fun addPillSpan( + renderedText: Spannable, + pillSpan: PillImageSpan, + startSpan: Int, + endSpan: Int + ) { + renderedText.setSpan(pillSpan, startSpan, endSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + } +} diff --git a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt index b2dc190c6f..2c5115f481 100644 --- a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt @@ -57,7 +57,6 @@ class PillsPostProcessor @AssistedInject constructor(@Assisted private val roomI private fun addPillSpans(renderedText: Spannable, roomId: String?) { addLinkSpans(renderedText, roomId) - roomId?.let { id -> addRawTextSpans(renderedText, id) } } private fun addPillSpan( @@ -80,31 +79,6 @@ class PillsPostProcessor @AssistedInject constructor(@Assisted private val roomI } } - // TODO move this into another PostProcessor when there is no html - private fun addRawTextSpans(renderedText: Spannable, roomId: String) { - if (renderedText.contains(MatrixItem.NOTIFY_EVERYONE)) { - addNotifyEveryoneSpans(renderedText, roomId) - } - } - - private fun addNotifyEveryoneSpans(renderedText: Spannable, roomId: String) { - val room: RoomSummary? = sessionHolder.getSafeActiveSession()?.getRoomSummary(roomId) - val matrixItem = MatrixItem.EveryoneInRoomItem( - id = roomId, - avatarUrl = room?.avatarUrl, - roomDisplayName = room?.displayName - ) - val pillSpan = createPillImageSpan(matrixItem) - - // search for notify everyone text - var foundIndex = renderedText.indexOf(MatrixItem.NOTIFY_EVERYONE, 0) - while (foundIndex >= 0) { - val endSpan = foundIndex + MatrixItem.NOTIFY_EVERYONE.length - addPillSpan(renderedText, pillSpan, foundIndex, endSpan) - foundIndex = renderedText.indexOf(MatrixItem.NOTIFY_EVERYONE, endSpan) - } - } - private fun createPillImageSpan(matrixItem: MatrixItem) = PillImageSpan(GlideApp.with(context), avatarRenderer, context, matrixItem) From 24a92d5a1eb6ae3f6497a05382bd8fa54391d246 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Mon, 14 Feb 2022 14:10:41 +0100 Subject: [PATCH 118/302] Setting background color for chips --- .../home/room/detail/timeline/render/EventTextRenderer.kt | 3 --- .../main/java/im/vector/app/features/html/PillImageSpan.kt | 5 +++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt index 29761e0d68..dab3f41570 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt @@ -29,7 +29,6 @@ import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.html.PillImageSpan import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.util.MatrixItem -import timber.log.Timber class EventTextRenderer @AssistedInject constructor(@Assisted private val roomId: String?, private val context: Context, @@ -74,9 +73,7 @@ class EventTextRenderer @AssistedInject constructor(@Assisted private val roomId var foundIndex = text.indexOf(MatrixItem.NOTIFY_EVERYONE, 0) while (foundIndex >= 0) { val endSpan = foundIndex + MatrixItem.NOTIFY_EVERYONE.length - //text.setSpan(ForegroundColorSpan(Color.RED), foundIndex, endSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) addPillSpan(text, createPillImageSpan(matrixItem), foundIndex, endSpan) - Timber.e("set span for text $text from index $foundIndex to $endSpan") foundIndex = text.indexOf(MatrixItem.NOTIFY_EVERYONE, endSpan) } } diff --git a/vector/src/main/java/im/vector/app/features/html/PillImageSpan.kt b/vector/src/main/java/im/vector/app/features/html/PillImageSpan.kt index ff2e2a9cdb..3a388cfc69 100644 --- a/vector/src/main/java/im/vector/app/features/html/PillImageSpan.kt +++ b/vector/src/main/java/im/vector/app/features/html/PillImageSpan.kt @@ -19,6 +19,7 @@ package im.vector.app.features.html import android.content.Context +import android.content.res.ColorStateList import android.graphics.Canvas import android.graphics.Paint import android.graphics.drawable.Drawable @@ -32,6 +33,7 @@ import im.vector.app.R import im.vector.app.core.glide.GlideRequests import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer +import im.vector.app.features.themes.ThemeUtils import org.matrix.android.sdk.api.session.room.send.MatrixItemSpan import org.matrix.android.sdk.api.util.MatrixItem import java.lang.ref.WeakReference @@ -117,6 +119,9 @@ class PillImageSpan(private val glideRequests: GlideRequests, setChipMinHeightResource(R.dimen.pill_min_height) setChipIconSizeResource(R.dimen.pill_avatar_size) chipIcon = icon + if (matrixItem is MatrixItem.EveryoneInRoomItem) { + chipBackgroundColor = ColorStateList.valueOf(ThemeUtils.getColor(context, R.attr.colorError)) + } setBounds(0, 0, intrinsicWidth, intrinsicHeight) } } From df35da5571f9ccce6419306be5fad3970efd0b60 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Mon, 14 Feb 2022 14:43:24 +0100 Subject: [PATCH 119/302] Fixing code format issues --- .../member/AutocompleteMemberController.kt | 28 ++++++++-------- .../member/AutocompleteMemberPresenter.kt | 32 +++++++++---------- .../timeline/render/EventTextRenderer.kt | 12 +++---- .../app/features/html/PillsPostProcessor.kt | 16 ++++++---- 4 files changed, 46 insertions(+), 42 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt index ce515ad6ad..04bcbd7f01 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt @@ -27,24 +27,24 @@ import org.matrix.android.sdk.api.util.toEveryoneInRoomMatrixItem import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject -class AutocompleteMemberController @Inject constructor(private val context: Context) - : TypedEpoxyController>() { +class AutocompleteMemberController @Inject constructor(private val context: Context) : + TypedEpoxyController>() { - /////////////////////////////////////////////////////////////////////////// - // FIELDS - /////////////////////////////////////////////////////////////////////////// + /* ========================================================================================== + * Fields + * ========================================================================================== */ var listener: AutocompleteClickListener? = null - /////////////////////////////////////////////////////////////////////////// - // DEPENDENCIES - /////////////////////////////////////////////////////////////////////////// + /* ========================================================================================== + * Dependencies + * ========================================================================================== */ @Inject lateinit var avatarRenderer: AvatarRenderer - /////////////////////////////////////////////////////////////////////////// - // SPECIALIZATION - /////////////////////////////////////////////////////////////////////////// + /* ========================================================================================== + * Specialization + * ========================================================================================== */ override fun buildModels(data: List?) { if (data.isNullOrEmpty()) { @@ -59,9 +59,9 @@ class AutocompleteMemberController @Inject constructor(private val context: Cont } } - /////////////////////////////////////////////////////////////////////////// - // HELPER METHODS - /////////////////////////////////////////////////////////////////////////// + /* ========================================================================================== + * Helper methods + * ========================================================================================== */ private fun buildHeaderItem(header: AutocompleteMemberItem.Header) { autocompleteHeaderItem { diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt index 3830742adc..73e5bfe7b9 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt @@ -37,23 +37,23 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, private val controller: AutocompleteMemberController ) : RecyclerViewPresenter(context), AutocompleteClickListener { - /////////////////////////////////////////////////////////////////////////// - // FIELDS - /////////////////////////////////////////////////////////////////////////// + /* ========================================================================================== + * Fields + * ========================================================================================== */ private val room by lazy { session.getRoom(roomId)!! } - /////////////////////////////////////////////////////////////////////////// - // INIT - /////////////////////////////////////////////////////////////////////////// + /* ========================================================================================== + * Init + * ========================================================================================== */ init { controller.listener = this } - /////////////////////////////////////////////////////////////////////////// - // PUBLIC API - /////////////////////////////////////////////////////////////////////////// + /* ========================================================================================== + * Public api + * ========================================================================================== */ fun clear() { controller.listener = null @@ -64,9 +64,9 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, fun create(roomId: String): AutocompleteMemberPresenter } - /////////////////////////////////////////////////////////////////////////// - // SPECIALIZATION - /////////////////////////////////////////////////////////////////////////// + /* ========================================================================================== + * Specialization + * ========================================================================================== */ override fun instantiateAdapter(): RecyclerView.Adapter<*> { return controller.adapter @@ -106,7 +106,7 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, } val items = mutableListOf().apply { - if(members.isNotEmpty()) { + if (members.isNotEmpty()) { add(membersHeader) addAll(members) } @@ -123,9 +123,9 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, controller.setData(items) } - /////////////////////////////////////////////////////////////////////////// - // CONST - /////////////////////////////////////////////////////////////////////////// + /* ========================================================================================== + * Const + * ========================================================================================== */ companion object { private const val ID_HEADER_MEMBERS = "ID_HEADER_MEMBERS" diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt index dab3f41570..d50a6fb297 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt @@ -35,9 +35,9 @@ class EventTextRenderer @AssistedInject constructor(@Assisted private val roomId private val avatarRenderer: AvatarRenderer, private val sessionHolder: ActiveSessionHolder) { - /////////////////////////////////////////////////////////////////////////// - // PUBLIC API - /////////////////////////////////////////////////////////////////////////// + /* ========================================================================================== + * Public api + * ========================================================================================== */ @AssistedFactory interface Factory { @@ -57,9 +57,9 @@ class EventTextRenderer @AssistedInject constructor(@Assisted private val roomId } } - /////////////////////////////////////////////////////////////////////////// - // HELPER METHODS - /////////////////////////////////////////////////////////////////////////// + /* ========================================================================================== + * Helper methods + * ========================================================================================== */ private fun addNotifyEveryoneSpans(text: Spannable, roomId: String) { val room: RoomSummary? = sessionHolder.getSafeActiveSession()?.getRoomSummary(roomId) diff --git a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt index 2c5115f481..506f5e773c 100644 --- a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt @@ -38,22 +38,26 @@ class PillsPostProcessor @AssistedInject constructor(@Assisted private val roomI private val sessionHolder: ActiveSessionHolder) : EventHtmlRenderer.PostProcessor { + /* ========================================================================================== + * Public api + * ========================================================================================== */ + @AssistedFactory interface Factory { fun create(roomId: String?): PillsPostProcessor } - /////////////////////////////////////////////////////////////////////////// - // SPECIALIZATION - /////////////////////////////////////////////////////////////////////////// + /* ========================================================================================== + * Specialization + * ========================================================================================== */ override fun afterRender(renderedText: Spannable) { addPillSpans(renderedText, roomId) } - /////////////////////////////////////////////////////////////////////////// - // HELPER METHODS - /////////////////////////////////////////////////////////////////////////// + /* ========================================================================================== + * Helper methods + * ========================================================================================== */ private fun addPillSpans(renderedText: Spannable, roomId: String?) { addLinkSpans(renderedText, roomId) From 49596dcea3edc9b52cffca078b231308bc75d82e Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Mon, 14 Feb 2022 15:57:23 +0100 Subject: [PATCH 120/302] Mocking check of permission to notify room --- .../session/room/model/PowerLevelsContent.kt | 1 - .../member/AutocompleteMemberController.kt | 1 - .../member/AutocompleteMemberPresenter.kt | 86 ++++++++++++------- 3 files changed, 55 insertions(+), 33 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PowerLevelsContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PowerLevelsContent.kt index 371fb922e6..5c46db7166 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PowerLevelsContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PowerLevelsContent.kt @@ -100,7 +100,6 @@ data class PowerLevelsContent( } } - // TODO use this to check if user can notify everyone => compare user role to room permission setting companion object { /** * Key to use for content.notifications and get the level required to trigger an @room notification. Defaults to 50 if unspecified. diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt index 04bcbd7f01..2034cee90a 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt @@ -84,7 +84,6 @@ class AutocompleteMemberController @Inject constructor(private val context: Cont private fun buildEveryoneItem(everyone: AutocompleteMemberItem.Everyone) { val host = this - autocompleteMatrixItem { everyone.roomSummary.let { room -> id(room.roomId) diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt index 73e5bfe7b9..476c7d850c 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt @@ -26,6 +26,7 @@ import im.vector.app.features.autocomplete.AutocompleteClickListener import im.vector.app.features.autocomplete.RecyclerViewPresenter import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.room.members.RoomMemberQueryParams 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.RoomMemberSummary @@ -77,33 +78,10 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, } override fun onQuery(query: CharSequence?) { - val queryParams = roomMemberQueryParams { - displayName = if (query.isNullOrBlank()) { - QueryStringValue.IsNotEmpty - } else { - QueryStringValue.Contains(query.toString(), QueryStringValue.Case.INSENSITIVE) - } - memberships = listOf(Membership.JOIN) - excludeSelf = true - } - - val membersHeader = AutocompleteMemberItem.Header( - ID_HEADER_MEMBERS, - context.getString(R.string.room_message_autocomplete_users) - ) - val members = room.getRoomMembers(queryParams) - .asSequence() - .sortedBy { it.displayName } - .disambiguate() - .map { AutocompleteMemberItem.RoomMember(it) } - .toList() - - // TODO check if user can notify everyone => compare user role to room permission setting: PowerLevelsContent - val everyone = room.roomSummary() - ?.takeIf { query.isNullOrBlank() || MatrixItem.NOTIFY_EVERYONE.startsWith("@$query") } - ?.let { - AutocompleteMemberItem.Everyone(it) - } + val queryParams = createQueryParams(query) + val membersHeader = createMembersHeader() + val members = createMemberItems(queryParams) + val everyone = createEveryoneItem(query) val items = mutableListOf().apply { if (members.isNotEmpty()) { @@ -111,10 +89,7 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, addAll(members) } everyone?.let { - val everyoneHeader = AutocompleteMemberItem.Header( - ID_HEADER_EVERYONE, - context.getString(R.string.room_message_autocomplete_notification) - ) + val everyoneHeader = createEveryoneHeader() add(everyoneHeader) add(it) } @@ -123,6 +98,55 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, controller.setData(items) } + /* ========================================================================================== + * Helper methods + * ========================================================================================== */ + + private fun createQueryParams(query: CharSequence?) = roomMemberQueryParams { + displayName = if (query.isNullOrBlank()) { + QueryStringValue.IsNotEmpty + } else { + QueryStringValue.Contains(query.toString(), QueryStringValue.Case.INSENSITIVE) + } + memberships = listOf(Membership.JOIN) + excludeSelf = true + } + + private fun createMembersHeader() = + AutocompleteMemberItem.Header( + ID_HEADER_MEMBERS, + context.getString(R.string.room_message_autocomplete_users) + ) + + private fun createMemberItems(queryParams: RoomMemberQueryParams) = + room.getRoomMembers(queryParams) + .asSequence() + .sortedBy { it.displayName } + .disambiguate() + .map { AutocompleteMemberItem.RoomMember(it) } + .toList() + + private fun createEveryoneHeader() = + AutocompleteMemberItem.Header( + ID_HEADER_EVERYONE, + context.getString(R.string.room_message_autocomplete_notification) + ) + + private fun createEveryoneItem(query: CharSequence?) = + room.roomSummary() + ?.takeIf { canNotifyEveryone() } + ?.takeIf { query.isNullOrBlank() || MatrixItem.NOTIFY_EVERYONE.startsWith("@$query") } + ?.let { + AutocompleteMemberItem.Everyone(it) + } + + private fun canNotifyEveryone() = true + // TODO use session object to check ? + /*conditionResolver.resolveSenderNotificationPermissionCondition( + Event(roomId = roomId), + SenderNotificationPermissionCondition(PowerLevelsContent.NOTIFICATIONS_ROOM_KEY) + )*/ + /* ========================================================================================== * Const * ========================================================================================== */ From 10d196596c6e7a28a63d85f23319c2b9e5e4fd9b Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Tue, 15 Feb 2022 11:19:16 +0100 Subject: [PATCH 121/302] Unmocking check of permission to notify room --- .../android/sdk/api/pushrules/PushRuleService.kt | 3 +++ .../notification/DefaultPushRuleService.kt | 7 +++++++ .../member/AutocompleteMemberPresenter.kt | 16 ++++++++++------ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/PushRuleService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/PushRuleService.kt index 88268f0f86..76885d8545 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/PushRuleService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/PushRuleService.kt @@ -50,6 +50,9 @@ interface PushRuleService { // fun fulfilledBingRule(event: Event, rules: List): PushRule? + fun resolveSenderNotificationPermissionCondition(event: Event, + condition: SenderNotificationPermissionCondition): Boolean + interface PushRuleListener { fun onEvents(pushEvents: PushEvents) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/DefaultPushRuleService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/DefaultPushRuleService.kt index 3e821b8956..cdc7350f8b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/DefaultPushRuleService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/DefaultPushRuleService.kt @@ -19,11 +19,13 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.Transformations import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.api.pushrules.Action +import org.matrix.android.sdk.api.pushrules.ConditionResolver import org.matrix.android.sdk.api.pushrules.PushEvents import org.matrix.android.sdk.api.pushrules.PushRuleService import org.matrix.android.sdk.api.pushrules.RuleKind import org.matrix.android.sdk.api.pushrules.RuleScope import org.matrix.android.sdk.api.pushrules.RuleSetKey +import org.matrix.android.sdk.api.pushrules.SenderNotificationPermissionCondition import org.matrix.android.sdk.api.pushrules.getActions import org.matrix.android.sdk.api.pushrules.rest.PushRule import org.matrix.android.sdk.api.pushrules.rest.RuleSet @@ -53,6 +55,7 @@ internal class DefaultPushRuleService @Inject constructor( private val removePushRuleTask: RemovePushRuleTask, private val pushRuleFinder: PushRuleFinder, private val taskExecutor: TaskExecutor, + private val conditionResolver: ConditionResolver, @SessionDatabase private val monarchy: Monarchy ) : PushRuleService { @@ -143,6 +146,10 @@ internal class DefaultPushRuleService @Inject constructor( return pushRuleFinder.fulfilledBingRule(event, rules)?.getActions().orEmpty() } + override fun resolveSenderNotificationPermissionCondition(event: Event, condition: SenderNotificationPermissionCondition): Boolean { + return conditionResolver.resolveSenderNotificationPermissionCondition(event, condition) + } + override fun getKeywords(): LiveData> { // Keywords are all content rules that don't start with '.' val liveData = monarchy.findAllMappedWithChanges( diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt index 476c7d850c..ab4b598153 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt @@ -24,17 +24,20 @@ import dagger.assisted.AssistedInject import im.vector.app.R import im.vector.app.features.autocomplete.AutocompleteClickListener import im.vector.app.features.autocomplete.RecyclerViewPresenter +import org.matrix.android.sdk.api.pushrules.SenderNotificationPermissionCondition import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.members.RoomMemberQueryParams 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.RoomMemberSummary import org.matrix.android.sdk.api.util.MatrixItem class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, @Assisted val roomId: String, - session: Session, + private val session: Session, private val controller: AutocompleteMemberController ) : RecyclerViewPresenter(context), AutocompleteClickListener { @@ -140,12 +143,13 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, AutocompleteMemberItem.Everyone(it) } - private fun canNotifyEveryone() = true - // TODO use session object to check ? - /*conditionResolver.resolveSenderNotificationPermissionCondition( - Event(roomId = roomId), + private fun canNotifyEveryone() = session.resolveSenderNotificationPermissionCondition( + Event( + senderId = session.myUserId, + roomId = roomId + ), SenderNotificationPermissionCondition(PowerLevelsContent.NOTIFICATIONS_ROOM_KEY) - )*/ + ) /* ========================================================================================== * Const From 6736bebc9cd75dce1d629e6778cd3563628aa2cb Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Tue, 15 Feb 2022 11:28:06 +0100 Subject: [PATCH 122/302] Changing changelog entry type to feature --- changelog.d/{5123.misc => 5123.feature} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog.d/{5123.misc => 5123.feature} (100%) diff --git a/changelog.d/5123.misc b/changelog.d/5123.feature similarity index 100% rename from changelog.d/5123.misc rename to changelog.d/5123.feature From 37a990368c6e03591a01cb2cebd0ab39d5a9f5c9 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Tue, 15 Feb 2022 15:20:06 +0100 Subject: [PATCH 123/302] Fixing text color of pills in light theme --- library/ui-styles/src/main/res/values/text_appearances.xml | 6 +++++- .../main/java/im/vector/app/features/html/PillImageSpan.kt | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/library/ui-styles/src/main/res/values/text_appearances.xml b/library/ui-styles/src/main/res/values/text_appearances.xml index 4ad3fd493e..8e30dd00d6 100644 --- a/library/ui-styles/src/main/res/values/text_appearances.xml +++ b/library/ui-styles/src/main/res/values/text_appearances.xml @@ -59,6 +59,10 @@ sans-serif-medium + + - \ No newline at end of file + diff --git a/vector/src/main/java/im/vector/app/features/html/PillImageSpan.kt b/vector/src/main/java/im/vector/app/features/html/PillImageSpan.kt index 3a388cfc69..ae285b074c 100644 --- a/vector/src/main/java/im/vector/app/features/html/PillImageSpan.kt +++ b/vector/src/main/java/im/vector/app/features/html/PillImageSpan.kt @@ -121,6 +121,8 @@ class PillImageSpan(private val glideRequests: GlideRequests, chipIcon = icon if (matrixItem is MatrixItem.EveryoneInRoomItem) { chipBackgroundColor = ColorStateList.valueOf(ThemeUtils.getColor(context, R.attr.colorError)) + // setTextColor API does not exist right now for ChipDrawable, use textAppearance + setTextAppearanceResource(R.style.TextAppearance_Vector_Body_OnError) } setBounds(0, 0, intrinsicWidth, intrinsicHeight) } From 96ed30ccc45ab47326a5058b73906be085540a98 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 17 Feb 2022 11:38:28 +0100 Subject: [PATCH 124/302] Adding header section only when necessary --- .../member/AutocompleteMemberPresenter.kt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt index ab4b598153..b646e22f17 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt @@ -88,12 +88,18 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, val items = mutableListOf().apply { if (members.isNotEmpty()) { - add(membersHeader) + if (everyone != null) { + // add header only when there is everyone tag as well + add(membersHeader) + } addAll(members) } everyone?.let { - val everyoneHeader = createEveryoneHeader() - add(everyoneHeader) + if (members.isNotEmpty()) { + // add header only when there are members as well + val everyoneHeader = createEveryoneHeader() + add(everyoneHeader) + } add(it) } } From d86d6526863cccb0a2cb656c24a2ecbc23225431 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Thu, 17 Feb 2022 11:10:18 +0000 Subject: [PATCH 125/302] Translated using Weblate (Japanese) Currently translated at 72.2% (2012 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 745 +++++++++++++--------- 1 file changed, 447 insertions(+), 298 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index a491d76b86..fbad27f1dc 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -82,7 +82,7 @@ 招待 ステッカーを送信しました。 画像を送信しました。 - 部屋 + ルーム 設定 履歴 OK @@ -95,7 +95,7 @@ 共有 削除 端末情報 - 暗号化された部屋での多人数通話はサポートされていません + 暗号化されたルームでのグループ通話はサポートされていません 招待 全ての発言を既読にする 履歴 @@ -106,11 +106,11 @@ 警告 お気に入り 会話 - 部屋 - ルーム名で絞り込み - お気に入りで絞り込み - 会話で絞り込み - ルームで絞り込み + ルーム + ルーム名で絞り込む + お気に入りで絞り込む + ユーザーで絞り込む + ルーム名で絞り込む 招待中 低優先度 会話 @@ -129,7 +129,7 @@ 前回アプリケーションは正常に停止しませんでした。クラッシュ報告の画面を開きますか? 不具合を報告しました 不具合の報告の送信に失敗しました (%s) - 部屋へ参加 + ルームに参加 通話が開始できません 音声通話 ビデオ通話 @@ -141,14 +141,14 @@ ログイン画面へ戻る 電話番号 電話番号 (任意で) - ユーザ名かパスワードが正しくありません - ユーザ名は半角英数字、ドット、ハイフン、アンダスコアのみで記して下さい + ユーザー名かパスワードが正しくありません + ユーザー名は半角英数字、ドット、ハイフン、アンダスコアのみで記して下さい パスワードが短すぎます(最小6文字) 正しくない電子メールアドレスのようです 正しくない電話番号のようです すでに登録されている電子メールアドレスです。 パスワードが一致しません - パスワードを忘れた? + パスワードを忘れましたか? 登録を続行するには電子メールを確認して下さい URLはhttp://か、https://で始めて下さい ログインできません:通信エラー @@ -156,7 +156,7 @@ 登録できません:通信エラー 登録できません 正しいURLを入力して下さい - ユーザ名かパスワードが正しくありません + ユーザー名かパスワードが正しくありません 原寸 大き目 中程度 @@ -167,21 +167,21 @@ %1$d分 %2$d秒 昨日 今日 - 部屋名 + ルーム名 通話終了 呼び出し中です… はい いいえ 続ける 最新の未読へ移動 - 部屋を退室 - 本当にこの部屋を退室しますか? + ルームを退出 + このルームを退出してよろしいですか? 作成 接続中 切断中 待機中 招待 - この部屋を退室する + このルームを退出する 検索 %sさんが文字入力中… %1$sさんと %2$sさんが文字入力中… @@ -202,10 +202,10 @@ 確認 無効にする 送信中 (%s%%) - このユーザ名はすでに使用されています + このユーザー名はすでに使用されています 削除 参加 - あなたは %s さんに呼ばれてこの部屋へ参加しました + あなたは %s さんに、このルームへ招待されています 新しい会話 参加者を追加 1名 @@ -214,19 +214,19 @@ 権限を司会者へ変更 権限を管理者へ変更 ここに送信文を入力 (暗号なし)… - サーバとの接続が失われました. + サーバーとの接続が失われました. 全て再送信 未送信の文を再送信 未送信の文を削除 ファイルが見つかりません あなたはこのルームで発言する権限がありません。 - 部屋の詳細 + ルームの詳細 参加者 ファイル 設定 お気に入り 低優先度 - 会話 + 対話 忘れる 自分のアイコン画像 表示名 @@ -238,8 +238,8 @@ このアカウントで通知を許可 この端末で通知を許可 会話で発言されたとき - 部屋で発言されたとき - 部屋へ招待されたとき + グループチャットでのメッセージ + ルームへ招待されたとき 通話の呼び出しがあったとき 自動発言プログラム(Bot)が発言した時 端末起動時に開始 @@ -260,7 +260,7 @@ 端末の電話帳 端末の電話帳の使用を許可 電話帳の国番号 - 端末 + セッション一覧 全てのメッセージにタイムスタンプを表示 タイムスタンプを12時間形式で表示 端末詳細 @@ -272,7 +272,7 @@ 認証 この操作には追加の認証が必要です。 \n続行するには、パスワードを入力してください。 - 受諾 + 送信 ログイン中のアカウント 言語を選択 言語 @@ -293,48 +293,48 @@ 1週間 1ヵ月 永久に - 部屋の画像アイコン - 部屋名 - 部屋の説明 - 部屋の属性 - 部屋の属性: + ルームの画像アイコン + ルーム名 + ルームの説明 + ルームの属性 + ルームの属性: お気に入り 低優先度 なし 参加と可視範囲 - 部屋一覧へ公開する - 部屋への参加 - 部屋の発言履歴の可視範囲 - 部屋の発言履歴を読める人は? - 部屋へ参加できる人は? + ルームの一覧へ公開する + ルームへの参加 + ルームの履歴の可視範囲 + ルームの履歴を読める人は\? + ルームへ参加できる人は\? 誰でも 参加者のみ (この設定を選択した時点から) 参加者のみ (招待を送った時点から) 参加者のみ (参加した時点から) - この部屋に招待された人のみ参加可能 - 部屋のリンクを知る人なら誰でも(ゲストユーザを除く) - 部屋のリンクを知る人なら誰でも(ゲストユーザも含む) + このルームに招待された人だけ + ルームのリンクを知る人なら誰でも(ゲストユーザーを除く) + ルームのリンクを知る人なら誰でも(ゲストユーザーも含む) 再入室禁止された参加者 拡張設定 - この部屋のサーバ内識別ID + このルームのサーバー内識別ID 実験的 - これらは予期せぬ不具合が生じるかもしれない実験的機能です. 慎重に使用してください. + これらは予期せぬ不具合が生じるかもしれない実験的機能です。慎重に使用してください。 エンドツーエンド暗号化 エンドツーエンド暗号化を使用中 暗号を有効にするためにはログアウトする必要があります. 認証された端末のみで暗号化 - この部屋では, この端末から認証されていない端末への暗号送信をしません. + このセッションでは、このルームの未検証のセッションに対して暗号化されたメッセージを送信しない。 新しいアドレス (記入例 #foo:matrix.org) - この部屋はサーバ内住所表記がありません + このルームにはローカルアドレスがありません 住所表記 住所表記が正しくありません \'%s\' は正しくない形式の住所表記です - この部屋の本住所表記が設定されていません. - 本住所表記の警告 + このルームのメインアドレスが設定されていません。 + メインアドレスの警告 メインアドレスとして設定 メインアドレスとして設定を解除 - 部屋固有IDをコピー - 部屋の住所表記をコピー + ルーム固有IDをコピー + ルームのアドレスをコピー セッションID 文字の大きさ とても小さい @@ -356,7 +356,7 @@ 写真撮影やビデオ通話には, ${app_name}アプリに端末のカメラの使用を許可する必要があります. 通話を開始できませんでした。後ほどお試しください 権限が無いため、一部の機能を利用できない可能性があります… - この部屋で会議を開始するためには招待権限が必要です + このルームで会議を開始するためには招待の権限が必要です とにかく送る ログアウト ホーム @@ -373,28 +373,28 @@ アカウントを作成 送信 飛ばす - ユーザ名または電子メール + ユーザー名または電子メール パスワード 新しいパスワード - ユーザ名 + ユーザー名 電子メールアドレス 電子メールアドレス (任意で) パスワード再確認 新しいパスワードを再確認 パスワードが違います - 電子メールアドレスが違います - 電話番号が違います - 電子メールアドレスまたは電話番号が違います - 接続先サーバを指定する(追加設定) - 指定が正しくありません + メールアドレスがありません + 電話番号が入力されていません + 電子メールアドレスまたは電話番号が入力されていません + 接続先サーバーを指定する(追加設定) + トークンが正しくありません メールと電話番号の同時登録はまだシステムが対応できませんが、電話番号だけの登録は可能です。 \n \n設定からプロフィールにメールアドレスを追加できます。 - このホームサーバはあなたがロボットではない認証を求めます - ユーザ名はすでに使用されています - ホームサーバ: - 認証サーバー: - 自分用電子メールアドレスで認証をします + このホームサーバーはあなたがロボットではない認証を求めます + ユーザー名はすでに使用されています + ホームサーバー: + IDサーバー: + メールアドレスを確認しました パスワードを初期化するには, アカウントに登録されている電子メールアドレスを入力してください: あなたのアカウントに登録された電子メールアドレスの入力が必要です. 新しいパスワードの入力が必要です. @@ -402,15 +402,15 @@ 電子メールアドレスの確認に失敗しました: 電子メールのリンクをクリックしたことを確認してください パスワードがリセットされました。 \n -\nすべてのセッションからログアウトしたため、プッシュ通知を受け取れなくなりました。通知を再び有効にするには、各デバイスで再ログインをお願いします。 +\n全てのセッションからログアウトしたため、プッシュ通知を受け取れなくなりました。通知を再び有効にするには、各デバイスで再ログインをお願いします。 登録ができません : 電子メールがあなた個人のものであるか確認できません 指定されたアクセストークンが認識されませんでした 不正な形式のJSON 有効なJSONを含んでいませんでした - ログイン要求が多すぎてサーバが対応できません + ログイン要求が多すぎてサーバーが対応できません まだクリックされていないeメールのリンク 以下の容量で画像を送信 - 部屋の説明 + ルームの説明 通話が接続されました 通話を接続中… 通話着信中 @@ -423,7 +423,7 @@ 写真または動画の撮影 動画を記録できません 保存 - 試写 + プレビュー 拒否 管理者権限操作 通話 @@ -433,11 +433,11 @@ この参加者の発言を全て非表示にする この参加者の発言を全て表示する 指名して呼掛け - ユーザID, 表示名, 電子メールアドレス + ユーザーID, 表示名, 電子メールアドレス 接続端末一覧を表示 - %sさんをこの部屋へ招待して本当によろしいですか? - ユーザIDで招待 - 電子メールまたはMatrixユーザID + %sさんをこのルームに招待してよろしいですか? + ユーザーIDで招待 + 電子メールまたはMatrixユーザーID 全て中止 ログアウト 無視 @@ -447,8 +447,8 @@ 結果なし 参加者 ファイル - 部屋 - 部屋一覧を見る + ルーム + ルーム一覧を見る 退室 会話 設定 @@ -461,8 +461,8 @@ 著作権 個人情報保護方針 パスワード: - ホームサーバ - 認証サーバー + ホームサーバー + IDサーバー メールアドレスが見つかりません。 この電話番号は既に使用されています。 パスワード変更 @@ -470,28 +470,28 @@ 新しいパスワード 新しいパスワードの確認 パスワードの更新に失敗しました - %sのすべてのメッセージを表示しますか? + %sの全てのメッセージを表示しますか? \n \nこの操作はアプリを再起動するため時間がかかる場合があります。 電話番号の認証時にエラーが発生しました - この部屋へのリンクを作成するには、部屋の住所表記が必要です。 - この部屋は暗号化されています。 - この部屋は暗号化されていません。 + このルームへのリンクを作成するには、アドレスが必要です。 + このルームは暗号化されています。 + このルームは暗号化されていません。 暗号化を有効にします \n(警告: 有効後にこれを無効にすることはできません!) - 部屋一覧 + ルーム一覧 外観 エンドツーエンド暗号化についての情報 公開端末名 - 部屋のEnd-to-end暗号鍵を出力 + ルームのEnd-to-end暗号鍵を出力 認証 履歴を検索 - あなたはこの部屋に参加していません。 - あなたはこの部屋で権限がありません。 - 部屋 %s は、見ることができません。 - ユーザ名 - ホームサーバ URL - 認証サーバ ーURL + あなたはこのルームに参加していません。 + あなたはこのルームで権限がありません。 + ルーム %s は、見ることができません。 + ユーザー名 + ホームサーバー URL + IDサーバーのURL ログイン Matrixアプリを追加 権限の数値は正の整数で入力してください。 @@ -512,49 +512,47 @@ ${app_name}はビデオ通話を行うためにカメラとマイクにアクセスする許可を必要としています。 \n \n次のポップアップでアクセスを許可して通話ができるようにしてください。 - Matrixユーザが電子メールアドレスや電話番号を元に他のユーザを検索するためには、${app_name}アプリがあなたの端末内電話帳へアクセスする許可が必要です。 - -${app_name}からあなた個人の電話帳への検索要求を許可する場合は、次のポップアップでアクセスを許可してください。 - ${app_name}はあなたの連絡先のメールアドレスや電話番号をもとに他のユーザーを見つけることができます。 + ${app_name}アプリでは、あなたの端末の電話帳のメールアドレスや電話番号をもとに、他のユーザーを検索することができます。${app_name}による電話帳の検索を許可する場合は、次のポップアップでアクセスを許可してください。 + ${app_name}はあなたの電話帳のメールアドレスや電話番号をもとに他のユーザーを見つけることができます。 \n -\nこのアプリがあなたの連絡先へアクセスすることを許可しますか? +\nこのアプリがあなたの電話帳へアクセスすることを許可しますか? 申し訳ありません。権限がないために操作が実行されませんでした 発言を通報する 既読 写真を撮影 動画を撮影 - 要求を無視する + 要求を無視 検証せずに共有する - 検証を開始する + 検証を開始 リクエストに user_id がありません。 リクエストに room_id がありません。 リクエストの送信に失敗しました。 ウィジェットを作成できません。 - この部屋のウィジェットを管理する権限が必要です + このルームのウィジェットを管理する権限が必要です ウィジェットの作成に失敗しました - ウィジェットをこの部屋から削除してもよろしいですか? + ウィジェットをこのルームから削除してもよろしいですか? サーバーが利用できないか、オーバーロードしている可能性があります このルームは検証されていない不明なセッションが含まれています。 \nこれは、そのセッションが主張するユーザーのものであるという保証がないことを意味します。 \n続行する前に、各セッションの検証プロセスを進めることをおすすめしますが、検証せずにメッセージを再送信することもできます。 \n \n不明なセッション: - 部屋に不明なデバイスが含まれています + ルームに不明なデバイスが含まれています キーが一致していることを確認 一致する場合は、下の確認ボタンを押します。そうでない場合は、他の誰かがこのデバイスを盗聴しているので、代わりにブロックボタンを押すことをおすすめします。将来この検証プロセスはより洗練されたものになるでしょう。 デバイスの検証 不明なデバイス - このデバイスから未認証のデバイスに暗号化されたメッセージを送信しない。 + このセッションでは、未検証のセッションに対して暗号化されたメッセージを送信しない 認証済みデバイスに対してのみ暗号化 インポート ローカルファイルからキーをインポート ルームキーをインポート - 部屋のエンドツーエンド暗号鍵をインポート + ルームのエンドツーエンド暗号鍵をインポート パスフレーズを確認 パスフレーズを入力 エクスポート 暗号鍵をローカルファイルにエクスポートする - 部屋の暗号鍵をエクスポート + ルームの暗号鍵をエクスポート 検証 通話 通知あり(音量大) @@ -565,27 +563,27 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 この招待はこのアカウントに関連付けられていない %s に送信されました。 \n別のアカウントでログインするか、このメールを自分のアカウントに追加してください。 あなたは%sにアクセスしようとしています。話し合いに参加しますか? - 部屋 - これは部屋のプレビューです。部屋でのやりとりはできません。 + ルーム + これはルームのプレビューです。ルームでのやり取りは無効化されています。 このユーザーにあなたと同じ権限を与えますが、この変更は取り消せません。 -\n本当によろしいですか? +\nよろしいですか? 端末の連絡先 (%d) - ユーザディレクトリ (%s) - Matrixユーザのみ - ユーザIDで招待する + ユーザーディレクトリ (%s) + Matrixユーザーのみ + ユーザーIDで招待する 1つまたは複数のメールアドレスか、Matrix IDを入力してください 信用する 信用しない フィンガープリント (%s): - リモートサーバのアイデンティティを確認できませんでした。 - 誰かが不当にあなたの通信を傍受しているか、リモートサーバの証明書をあなたの電話が信用していない可能性があります。 - サーバの管理者が、これは想定されていることであると言っているのであれば、以下のフィンガープリントが管理者によるフィンガープリントと一致していることを確認してください。 + リモートサーバーのIDを確認できませんでした。 + 誰かが不当にあなたの通信を傍受しているか、リモートサーバーの証明書をあなたの電話が信用していない可能性があります。 + サーバーの管理者が、これは想定されていることであると言っているのであれば、以下のフィンガープリントが管理者によるフィンガープリントと一致していることを確認してください。 証明書はあなたの電話に信頼されていたものから変更されています。これはきわめて異常な事態です。この新しい証明書は承認しないことを強く推奨します。 - 証明書は以前信頼されていたものから信頼されていないものへと変更されています。サーバがその証明書を更新した可能性があります。予測されるフィンガープリントを取得するために、サーバの管理者に連絡してください。 - サーバの管理者が上のフィンガープリントと一致するものを発行した場合に限り、証明書を承認してください。 + 証明書は以前信頼されていたものから信頼されていないものへと変更されています。サーバーがその証明書を更新した可能性があります。予測されるフィンガープリントを取得するために、サーバーの管理者に連絡してください。 + サーバーの管理者が上のフィンガープリントと一致するものを発行した場合に限り、証明書を承認してください。 不正な形式のIDです。メールアドレスまたは\'@localpart:domain\'のようなMatrix IDを入力してください このコンテンツを報告する理由 - このユーザによるすべてのメッセージを非表示にしますか? + このユーザーによる全てのメッセージを非表示にしますか? \n \nこの操作はアプリを再起動するため時間がかかる場合があります。 アップロードをキャンセルする @@ -597,22 +595,22 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 このアプリのシステムの情報を見る。 アプリの情報 自分の表示名を含むメッセージ - 自分のユーザネームを含むメッセージ + 自分のユーザー名を含むメッセージ バージョン olmのバージョン サードパーティの通知 ホーム画面 - 逃した通知がある部屋を固定する - 未読のメッセージがある部屋を固定する + 逃した通知があるルームをピン止めする + 未読のあるルームをピン止めする 分析 データ節約モード メールアドレスを認証できません。メールを確認して、そこに記載してあるリンクをクリックしてください。その後、「続ける」をクリックしてください。 この通知の対象を削除してよろしいですか? %1$s %2$sを削除してよろしいですか? コード - %s はこの部屋のタイムラインのある箇所を読み込もうとしましたが、見つかりませんでした。 + %s はこのルームのタイムラインのある箇所を読み込もうとしましたが、見つかりませんでした。 イベント情報 - ユーザID + ユーザーID Curve25519 固有鍵 アルゴリズム セッションID @@ -629,11 +627,11 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 ブラックリスト ブラックリストから除外する このデバイスが信頼できることを確認するために、その所有者に何らかの他の方法(直接会って、または、電話で)連絡し、以下のキーが、そのデバイスの「設定」で確認できるキーと一致するかお尋ねください: - 部屋のディレクトリを選択 - 公開の部屋を表示するホームサーバを入力してください + ルームのディレクトリを選択 + 公開のルームを表示するホームサーバーを入力してください サーバー名 - %sサーバ上のすべての部屋 - すべてのローカルの %s 部屋 + %sサーバー上の全てのルーム + 全てのローカルの %s ルーム メッセージが未送信です。今 %1$s または %2$s しますか? 不明なデバイスが存在しているため、メッセージを送ることができませんでした。今 %1$s または %2$s しますか? 要求されたフィンガープリントキー Ed25519 @@ -647,50 +645,50 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 音量大 暗号化されたメッセージ 退出 - コミュニティの詳細 + コミュニティーの詳細 読み込み中… - コミュニティ - コミュニティで絞り込み + コミュニティー + コミュニティー名で絞り込む 招待 - コミュニティ + コミュニティー グループがありません - %sと新しい会話を開始して本当によろしいですか? - 音声通話を開始して本当によろしいですか? - 本当にビデオ通話を開始しますか? + %sと新しい会話を開始してよろしいですか? + 音声通話を開始してよろしいですか? + ビデオ通話を開始してよろしいですか? グループリスト - ユーザーを禁止するとこの部屋から追い出され、二度と参加できなくなります。 - すべてのメッセージ (大音量) - すべてのメッセージ + ユーザーをブロックすると、ユーザーはこのルームから削除され、二度と参加できなくなります。 + 全てのメッセージ (大音量) + 全てのメッセージ ミュート ホーム画面にショートカットを作成 インラインURLプレビュー 通知 - この部屋はコミュニティの特色を表示していません - 所属するコミュニティ - 新しいコミュニティID (記入例 +foo:matrix.org) - 無効なコミュニティID - \'%s\' は有効なコミュニティIDではありません + このルームはコミュニティーの特色を表示していません + 所属するコミュニティー + 新しいコミュニティーID (記入例 +foo:matrix.org) + 無効なコミュニティーID + \'%s\' は有効なコミュニティーIDではありません ルームのエンドツーエンド暗号鍵は \'%s\' に保存されました。 \n \n警告: このファイルは、アプリケーションをアンインストールすると削除されることがあります。 暗号鍵を要求している新しい端末 \'%s\' を追加しました。 未認証の端末 \'%s\' が暗号鍵を要求しています。 作成 - コミュニティを作成 - コミュニティの名前 + コミュニティーを作成 + コミュニティーの名前 - コミュニティID + コミュニティーID ホーム 参加者 - 部屋 - ユーザがいません - 部屋 + ルーム + ユーザーがいません + ルーム 参加済 招待済 グループのメンバーをフィルタリングする - グループの部屋を絞り込み - 管理者はこのコミュニティの詳細を規定していません。 + グループのルームを絞り込み + 管理者はこのコミュニティーの詳細を規定していません。 あなたは%2$sによって%1$sから除外されました あなたは%2$sによって%1$sへの参加を禁止されました 理由: %1$s @@ -712,12 +710,12 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 %d件の新しいメッセージ - %d部屋 + %dルーム - %2$s に %1$s 部屋見つかりました + %2$s に %1$s ルーム見つかりました - 部屋の履歴を消す + ルームの履歴を消す アバター 名前があがったときのみ 通知のプライバシー @@ -768,10 +766,10 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 %d個選択済 低プライバシー - • 通知中のメッセージの内容は Matrixのホームサーバから直接安全に入手しています + • 通知中のメッセージの内容は Matrixのホームサーバーから直接安全に入手しています ・通知は メタデータとメッセージのデータ を含みます • 通知は メッセージの内容を表示しません - ユーザの名前をあげるときバイブレーションで通知 + ユーザーの名前をあげるときバイブレーションで通知 送信の前にメディアをプレビュー アカウントを停止 自分のアカウントを停止 @@ -792,7 +790,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 %d件の通知された未読メッセージ - %d部屋 + %dルーム %2$s件 中 %1$s件 @@ -803,15 +801,15 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 メッセージを送信するには、キーボードのエンターキーを使用してください ボイスメッセージを送信 動作を表示 - 指定したIDのユーザをブロック - 指定したIDのユーザのブロックを解除 - ユーザの権限レベルを決める - 指定したIDのユーザの管理者権限を取り消す - 指定したユーザを現在の部屋に招待 - 指定したエイリアスの部屋に参加 - 部屋を退室 - 部屋のテーマを設定 - 指定したIDのユーザとの接続を切断 + 指定したIDのユーザーをブロック + 指定したIDのユーザーのブロックを解除 + ユーザーの権限レベルを決める + 指定したIDのユーザーの管理者権限を取り消す + 指定したユーザーを現在のルームに招待 + 指定されたアドレスのルームに参加します + ルームを退室 + ルームのテーマを設定 + 指定したIDのユーザーとの接続を切断 表示するニックネームを変更 Markdown書式の入/切 Matrixアプリの管理を修正するには @@ -819,39 +817,39 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 %d名の参加者 - %d部屋 + %dルーム アバターを読み込み - %1$s ホームサーバを使用し続けるには、利用規約を読み、同意する必要があります。 + %1$s ホームサーバーを使用し続けるには、利用規約を読み、同意する必要があります。 エラー アバターに通知を表示 今すぐ見る アカウントを停止 - この操作によりあなたのアカウントは永久に使えなくなります。あなたはログインできなくなり、誰も同じユーザIDを再登録できなくなります。アカウントが参加しているすべてのルームを退出し、IDサーバからアカウントの詳細を削除することになります。 この操作は取り消しできません + この操作により、あなたのアカウントは永久に使えなくなります。あなたはログインできなくなり、誰も同じユーザーIDを再登録できなくなります。アカウントが参加している全てのルームを退出し、IDサーバーからアカウントの詳細は削除されます。 この操作は取り消せません。 \n -\nあなたのアカウントを停止することによって デフォルトではあなたが送信したメッセージの削除はされません。メッセージを削除を望む場合は、以下のボックスにチェックを入れてください。 +\nアカウントを停止しても、 デフォルトではあなたが送信したメッセージは忘却されません。メッセージの忘却を望む場合は、以下のボックスにチェックを入れてください。 \n -\nMatrixでのメッセージの可視性は電子メールと同様のものです。メッセージを削除すると、あなたが送信したメッセージが新規または未登録のユーザーと共有されないことを意味しますが、すでにこれらのメッセージにアクセスをしている登録ユーザーはそのコピーにアクセスできます。 - アカウントを停止したとき自分の送信した全てのメッセージを削除 (警告: この操作により、将来的なユーザが会話を不完全な形で見ることになります) +\nMatrixのメッセージの可視性は、電子メールと同様のものです。メッセージを忘却すると、あなたが送信したメッセージは、新規または未登録のユーザーには共有されることはありませんが、すでにメッセージを取得している登録ユーザーは、今後もそのコピーにアクセスできます。 + アカウントを停止したとき自分の送信した全てのメッセージを削除 (警告: この操作により、将来的なユーザーが会話を不完全な形で見ることになります) 続けるには、パスワードを入力してください: アカウントを停止 パスワードを入力してください。 このルームは置き換えられており、アクティブではありません。 ここで会話が続いています - この部屋は別の会話の続きです + このルームは別の会話の続きです より古いメッセージを見るには、ここをクリックしてください リソース制限の超過 管理者に連絡 あなたのサービス管理者に連絡 - このホームサーバはリソース制限の1つを超過しているため、 ユーザがログインできなくなることがあります - このホームサーバはリソース制限の1つを超過しています。 - このホームサーバは月間アクティブユーザ上限に達しているため、 ユーザがログインできなくなることがあります - このホームサーバは月間アクティブユーザ上限に達しています。 + このホームサーバーはリソース制限の1つを超過しているため、 ユーザーがログインできなくなることがあります + このホームサーバーはリソース制限の1つを超過しています。 + このホームサーバーは月間アクティブユーザー上限に達しているため、 ユーザーがログインできなくなることがあります + このホームサーバーは月間アクティブユーザー上限に達しています。 この上限を上げるには %s してください。 このサービスを使い続けるには %s してください。 - 最初に部屋のメンバーのみを読み込むことによりパフォーマンスを向上。 - あなたのホームサーバは部屋のメンバーの簡易読み込みをサポートしていません。後で試してください。 - 部屋のメンバーの簡易読み込み + 最初にルームのメンバーのみを読み込むことによりパフォーマンスを向上。 + あなたのホームサーバーはルームのメンバーの簡易読み込みをサポートしていません。後で試してください。 + ルームのメンバーの簡易読み込み 申し訳ありません、エラーが発生しました Version %s エクスポートされた鍵を暗号化するパスフレーズを作成してください。 キーをインポートするには、同じパスフレーズを入力する必要があります。 @@ -945,19 +943,19 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 削除済みのメッセージを表示 削除されたメッセージの代わりに削除されたという通知を表示します。 ユーザーによって削除されたイベント - 新しい部屋を作成 + 新しいルームを作成 変更 ネットワークを変更 - 全てのコミュニティ - 部屋 + 全てのコミュニティー + ルーム ダイレクトメッセージ - 新しい部屋 + 新しいルーム 作成 名前 - 公開する - 部屋が公開され、誰でもこの部屋に参加できるようになります - 部屋一覧 - 部屋一覧にこの部屋が公開されます + 公開 + 誰でもこのルームに参加できるようになります + ルーム一覧 + ルームの一覧へ公開する 一般 セキュリティとプライバシー ヘルプと概要 @@ -973,7 +971,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 設定 お気に入りに追加 お気に入りから削除 - 部屋から退出 + ルームから退出 長押しすると、追加のオプションが表示されます 開発者モード 設定 @@ -985,14 +983,14 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 詳細 その他の設定 管理者としての操作 - 部屋の設定 + ルームの設定 通知 %1$d 人の参加者 アップロード - 部屋を退室 - 部屋から退室中… + ルームを退出 + ルームから退室中… 管理者 モデレーター カスタム @@ -1030,9 +1028,9 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 アカウントデータ 削除… 削除の確認 - このイベントを削除してよろしいですか?部屋名やトピックの変更を削除すると、変更が元に戻る点にご注意ください。 + このイベントを削除してよろしいですか?ルーム名やトピックの変更を削除すると、変更が元に戻る点にご注意ください。 暗号化は有効です - この部屋内でのメッセージはエンドツーエンド暗号化されます。詳細の確認や検証はユーザーのプロフィールをご確認ください。 + このルーム内でのメッセージはエンドツーエンド暗号化されます。詳細の確認や検証はユーザーのプロフィールをご確認ください。 暗号化が有効化されていません 通知設定 切断 @@ -1112,7 +1110,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 セキュアバックアップを設定 管理 セキュアバックアップ - 部屋を作成中… + ルームを作成中… 招待されています %s からの招待 このセッションは正常に検証されました。 @@ -1146,7 +1144,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 リアルタイム接続を確立できませんでした。 \nホームサーバーの管理者に、通話が正常に動作するためにTURNを設定するようご連絡ください。 再び表示しない - アイデンティティサーバーが設定されていません。 + IDサーバーが設定されていません。 終了 拒否 承諾 @@ -1162,12 +1160,12 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 なし トピック ルーム名 - この部屋内のメッセージはエンドツーエンド暗号化されていません。 + このルーム内のメッセージはエンドツーエンド暗号化されていません。 ここでのメッセージはエンドツーエンド暗号化されていません。 設定 - あなたにはこの部屋の暗号化を有効にする権限がありません。 + あなたにはこのルームの暗号化を有効にする権限がありません。 未読メッセージ - タイムラインでスワイプして返信を有効にする + タイムラインでのスワイプによる返信を有効にする タイムラインで非表示のイベントを表示する QR コードをスキャン QR コード画像 @@ -1206,54 +1204,54 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 %sを削除しますか? 認証が必要です あなたのパスワードを確認する - 暗号化された部屋での検索はまだサポートされていません。 - 禁止されたユーザーをフィルタリングする + 暗号化されたルームでの検索はまだサポートされていません。 + ブロックされたユーザーを絞り込む トピックを変更する ルームをアップグレード - m.room.server_acl eventsを送信します - 権限を変更する - 部屋名を変更する - 履歴を見えるように変更する - 部屋の暗号化を有効にする - 部屋のメインアドレスを変更する - 部屋のアバターを変更する - ウィジェットを変更する - 全員に通知する - 他の人から送信されたメッセージを削除する - 禁止ユーザー - キックユーザー + m.room.server_acl eventsを送信 + 権限を変更 + ルーム名の変更 + 履歴の見え方の変更 + ルームの暗号化の有効化 + ルームのメインアドレスの変更 + ルームのアバターの変更 + ウィジェットの変更 + 全員への通知 + 他の人から送信されたメッセージの削除 + ユーザーのブロック + ユーザーのキック 設定を変更する 招待されたユーザー メッセージを送る デフォルトルール - 部屋のさまざまな部分を変更するための必要な役割を更新する権限がありません - 部屋のさまざまな部分を変更するために必要な役割を選択します - 部屋の権限 + ルームに関する変更を行うために必要な役割を更新する権限がありません + ルームに関する変更を行うために必要な役割を選択 + ルームの権限 権限 - 部屋のさまざまな部分を変更するために必要な役割を表示し更新します。 - ユーザーの禁止を解除すると、ユーザーは再び部屋に参加できるようになります。 + ルームに関する変更を行うために必要な役割を表示し更新します。 + ブロックを解除すると、ユーザーは再びルームに参加できるようになります。 禁止されたユーザー 禁止の理由 ユーザーの禁止を解除する - キックするユーザーは、この部屋から削除されます。 + キックするユーザーは、このルームから削除されます。 \n -\n再び参加するのを防ぐためには永久追放する必要があります。 +\n再参加を防ぐためには、キックの代わりにブロックする必要があります。 キックする理由 ユーザーをキックする このユーザーの招待をキャンセルしてよろしいですか? 招待をキャンセル - このユーザーを解除すると、そのユーザーからのすべてのメッセージが再び表示されます。 + このユーザーを解除すると、そのユーザーからの全てのメッセージが再び表示されます。 ユーザーを無視しない - このユーザーを無視すると、あなたが共有している部屋からそのユーザーのメッセージが削除されます。 + このユーザーを無視すると、あなたが共有しているルームからそのユーザーのメッセージが削除されます。 \n -\nこの動作は設定からいつでも元に戻すことができます。 +\nこの動作は、設定からいつでも元に戻すことができます。 ユーザーを無視する 広角 - あなたは自分自身を降格させているので、この変更を元に戻すことはできません。あなたが部屋の中で最後の特権ユーザーである場合、特権を取り戻すことはできません。 + あなたは自分自身を降格させようとしているため、今後、この変更を元に戻すことはできなくなります。あなたがルームの中で最後の特権ユーザーである場合、特権を再取得することはできません。 降格しますか? 招待をキャンセル - この部屋は公開されていません。 招待なしで再参加することはできません。 - このアクションを実行するには、設定にIDサーバーを追加します。 + このルームは公開されていません。 招待がなければ再び参加することはできません。 + このアクションを実行するには、設定にIDサーバーを追加してください。 連絡先へのアクセスを許可します。 QRコードをスキャンするには、カメラへのアクセスを許可する必要があります。 通話をかけました @@ -1262,7 +1260,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 コールし直す 通話をやり直す アクティブな通話(%s) - あなたのホームサーバがアシスト機能を提供しない場合、代わりに%sを使用します(IPアドレスは通話中に共有されます) + あなたのホームサーバーがアシスト機能を提供しない場合、代わりに%sを使用します(IPアドレスは通話中に共有されます) ビデオ通話が行われています… フォールバックコールアシストサーバーを許可する 有効な認証情報ではありません @@ -1270,8 +1268,8 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 通話が確実に機能させるためには、ホームサーバー(%1$s)の管理者にTURNサーバーの設定を依頼してください。 \n \n代わりに、%2$sのパブリックサーバーを使用することもできますが、信頼性は低く、あなたのIPアドレスがそのサーバーと共有されてしまいます。これは設定から管理することができます。 - ルームディレクトリのすべての部屋を詳しい説明を含めて表示します。 - 部屋の詳しい説明を表示する + ルームのディレクトリ内の全てのルームを表示(露骨なコンテンツのあるルームを含む)する。 + 露骨なコンテンツのあるルームを表示 ルームディレクトリ 新着情報 戻る @@ -1283,74 +1281,74 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 会話を始める %1$sがエンドツーエンド暗号化をオンにしました。 エンドツーエンド暗号化をオンにしました。 - ゲストが部屋に入るのを防いでいます。 - %1$sはゲストが部屋に参加するのを妨げました。 - ゲストが部屋に参加するのを妨ぎました。 - %1$sはゲストが部屋に参加するのを妨ぎました。 + ゲストがルームに入るのを拒否しています。 + %1$sはゲストがルームに参加するのを拒否しています。 + ゲストがルームに入るのを拒否しています。 + %1$sはゲストがルームに参加するのを拒否しました。 ここへのゲストの入室を許可しました。 %1$sはここにゲストが参加することを許可しました。 - この部屋へのゲストの入室を許可しました。 - %1$s がゲストの部屋への参加を許可しました。 + ゲストにルームへの参加を許可しました。 + %1$s がゲストにルームへの参加を許可しました。 システムデフォルト - この部屋のメインおよび代替のアドレスを変更しました。 - この部屋の代替アドレスを変更しました。 + このルームのメインおよび代替のアドレスを変更しました。 + このルームの代替アドレスを変更しました。 - この部屋の代替アドレス%1$sを削除しました。 + このルームの代替アドレス%1$sを削除しました。 - この部屋の代替アドレス%1$sを追加しました。 + このルームの代替アドレス%1$sを追加しました。 - この部屋のメインアドレスを削除しました。 - この部屋のメイン・アドレスを%1$sに設定しました。 - この部屋のアドレスとして、%1$sを追加し%2$sを削除しました。 + このルームのメインアドレスを削除しました。 + このルームのメインアドレスを%1$sに設定しました。 + このルームのアドレスとして、%1$sを追加し%2$sを削除しました。 - この部屋のアドレスの%1$sを削除しました。 + このルームのアドレスの%1$sを削除しました。 %1$sの招待を取り消しました。理由:%2$s %1$sの招待を受諾しました%2$。理由:%2$s - %1$sの部屋への招待を取り消しました。理由:%2$s + %1$sのルームへの招待を取り消しました。理由:%2$s %1$sにルームへの招待状を送りました。理由:%2$s VoIPカンファレンスをリクエストしました - このルームのサーバのACLを変更しました。 - このルームのサーバACLを設定しました。 + このルームのサーバーのアクセス制御リストを変更しました。 + このルームのサーバーアクセス制御リストを設定しました。 ここをアップグレードしました。 あなたはこのルームをアップグレードしました。 通話を終えました。 - 通話に応えました。 + 通話に応答しました。 通話を設定するためのデータを送信しました。 - この部屋のアドレスを変更しました。 - %1$s はこの部屋のメインおよび代替アドレスを変更しました。 - %1$s がこの部屋のアドレスを変更しました。 - %1$sはこの部屋の代替アドレスを変更しました。 + このルームのアドレスを変更しました。 + %1$s はこのルームのメインおよび代替アドレスを変更しました。 + %1$s がこのルームのアドレスを変更しました。 + %1$sはこのルームの代替アドレスを変更しました。 - %1$s がこの部屋の代替アドレス%2$sを削除しました。 + %1$s がこのルームの代替アドレス%2$sを削除しました。 - %1$s はこの部屋の代替アドレス%2$sを追加しました。 + %1$s はこのルームの代替アドレス%2$sを追加しました。 - %1$sがこの部屋のメインアドレスを削除しました。 - %1$sがこの部屋のメインアドレスを%2$sに設定しました。 - %1$sはこの部屋のアドレスとして %2$sを追加し%3$sを削除しました。 + %1$sがこのルームのメインアドレスを削除しました。 + %1$sがこのルームのメインアドレスを%2$sに設定しました。 + %1$sはこのルームのアドレスとして %2$sを追加し%3$sを削除しました。 - %1$s はこの部屋のアドレスの%2$sを削除しました。 + %1$s はこのルームのアドレスの%2$sを削除しました。 - この部屋のアドレスとして%1$sが追加されました。 + このルームのアドレスとして%1$sが追加されました。 %1$sが%2$s にルームへの招待を送りました。理由:%3$s %1$sが%2$sのルームへの招待を取り消しました。理由:%3$s %1$sが %2$sの招待を承諾しました。理由:%3$s %1$sは%2$sの招待を取り下げました。理由:%3$s - %1$sはこの部屋のアドレスとして%2$sを追加しました。 + %1$sはこのルームのアドレスとして%2$sを追加しました。 あなたのプロフィールが更新されました %1$s - %sがこのルームのサーバのACLを変更しました。 + %sがこのルームのサーバーのアクセス制御リストを変更しました。 IPリテラルに一致するサーバーは禁止されています。 ・IPリテラルに一致するサーバーを許可します。 ・%sに一致するサーバーは許可されています。 ・%sに一致するサーバーは禁止されています。 - %sがこのルームのサーバACLを設定しました。 + %sがこのルームのサーバーアクセス制御リストを設定しました。 %sがここをアップグレードしました。 %s がこのルームをアップグレードしました。 エンドツーエンド暗号化をオンにしました (%1$s) @@ -1394,7 +1392,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 初期同期: \nアカウントデータをインポートしています 初期同期: -\nコミュニティをインポートしています +\nコミュニティーをインポートしています 初期同期: \nルームをインポートしています 初期同期: @@ -1466,7 +1464,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 入室と退室イベントの表示 Use /confettiコマンドを使用するか、❄️または🎉を含むメッセージを送信します チャットでエフェクトを表示する - 部屋のメンバーのイベントを表示する + ルームのメンバーのイベントを表示する ホームサーバーがこの機能をサポートしている場合は、チャット内のリンクをプレビューします。 ボット、ブリッジ、ウィジェット、ステッカーパックの管理をします。 \nユーザーに代わり、構成データを受信しウィジェットを変更、ルーム招待の送信、権限の設定などができます。 @@ -1512,7 +1510,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 \n%1$s FCMトークンのホームサーバーへの登録が成功しました。 トークンの登録 - アカウントを追加する + アカウントを追加 [%1$s] \nこのエラーは、${app_name}の管理外です。スマホにはGoogleアカウントがありません。アカウントマネージャーを開いて、Googleアカウントを追加してください。 %1$s @@ -1521,7 +1519,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 \n%1$s FCMトークンの取得に失敗しました: \n%1$s - 🎉すべてのサーバの参加を禁止されています!このルームは使用できなくなりました。 + 🎉全てのサーバーの参加を禁止されています!このルームは使用できなくなりました。 変化がありません。 • サーバーにマッチするIPリテラルが禁止されています。 • サーバーにマッチするIPリテラルが許可されるようになりました。 @@ -1551,7 +1549,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 続けるには利用規約に同意する必要があります。 全てブロック 許可 - 部屋ID + ルームID ウィジェットID あなたのテーマ あなたのユーザーID @@ -1562,7 +1560,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 アクティブなウィジェット 自分 新しいメッセージ - 部屋 + ルーム 新しいイベント 不明なIP @@ -1574,7 +1572,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 選択 詳細情報: %s ローカルアドレスを追加する - この部屋はローカルアドレスがありません + このルームにはローカルアドレスがありません アドレス \"%1$s\" を削除しますか? メインアドレス これがメインアドレスです @@ -1584,10 +1582,10 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 Eメールで招待 詳細 人を招待する - とにかく参加する - 部屋を追加する + とにかく参加 + ルームを追加 %s はあなたを招待しています - この部屋で電話会議をする権利がありません + このルームでグループ通話をする権利がありません オーディオミーティングを開始する 安全バックアップを設定 暗号鍵バックアップで管理 @@ -1640,7 +1638,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 リカバリーキーを入力 リカバリーキーを使用 ログアウトしたりこの端末を失くしたりすればメッセージへのアクセスを失う可能性があります。 - 本当によろしいですか? + 続行しますか? 暗号鍵が現在バックグラウンドでホームサーバーへバックアップされています。初期バックアップは数分かかることがあります。 バックアップが開始されました 予期せぬエラー @@ -1651,7 +1649,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 中止 上書き 違うセッションにより設定されたキーのバックアップが存在してます。上書きしますか? - ホームサーバにバックアップが存在しています + ホームサーバーにバックアップが存在しています リカバリーキーが保存されました。 リカバリーキーが%sに保存されました。 \n @@ -1664,11 +1662,11 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 暗号鍵がバックアップ中です。 (高度)リカバリーキーを使用して設定 または、リカバリーキーでバックアップを保護し、安全な場所に保存してください。 - 暗号鍵のコピーを暗号化してホームサーバに保存します。バックアップを保護するためにパスフレーズを設定してください。 + 暗号鍵のコピーを暗号化してホームサーバーに保存します。バックアップを保護するためにパスフレーズを設定してください。 \n \n最高度のセキュリティのために、アカウントのパスワードと異なることが大切です。 パスフレーズを使用してバックアップを保護します。 - 暗号化が有効な部屋で送信されたメッセージはエンドツーエンド暗号化によって保護されます。メッセージを読むための暗号鍵を持っているのは送受信者のみです。 + 暗号化が有効なルームで送信されたメッセージはエンドツーエンド暗号化によって保護されます。メッセージを読むための暗号鍵を持っているのは送受信者のみです。 \n \n暗号鍵を失わないように保護されたバックアップをしてください。 (高度) @@ -1705,7 +1703,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 ウィジェットを再読込 クッキーを設定し%sとデータを交換する可能性があります: ウィジェットの追加者: - **送信に失敗 - 部屋を開いてください + **送信に失敗 - ルームを開いてください 新しい招待 %1$sと%2$s %1$s に %2$s と %3$s @@ -1719,42 +1717,42 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 %d件の招待 既にリストに載っているサーバーです - サーバーまたはその部屋一覧が見つかりません + サーバーまたはそのルーム一覧が見つかりません 検索される新しいサーバーの名前を入力します。 新しいサーバーを追加 - あなたのサーバ + あなたのサーバー 暗号化されたメッセージの復元 セッションの公開名は会話中の相手に閲覧できます - 部屋のバージョン + ルームのバージョン banされたユーザー%d人 - この部屋が含まれているスペースの参加者誰でも発見し参加できます。部屋をスペースに追加できるのは部屋の管理者だけです。 + このルームのあるスペースの参加者は誰でも発見し参加できます。ルームをスペースに追加できるのは、ルームの管理者だけです。 スペースのメンバーのみ - 誰でも部屋を発見し参加できます + 誰でもルームを発見し参加できます 公開 - 参加された人のみが部屋を発見し参加できます + 招待された人だけが発見し参加できます プライベート 不明のアクセス設定(%s) 誰でもノックができ、メンバーがその参加を承認または拒否できます - 現在の部屋一覧可視性状態を取得できません(%1$s)。 - この部屋を%1$sの部屋一覧に公開しますか? + 現在のルーム一覧の見え方を取得できません(%1$s)。 + このルームを%1$sのルーム一覧に公開しますか? アドレスを非公開にする アドレスを公開 - 同じホームサーバー(%1$s)の他のユーザーがこの部屋を見つけられるようにアドレスを設定できます。 + アドレスを設定すれば、他のユーザーがあなたのホームサーバー (%1$s) を通じてこのルームを見つけられるようになります。 ローカルアドレス 新しい公開アドレス(例: #alias:server) 他の公開アドレスはまだありません。以下から追加できます。 他の公開アドレスはまだありません。 - 部屋を%1$sの部屋一覧に公開しますか? + このルームを%1$sのルーム一覧に公開しますか? \"%1$s\"を非公開にしますか? 公開 手動で新しいアドレスを公開 他の公開アドレス: - 公開されたアドレスを通して、どのサーバーのどのユーザーでもこの部屋に参加できます。アドレスを公開するには、まずローカルアドレスとして設定する必要があります。 + 公開されたアドレスを通して、どのサーバーのどのユーザーでもこのルームに参加できます。アドレスを公開するには、まずローカルアドレスとして設定する必要があります。 公開アドレス - 部屋のアドレス - 部屋のアドレス及び部屋一覧における可視性を管理できます。 + ルームのアドレス + ルームのアドレス及びルーム一覧における可視性を管理できます。 スペースのアドレスを管理できます。 スペースのアドレス ルームのアドレス @@ -1766,7 +1764,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 招待 おすすめのルーム スペース - ホームサーバAPIのURL + ホームサーバーAPIのURL 復旧用のメールアドレスを設定します。後からオプションでメールアドレスや電話番号を使用して知人に見つけてもらえるようにできます。 電話番号を設定して、後からオプションで知人に見つけてもらえるようにできます。 %s を使用してみてください @@ -1843,25 +1841,24 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 プッシュルール エキスパート クイックリアクション - あなたはすでにこの部屋を見ています! + あなたはすでにこのルームを見ています! その他のサードパーティーの通知 Matrix SDK バージョン ファイル\"%1$s\"からe2eキーをインポートします。 キーのバックアップデータの取得中にエラーが発生しました 信頼情報の取得中にエラーが発生しました - ルーム作成されましたが、一部の招待が送信されていません -\n理由: + ルームが作成されましたが、一部の招待が送信されていません。理由: \n \n%s - ルーム設定 + ルームの設定 トピック ルームトピック(オプション) ルーム名 - この部屋はプレビューできません。参加しますか? - 現在、この部屋にはアクセスできません。 + このルームはプレビューできません。参加しますか? + 現在、このルームにはアクセスできません。 \n後でもう一度やり直すか、ルームの管理者にアクセス権があるかどうかを確認するよう依頼してください。 ${app_name}では、誰でも読めるルームのプレビューがまだサポートされていません - この部屋はプレビューできません + このルームはプレビューできません お待ち下さい… ネットワークがありません。インターネット接続を確認してください。 不正な形式のイベント、表示できません @@ -1908,8 +1905,8 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 リクエストはキャンセルされました キーの検証 レガシー検証を使います。 - 何も表示されませんか?すべてのクライアントがインタラクティブ検証をまだサポートしているわけではありません。その場合はレガシー検証を使用してください。 - 取得 + 何も表示されませんか?全てのクライアントがインタラクティブ検証をまだサポートしているわけではありません。その場合はレガシー検証を使用してください。 + 了解 このユーザーとのメッセージはエンドツーエンドで暗号化され第三者が読むことはできません。 完了しました! 相手が確認するのを待っています… @@ -1925,7 +1922,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 短い文字列を比較して検証します。 認証が無効または期限切れのため、ログアウトされました。 構成を使用する - ${app_name}がuserIdドメイン\"%1$s \"のカスタムサーバ構成を検出しました。 + ${app_name}がuserIdドメイン\"%1$s \"のカスタムサーバー構成を検出しました。 \n%2$s サーバーオプションをおまかせする 無効なホームサーバーディスカバリーレスポンス @@ -1943,13 +1940,13 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 タップしスペースを編集する スペースを選択する アクセス可能なスペース - スペースメンバーが検索してアクセスすることを許可します。 - スペースメンバー %sは検索、プレビュー、参加することができます。 + スペースのメンバーに発見とアクセスを許可します。 + スペース%sのメンバーが検索、プレビュー、参加できます。 プライベート(招待のみ) デフォルトのメディアソース デフォルトの圧縮 - ルームアップグレード - botによるメッセージ + ルームのアップグレード + ボットによるメッセージ ルーム招待 \@roomを含むメッセージ ルームがアップグレードされたとき @@ -1957,8 +1954,8 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 グループメッセージ 暗号化されたダイレクトメッセージ ダイレクトメッセージ - 私のユーザーネームを含むメッセージ - 自分のディスプレーネームを含むメッセージ + 自分のユーザー名 + 自分のディスプレーネーム グループチャットでのメッセージの暗号化 個別チャットでのメッセージの暗号化 通知してください @@ -1975,7 +1972,7 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 キー共有リクエストの送信履歴 結果がありません 自分で電話をかけることはできません。参加者が招待を受け入れるのを待ちます - ミーティングはJitsiのセキュリティとパーミッションポリシーを使用します。会議中は、現在ルームにいるすべての人に招待状が表示されます。 + ミーティングはJitsiのセキュリティとパーミッションポリシーを使用します。会議中は、現在ルームにいる全ての人に招待状が表示されます。 権限がありません 音声メッセージを送信するには、マイクの権限を許可してください。 この動作を行うには、システム設定からカメラの権限を許可してください。 @@ -2006,10 +2003,10 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 IDサーバー ボット、ブリッジ、ウィジェット、ステッカーパックを使う 他の人が見つけられるように - 規約を見直す + 規約を確認する 利用規約 編集履歴を表示 - 部屋に参加しています… + ルームに参加しています… 提案 連絡先 最近の @@ -2062,4 +2059,156 @@ ${app_name}からあなた個人の電話帳への検索要求を許可する場 %s のURLにあるホームサーバーに接続できません。リンクをチェックするか、手動でホームサーバーを選択してください。 後で スペース + スレッドから + 参加している全スレッドを表示 + 現在のルームのスレッドを全て表示 + ユーザーをブロックすると、ユーザーはこのスペースから削除され、二度と参加できなくなります。 + PINコードを有効にする + これを招待者のみ参加可能に設定しました。 + ルームの設定 + コンテンツが報告されました + ヘルプとサポート + ヘルプ + ${app_name} ポリシー + ここ + キーワードを追加 + 自分のスレッド + 全てのスレッド + ユーザーを自動的に招待 + ユーザー + このユーザーの禁止を解除すると、そのユーザーはスペースに再び参加できるようになります。 + このルームを招待者のみ参加可能に設定しました。 + 低優先度から削除 + 低優先度に追加 + スパムとして報告済 + このルームにファイルはありません + このルームにメディアはありません + 公開ルームをアップグレード + プライベートスペース + 公開スペース + 送信済 + 送信中 + 種類 + 確認済 + 選択済 + ビデオ + 画像 + スクリーンショット + 接続 + 投票 + 投票 + コード + 役割 + 送信 + 招待 + 暗号化されていません + 終了 + 再読み込み + セッション一覧 + 警告 + 無視を解除 + あなた + 動画。 + 絵文字で検証 + 待機中… + ステッカー + ファイル + 音声 + 画像。 + イライラシェイク + 警告 + 警告 + 成功しました! + 続ける + 警告! + ロケーション + メディア + 投票終了 + 投票を終了しますか? + 投票を削除 + スペースを作成 + スペースに参加 + スペースを退出 + スペースにようこそ! + ルームを管理 + このスペースにはルームがありません + 音声メッセージを再生できません + 音声メッセージを録音できません + グループ通話が開始しました + ルームのアップグレードには権限が必要です + アップグレード + アップグレードが必要です + プライベートルームをアップグレード + 音声メッセージを一時停止 + 音声メッセージを有効にする + このメールアドレスをアカウントにリンク + 投票を編集 + 投票を編集 + 地図 + 投票を終了 + 投票を終了 + 選択肢 %1$d + 選択肢を作成 + ロケーション + ロケーションを共有 + ロケーションの共有を有効にする + 地図を読み込めませんでした + スレッドで返信 + ロケーションを共有 + ロケーションを共有 + カメラを開く + 画像と動画を送信 + ファイルをアップロード + 連絡先を開く + ステッカーを送信 + 投票を作成 + ロケーションを共有 + スペースに関する変更を行うために必要な役割を更新する権限がありません + スペースに関する変更を行うために必要な役割を選択 + スペースに関する変更を行うために必要な役割を表示し更新します。 + フィルター + スレッド + スレッド + スペースをアップグレード + スペース名の変更 + スペースの権限 + 応答がありません + 応答がありません + スレッドへのリンクをコピー + 有効にする + もっと知る + あなたのIDサーバーのポリシー + 新しいルームを作成 + 認証コードが正しくありません。 + IDサーバーのURLを入力してください + 名前、ID、メールアドレスで検索 + システムの設定 + バージョン + 現在のルームのアバターを変更 + ルーム名を設定 + アカウントの設定 + キーワード + ルームから退出しました! + 吹き出しでメッセージを表示 + 電子メールによる通知 + セッションからサインアウトしました! + なし + メンションとキーワードのみ + ルームのスレッドを絞り込む + 退出 + モバイルでは、暗号化されたルームでのメンションとキーワードの通知は受信できません。 + ルームの暗号化の有効化 + スペースのメインアドレスの変更 + スペースのアバターの変更 + 投票を作成 + 投票を作成 + 暗号化が正しく設定されていないためメッセージを送ることができません。クリックして設定を開いてください。 + 暗号化が正しく設定されていないためメッセージを送ることができません。管理者に連絡して、暗号化を正しい状態に復元してください。 + %2$dの%1$d + あなたはすでにこのスレッドを見ています! + ルームに表示 + ルームに表示 + スレッドを表示 + ポリシー + このルームへの参加は許可されていません \ No newline at end of file From b4596682380519af17cf2d6a51642706848fcf53 Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Thu, 17 Feb 2022 10:31:43 +0000 Subject: [PATCH 126/302] Translated using Weblate (Japanese) Currently translated at 72.2% (2012 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index fbad27f1dc..1c14024c3d 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1313,7 +1313,7 @@ このルームのサーバーアクセス制御リストを設定しました。 ここをアップグレードしました。 あなたはこのルームをアップグレードしました。 - 通話を終えました。 + 通話を終了しました。 通話に応答しました。 通話を設定するためのデータを送信しました。 このルームのアドレスを変更しました。 @@ -2211,4 +2211,8 @@ スレッドを表示 ポリシー このルームへの参加は許可されていません + "トピック: " + トラブルシューティング + 添付ファイルを取得中にエラーが発生しました。 + キーバックアップのバナーを閉じる \ No newline at end of file From 11dacbab81bb970af65c6bef78f4abd15fed1cdc Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 17 Feb 2022 13:59:30 +0100 Subject: [PATCH 127/302] Revert "Adding header section only when necessary" This reverts commit 96ed30ccc45ab47326a5058b73906be085540a98. --- .../member/AutocompleteMemberPresenter.kt | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt index b646e22f17..ab4b598153 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt @@ -88,18 +88,12 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, val items = mutableListOf().apply { if (members.isNotEmpty()) { - if (everyone != null) { - // add header only when there is everyone tag as well - add(membersHeader) - } + add(membersHeader) addAll(members) } everyone?.let { - if (members.isNotEmpty()) { - // add header only when there are members as well - val everyoneHeader = createEveryoneHeader() - add(everyoneHeader) - } + val everyoneHeader = createEveryoneHeader() + add(everyoneHeader) add(it) } } From df3fc38054e2645befe9876c138dcfeb4c9011e7 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 17 Feb 2022 14:14:44 +0100 Subject: [PATCH 128/302] Adding header section only when "@room" is available --- .../autocomplete/member/AutocompleteMemberPresenter.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt index ab4b598153..ce3b9c6a7e 100644 --- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt +++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberPresenter.kt @@ -85,10 +85,14 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context, val membersHeader = createMembersHeader() val members = createMemberItems(queryParams) val everyone = createEveryoneItem(query) + // add headers only when user can notify everyone + val canAddHeaders = canNotifyEveryone() val items = mutableListOf().apply { if (members.isNotEmpty()) { - add(membersHeader) + if (canAddHeaders) { + add(membersHeader) + } addAll(members) } everyone?.let { From 0a87486f65d2e9c67a924522cff60848f9667a34 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 17 Feb 2022 14:19:17 +0100 Subject: [PATCH 129/302] Removing TODO --- .../src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt index b665ef7116..302f7387fa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt @@ -43,7 +43,6 @@ sealed class MatrixItem( override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar) } - // TODO is it correct to represent it by a Matrix Item ? => to confirm data class EveryoneInRoomItem(override val id: String, override val displayName: String = NOTIFY_EVERYONE, override val avatarUrl: String? = null, From 41bd516ca9144ee7dfb6cf86dd15b829fca868cf Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 17 Feb 2022 14:50:12 +0100 Subject: [PATCH 130/302] Updating changelog entry --- changelog.d/2782.misc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/2782.misc b/changelog.d/2782.misc index 6c340219d5..dc20050369 100644 --- a/changelog.d/2782.misc +++ b/changelog.d/2782.misc @@ -1 +1 @@ -Collapse ACL events +Collapse successive ACLs events in room timeline From 6e013e1737efcdef900727a3630fedb1bd7e38b3 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Thu, 17 Feb 2022 13:32:48 +0000 Subject: [PATCH 131/302] Translated using Weblate (Japanese) Currently translated at 74.2% (2067 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 114 ++++++++++++++++------ 1 file changed, 83 insertions(+), 31 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 1c14024c3d..bfb07181f1 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -30,7 +30,7 @@ %1$sと他%2$d名 - %1$sは、今後のルーム履歴を%2$sに表示させました + %1$sは、今後のルーム履歴を%2$sに見えるように設定しました ルームのメンバー全員、招待された時点から。 ルームのメンバー全員、参加した時点から。 ルームのメンバー全員。 @@ -539,7 +539,7 @@ \n不明なセッション: ルームに不明なデバイスが含まれています キーが一致していることを確認 - 一致する場合は、下の確認ボタンを押します。そうでない場合は、他の誰かがこのデバイスを盗聴しているので、代わりにブロックボタンを押すことをおすすめします。将来この検証プロセスはより洗練されたものになるでしょう。 + 一致する場合は、下の確認ボタンを押します。そうでない場合は、他の誰かがこのデバイスを盗聴しているので、代わりにブロックボタンを押すことをおすすめします。今後この検証プロセスはより洗練されたものになるでしょう。 デバイスの検証 不明なデバイス このセッションでは、未検証のセッションに対して暗号化されたメッセージを送信しない @@ -562,7 +562,7 @@ ダウンロードファイルに保存しますか? この招待はこのアカウントに関連付けられていない %s に送信されました。 \n別のアカウントでログインするか、このメールを自分のアカウントに追加してください。 - あなたは%sにアクセスしようとしています。話し合いに参加しますか? + あなたは%sにアクセスしようとしています。ディスカッションに参加しますか? ルーム これはルームのプレビューです。ルームでのやり取りは無効化されています。 このユーザーにあなたと同じ権限を与えますが、この変更は取り消せません。 @@ -830,7 +830,7 @@ \nアカウントを停止しても、 デフォルトではあなたが送信したメッセージは忘却されません。メッセージの忘却を望む場合は、以下のボックスにチェックを入れてください。 \n \nMatrixのメッセージの可視性は、電子メールと同様のものです。メッセージを忘却すると、あなたが送信したメッセージは、新規または未登録のユーザーには共有されることはありませんが、すでにメッセージを取得している登録ユーザーは、今後もそのコピーにアクセスできます。 - アカウントを停止したとき自分の送信した全てのメッセージを削除 (警告: この操作により、将来的なユーザーが会話を不完全な形で見ることになります) + アカウントを停止したとき自分の送信した全てのメッセージを削除(警告: この操作により、今後のユーザーは会話を不完全な形で見ることになります) 続けるには、パスワードを入力してください: アカウントを停止 パスワードを入力してください。 @@ -957,7 +957,7 @@ ルーム一覧 ルームの一覧へ公開する 一般 - セキュリティとプライバシー + セキュリティーとプライバシー ヘルプと概要 ダイレクトメッセージ (編集済み) @@ -979,7 +979,7 @@ その他のセッション 暗号化を有効にする 暗号化設定は有効化後変更できません。 - セキュリティ + セキュリティー 詳細 その他の設定 管理者としての操作 @@ -1067,7 +1067,7 @@ このコンテンツを報告する理由 報告する ユーザーを無視する - ユーザーを無視する + ユーザーを無視 警告: 元の大きさのまま画像を送信する @@ -1122,7 +1122,7 @@ 検証リクエスト 通話の開始前に確認する 意図しない通話を阻止する - お使いの端末は脆弱性のある古いTLSセキュリティプロトコルを使用しています、このセキュリティでは接続できません + お使いの端末は脆弱性のある古いTLSセキュリティープロトコルを使用しています、このセキュリティーでは接続できません SSLエラー。 SSLエラー:相手のアイデンティティが認証されていません。 このURLからホームサーバーに接続できませんでした、ご確認ください @@ -1219,7 +1219,7 @@ 全員への通知 他の人から送信されたメッセージの削除 ユーザーのブロック - ユーザーのキック + ユーザーの除去 設定を変更する 招待されたユーザー メッセージを送る @@ -1233,11 +1233,11 @@ 禁止されたユーザー 禁止の理由 ユーザーの禁止を解除する - キックするユーザーは、このルームから削除されます。 + このユーザーはルームから除去されます。 \n -\n再参加を防ぐためには、キックの代わりにブロックする必要があります。 - キックする理由 - ユーザーをキックする +\n再参加を防ぐためには、除去する代わりにブロックする必要があります。 + 除去の理由 + ユーザーを除去 このユーザーの招待をキャンセルしてよろしいですか? 招待をキャンセル このユーザーを解除すると、そのユーザーからの全てのメッセージが再び表示されます。 @@ -1352,9 +1352,9 @@ %sがここをアップグレードしました。 %s がこのルームをアップグレードしました。 エンドツーエンド暗号化をオンにしました (%1$s) - あなたは今後のメッセージを%1$sに見えるようにしました - 今後のルーム履歴を%1$sに表示させました - %1$s は将来のメッセージを %2$sに見えるようにしました + あなたは今後のメッセージを%1$sに見えるように設定しました + 今後のルーム履歴を%1$sに見えるように設定しました + %1$s は今後のメッセージを %2$sに見えるように設定しました %sが通話を設定するためのデータを送信しました。 通話をしました。 ビデオ通話をしました。 @@ -1362,8 +1362,8 @@ %1$sが%2$sを永久追放しました。理由: %3$s あなたが%1$sの禁止を解除しました。理由: %2$s %1$sが%2$sの禁止を解除しました。理由: %3$s - あなたは%1$sをキックしました。理由: %2$s - %1$sが%2$sをキックしました。理由: %3$s + あなたは%1$sを除去しました。理由: %2$s + %1$sが%2$sを除去しました。理由: %3$s あなたは招待を拒否しました。理由: %1$s %1$s は招待を拒否しました。理由: %2$s 退出しました。理由: %1$s @@ -1453,14 +1453,14 @@ ディスカバリー設定を管理します。 ディスカバリー(発見) これにより、現在のキーまたはフレーズが置き換えられます。 - 新しいセキュリティキーを生成するか、既存のバックアップに新しいセキュリティフレーズを設定します。 + 新しいセキュリティーキーを生成するか、既存のバックアップに新しいセキュリティーフレーズを設定します。 サーバー上の暗号化キーをバックアップすることにより、暗号化されたメッセージとデータへのアクセスが失われるのを防ぎます。 メッセージ作成画面に絵文字キーボードを開くボタンを追加する 絵文字キーボードを表示する アバターと表示名の変更が含まれます。 アカウントイベントを表示する - 招待、キック、禁止は影響を受けません。 - 招待/入室/退室/キック/禁止イベントや、アバター/表示名の変更など。 + 招待、削除、禁止は影響を受けません。 + 招待/参加/退出/削除/禁止イベントや、アバター/表示名の変更などを含む。 入室と退室イベントの表示 Use /confettiコマンドを使用するか、❄️または🎉を含むメッセージを送信します チャットでエフェクトを表示する @@ -1664,7 +1664,7 @@ または、リカバリーキーでバックアップを保護し、安全な場所に保存してください。 暗号鍵のコピーを暗号化してホームサーバーに保存します。バックアップを保護するためにパスフレーズを設定してください。 \n -\n最高度のセキュリティのために、アカウントのパスワードと異なることが大切です。 +\n最高度のセキュリティーのために、アカウントのパスワードと異なることが大切です。 パスフレーズを使用してバックアップを保護します。 暗号化が有効なルームで送信されたメッセージはエンドツーエンド暗号化によって保護されます。メッセージを読むための暗号鍵を持っているのは送受信者のみです。 \n @@ -1732,7 +1732,7 @@ 誰でもルームを発見し参加できます 公開 招待された人だけが発見し参加できます - プライベート + 非公開 不明のアクセス設定(%s) 誰でもノックができ、メンバーがその参加を承認または拒否できます 現在のルーム一覧の見え方を取得できません(%1$s)。 @@ -1918,7 +1918,7 @@ このセッションを検証して、信頼済みとしてマークします。やり取りの前に検証することで、より安全にメッセージすることができます。 入力された検証要求 検証を開始します - 最大限のセキュリティを確保するために、これを行うか、別の信頼できる通信手段を用いることをお勧めします。 + 最大限のセキュリティーを確保するために、これを行うか、別の信頼できる通信手段を用いることをお勧めします。 短い文字列を比較して検証します。 認証が無効または期限切れのため、ログアウトされました。 構成を使用する @@ -1942,7 +1942,7 @@ アクセス可能なスペース スペースのメンバーに発見とアクセスを許可します。 スペース%sのメンバーが検索、プレビュー、参加できます。 - プライベート(招待のみ) + 非公開(招待のみ) デフォルトのメディアソース デフォルトの圧縮 ルームのアップグレード @@ -1972,7 +1972,7 @@ キー共有リクエストの送信履歴 結果がありません 自分で電話をかけることはできません。参加者が招待を受け入れるのを待ちます - ミーティングはJitsiのセキュリティとパーミッションポリシーを使用します。会議中は、現在ルームにいる全ての人に招待状が表示されます。 + ミーティングはJitsiのセキュリティーとパーミッションポリシーを使用します。会議中は、現在ルームにいる全ての人に招待状が表示されます。 権限がありません 音声メッセージを送信するには、マイクの権限を許可してください。 この動作を行うには、システム設定からカメラの権限を許可してください。 @@ -2037,9 +2037,9 @@ アドレス 継続する ファイル - ユーザーをキックすると、このスペースから削除されます。 + このユーザーはスペースから除去されます。 \n -\n再参加を防ぐには、代わりにブロックしてください。 +\n再参加を防ぐためには、除去する代わりにブロックする必要があります。 通話を終了しています… 通知を待機しています \@room @@ -2084,7 +2084,7 @@ このルームにファイルはありません このルームにメディアはありません 公開ルームをアップグレード - プライベートスペース + 非公開スペース 公開スペース 送信済 送信中 @@ -2138,7 +2138,7 @@ ルームのアップグレードには権限が必要です アップグレード アップグレードが必要です - プライベートルームをアップグレード + 非公開ルームをアップグレード 音声メッセージを一時停止 音声メッセージを有効にする このメールアドレスをアカウントにリンク @@ -2213,6 +2213,58 @@ このルームへの参加は許可されていません "トピック: " トラブルシューティング - 添付ファイルを取得中にエラーが発生しました。 + 添付ファイルの取得中にエラーが発生しました。 キーバックアップのバナーを閉じる + キーワードに「%s」を含めることはできません + %sへのメール通知を有効にする + ヒント:メッセージを長押しして「%s」を使う。 + スレッドを使うと、会話のテーマを保ったり、会話を追跡したりするのが容易になります。 + あなたの非公開スペース + あなたの公開スペース + 自分のみ + スレッドでディスカッションを整理して管理 + %sを待機しています… + このデバイスでスキャン + 検証を送信済 + 手動で検証 + このセッションを検証 + 音声 + ルームのアドレスを入力してください + このアドレスはすでに使用されています + スペースのアドレス + ルームのアドレス + 一致しません + 一致しています + 自分のセッション一覧を表示 + サインイン + サインアウトしました + データを消去 + データを消去 + 全てのデータを消去 + Matrix ID + サインアウトしました + サインイン + 個人データを消去 + 履歴を消去 + %1$sに接続 + シングルサインオン + アカウントを作成 + サーバーに接続 + コミュニティー + チーム + この機能はベータ版です + 新しいスペースを作成 + キーワードは「.」から始めることができません + 電子メールによる通知を受け取るには、メールアドレスをMatrixのアカウントと連携してください + 不適切として報告済 + ネットワークの接続がありません + 添付ファイルを送信 + 詳細なログを有効にする。 + メールアドレスか電話番号でアカウントを見つけてもらえるようにするには、IDサーバー(%s)の利用規約への同意が必要です。 + ${app_name}はロケーションにアクセスできませんでした + ${app_name}はロケーションにアクセスできませんでした。後でもう一度やり直してください。 + 音声メッセージ(%1$s) + 推奨のルームバージョンへとアップグレード + 音声メッセージを録音 + あなたのホームサーバーのポリシー \ No newline at end of file From 5f1cd97865631147ab39148f48587eb9f165a387 Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Thu, 17 Feb 2022 13:53:02 +0000 Subject: [PATCH 132/302] Translated using Weblate (Japanese) Currently translated at 74.2% (2067 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index bfb07181f1..8701820a3a 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2267,4 +2267,5 @@ 推奨のルームバージョンへとアップグレード 音声メッセージを録音 あなたのホームサーバーのポリシー + いちばん下へジャンプ \ No newline at end of file From 3c821fa9043de89620352c6db8a5c47d5dba1554 Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Thu, 17 Feb 2022 17:00:12 +0000 Subject: [PATCH 133/302] Translated using Weblate (Japanese) Currently translated at 76.1% (2122 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 8701820a3a..83cd387a7b 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2268,4 +2268,7 @@ 音声メッセージを録音 あなたのホームサーバーのポリシー いちばん下へジャンプ + %sを入力する + %sが読みました + %1$sと%2$sが読みました \ No newline at end of file From 551e1e7d184ebc6039e9fb666eecca3ea40f4b00 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Thu, 17 Feb 2022 16:59:30 +0000 Subject: [PATCH 134/302] Translated using Weblate (Japanese) Currently translated at 76.1% (2122 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 60 +++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 83cd387a7b..4add3097d2 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -263,7 +263,7 @@ セッション一覧 全てのメッセージにタイムスタンプを表示 タイムスタンプを12時間形式で表示 - 端末詳細 + セッションの詳細 ID(端末固有番号) 公開端末名 公開端末名の更新 @@ -1182,7 +1182,7 @@ インテグレーションが無効になっています インテグレーションマネージャー インテグレーションを許可 - データセーブモードでは、特定のフィルターを適用することで、プレゼンスの更新やタイピングの通知がフィルタリングされます。 + データ節約モードでは、特定のフィルターを適用することで、プレゼンスの更新やタイピングの通知がフィルタリングされます。 FCMトークンが正常に取得されました: \n%1$s Firebaseトークン @@ -2267,8 +2267,62 @@ 推奨のルームバージョンへとアップグレード 音声メッセージを録音 あなたのホームサーバーのポリシー - いちばん下へジャンプ + 一番下に移動 %sを入力する %sが読みました %1$sと%2$sが読みました + ファイルを使用 + アカウントのパスワード + 暗号化を有効にしますか? + 他のルーム + キャンセルしました + matrix.orgを選択 + このスペースを公開 + ルームを追加 + 既存のスペースを追加 + 既存のルームを追加 + 全てのルームとスペースから退出 + セットアップを終了 + ランダム + スペースを作成しています… + 非公開 + 公開 + ルームを新しいバージョンにアップグレード + スペースを作成 + イベントを送信しました! + 送信に失敗した全てのメッセージを削除 + 失敗しました + 公開スペース + 公開されたルーム + アバターを削除 + アバターを変更 + かけ直す + ダイヤルパッド + Matrixのリンク + 現在のPINコードを変更 + PINコードを変更 + PINコードと生体認証でアクセスを保護できます。 + アクセスを保護 + PINコードをリセットするには、再ログインして新しいコードを作成してください。 + 新しいPINコード + PINコードをリセット + PINコードを忘れましたか? + PINコードを入力 + PINコードを確認 + ユーザーのロケーションをタイムラインに表示 + 一度有効にすると、ロケーションはどのルームにも送れるようになります + サードパーティー製ライブラリー + いつでも設定から無効にできます + 私たちは情報を第三者と共有することはありません + 私たちはアカウントのデータを記録したり分析したりすることはありません + Elementの改善を手伝う + リンクを知っている人を対象に、このルームを公開しました。 + どのユーザーも無視していません + キーワードを入力するとリアクションを検索できます。 + 変更を加えませんでした + %1$sは変更を加えませんでした + ファイル「%1$s」(%2$s)は大きすぎてアップロードできません。制限は%3$sです。 + + %d人のユーザーが読みました + \ No newline at end of file From 6e68f9a224c5b0fa5a2e5569f460af59d980b86c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 4 Feb 2022 17:38:49 +0100 Subject: [PATCH 135/302] Remove piwik configuration, it was not used. --- .idea/dictionaries/bmarty.xml | 1 + vector/src/main/res/values/config.xml | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.idea/dictionaries/bmarty.xml b/.idea/dictionaries/bmarty.xml index f99842f067..ed572b573f 100644 --- a/.idea/dictionaries/bmarty.xml +++ b/.idea/dictionaries/bmarty.xml @@ -28,6 +28,7 @@ previewable previewables pstn + rageshake riotx signin signout diff --git a/vector/src/main/res/values/config.xml b/vector/src/main/res/values/config.xml index 8f23c2e1be..3799d5a28d 100755 --- a/vector/src/main/res/values/config.xml +++ b/vector/src/main/res/values/config.xml @@ -5,7 +5,8 @@ https://matrix.org - https://piwik.riot.im + + https://riot.im/bugreports/submit riot-android element-auto-uisi From e44ff1e303845c60cb2c437ec05e5fa4ca9c8bb4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 4 Feb 2022 21:03:31 +0100 Subject: [PATCH 136/302] Update preferred_jitsi_domain value from "jitsi.riot.im" to "meet.element.io" --- vector/src/main/res/values/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values/config.xml b/vector/src/main/res/values/config.xml index 3799d5a28d..78b92cbfa4 100755 --- a/vector/src/main/res/values/config.xml +++ b/vector/src/main/res/values/config.xml @@ -22,7 +22,7 @@ im.vector.app.android - jitsi.riot.im + meet.element.io matrix.org From f57ece5ca80f4e498adb77cc189e9119799a6177 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 4 Feb 2022 21:15:51 +0100 Subject: [PATCH 137/302] Add icon to the project! --- .idea/icon.png | Bin 0 -> 14783 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .idea/icon.png diff --git a/.idea/icon.png b/.idea/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6f7872211b0f603c5340b3d0d2eae6c878e89233 GIT binary patch literal 14783 zcmeIZ^oXy600fZxD#)=D!ySC_R%EXe9A|4pjwJVmQ}$;$RY^4Gw%0%) zIm2g<9~lOaY|kRznXF{3?TTwS>fxC68CC6O9?j+t#t!}pwbMvWbAKS6xH56ysHZPh z_0`dh_&=`NeSeb8vK)f#%p}?A{xWni{ zD&$l?Akcp*xnv*)5>hTuC=~+^1bQ5*LJ8s}C5M1OjJ#M9&>PVIKlJ~j7FeQF866!P zGe;s@`(4s9f^tR)SH%T(4yUa(<-JWG&=?&gLE(T%k}FQiReB@pI7h_2zPL+0Ll(_< zap-vOuXSJ%|Ha(coV&a~zSiVJuE|7$Ks$xr|9cp{3jSVpRSSPW7uiwozISwSX-Ld! zU1)PV(;c!FJ|}rx9-~6(RcrGjsCj#=j!dlF#Nf`dg+;?%qYHYWKwdF&$U7FJm2tG0 z8_X#X)_X{O>^9v{BMXj9P@&xWx|m-60bMS78};|rR)q!6SGVbUj?i2NoXVIg?S4m@ zxk;&qs}tW$*nObsQ+hi4c6Rf)g_h7l@cvYtNH1A1BTmJ5q+;>xHDJh0k zB+el(m{iCww~5NfCf>)6T`AFq5*4RH+4V++$MViZ-2g^|;vEku7i)pp;bC-MS)k5n zQ);hs=mZ1qJL{;?y2gm92y7;k{;w??_iyGf`rM6EJlddwY?2onCNadd#G3U-h1<%J z%*OSff+mPOon687dg)kL6(2Cb*=63ARUYO0f4%i?4$*<13@f~U(Xq+_D)|#2_B@If zt@{fWU&^WmL9_$!lS@V_Wk7cM1uoQlFH0&b$Hdx>^AFGsZdY$fSUFQ`Kx}%s$|t}4 z%2%}DVm{KFDJE9^vzy<)f6Kh~Th+lNb+*yHm5(RoPQcM^|6ZPIO+#b>irn* znLlli`yf)T-)~R{cT&Zrm!TFML|4;+L77}0sZJ6$_(g*32b*~p>z2PkYQaKuZ=`xj z+SPK&*bt}dCCOL*oK^(6;em#{ydT_w%h0jeSvQqQKn1;&t9r`mqyw_c+1Z))h>N4D;FB(N zty9e`ED$#~;=YuZ_lDj8cG0x#!#J!JqJwlz3#Z7suq>V2{pLxS6 zCqLB_Yxva3A)%L@>|50P;&<{euVo%bo8dvHC4Yx$;r;pJpYf)+M=R0N<#cc8v|ocL ziZqTwF466pWJ;e_<$T+QZ^ul0U8c90*l>1no2)MCd46uh93gHs@p5~6_lr{Q2%z`A zSCys7pJ2#;KW*4R{3W1~P38eAj#cKR7y&o^t8y=5}MK&Nt?=O|bTmNLhe%%p$nE zc<6pY@H|DI#y|S4xg%^+Q7=yhb5bcAT%o5e^vVfP>zI)$6?XU%&Z)5Ph+=wmN*6$iRpTJ)rZr)(|d;{>!aluWEryeS_;eJsd~VyZeX` zOZfH3A%Dtl{9PXpKM_lfF{+pk>aAdg^hbc*80Z?R`BZ>zwI8!1$G0pdMwt38D^Z=B zACR-y)KE1V---{8(TWTV6urDK^9RbCUj`;(%hC1I9u_VkMgr-(T-(YiE1**UX~99r?TrU4@M@EF0#H`3?-A zcX}i4T#t~MNikkTxw<$zi!hs;Il4^SieE0WFjv15^3BqA5D`&TjY_mBJB3Y*q)`O^ z-v1RNTpTM=s9}XzpE97#EKr38FfGrYi(mCz9)+AISe-*zxY$>3$Q#9_|E>oDgoqDn zL^>WS44zv*yafl7{RyMy`hk6LT3uvPXcQ=dSmM7m-G*O#vfZ&S&OP&%~06-F;x`!Tp9-RNj}X}SQVT2pLK zoWSG9E^CS2NAP#fj#Qh~Y#(XD=vmsTwx|&sZ@24RKVNC|N1U4N`X0FiBoc*RwpSfc zlePSZ)fY5UMEyov*EEgvyYt_&h=MJ&KC8T!zaH@h9G0kxQ`@a4RA>`>?C1pIGt-xS ze7~4X;jzv){xXIoqRK_kF@C!B0#;U8%);9x{|KiZ1GX&V70hj>YfpL{nk!oULSr>6W(%`5{)N8Nc~%reMMkS>+a zvTA|{SaCvw5)D{F?MmAb-r)WFlXJ}Eapn0z>Af5VQwCR z3o{l<7BX#g*1pHFK#|Xnm^&(8_lsd6ho~1mNJ7pj9MSC;7OiMr2E3n^oOq&tGrc?K z*-f=qe?eAw*7~{o9=4`hiA_V_n}q2^Ath%evBy0E_07&dN601|2J$qZc{s1`9fsAD z=K(J0^R0n?-PDQe`(b4oA$^na{;lEx9=VQ7bgZPdN^mauknxn+$;m*$(!O>=ej=n{LP6jqiICrBTbNV4AX;Xa{gXUr&@dZ)gg%jt=>4T~m{B0Evr+5A7f z+oW6<8+7~HMReX#ho8nOoZghPi=64PB-I+(j;C>?AbnuMg4AJ&!LygGbw%>&#i-`G z!!R{I`uQQsikB;e!Jl$sbdCn~0XaMcuPe1N?1_8NrT4iY^yg6Oog$o~MD#>N6c-H3bil`x->ZqeN;CgUbzv z(V7>Lr~*}SHY0jILWarFpX=TSMPXt{Lbf>jEl8|NZfZOxBgT0JCA|)l)AqpWT4dx1 zWvM_JO})e!MeAaY9~FSwU3;FRyl9;rpfQ2^%kS>Cc1zEwuPtmkZ_>A}4I9NTJB-Y= zbxeH_7vqlwhrw>-iPe=@ZKcZ8@Vw;592uy@XrzT(3VY}(Rw*KFczUQUSNN`ax*MkHT#T!< z0kGLh&MfXskMBqEJ8h-f-L8$_ifWqKFD8)zoRBo#N|o5IxJCU)@I-Y_Iy(p5!hcwP zmc{31{S7nDKwy=zx!u$RsSv4cxx_|Pd{!zQ$hPtTGD44W%L`GpvvBmet zkBw~#n>a-q*W^TXG`9kk3a?gTU4{q^UoNuwL=16^2Jc)N6`3OCy7GqykF>0GtnjG5 z@~Xw+keEv=Dw;5Ei3ESTYqp6Z0UJI8=F$xVT?rfxF2?9Zcj9*j-23PD+)95ZZb@roS& zQneH#ed5-0OOuVAj8<(>z^FEL?l=X_dd`pKzp3hrarIm793HIuqCN=6NqMA=f3HS> zs1Dvl>Sb+G8~)@B+^yaypo|j<7KbY%0(4y_v&;yWj5x+!SeA>@8Q_~a-m!?AgugmG zD@6~4+&%Yn@>2)`MCoZ&tWpQa*R#h53S~xjfAvUoz6ZB}q7VI`CXM+DR0mW6 zbMg*lT%+~wvsO{Y>t=0pn;STh?j1&4m;rJ9XR-RehUT`4bXiABsgM=;YkFwft;AT{ z+f)bNrSI6{548uL%g5#mwZ0jjOPQx$qQCa*tqM4E{0wtw`-f4Q>4_1%uEPlYb-LbR zcowF=wrty4Qqt{*Kd<{COR8v-ov~1x^wdN?w$QWHeU!aCxU5hli21!na50z0jIMo%?M1^b@u0`r)Rg#g-niyX5fi3Vi|ife*c@?0=(#)_OlJ zd$YYO=2<-)U>4WJ4^1|X|K$kd7DOj67=9k6qVzC)60-iY>tJe5MDV+~Cby+YrMX)m zDrei_z(wFz6M`I`+alBPdX*El{%F6~+DRj0Mg0t0#yfuFaxy2wqrxbSV$J@b9D8$V zK0xiAf>?t=7C$*WYeSQe2f&YtJX?G&OOoL45t|14-Z7s-m%8x&X=+Y_+ZELTDA3Bi z1Ok1^G?ZfZ%2~;vbQ56@$sqk==K!^Rw7Om_txN2)vmu9vGRp*awhU78>+Vn)6;Tsk z!m7Rgc489gBSN`56R*o_}FhoZNJ(=vIfif&`ZYk9@xA#}2(*#g`twypcICl2) zmVp`wS7;Ehi@OuF-E(s96ve@K_OsJXYsn*Na&ov$I_KOMbzl0I~BR}><)ki?<^rf6F{mX&rXUw0bJO0%-0td6i|+xF2zOwlVAKeAIK1xt_J|)Sc_Fl z;fi0SHr+oNx^}!#)Lg&k01jaFI^AnqJ}lWn8J~{sHf=IV^_o+o)!CXwgOUx^|Hjh2 zcBB0ada&l!Xf>e>1{@2>qj$TaqJo0gV(!y)9d&o)x33I15}Qg%23e!kInt~R1qE_A z=+(f{OYr#RLjC`%>ZC)1E$nGTmUd966hMe zbXzkGXc`$COJ|Yy-@8j$UAwqZ-j~tM%6Y4BmxB0epi)+RYASYG+2odiwRMOijq2G+ z`imkXvSKs7$8c>#`m9*%*&3Mrr&=!McY~<8s+tbeldD;p4EA9cy8&&b1Bx>_!I9A~ z4OK-^Rkc*n-L2kYFlv@Cd}c#yo%2@ty>IPRTd~V7>tA_ZNd-Wy<5*-%+PgD6%v?BR zU$+XM?*$lYQ|)_J#o#U7+_D1o6YiTxUyj_I9{yurD}3`bw`CjQvb{iQF{{Wxa*Mm% zTeQJrs&G@oLhO1fiuk5;}HNICL>?=BRq>HR${i zcyxVV%>B<_8F83E=Z!z7Um8$*&LQ8*%rL_eDj(yF-?qp&yU+YCdxr&5t3DvHsB<2U zxu;1G42L0L<=%8oQ$tOo3^Jr#9iQx@Dv`hPg;MPKAI{UiT$$?+7XCYSyYF*7tJ43v zQxWe|G-iMNkXETHHTku#MNaoZ^_a@XFe_%dXz$^Fln34W&zrHdEMQVDqlT}$!p2fY z>i}^;_uGIFe{H`1mF#?2_8z2?JaO-~LkUw1>rcgFA0*qw5gA}+`k3aO~;v>=0lQh0uw}==Nl`(Z8F;-_s7S^ z*xucuOWFnoaiLITii;J&7p;uotH zdpx71AyAm^UbegM;+S;2v7>DzQBwHjYkn+Qq2gBsHKctt^}97Ci;@DBH4%t9f9-vf zcQyXp%A|^VaBo=sOQ&MpnNtVk$jO6WJBqLuZ<4X0$oe@LtkxbnbdTd=@q8 zw|071A267Iz`5m_(F*ayYYBWW`wzX^R)5(F`?{RCP#W(|SM~nEX0p&uoJ!JT`y?%E z6vTJDp$+f>%C%p$ue_Z`YwGl5fU1&zrO^Uu?W!Tr#I4vqA1?=d|(?EX3e z(;3#0sVJUP_{rpbwbcIU< z3`Wp|nwmL_iwpTMkF;1DZFr}>sT-}1bcQmp=)ti+>1qoVb= zKgFC_*CeTsZo;JBiYOW|pfb`53Nz+Z?mcMqAoaE6k-PRz3y6-U0d5auEofrG_ zCaIzhwL4u*8F}FE+06@m?=nnAO%pkrEVAnhHyQQLeu#^|!M(C)gxU~YZ%YxON0$lq zng!XCo|7w@ld{k!;9C&tr80?1u@h{G2H4sje`=uXs*8S@AlK&<-m%~qt7bbjJ#FR7 zDsH+H=x;&7nhsN=Sq)J-b#4)llGFBl$QhRSGr%PtV0F@h^?tT%yxIKocjBlsW~j+m z*ftTMtOes6oWJGe@mcwmXb_=!70Mh)QOgO_sgtv*V)NiTT-!JvKt!pe2}|9Gd{c6! zJ#q2gm$iPEuYmx?crO^$)oUC@gc4FU#jKW{T^|JH^>RfG>Hn7nJ_>gyp5Obrx#65l z@O5(BL_74Sr_5=ic8?1Fe62P*b1)LMl00PgTh?p0XxjFttW?6GuF;&zIf*PN5R01D(w#x?o zChi4>>Td$MLXqrd?Hz~7k>!4QW{z@)U97&k;P!|qvh%M!#7)@P=7 zr3by%90qLL5C#Tz5FV}*_U(rzNcz5SWj%NAYHpcfKLmB}ot2Gs40|sx->WO9`+;qn z5b!vO==*7zIC6=o9zVj@prijlDq6xgJV{+Y!glM^W7Gz6kGk+%hXGXWafr zd06;~BT_E^QE?+O%W7xKQ{p`R5ED%Y@2De2W(KeS?R<--X82;I}%yn zxnT4TrPu0q%`on=86bFYw!4}vGKuijNBA5{$>NDVg3K+zx`Tjm^C-S4%(vV+_19`X z7ZLsm@Zqb20DCI766litcduYoHtNJNsYu(x%g;y&d^Z~+>Q=AD3M5Uq1o<)dqxWf3 zLD325pD~>ahGhW?ca7yzVRtRxeBjwmEl)<)q7Ua{@HG|Y2RnMd)=1P7Rlq9JfHDCX zBJ9=z##gDiO!~N3i^OEiEn1nv2SC!_b$ZgkeWK4I}AU=m@Htr{d4%s zR3gN?SX-kF1=Oc<(x9jzX}$^(_En7ZOXxmr?XQ2uGrPPpk0(LgBgjL;qaiXCAigf~ zKN);(QRg&iCHpn7(B4tIF3xK9$JuWQKPQ&670qG3CuXh!S;tu~j4_E%ld6$_01$$o z(Z6QcgS?u3BK0dE8&gd3uuAr~G{fp=Y)2VtZ!BKNqx8Ym<1oaebi02hfR1Jxud``~ zu#0Yw8zIWvnuk{(4l12m!@N^EzxYwhmL^2Onw^81my=lR;Rfc6tx`xX-&NWO5Ar7O zo3EIrt;|0&T4_U)@pW=KBfKp8L(O-WZGC(=w*gjb;QY{{!p=G3OG` z9vrj<{Ay012%1>5(elR5`C=iT`HISC?WlcY?M0+BkDZH$hd&~+V)0bEykJ^)e6MP4 zJ2C$s^fO*I<9fo;cMwjYaJUv)F!0|&l8V3k6%C>`nNvC(+?R)pJ(FHrF%mNDkHe7wiorm1M%j~ z_Ew^LZ83_nkxB9KsvZ2p;vyUAY%{-rZkd&vXSu@_rQdQDbh0pdeYNwKLGk1?@xtX4 zQBL7&HQ?g-RnB`g&EfFy(5de7chY5#>Nrpzla`itTC)Bu_?vKiIX{te)qUkkob_*S z-RRadQH)fV2K@c+9uHRPjNaPSRS{HBGp=mx|j1y5$aXxP{a@jiTA+m(*#vQabKBeAc za}kr$Eyeu9dyB0{<6CKQYg6B@FZIWz8zk0LijE=*lrIj3k9aP(bcc&<2rsVtMp+7i zpLgUjT*bV+hg|t1ePn&LG3{gz`&E6aqGKBDe%iLT_`R~V{;U}KFoK(kRFPo{ZJdUH zbmdQCHhzYL`1@i?P;fXJ(f+?;5qVYQDZlcmK7%4H**eGK)kRmvQ0wcY;T`8yt(tY= zHk<60))Tq2?E-O*pZDEQm(W_bgG{< z(RR++bK`qmT+^u2wyp_aQyj;(SsKmZ<8mj~GFQ2%wH4oKGr`dpoq#8GY6!+gzKz$ixU-f z7`IS@&7l`faw#MvuxAw|{rfE@=pPJ>y4xy$Hni#({*2B$j@il?AR!7v6i3vI@031~ zZC+o)PELNlL|*uw*46Mg{lzDt_L5~RH#XoSn2?}3So1ognkUtPUgJ6M#D^e;8Pi#C zI6~Hg+Asa{5xmu!QJ$Upps6V-2F^wbFKkgvD~DXIc83)W0p^ zG#RyX&A&6DY}O+9re-~+`EU6Ca79Fp(uLLnnRa#I6|>QFOvpmP5FK&ec8g8Y^qZ+X=_~5L{T6tJuP(r%$DILcx_}@7l)B!Qm zw}81SzH~t}k1&X`Q>e|8W99Pj&nkzYS6LmFBUF+?v%e_bTg3SIYKu1pl||{;R_cu> zxaD#6bnJX<-kkZSEy^s?2vzBwhGgKKZoAeIv{J|C1Ng5Wwf^XX^Tb1l;+F-=8W}x4 zm+Y^10>)3;pw`v0S4Xeaj!OaBaC_;6+TiP^vi=f_x(cA2BIE8{#ae1U{{GT(QOHCM&D8bq9XV8egl*7W`QXIPV4V6<9|}h3n2S5SnNBoj(NXL^KeBQ>bzBi@0QOcR^1xpExGW~ei665RU=l&H_@?D#i*0R_6DF{80j(sU533^ z-%`wL3E3Pc2p#l(ik!bao}=+KM&Se z%`vH&>FH^@Ndv;~FY;nuzWA0m!ioCQO zi5Seh@93r>37E9?;6Bo;cf2pT!92T0);*+;L6lU{52}@Ib0v0Svujw?o*a3Cxjhp1 zxOAJI=R5B(aMAIQx^~a8?>pY{r~XdtbKS6o_jB!^P>_~#FNdQSrgqFyY}E$d#8%Ci5kHbSi^!6nDWNWT^r|pHvAFBzw#I=tIV^Uq$1APT9pJu z+`H0Rvf{Nba%-?ZCRdkzsFZsLXXhn+S{pXh2YY=$gn+}xgz{FAx>RbQ0@fi>zi<+vDX#J9uSZo6R7+~vj(C>k7uelY zXg(0kW`({dI@rE{Q0a3`kWd8oH((?BP4}jH6xXy`0>|GN z$=WZV3cr2x^8PIG$x&@;8_r~Yph$x!9_G=GJSbW|D}Q!Jxjs(gVKIe3DYm!ti+^!B zwep5{&2X%ndi7&?UniZ@JMfWBL9Wy6S2L9}kHU02Z{m&6+`aVWKJH&@^AhfVK#5Zd!)yesr?i;5xo2(5+eN zM#_~eSXt=ZmE zCemMS_8j~MZWa91BV_M~nO(Pap!?}84VS@Yi$_de3$V3~?+99i=1kbHu`tx1Y2_2& zPk$w`dq+3@y0a-onWnh+jI+GQ1J?(cO#C1}mjHW+y=U8E&1f3-#S@R)9|~mk85uUT zp$>h-hVUbIS*P3Lze3!A@ zi`8x7y>#uiqD|}4v2Gjn>Z!0nef}AXjNn(GutYWg;+(HRVS#x&*+Fw9L-zgopGKhh z4F+fE3a3A8ekWCHj9aDbcnI`bSmMa^vlLjy78KDWiCj%+du0cXVPDNg5>4utC&VXy z-U}A{x$91dA+V|IjLMl5yyq=^3nBYp-KEMd2E}Ey1#%5 zG+z_UXwCgS-LbKB>z*uf%6rA4`NSli?`QtBvWD`=4eFdf&Kivu?tVM;2_vv|wQYBK?75yc zRq4_gdhLQAJBU8O9E=Cee&&`>_%M1reAb*@Z_PDfmz<>cjmK_DL}$wV+X`?$Ekrgt zrWqr_O3FnB+4(aqv)=bPs$WCA{6dkZP&VnXVoHF=ESVxmYoU@moNJadne+PWL9xns zJ*($KQm%-his!yGx{^!<&+9z!K||R{LW)n0VzlS{&RD^^2D!R=GG~cQj_p!%jB7Yo z3_n&v5D1H@DMwRh(Pwkuxti-eu(PTq0m@r=YHusYh{1C5X3hXN@gIpy#5}vF+yt#| z0uFYhs|)GD$e&7O7>n)A;Cd*B*p{ zr)i-8nj29po2%uc+kr;UYSeM_khYGL{s|k(cM^k;!_D+l$gmIokAGSM?k~_A$%S_4 zRY1d3#BZX!KxBbypRMZ8x}Za691OQfTSc5%vR?^^SgRP(+o)t(fZ2iULmQFdH)#eu zJsSn6BhP!&W2UNKX{I+cH^)H zQLy(+Qb|hqG@*NbbQ14=?cHY|AJ-dOQhkl;x!sX>{6K+n??hVtEqiXX*pb6UiehM%Z38&=JOgE_n!e|p$c3`%+^a6kMP$0$1y)x z08Hkj*BAftEpjo_i2^iwFh_%M9j~j{DnA?aj^ukfC7$DZ_9Rj+R8>n$DPkjeAa_?1 zH@O>5t*D}fB>USLbJjFW58Q{P>E?zz7K_TsU*Gqh6sPX7v`EpcV!UhUR&aVFafRBrNReluY2k&*u2G7&{(E zVy0c#=L&TP{_(>_4yGr(k(w=)k_IQVGc^nMIwmA~TR~MZCoxvDW0R-e)5N9Jtyu?k z;(_A5Ksee3Qb9Zy;tBN(9rq3Pxe&@zdZkDXPwC`bJ^hZ@j2W1;$jCl>TJ(S!<(cTD zG+Qi_^MjI?`p0Gygz8X&A6tHJ^?u0OI&f->pUL@-L}iPIknef z`}iAJ(W6OvJ933aMCKH``EBn~HM{VTyj}9df0GD$`F6YxED+>P(omZ~8kWt^rT;n5 z&cLUk*huMMZ_0#oj1UG^ei=Vr$J10)aapfiyKBj#_#Zi3hiSFuzm@^ZHIKMUY&kY& zzVd1;-E2+bPuzH&vQw!*PG02c4kJ!Z?+LeET5mQY+iN$^WbooAH)0>3!+xK+r4sqv zwoot0Ek#nC98Ry(a&#`((c;~^ziwvfG3S0_25+HarGt&P9lBe|ut%%sI%qj)2;}%z zcRqD^+zQ_=hMK~=OLv-%bh{@LlfE`SbRmaFzu@L9umxv-x(zNtLX(V`gO+@`=(R_O z6~MIdDg(a{%$Mq{}P z)`W^x4H{IBL!-ehm1I(wt>k&P!hIx&{FJqGW)Q|W^y_ZIAbE7exNn+J_arXp>LDpI z{>8Q<`r*#ToWAufGx7_VS@tiz0IL}7^8C}SPADVJj=>v>ctVWxFn2t<*zcvFjUM+s zKA0>YusNp>Q_@IQQk2}d`z`hzDlL{l`HQ|)OXX6oO35?4Kh=T$(^N#;&G~Joi$L-3 zF0@3#oWpmU04r$t-NqzdEY!9uL0g}YK`d(R!fu6xX;4G}j}DgZ=?qXjbY#Hs7v9N! z>s@SS7U}tA&65YK5XraGlt`1j3}?jgGo0!t% zk%Z>nIa?P9J_~`-pU|$?oj-CGwz!SA1F!nSI$!5p|GN2I1AhlCu~eg1y(o$l*M2>TJ_|irDvQ zO}~jZD^Y1>{SK`6Z?shQ7SNJ8P#r{=I`d?r*amdJoln|I1z4rV9SzxWpK0a-$qs#j zXT<(#WcmC}L_DkLKb1v9r_>z#s{gPR#6CHX%!R=S-Tt!R`a5YXp&~m?Vo7Oevpd)X z$u<7G71ZZ>x7uCFSnGalO!np0H#r)+&dsLBU1qi26B;}?RG*nM58Fk{Mlv|_KV`tf z!Oti8gn?!8k5M!}r-USU7MLu@<^y-LWP$Jo`-S3rotJXs&6v^nXO^7>c=uodt_WB`fe1?*paZ*Y= zY9HW3U;Wkv2EFD5<_`7cZB79r}uHAjV|M-Dxv0)g7 zfeoY*lBi+qp~iFF0;S^ch8C1-&1kq@blnH#4f<}QiXPIui8BO5Jh}!eO8pO;q(pf6 zujid=<&Y*LPGSy42KxQzyAk{#tkQdp_B{!R)}-{`HyCkrm=+XjOH-?n1i{vMRO0i|)> zGk0LztuWaAt`<^Ib?zOao^enC9q{MCE|FY**THK|Lf#ZTAW(Hazbl_q_Y)S}Ru&oP zfwWkB>j9253(%@EMs*;xWGoF*;Z}7_j1$6cI!2R$mLK)MPCc0$O1O(P`mC!&FrWbX z?`A*f_w}}v3d79Ffp~S(IZIxDg*~~6%T%NUEo--$!=5ny@3UdVn&kRYGMbx)69L!; m^)TQraD%6$?{oGQ*iN4;K3w;V0r Date: Thu, 17 Feb 2022 18:20:20 +0100 Subject: [PATCH 138/302] Changelog --- changelog.d/5254.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5254.misc diff --git a/changelog.d/5254.misc b/changelog.d/5254.misc new file mode 100644 index 0000000000..2ae642e9b7 --- /dev/null +++ b/changelog.d/5254.misc @@ -0,0 +1 @@ +Change preferred jitsi domain from `jitsi.riot.im` to `meet.element.io` \ No newline at end of file From 8f42167fcead16148feb66358771a1ce73cf2d41 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Thu, 17 Feb 2022 17:17:36 +0000 Subject: [PATCH 139/302] Translated using Weblate (Japanese) Currently translated at 76.5% (2132 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 4add3097d2..f8011baea6 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -646,7 +646,7 @@ 暗号化されたメッセージ 退出 コミュニティーの詳細 - 読み込み中… + 読み込んでいます… コミュニティー コミュニティー名で絞り込む 招待 @@ -847,7 +847,7 @@ このホームサーバーは月間アクティブユーザー上限に達しています。 この上限を上げるには %s してください。 このサービスを使い続けるには %s してください。 - 最初にルームのメンバーのみを読み込むことによりパフォーマンスを向上。 + 最初にルームのメンバーのみを読み込むことでパフォーマンスを向上。 あなたのホームサーバーはルームのメンバーの簡易読み込みをサポートしていません。後で試してください。 ルームのメンバーの簡易読み込み 申し訳ありません、エラーが発生しました @@ -1053,7 +1053,7 @@ サムネイル送信中 (%1$s / %2$s) ファイル暗号化中… ファイル送信中 (%1$s / %2$s) - ファイルをダウンロード中 %1$s… + ファイル %1$s をダウンロードしています… ファイル 連絡先 カメラ @@ -1173,7 +1173,7 @@ QR コードによる追加 コードを共有 ${app_name} で会話しましょう: %s - フレンドを招待 + 友達を招待 既知のユーザー 無効なQRコード (無効な URI)! パスワードが一致しません @@ -1624,7 +1624,7 @@ リカバリーキーを入力してください 履歴をアンロック 鍵をインポート中… - 鍵をダウンロード中… + 鍵をダウンロードしています… リカバリーキーを計算しています… バックアップを復元: ネットワークエラー: 接続を確認して再試行してください。 @@ -2268,7 +2268,7 @@ 音声メッセージを録音 あなたのホームサーバーのポリシー 一番下に移動 - %sを入力する + %sを入力 %sが読みました %1$sと%2$sが読みました ファイルを使用 @@ -2325,4 +2325,14 @@ %d人のユーザーが読みました + スペースへのアクセス + このサーバーはポリシーを提供していません。 + 数秒かかるかもしれません。少々お待ちください。 + 利用可能な言語を読み込んでいます… + ユーザーを招待 + ユーザーを招待しています… + パスワードを選択してください。 + メンバーを追加 + ログインを検証 + メッセージ… \ No newline at end of file From bdfe5639ee3a5b829a14a18a4958207a8be4d890 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Fri, 18 Feb 2022 09:53:09 +0100 Subject: [PATCH 140/302] Renaming merged event item class --- .../detail/timeline/factory/MergedHeaderItemFactory.kt | 10 +++++----- ...tMergedEventsItem.kt => MergedSimilarEventsItem.kt} | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) rename vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/{DefaultMergedEventsItem.kt => MergedSimilarEventsItem.kt} (96%) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt index 0b8c2eb572..76ed024370 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt @@ -27,10 +27,10 @@ import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventVisi import im.vector.app.features.home.room.detail.timeline.helper.canBeMerged import im.vector.app.features.home.room.detail.timeline.helper.isRoomConfiguration import im.vector.app.features.home.room.detail.timeline.item.BasedMergedItem -import im.vector.app.features.home.room.detail.timeline.item.DefaultMergedEventsItem -import im.vector.app.features.home.room.detail.timeline.item.DefaultMergedEventsItem_ import im.vector.app.features.home.room.detail.timeline.item.MergedRoomCreationItem import im.vector.app.features.home.room.detail.timeline.item.MergedRoomCreationItem_ +import im.vector.app.features.home.room.detail.timeline.item.MergedSimilarEventsItem +import im.vector.app.features.home.room.detail.timeline.item.MergedSimilarEventsItem_ import im.vector.app.features.home.room.detail.timeline.tools.createLinkMovementMethod import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.query.QueryStringValue @@ -83,7 +83,7 @@ class MergedHeaderItemFactory @Inject constructor(private val activeSessionHolde event: TimelineEvent, eventIdToHighlight: String?, requestModelBuild: () -> Unit, - callback: TimelineEventController.Callback?): DefaultMergedEventsItem_? { + callback: TimelineEventController.Callback?): MergedSimilarEventsItem_? { val mergedEvents = timelineEventVisibilityHelper.prevSameTypeEvents( items, currentPosition, @@ -129,7 +129,7 @@ class MergedHeaderItemFactory @Inject constructor(private val activeSessionHolde else -> null } summaryTitleResId?.let { summaryTitle -> - val attributes = DefaultMergedEventsItem.Attributes( + val attributes = MergedSimilarEventsItem.Attributes( summaryTitleResId = summaryTitle, isCollapsed = isCollapsed, mergeData = mergedData, @@ -139,7 +139,7 @@ class MergedHeaderItemFactory @Inject constructor(private val activeSessionHolde requestModelBuild() } ) - DefaultMergedEventsItem_() + MergedSimilarEventsItem_() .id(mergeId) .leftGuideline(avatarSizeProvider.leftGuideline) .highlighted(isCollapsed && highlighted) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/DefaultMergedEventsItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedSimilarEventsItem.kt similarity index 96% rename from vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/DefaultMergedEventsItem.kt rename to vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedSimilarEventsItem.kt index 65675efca9..f012ca6cdc 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/DefaultMergedEventsItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedSimilarEventsItem.kt @@ -28,7 +28,7 @@ import im.vector.app.R import im.vector.app.features.home.AvatarRenderer @EpoxyModelClass(layout = R.layout.item_timeline_event_base_noinfo) -abstract class DefaultMergedEventsItem : BasedMergedItem() { +abstract class MergedSimilarEventsItem : BasedMergedItem() { override fun getViewStubId() = STUB_ID From 3702ccd2bafa9458f140f6398f7642718b8622ad Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 2 Feb 2022 19:05:03 +0100 Subject: [PATCH 141/302] Defensive coding to ensure encryption when room was once e2e --- .../sdk/api/session/crypto/CryptoService.kt | 8 +++++ .../crypto/CryptoSessionInfoProvider.kt | 2 ++ .../internal/crypto/DefaultCryptoService.kt | 4 +++ .../internal/crypto/store/IMXCryptoStore.kt | 2 ++ .../crypto/store/db/RealmCryptoStore.kt | 16 ++++++++- .../store/db/RealmCryptoStoreMigration.kt | 4 ++- .../store/db/migration/MigrateCryptoTo015.kt | 36 +++++++++++++++++++ .../crypto/store/db/model/CryptoRoomEntity.kt | 5 ++- .../room/relation/DefaultRelationService.kt | 6 ++-- .../session/room/relation/EventEditor.kt | 16 ++++----- .../session/room/send/DefaultSendService.kt | 8 ++--- .../queue/EventSenderProcessorCoroutine.kt | 2 +- .../room/summary/RoomSummaryUpdater.kt | 3 +- 13 files changed, 89 insertions(+), 23 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index e3f00a24b6..9b617f3e4f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -113,6 +113,14 @@ interface CryptoService { fun isRoomEncrypted(roomId: String): Boolean + /** + * This is a bit different than isRoomEncrypted + * A room is encrypted when there is a m.room.encryption state event in the room (malformed/invalid or not) + * But the crypto layer has additional guaranty to ensure that encryption would never been reverted + * It's defensive coding out of precaution (if ever state is reset) + */ + fun shouldEncryptInRoom(roomId: String?): Boolean + fun encryptEventContent(eventContent: Content, eventType: String, roomId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoSessionInfoProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoSessionInfoProvider.kt index 82eced4371..2a58d731e5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoSessionInfoProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoSessionInfoProvider.kt @@ -35,6 +35,8 @@ internal class CryptoSessionInfoProvider @Inject constructor( ) { fun isRoomEncrypted(roomId: String): Boolean { + // We look at the presence at any m.room.encryption state event no matter if it's + // the latest one or if it is well formed val encryptionEvent = monarchy.fetchCopied { realm -> EventEntity.whereType(realm, roomId = roomId, type = EventType.STATE_ROOM_ENCRYPTION) .isEmpty(EventEntityFields.STATE_KEY) 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 0646e4d2b8..f10cde6759 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 @@ -634,6 +634,10 @@ internal class DefaultCryptoService @Inject constructor( return cryptoSessionInfoProvider.isRoomEncrypted(roomId) } + override fun shouldEncryptInRoom(roomId: String?): Boolean { + return roomId?.let { cryptoStore.roomWasOnceEncrypted(it) } ?: false + } + /** * @return the stored device keys for a user. */ 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 82fb565377..46f94bc3bc 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 @@ -240,6 +240,8 @@ internal interface IMXCryptoStore { */ fun getRoomAlgorithm(roomId: String): String? + fun roomWasOnceEncrypted(roomId: String): Boolean + fun shouldEncryptForInvitedMembers(roomId: String): Boolean fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) 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 33578ba06a..a07827c033 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 @@ -631,7 +631,15 @@ internal class RealmCryptoStore @Inject constructor( override fun storeRoomAlgorithm(roomId: String, algorithm: String?) { doRealmTransaction(realmConfiguration) { - CryptoRoomEntity.getOrCreate(it, roomId).algorithm = algorithm + CryptoRoomEntity.getOrCreate(it, roomId).let { entity -> + entity.algorithm = algorithm + // store anyway the new algorithm, but mark the room + // as having been encrypted once whatever, this can never + // go back to false + if (algorithm == MXCRYPTO_ALGORITHM_MEGOLM) { + entity.wasEncryptedOnce = true + } + } } } @@ -641,6 +649,12 @@ internal class RealmCryptoStore @Inject constructor( } } + override fun roomWasOnceEncrypted(roomId: String): Boolean { + return doWithRealm(realmConfiguration) { + CryptoRoomEntity.getById(it, roomId)?.wasEncryptedOnce ?: false + } + } + override fun shouldEncryptForInvitedMembers(roomId: String): Boolean { return doWithRealm(realmConfiguration) { CryptoRoomEntity.getById(it, roomId)?.shouldEncryptForInvitedMembers 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 685b2d2967..cac6499486 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 @@ -32,6 +32,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo012 import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo013 import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo014 +import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo015 import timber.log.Timber import javax.inject.Inject @@ -46,7 +47,7 @@ internal class RealmCryptoStoreMigration @Inject constructor() : 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) - val schemaVersion = 14L + val schemaVersion = 15L override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { Timber.d("Migrating Realm Crypto from $oldVersion to $newVersion") @@ -65,5 +66,6 @@ internal class RealmCryptoStoreMigration @Inject constructor() : RealmMigration if (oldVersion < 12) MigrateCryptoTo012(realm).perform() if (oldVersion < 13) MigrateCryptoTo013(realm).perform() if (oldVersion < 14) MigrateCryptoTo014(realm).perform() + if (oldVersion < 15) MigrateCryptoTo015(realm).perform() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt new file mode 100644 index 0000000000..7bfea7d72f --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 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.internal.crypto.store.db.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +// Version 14L Update the way we remember key sharing +class MigrateCryptoTo015(realm: DynamicRealm) : RealmMigrator(realm, 15) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("CryptoRoomEntity") + ?.addField(CryptoRoomEntityFields.WAS_ENCRYPTED_ONCE, Boolean::class.java) + ?.setNullable(CryptoRoomEntityFields.WAS_ENCRYPTED_ONCE, true) + ?.transform { + val currentAlgorithm = it.getString(CryptoRoomEntityFields.ALGORITHM) + it.set(CryptoRoomEntityFields.WAS_ENCRYPTED_ONCE, currentAlgorithm == MXCRYPTO_ALGORITHM_MEGOLM) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoRoomEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoRoomEntity.kt index 711b698464..6167314b5a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoRoomEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoRoomEntity.kt @@ -27,7 +27,10 @@ internal open class CryptoRoomEntity( // Store the current outbound session for this room, // to avoid re-create and re-share at each startup (if rotation not needed..) // This is specific to megolm but not sure how to model it better - var outboundSessionInfo: OutboundGroupSessionInfoEntity? = null + var outboundSessionInfo: OutboundGroupSessionInfoEntity? = null, + // a security to ensure that a room will never revert to not encrypted + // even if a new state event with empty encryption, or state is reset somehow + var wasEncryptedOnce: Boolean? = false ) : RealmObject() { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt index 3abf28fdd4..848e14ff57 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt @@ -30,7 +30,6 @@ import org.matrix.android.sdk.api.util.Cancelable import org.matrix.android.sdk.api.util.NoOpCancellable import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.toOptional -import org.matrix.android.sdk.internal.crypto.CryptoSessionInfoProvider import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity @@ -48,7 +47,6 @@ internal class DefaultRelationService @AssistedInject constructor( private val eventEditor: EventEditor, private val eventSenderProcessor: EventSenderProcessor, private val eventFactory: LocalEchoEventFactory, - private val cryptoSessionInfoProvider: CryptoSessionInfoProvider, private val findReactionEventForUndoTask: FindReactionEventForUndoTask, private val fetchEditHistoryTask: FetchEditHistoryTask, private val fetchThreadTimelineTask: FetchThreadTimelineTask, @@ -146,7 +144,7 @@ internal class DefaultRelationService @AssistedInject constructor( ?.also { saveLocalEcho(it) } ?: return null - return eventSenderProcessor.postEvent(event, cryptoSessionInfoProvider.isRoomEncrypted(roomId)) + return eventSenderProcessor.postEvent(event) } override fun getEventAnnotationsSummary(eventId: String): EventAnnotationsSummary? { @@ -202,7 +200,7 @@ internal class DefaultRelationService @AssistedInject constructor( saveLocalEcho(it) } } - return eventSenderProcessor.postEvent(event, cryptoSessionInfoProvider.isRoomEncrypted(roomId)) + return eventSenderProcessor.postEvent(event) } override suspend fun fetchThreadTimeline(rootThreadEventId: String): Boolean { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/EventEditor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/EventEditor.kt index 4551f390e7..b54cd71e50 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/EventEditor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/EventEditor.kt @@ -23,7 +23,6 @@ import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.util.Cancelable import org.matrix.android.sdk.api.util.NoOpCancellable -import org.matrix.android.sdk.internal.crypto.CryptoSessionInfoProvider import org.matrix.android.sdk.internal.database.mapper.toEntity import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository @@ -33,7 +32,6 @@ import javax.inject.Inject internal class EventEditor @Inject constructor(private val eventSenderProcessor: EventSenderProcessor, private val eventFactory: LocalEchoEventFactory, - private val cryptoSessionInfoProvider: CryptoSessionInfoProvider, private val localEchoRepository: LocalEchoRepository) { fun editTextMessage(targetEvent: TimelineEvent, @@ -51,7 +49,7 @@ internal class EventEditor @Inject constructor(private val eventSenderProcessor: } else if (targetEvent.root.sendState.isSent()) { val event = eventFactory .createReplaceTextEvent(roomId, targetEvent.eventId, newBodyText, newBodyAutoMarkdown, msgType, compatibilityBodyText) - return sendReplaceEvent(roomId, event) + return sendReplaceEvent(event) } else { // Should we throw? Timber.w("Can't edit a sending event") @@ -72,7 +70,7 @@ internal class EventEditor @Inject constructor(private val eventSenderProcessor: } else if (targetEvent.root.sendState.isSent()) { val event = eventFactory .createPollReplaceEvent(roomId, pollType, targetEvent.eventId, question, options) - return sendReplaceEvent(roomId, event) + return sendReplaceEvent(event) } else { Timber.w("Can't edit a sending event") return NoOpCancellable @@ -82,12 +80,12 @@ internal class EventEditor @Inject constructor(private val eventSenderProcessor: private fun sendFailedEvent(targetEvent: TimelineEvent, editedEvent: Event): Cancelable { val roomId = targetEvent.roomId updateFailedEchoWithEvent(roomId, targetEvent.eventId, editedEvent) - return eventSenderProcessor.postEvent(editedEvent, cryptoSessionInfoProvider.isRoomEncrypted(roomId)) + return eventSenderProcessor.postEvent(editedEvent) } - private fun sendReplaceEvent(roomId: String, editedEvent: Event): Cancelable { + private fun sendReplaceEvent(editedEvent: Event): Cancelable { localEchoRepository.createLocalEcho(editedEvent) - return eventSenderProcessor.postEvent(editedEvent, cryptoSessionInfoProvider.isRoomEncrypted(roomId)) + return eventSenderProcessor.postEvent(editedEvent) } fun editReply(replyToEdit: TimelineEvent, @@ -107,7 +105,7 @@ internal class EventEditor @Inject constructor(private val eventSenderProcessor: eventId = replyToEdit.eventId ) ?: return NoOpCancellable updateFailedEchoWithEvent(roomId, replyToEdit.eventId, editedEvent) - return eventSenderProcessor.postEvent(editedEvent, cryptoSessionInfoProvider.isRoomEncrypted(roomId)) + return eventSenderProcessor.postEvent(editedEvent) } else if (replyToEdit.root.sendState.isSent()) { val event = eventFactory.createReplaceTextOfReply( roomId, @@ -119,7 +117,7 @@ internal class EventEditor @Inject constructor(private val eventSenderProcessor: compatibilityBodyText ) .also { localEchoRepository.createLocalEcho(it) } - return eventSenderProcessor.postEvent(event, cryptoSessionInfoProvider.isRoomEncrypted(roomId)) + return eventSenderProcessor.postEvent(event) } else { // Should we throw? Timber.w("Can't edit a sending event") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt index 8c0ea0ec4c..28c17f38b6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt @@ -46,7 +46,7 @@ import org.matrix.android.sdk.api.util.Cancelable import org.matrix.android.sdk.api.util.CancelableBag import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.api.util.NoOpCancellable -import org.matrix.android.sdk.internal.crypto.CryptoSessionInfoProvider +import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.WorkManagerProvider import org.matrix.android.sdk.internal.session.content.UploadContentWorker @@ -66,7 +66,7 @@ internal class DefaultSendService @AssistedInject constructor( private val workManagerProvider: WorkManagerProvider, @SessionId private val sessionId: String, private val localEchoEventFactory: LocalEchoEventFactory, - private val cryptoSessionInfoProvider: CryptoSessionInfoProvider, + private val cryptoStore: IMXCryptoStore, private val taskExecutor: TaskExecutor, private val localEchoRepository: LocalEchoRepository, private val eventSenderProcessor: EventSenderProcessor, @@ -303,7 +303,7 @@ internal class DefaultSendService @AssistedInject constructor( private fun internalSendMedia(allLocalEchoes: List, attachment: ContentAttachmentData, compressBeforeSending: Boolean): Cancelable { val cancelableBag = CancelableBag() - allLocalEchoes.groupBy { cryptoSessionInfoProvider.isRoomEncrypted(it.roomId!!) } + allLocalEchoes.groupBy { cryptoStore.roomWasOnceEncrypted(it.roomId!!) } .apply { keys.forEach { isRoomEncrypted -> // Should never be empty @@ -334,7 +334,7 @@ internal class DefaultSendService @AssistedInject constructor( } private fun sendEvent(event: Event): Cancelable { - return eventSenderProcessor.postEvent(event, cryptoSessionInfoProvider.isRoomEncrypted(event.roomId!!)) + return eventSenderProcessor.postEvent(event) } private fun createLocalEcho(event: Event) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt index eb69161614..f892dcee55 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt @@ -92,7 +92,7 @@ internal class EventSenderProcessorCoroutine @Inject constructor( } override fun postEvent(event: Event): Cancelable { - return postEvent(event, event.roomId?.let { cryptoService.isRoomEncrypted(it) } ?: false) + return postEvent(event, cryptoService.shouldEncryptInRoom(event.roomId)) } override fun postEvent(event: Event, encrypt: Boolean): Cancelable { 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 a7887d77f8..1c1d59fb3d 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 @@ -119,9 +119,8 @@ internal class RoomSummaryUpdater @Inject constructor( roomSummaryEntity.roomType = roomType Timber.v("## Space: Updating summary room [$roomId] roomType: [$roomType]") - // Don't use current state for this one as we are only interested in having MXCRYPTO_ALGORITHM_MEGOLM event in the room val encryptionEvent = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_ENCRYPTION, stateKey = "")?.root - Timber.v("## CRYPTO: currentEncryptionEvent is $encryptionEvent") + Timber.d("## CRYPTO: currentEncryptionEvent is $encryptionEvent") val latestPreviewableEvent = RoomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId) From 9c9695546cb9e8564b59406e26d356359c1976f4 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 2 Feb 2022 19:11:30 +0100 Subject: [PATCH 142/302] update change log --- changelog.d/5136.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5136.misc diff --git a/changelog.d/5136.misc b/changelog.d/5136.misc new file mode 100644 index 0000000000..43404acc31 --- /dev/null +++ b/changelog.d/5136.misc @@ -0,0 +1 @@ +Defensive coding to ensure encryption when room was once e2e \ No newline at end of file From 48fffc3dcf09f62b2e9e48dadc91c7e2366e8666 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 18 Feb 2022 10:08:44 +0100 Subject: [PATCH 143/302] Code review --- .../android/sdk/api/session/crypto/CryptoService.kt | 8 -------- .../android/sdk/internal/crypto/DefaultCryptoService.kt | 4 ---- .../android/sdk/internal/crypto/store/IMXCryptoStore.kt | 6 ++++++ .../room/send/queue/EventSenderProcessorCoroutine.kt | 7 ++++--- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index 9b617f3e4f..e3f00a24b6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -113,14 +113,6 @@ interface CryptoService { fun isRoomEncrypted(roomId: String): Boolean - /** - * This is a bit different than isRoomEncrypted - * A room is encrypted when there is a m.room.encryption state event in the room (malformed/invalid or not) - * But the crypto layer has additional guaranty to ensure that encryption would never been reverted - * It's defensive coding out of precaution (if ever state is reset) - */ - fun shouldEncryptInRoom(roomId: String?): Boolean - fun encryptEventContent(eventContent: Content, eventType: String, roomId: String, 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 f10cde6759..0646e4d2b8 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 @@ -634,10 +634,6 @@ internal class DefaultCryptoService @Inject constructor( return cryptoSessionInfoProvider.isRoomEncrypted(roomId) } - override fun shouldEncryptInRoom(roomId: String?): Boolean { - return roomId?.let { cryptoStore.roomWasOnceEncrypted(it) } ?: false - } - /** * @return the stored device keys for a user. */ 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 46f94bc3bc..96ea5c03fa 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 @@ -240,6 +240,12 @@ internal interface IMXCryptoStore { */ fun getRoomAlgorithm(roomId: String): String? + /** + * This is a bit different than isRoomEncrypted + * A room is encrypted when there is a m.room.encryption state event in the room (malformed/invalid or not) + * But the crypto layer has additional guaranty to ensure that encryption would never been reverted + * It's defensive coding out of precaution (if ever state is reset) + */ fun roomWasOnceEncrypted(roomId: String): Boolean fun shouldEncryptForInvitedMembers(roomId: String): Boolean diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt index f892dcee55..5b4efa5df6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessorCoroutine.kt @@ -26,9 +26,9 @@ import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.getRetryDelay import org.matrix.android.sdk.api.failure.isLimitExceededError import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.util.Cancelable +import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.task.CoroutineSequencer import org.matrix.android.sdk.internal.task.SemaphoreCoroutineSequencer @@ -54,7 +54,7 @@ private const val MAX_RETRY_COUNT = 3 */ @SessionScope internal class EventSenderProcessorCoroutine @Inject constructor( - private val cryptoService: CryptoService, + private val cryptoStore: IMXCryptoStore, private val sessionParams: SessionParams, private val queuedTaskFactory: QueuedTaskFactory, private val taskExecutor: TaskExecutor, @@ -92,7 +92,8 @@ internal class EventSenderProcessorCoroutine @Inject constructor( } override fun postEvent(event: Event): Cancelable { - return postEvent(event, cryptoService.shouldEncryptInRoom(event.roomId)) + val shouldEncrypt = event.roomId?.let { cryptoStore.roomWasOnceEncrypted(it) } ?: false + return postEvent(event, shouldEncrypt) } override fun postEvent(event: Event, encrypt: Boolean): Cancelable { From b8a3bda1abb4b08a5f65b9c9fdc97e21e00a5bbf Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Fri, 18 Feb 2022 09:41:49 +0000 Subject: [PATCH 144/302] Translated using Weblate (Japanese) Currently translated at 76.6% (2135 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 53 ++++++++++++----------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index f8011baea6..653d1e4ccc 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -88,7 +88,7 @@ OK キャンセル 保存 - 退室 + 退出 送信 再送信 削除 @@ -146,7 +146,7 @@ パスワードが短すぎます(最小6文字) 正しくない電子メールアドレスのようです 正しくない電話番号のようです - すでに登録されている電子メールアドレスです。 + 既に登録されている電子メールアドレスです。 パスワードが一致しません パスワードを忘れましたか? 登録を続行するには電子メールを確認して下さい @@ -181,7 +181,7 @@ 切断中 待機中 招待 - このルームを退出する + このルームを退出 検索 %sさんが文字入力中… %1$sさんと %2$sさんが文字入力中… @@ -202,7 +202,7 @@ 確認 無効にする 送信中 (%s%%) - このユーザー名はすでに使用されています + このユーザー名は既に使用されています 削除 参加 あなたは %s さんに、このルームへ招待されています @@ -237,7 +237,7 @@ 通知音 このアカウントで通知を許可 この端末で通知を許可 - 会話で発言されたとき + 1対1のチャットでのメッセージ グループチャットでのメッセージ ルームへ招待されたとき 通話の呼び出しがあったとき @@ -391,7 +391,7 @@ \n \n設定からプロフィールにメールアドレスを追加できます。 このホームサーバーはあなたがロボットではない認証を求めます - ユーザー名はすでに使用されています + ユーザー名は既に使用されています ホームサーバー: IDサーバー: メールアドレスを確認しました @@ -449,7 +449,7 @@ ファイル ルーム ルーム一覧を見る - 退室 + 会話から退出 会話 設定 Version @@ -591,14 +591,14 @@ 検索 メッセージ ディレクトリを検索中… - サードパーティの通知 + サードパーティーの使用に関する掲示 このアプリのシステムの情報を見る。 アプリの情報 自分の表示名を含むメッセージ 自分のユーザー名を含むメッセージ バージョン olmのバージョン - サードパーティの通知 + サードパーティーの使用に関する掲示 ホーム画面 逃した通知があるルームをピン止めする 未読のあるルームをピン止めする @@ -806,7 +806,7 @@ ユーザーの権限レベルを決める 指定したIDのユーザーの管理者権限を取り消す 指定したユーザーを現在のルームに招待 - 指定されたアドレスのルームに参加します + 指定されたアドレスのルームに参加 ルームを退室 ルームのテーマを設定 指定したIDのユーザーとの接続を切断 @@ -829,7 +829,7 @@ \n \nアカウントを停止しても、 デフォルトではあなたが送信したメッセージは忘却されません。メッセージの忘却を望む場合は、以下のボックスにチェックを入れてください。 \n -\nMatrixのメッセージの可視性は、電子メールと同様のものです。メッセージを忘却すると、あなたが送信したメッセージは、新規または未登録のユーザーには共有されることはありませんが、すでにメッセージを取得している登録ユーザーは、今後もそのコピーにアクセスできます。 +\nMatrixのメッセージの可視性は、電子メールと同様のものです。メッセージを忘却すると、あなたが送信したメッセージは、新規または未登録のユーザーには共有されることはありませんが、既にメッセージを取得している登録ユーザーは、今後もそのコピーにアクセスできます。 アカウントを停止したとき自分の送信した全てのメッセージを削除(警告: この操作により、今後のユーザーは会話を不完全な形で見ることになります) 続けるには、パスワードを入力してください: アカウントを停止 @@ -1128,7 +1128,7 @@ このURLからホームサーバーに接続できませんでした、ご確認ください 有効なMatrixサーバーアドレスではありません このURLは検索結果に表示できません、ご確認ください - この電話番号はすでに使用されています。 + この電話番号は既に使用されています。 復旧用のメールアドレスを設定します。後からオプションでメールアドレスや電話番号を使用して知人に見つけてもらえるようにできます。 シングルサインオンを使用してサインインする HDを使用する @@ -1459,9 +1459,9 @@ 絵文字キーボードを表示する アバターと表示名の変更が含まれます。 アカウントイベントを表示する - 招待、削除、禁止は影響を受けません。 + 招待、削除、ブロックは影響を受けません。 招待/参加/退出/削除/禁止イベントや、アバター/表示名の変更などを含む。 - 入室と退室イベントの表示 + 参加・退出イベントを表示 Use /confettiコマンドを使用するか、❄️または🎉を含むメッセージを送信します チャットでエフェクトを表示する ルームのメンバーのイベントを表示する @@ -1476,9 +1476,9 @@ ${app_name}は、デバイスの限られたリソース(バッテリー)を維持する方法でバックグラウンド同期をします。 \nデバイスの状態によっては、OSによって同期が延期される場合があります。 LEDの色、振動、音を選択してください… - サイレント通知を構成する - 通話の通知を設定する - うるさい通知を設定する + サイレント通知を設定 + 通話の通知を設定 + うるさい通知を設定 アプリはバックグラウンドでホームサーバーに接続する必要がないためバッテリー使用量を減らすことができます 最適化を無視する 画面をオフにした状態でデバイスのプラグを抜いて一定時間静止したままにすると、デバイスは機内モードになります。 これにより、アプリがネットワークにアクセスできなくなり、ジョブ、同期、および標準のアラームが防止されます。 @@ -1554,7 +1554,7 @@ あなたのテーマ あなたのユーザーID あなたのアバターURL - ブラウザで開く + ブラウザーで開く ウィジェットをロードする ウィジェット アクティブなウィジェット @@ -1841,8 +1841,8 @@ プッシュルール エキスパート クイックリアクション - あなたはすでにこのルームを見ています! - その他のサードパーティーの通知 + あなたは既にこのルームを見ています! + その他のサードパーティーの使用に関する掲示 Matrix SDK バージョン ファイル\"%1$s\"からe2eキーをインポートします。 キーのバックアップデータの取得中にエラーが発生しました @@ -1876,8 +1876,8 @@ 会話 ここで未読メッセージに追いつく ホームへようこそ! - 未読メッセージはもうありません - 追いついてきました! + 未読メッセージはありません + 未読はありません! %sがセッションを検証を要求しています インタラクティブセッション検証 ルームに参加してアプリの使用を開始します。 @@ -1955,7 +1955,7 @@ 暗号化されたダイレクトメッセージ ダイレクトメッセージ 自分のユーザー名 - 自分のディスプレーネーム + 自分の表示名 グループチャットでのメッセージの暗号化 個別チャットでのメッセージの暗号化 通知してください @@ -2196,7 +2196,7 @@ メンションとキーワードのみ ルームのスレッドを絞り込む 退出 - モバイルでは、暗号化されたルームでのメンションとキーワードの通知は受信できません。 + 携帯端末では、暗号化されたルームでのメンションとキーワードの通知は受信できません。 ルームの暗号化の有効化 スペースのメインアドレスの変更 スペースのアバターの変更 @@ -2205,7 +2205,7 @@ 暗号化が正しく設定されていないためメッセージを送ることができません。クリックして設定を開いてください。 暗号化が正しく設定されていないためメッセージを送ることができません。管理者に連絡して、暗号化を正しい状態に復元してください。 %2$dの%1$d - あなたはすでにこのスレッドを見ています! + あなたは既にこのスレッドを見ています! ルームに表示 ルームに表示 スレッドを表示 @@ -2230,7 +2230,7 @@ このセッションを検証 音声 ルームのアドレスを入力してください - このアドレスはすでに使用されています + このアドレスは既に使用されています スペースのアドレス ルームのアドレス 一致しません @@ -2335,4 +2335,5 @@ メンバーを追加 ログインを検証 メッセージ… + このファイルは大きすぎてアップロードできません。 \ No newline at end of file From bda92a9ab451c313d9d19102c0f111be32ff1bfb Mon Sep 17 00:00:00 2001 From: NIkita Fedrunov Date: Fri, 18 Feb 2022 10:23:56 +0100 Subject: [PATCH 145/302] track screen event when user enters the screen instead of when user leaves the screen --- changelog.d/5256.misc | 1 + .../im/vector/app/core/platform/VectorBaseActivity.kt | 6 +++--- .../platform/VectorBaseBottomSheetDialogFragment.kt | 10 +++------- .../im/vector/app/core/platform/VectorBaseFragment.kt | 6 +++--- .../app/features/analytics/screen/ScreenEvent.kt | 6 +----- .../app/features/call/dialpad/DialPadFragment.kt | 7 +------ .../java/im/vector/app/features/home/HomeActivity.kt | 8 +------- .../features/home/room/detail/RoomDetailActivity.kt | 8 +------- .../features/settings/VectorSettingsBaseFragment.kt | 10 +++------- 9 files changed, 17 insertions(+), 45 deletions(-) create mode 100644 changelog.d/5256.misc diff --git a/changelog.d/5256.misc b/changelog.d/5256.misc new file mode 100644 index 0000000000..e20f52c7aa --- /dev/null +++ b/changelog.d/5256.misc @@ -0,0 +1 @@ +Analytics screen events are now tracked on screen enter instead of screen leave \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index 5767acd44b..6c49a1ff01 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -98,7 +98,6 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver * ========================================================================================== */ protected var analyticsScreenName: MobileScreen.ScreenName? = null - private var screenEvent: ScreenEvent? = null protected lateinit var analyticsTracker: AnalyticsTracker @@ -337,7 +336,9 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver override fun onResume() { super.onResume() Timber.i("onResume Activity ${javaClass.simpleName}") - screenEvent = analyticsScreenName?.let { ScreenEvent(it) } + analyticsScreenName?.let { + ScreenEvent(it).send(analyticsTracker) + } configurationViewModel.onActivityResumed() if (this !is BugReportActivity && vectorPreferences.useRageshake()) { @@ -376,7 +377,6 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver override fun onPause() { super.onPause() - screenEvent?.send(analyticsTracker, analyticsScreenName) Timber.i("onPause Activity ${javaClass.simpleName}") rageShake.stop() diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt index 869a12e871..11bfcdd9ef 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -54,7 +54,6 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomShe * ========================================================================================== */ protected var analyticsScreenName: MobileScreen.ScreenName? = null - private var screenEvent: ScreenEvent? = null protected lateinit var analyticsTracker: AnalyticsTracker @@ -139,12 +138,9 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomShe override fun onResume() { super.onResume() Timber.i("onResume BottomSheet ${javaClass.simpleName}") - screenEvent = analyticsScreenName?.let { ScreenEvent(it) } - } - - override fun onPause() { - super.onPause() - screenEvent?.send(analyticsTracker) + analyticsScreenName?.let { + ScreenEvent(it).send(analyticsTracker) + } } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index 6bd62707f2..7b8eda76ff 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -59,7 +59,6 @@ abstract class VectorBaseFragment : Fragment(), MavericksView * ========================================================================================== */ protected var analyticsScreenName: MobileScreen.ScreenName? = null - private var screenEvent: ScreenEvent? = null protected lateinit var analyticsTracker: AnalyticsTracker @@ -145,14 +144,15 @@ abstract class VectorBaseFragment : Fragment(), MavericksView override fun onResume() { super.onResume() Timber.i("onResume Fragment ${javaClass.simpleName}") - screenEvent = analyticsScreenName?.let { ScreenEvent(it) } + analyticsScreenName?.let { + ScreenEvent(it).send(analyticsTracker) + } } @CallSuper override fun onPause() { super.onPause() Timber.i("onPause Fragment ${javaClass.simpleName}") - screenEvent?.send(analyticsTracker) } @CallSuper diff --git a/vector/src/main/java/im/vector/app/features/analytics/screen/ScreenEvent.kt b/vector/src/main/java/im/vector/app/features/analytics/screen/ScreenEvent.kt index 1ad4a1fa32..400bede415 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/screen/ScreenEvent.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/screen/ScreenEvent.kt @@ -16,7 +16,6 @@ package im.vector.app.features.analytics.screen -import android.os.SystemClock import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.plan.MobileScreen import timber.log.Timber @@ -25,8 +24,6 @@ import timber.log.Timber * Track a screen display. Unique usage. */ class ScreenEvent(val screenName: MobileScreen.ScreenName) { - private val startTime = SystemClock.elapsedRealtime() - // Protection to avoid multiple sending private var isSent = false @@ -42,8 +39,7 @@ class ScreenEvent(val screenName: MobileScreen.ScreenName) { isSent = true analyticsTracker.screen( MobileScreen( - screenName = screenNameOverride ?: screenName, - durationMs = (SystemClock.elapsedRealtime() - startTime).toInt() + screenName = screenNameOverride ?: screenName ) ) } diff --git a/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt b/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt index b33ce25f55..9d77680ff5 100644 --- a/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt +++ b/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt @@ -69,12 +69,7 @@ class DialPadFragment : Fragment(), TextWatcher { private var screenEvent: ScreenEvent? = null override fun onResume() { super.onResume() - screenEvent = ScreenEvent(MobileScreen.ScreenName.Dialpad) - } - - override fun onPause() { - super.onPause() - screenEvent?.send(analyticsTracker) + ScreenEvent(MobileScreen.ScreenName.Dialpad).send(analyticsTracker) } override fun onCreateView( 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 f6b32973a0..b7bfdef21c 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 @@ -163,14 +163,8 @@ class HomeActivity : } private val drawerListener = object : DrawerLayout.SimpleDrawerListener() { - private var drawerScreenEvent: ScreenEvent? = null override fun onDrawerOpened(drawerView: View) { - drawerScreenEvent = ScreenEvent(MobileScreen.ScreenName.Sidebar) - } - - override fun onDrawerClosed(drawerView: View) { - drawerScreenEvent?.send(analyticsTracker) - drawerScreenEvent = null + ScreenEvent(MobileScreen.ScreenName.Sidebar).send(analyticsTracker) } override fun onDrawerStateChanged(newState: Int) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index f5bf086e96..f40bee44db 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -158,14 +158,8 @@ class RoomDetailActivity : } private val drawerListener = object : DrawerLayout.SimpleDrawerListener() { - private var drawerScreenEvent: ScreenEvent? = null override fun onDrawerOpened(drawerView: View) { - drawerScreenEvent = ScreenEvent(MobileScreen.ScreenName.Breadcrumbs) - } - - override fun onDrawerClosed(drawerView: View) { - drawerScreenEvent?.send(analyticsTracker) - drawerScreenEvent = null + ScreenEvent(MobileScreen.ScreenName.Breadcrumbs).send(analyticsTracker) } override fun onDrawerStateChanged(newState: Int) { diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt index 4185fde663..c907168954 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt @@ -44,7 +44,6 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), Maverick * ========================================================================================== */ protected var analyticsScreenName: MobileScreen.ScreenName? = null - private var screenEvent: ScreenEvent? = null protected lateinit var analyticsTracker: AnalyticsTracker @@ -91,17 +90,14 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), Maverick override fun onResume() { super.onResume() Timber.i("onResume Fragment ${javaClass.simpleName}") - screenEvent = analyticsScreenName?.let { ScreenEvent(it) } + analyticsScreenName?.let { + ScreenEvent(it).send(analyticsTracker) + } vectorActivity.supportActionBar?.setTitle(titleRes) // find the view from parent activity mLoadingView = vectorActivity.findViewById(R.id.vector_settings_spinner_views) } - override fun onPause() { - super.onPause() - screenEvent?.send(analyticsTracker) - } - abstract fun bindPref() abstract var titleRes: Int From e15968bc03e043fcfe0a6fc36be8a4e99f9a7ba3 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Fri, 18 Feb 2022 11:41:38 +0000 Subject: [PATCH 146/302] Translated using Weblate (Japanese) Currently translated at 77.2% (2152 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 160 ++++++++++++---------- 1 file changed, 90 insertions(+), 70 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 653d1e4ccc..4edeee4c30 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -40,7 +40,7 @@ %1$s がVoIP会議をリクエストしました VoIP会議が開始されました VoIP会議が終了しました - (アバターも変更された) + (アバターも変更されました) %1$s がルーム名を削除しました %1$s がルームトピックを削除しました %1$s がプロフィール %2$s を更新しました @@ -118,13 +118,13 @@ %d名 - バグを報告 - 不具合の内容と状況の説明をお願い致します。あなたは何をしましたか?何が起こると思いますか?実際何が起こったのですか? - ここに不具合内容を説明 - 画面のスクリーンショット画像を送信 - 不具合発生時の動作記録を送信 + 不具合を報告 + 不具合の内容と状況の説明をお願いします。何をしましたか?何が起こるべきでしたか?実際に起こった事象は何でしょうか? + ここに不具合の内容を記述 + スクリーンショットの画像を送信 + クラッシュ時の動作記録を送信 動作記録を送信 - 開発者が問題を診断するために、このクライアントの動作記録がバグの報告と一緒に送信されます。このバグの報告は、ログとスクリーンショットを含め、公開されません。上記文章のみを送信したい場合は以下のチェックを解除してください: + 開発者が問題を診断するために、このクライアントの動作記録が不具合報告と一緒に送信されます。不具合報告は、動作記録とスクリーンショットを含めて、公開されることはありません。上記の説明文だけを送信したい場合は、以下のチェックを解除してください。 あなたは不満で端末を振っているようです。不具合報告の画面を開きますか? 前回アプリケーションは正常に停止しませんでした。クラッシュ報告の画面を開きますか? 不具合を報告しました @@ -183,14 +183,14 @@ 招待 このルームを退出 検索 - %sさんが文字入力中… - %1$sさんと %2$sさんが文字入力中… - %1$sさん、%2$sさん他が文字入力中… + %sさんが文字入力しています… + %1$sさんと %2$sさんが文字入力しています… + %1$sさん、%2$sさん他が文字入力しています… 暗号文を送信… 明るいテーマ 暗いテーマ 黒いテーマ - 同期中… + 同期しています… メッセージ メンバー詳細 引用 @@ -317,7 +317,7 @@ 再入室禁止された参加者 拡張設定 このルームのサーバー内識別ID - 実験的 + ラボ これらは予期せぬ不具合が生じるかもしれない実験的機能です。慎重に使用してください。 エンドツーエンド暗号化 エンドツーエンド暗号化を使用中 @@ -397,7 +397,7 @@ メールアドレスを確認しました パスワードを初期化するには, アカウントに登録されている電子メールアドレスを入力してください: あなたのアカウントに登録された電子メールアドレスの入力が必要です. - 新しいパスワードの入力が必要です. + 新しいパスワードの入力が必要です。 %s へ電子メールが送信されました. リンクをたどったら以下をクリックしてください. 電子メールアドレスの確認に失敗しました: 電子メールのリンクをクリックしたことを確認してください パスワードがリセットされました。 @@ -412,11 +412,11 @@ 以下の容量で画像を送信 ルームの説明 通話が接続されました - 通話を接続中… + 通話を接続しています… 通話着信中 ビデオ通話の着信中 音声通話の着信中 - 通話中… + 通話しています… 映像の接続に失敗 カメラを開始できません 他の端末で通話に応答しました @@ -452,7 +452,7 @@ 会話から退出 会話 設定 - Version + バージョン 利用規約 著作権 個人情報保護方針 @@ -465,7 +465,7 @@ IDサーバー メールアドレスが見つかりません。 この電話番号は既に使用されています。 - パスワード変更 + パスワードを変更 現在のパスワード 新しいパスワード 新しいパスワードの確認 @@ -490,7 +490,7 @@ あなたはこのルームで権限がありません。 ルーム %s は、見ることができません。 ユーザー名 - ホームサーバー URL + ホームサーバーのURL IDサーバーのURL ログイン Matrixアプリを追加 @@ -512,7 +512,7 @@ ${app_name}はビデオ通話を行うためにカメラとマイクにアクセスする許可を必要としています。 \n \n次のポップアップでアクセスを許可して通話ができるようにしてください。 - ${app_name}アプリでは、あなたの端末の電話帳のメールアドレスや電話番号をもとに、他のユーザーを検索することができます。${app_name}による電話帳の検索を許可する場合は、次のポップアップでアクセスを許可してください。 + ${app_name}では、あなたの端末の電話帳のメールアドレスや電話番号をもとに、他のユーザーを検索することができます。${app_name}による電話帳の検索を許可する場合は、次のポップアップでアクセスを許可してください。 ${app_name}はあなたの電話帳のメールアドレスや電話番号をもとに他のユーザーを見つけることができます。 \n \nこのアプリがあなたの電話帳へアクセスすることを許可しますか? @@ -557,7 +557,7 @@ 通話 通知あり(音量大) 通知あり(音量小) - 不具合報告 + 不具合の報告 開封確認メッセージのリスト ダウンロードファイルに保存しますか? この招待はこのアカウントに関連付けられていない %s に送信されました。 @@ -590,9 +590,9 @@ ダウンロードをキャンセルする 検索 メッセージ - ディレクトリを検索中… + ディレクトリを検索しています… サードパーティーの使用に関する掲示 - このアプリのシステムの情報を見る。 + このアプリの情報をシステム設定で表示する。 アプリの情報 自分の表示名を含むメッセージ 自分のユーザー名を含むメッセージ @@ -693,13 +693,13 @@ あなたは%2$sによって%1$sへの参加を禁止されました 理由: %1$s 再参加 - バグを報告するには端末を降ってください + 端末を振って不具合を報告 %dメンバーシップの変更 参加者を表示 見出しを開く - 同期中… + 同期しています… %d名の参加者 @@ -717,7 +717,7 @@ ルームの履歴を消す アバター - 名前があがったときのみ + メンションのみ 通知のプライバシー 標準 このアプリはバックグラウンド動作の権限が必要です @@ -731,7 +731,7 @@ 許可がないため、この操作を実行できません。 実行 システムアラート - 可能であれば、英語で説明を書いてください。 + 可能であれば、英語で説明文を記述してください。 音声を送信 スタンプを送信 使用可能なスタンプパックがありません。 @@ -851,7 +851,7 @@ あなたのホームサーバーはルームのメンバーの簡易読み込みをサポートしていません。後で試してください。 ルームのメンバーの簡易読み込み 申し訳ありません、エラーが発生しました - Version %s + バージョン %s エクスポートされた鍵を暗号化するパスフレーズを作成してください。 キーをインポートするには、同じパスフレーズを入力する必要があります。 パスフレーズの作成 パスフレーズは一致する必要があります @@ -922,10 +922,10 @@ 検証 バックアップから復元 バックアップを削除 - 鍵をバックアップ中… + 鍵をバックアップしています… 全ての鍵をバックアップしました - %d 件の鍵をバックアップ中… + %d 件の鍵をバックアップしています… バージョン アルゴリズム @@ -990,7 +990,7 @@ アップロード ルームを退出 - ルームから退室中… + ルームから退室しています… 管理者 モデレーター カスタム @@ -1048,11 +1048,11 @@ 完了 無視 レビュー - 待機中… - サムネイル暗号化中… - サムネイル送信中 (%1$s / %2$s) - ファイル暗号化中… - ファイル送信中 (%1$s / %2$s) + 待機しています… + サムネイルを暗号化しています… + サムネイルを送信しています (%1$s / %2$s) + ファイルを暗号化しています… + ファイルを送信しています (%1$s / %2$s) ファイル %1$s をダウンロードしています… ファイル 連絡先 @@ -1110,7 +1110,7 @@ セキュアバックアップを設定 管理 セキュアバックアップ - ルームを作成中… + ルームを作成しています… 招待されています %s からの招待 このセッションは正常に検証されました。 @@ -1166,7 +1166,7 @@ あなたにはこのルームの暗号化を有効にする権限がありません。 未読メッセージ タイムラインでのスワイプによる返信を有効にする - タイムラインで非表示のイベントを表示する + タイムラインで非表示のイベントを表示 QR コードをスキャン QR コード画像 QR コード @@ -1193,17 +1193,17 @@ カスタムルールの読み込みに失敗しました。再試行してください。 一部の通知はカスタム設定で無効になっています。 一部のメッセージがサイレントに設定されていることに注意してください(音を出さずに通知します)。 - 1つ以上のテストが失敗しました。調査に役立つバグレポートを送信してください。 + 1つ以上のテストが失敗しました。調査用の不具合報告を送信してください。 1つ以上のテストが失敗しました。提案された修正を試してください。 - 基本的な診断はOKです。 それでも通知が届かない場合は、調査に役立つバグレポートを送信してください。 - 実行中… (%1$dの %2$d) + 基本的な診断はOKです。 それでも通知が届かない場合は、調査用の不具合報告を送信してください。 + 実行しています… (%1$dの %2$d) テストを実行する 診断トラブルシューティング イベントごとの通知の優先順位 メールであなたに送ったリンクをクリックして確認してください。 %sを削除しますか? 認証が必要です - あなたのパスワードを確認する + パスワードを確認 暗号化されたルームでの検索はまだサポートされていません。 ブロックされたユーザーを絞り込む トピックを変更する @@ -1519,8 +1519,8 @@ \n%1$s FCMトークンの取得に失敗しました: \n%1$s - 🎉全てのサーバーの参加を禁止されています!このルームは使用できなくなりました。 - 変化がありません。 + 🎉全てのサーバーの参加がブロックされています!このルームは使用できなくなりました。 + 変更はありません。 • サーバーにマッチするIPリテラルが禁止されています。 • サーバーにマッチするIPリテラルが許可されるようになりました。 • %sに一致するサーバーが許可リストから削除されました。 @@ -1601,7 +1601,7 @@ バックアップを削除 バックアップの状態を確認中 バックアップの削除に失敗しました(%s) - バックアップを削除中… + バックアップを削除しています… このセッションで暗号鍵のバックアップを使用するには、パスフレーズまたはリカバリーキーでバックアップを復元してください。 バックアップは%sという未検証セッションによる不正なしょめいがあります バックアップは%sという検証されたセッションによる不正な署名があります @@ -1623,7 +1623,7 @@ このリカバリーキーではバックアップを復号できませんでした。正しいリカバリーキーを入力したことを確認してください。 リカバリーキーを入力してください 履歴をアンロック - 鍵をインポート中… + 鍵をインポートしています… 鍵をダウンロードしています… リカバリーキーを計算しています… バックアップを復元: @@ -1631,7 +1631,7 @@ このパスフレーズではバックアップを復号できませんでした。正しい復元パスフレーズを入力したことを確認してください。 リカバリーキーを喪失しましたか? 設定で新しいリカバリーキーを設定できます。 メッセージの復元 - バックアップのバージョンを取得中… + バックアップのバージョンを取得しています… 暗号化されたメッセージ履歴のロックを解除するには、復元パスフレーズを使用してください 復元パスフレーズをご存知でなければ、%sができます。 リカバリーキーを使用して暗号化されたメッセージ履歴をアンロックします @@ -1641,7 +1641,7 @@ 続行しますか? 暗号鍵が現在バックグラウンドでホームサーバーへバックアップされています。初期バックアップは数分かかることがあります。 バックアップが開始されました - 予期せぬエラー + 予期しないエラー リカバリーキー パスフレーズを使用してリカバリーキーを生成中です。数秒かかることがあります。 リカバリーキーを共有… @@ -1817,19 +1817,19 @@ あなたの会話。 それを所有する。 アカウントの復旧用のメールアドレスを設定して、後からオプションで知人に見つけてもらえるようにできます。 ここが%sとのダイレクトメッセージのスタート地点です。 - 編集が見つかりません - メッセージを編集する - ファイル %1$s はダウンロードされました! + 変更履歴はありません + メッセージの変更履歴 + ファイル %1$s をダウンロードしました! ビデオの圧縮%d%% 画像を圧縮しています… - 暗号化されたルームで完全な履歴を表示する + 暗号化されたルームで完全な履歴を表示 フィードバックを与える フィードバックを送信できませんでした (%s) ありがとうございます、あなたのフィードバックは正常に送信されました - ご質問がある場合は、私にご連絡ください + 追加で確認が必要な事項がある場合は、連絡可 フィードバック - 現在、spaceのベータ版を使用しています。お客様のフィードバックは次のバージョンに反映されます。ご意見を参考にさせていただくため、お客様のプラットフォームとユーザー名を記載させていただきます。 - スペースについてフィードバック + 現在「スペース」のベータ版を使用しています。あなたのフィードバックは今後のバージョンに反映されます。ご意見を最大限に参考にさせていただくため、あなたのプラットフォームとユーザー名を記録させていただきます。 + スペースについてのフィードバック 提案の送信に失敗しました(%s) ありがとうございます、提案は正常に送信されました トークンの登録 @@ -1838,7 +1838,7 @@ push_key: 登録されたプッシュゲートウェイはありません プッシュルールが定義されていません - プッシュルール + プッシュ通知に関するルール エキスパート クイックリアクション あなたは既にこのルームを見ています! @@ -1969,7 +1969,7 @@ %d 通話できません デフォルトで使いもう尋ねない - キー共有リクエストの送信履歴 + キー共有リクエストの履歴を送信 結果がありません 自分で電話をかけることはできません。参加者が招待を受け入れるのを待ちます ミーティングはJitsiのセキュリティーとパーミッションポリシーを使用します。会議中は、現在ルームにいる全ての人に招待状が表示されます。 @@ -1978,24 +1978,24 @@ この動作を行うには、システム設定からカメラの権限を許可してください。 このアクションを実行するには、いくつかの権限が不足しています。システム設定から権限を付与してください。 IDサーバーに接続できませんでした - IDサーバーのURLを入力する - あなた既存の連絡先を発見するために、あなたの連絡先データ(電話番号や電子メール)を設定されたIDサーバー(%1$s)に送信することに同意しますか? + IDサーバーのURLを入力 + 連絡先を発見するために、あなたの連絡先のデータ(電話番号や電子メール)を、設定されたIDサーバー(%1$s)に送信することに同意しますか? \n -\nプライバシー保護のため、送信データは送信前に必ずハッシュ化されます。 - メールや電話番号の送信 +\nプライバシーの保護のため、データは送信前にハッシュ化されます。 + メールと電話番号を送信 同意する 同意を撤回する あなたの連絡先から他のユーザーを発見するために、電子メールや電話番号をこのIDサーバーに送信することに同意していません。 あなたの連絡先から他のユーザーを発見するために、このIDサーバーにメールや電話番号を送信することに同意しています。 - メールや電話番号の送信 + メールと電話番号を送信 未確認 - %sに確認メールを送りました。まず、メールを確認してリンクをクリックしてください。 + %sに確認メールを送りました。まず、メールを確認してリンクをクリックしてください %sに確認のためのメールを送りました。メールにて確認リンクをクリックしてください - 発見できる電話番号 + 検出可能な電話番号 IDサーバーとの接続を解除すると、他のユーザーから自分を発見できなくなり、メールや電話で他のユーザーを招待することができなくなります。 電話番号を追加すると、ディスカバリーオプションが表示されます。 メールを追加すると、ディスカバリーオプションが表示されます。 - 現在、IDサーバーを使用していません。既存の連絡先を発見したり、その連絡先から発見できるようにするには、以下のように設定します。 + 現在、IDサーバーを使用していません。あなたの知っている連絡先を発見したり、その連絡先から発見されるようにするには、以下のように設定します。 %1$sを使って知り合いを見つけたり、見つけられるようにしています。 IDサーバーを変更 IDサーバーの設定 @@ -2003,21 +2003,21 @@ IDサーバー ボット、ブリッジ、ウィジェット、ステッカーパックを使う 他の人が見つけられるように - 規約を確認する + 規約を確認 利用規約 編集履歴を表示 ルームに参加しています… 提案 連絡先 最近の - 検索結果を得るために入力を始める + 入力すると検索結果が表示されます 結果が見つかりません、matrix IDを使ってサーバー上で検索してください。 クリップボードにコピーされたリンク - メイン画面に未読通知専用のタブを追加しました。 - ルーム名を検索する + メイン画面に未読通知専用のタブを追加する。 + ルーム名を検索 名前もしくはID (#例えば:matrix.org) ルームディレクトリを見る - 新しいルームをつくる + 新しいルームを作成 お探しのものが見つかりませんか? あなたの提案をここに書いてください ご意見・ご感想をお聞かせください。 @@ -2110,7 +2110,7 @@ あなた 動画。 絵文字で検証 - 待機中… + 待機しています… ステッカー ファイル 音声 @@ -2336,4 +2336,24 @@ ログインを検証 メッセージ… このファイルは大きすぎてアップロードできません。 + この情報の送信に同意しますか? + 連絡先を発見するには、連絡先のデータ(電話番号や電子メール)をあなたのIDサーバーに送信する必要があります。プライバシーの保護のため、データは送信前にハッシュ化されます。 + 連絡先を発見するには、連絡先のデータをあなたのIDサーバーに送信する必要があります。 +\n +\nプライバシーの保護のため、データは送信前にハッシュ化されます。この情報を送信することに同意しますか? + メールアドレスと電話番号を %s に送信 + このIDサーバーはポリシーを提供していません + IDサーバーのポリシーを隠す + IDサーバーのポリシーを表示 + アカウントの新しいパスワードを設定… + シェイクを検出しました! + 電話を振って、しきい値を試してください + 検出のしきい値 + 予期しないエラーが生じた際に、${app_name}はより頻繁にクラッシュするかもしれません + 素早くクラッシュ + 開発者モードは隠された機能を有効にするため、アプリケーションが不安定になる恐れがあります。開発者向けです! + 復号エラーが生じた際に、自動的にログを送信 + 復号エラーを自動的に報告する。 + 変更を有効にするにはアプリケーションの再起動が必要です。 + LaTeXによる数学表記を有効にする \ No newline at end of file From c11a0192c057bca75c774aaa50e5337d1e16d6af Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Fri, 18 Feb 2022 12:52:17 +0000 Subject: [PATCH 147/302] Translated using Weblate (Japanese) Currently translated at 77.4% (2157 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 128 +++++++++++----------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 4edeee4c30..cd9eb82f92 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -302,7 +302,7 @@ 低優先度 なし 参加と可視範囲 - ルームの一覧へ公開する + ルームの一覧へ公開 ルームへの参加 ルームの履歴の可視範囲 ルームの履歴を読める人は\? @@ -366,7 +366,7 @@ ルーム ルーム一覧 利用者一覧 - 送信する + 送信 サインアウト アカウントを作成 ログイン @@ -430,8 +430,8 @@ ダイレクトメッセージ 再入室禁止 再入室禁止解除 - この参加者の発言を全て非表示にする - この参加者の発言を全て表示する + この参加者の発言を全て非表示 + この参加者の発言を全て表示 指名して呼掛け ユーザーID, 表示名, 電子メールアドレス 接続端末一覧を表示 @@ -456,7 +456,7 @@ 利用規約 著作権 個人情報保護方針 - 3秒間画面を表示する + 3秒間画面を表示 利用規約 著作権 個人情報保護方針 @@ -517,12 +517,12 @@ \n \nこのアプリがあなたの電話帳へアクセスすることを許可しますか? 申し訳ありません。権限がないために操作が実行されませんでした - 発言を通報する + 発言を通報 既読 写真を撮影 動画を撮影 要求を無視 - 検証せずに共有する + 検証せずに共有 検証を開始 リクエストに user_id がありません。 リクエストに room_id がありません。 @@ -551,7 +551,7 @@ パスフレーズを確認 パスフレーズを入力 エクスポート - 暗号鍵をローカルファイルにエクスポートする + 暗号鍵をローカルファイルにエクスポート ルームの暗号鍵をエクスポート 検証 通話 @@ -570,7 +570,7 @@ 端末の連絡先 (%d) ユーザーディレクトリ (%s) Matrixユーザーのみ - ユーザーIDで招待する + ユーザーIDで招待 1つまたは複数のメールアドレスか、Matrix IDを入力してください 信用する 信用しない @@ -586,8 +586,8 @@ このユーザーによる全てのメッセージを非表示にしますか? \n \nこの操作はアプリを再起動するため時間がかかる場合があります。 - アップロードをキャンセルする - ダウンロードをキャンセルする + アップロードをキャンセル + ダウンロードをキャンセル 検索 メッセージ ディレクトリを検索しています… @@ -600,8 +600,8 @@ olmのバージョン サードパーティーの使用に関する掲示 ホーム画面 - 逃した通知があるルームをピン止めする - 未読のあるルームをピン止めする + 逃した通知があるルームをピン止め + 未読のあるルームをピン止め 分析 データ節約モード メールアドレスを認証できません。メールを確認して、そこに記載してあるリンクをクリックしてください。その後、「続ける」をクリックしてください。 @@ -625,7 +625,7 @@ 認証する 認証を取り消す ブラックリスト - ブラックリストから除外する + ブラックリストから除外 このデバイスが信頼できることを確認するために、その所有者に何らかの他の方法(直接会って、または、電話で)連絡し、以下のキーが、そのデバイスの「設定」で確認できるキーと一致するかお尋ねください: ルームのディレクトリを選択 公開のルームを表示するホームサーバーを入力してください @@ -686,7 +686,7 @@ ルーム 参加済 招待済 - グループのメンバーをフィルタリングする + グループのメンバーをフィルタリング グループのルームを絞り込み 管理者はこのコミュニティーの詳細を規定していません。 あなたは%2$sによって%1$sから除外されました @@ -780,7 +780,7 @@ 解析データを送信 ${app_name}はアプリを改善するため、匿名の解析データを収集します。 ${app_name}を改善するのを助けるため、解析を許可してください。 - はい、助けたいです! + はい、手伝いたいです! あなたは現在どのコミュニティーのメンバーでもありません。 ここに入力… @@ -865,7 +865,7 @@ 展開 畳む メッセージとエラーの場合 - とにかく通話する + とにかく通話 了承 このホームサーバーの方針を閲覧し承認してください: 通話設定画面 @@ -955,7 +955,7 @@ 公開 誰でもこのルームに参加できるようになります ルーム一覧 - ルームの一覧へ公開する + ルームの一覧へ公開 一般 セキュリティーとプライバシー ヘルプと概要 @@ -978,7 +978,7 @@ 現在のセッション その他のセッション 暗号化を有効にする - 暗号化設定は有効化後変更できません。 + 有効にすると、あとで無効にすることはできません。 セキュリティー 詳細 その他の設定 @@ -1065,8 +1065,8 @@ その他の報告… コンテンツの報告 このコンテンツを報告する理由 - 報告する - ユーザーを無視する + 報告 + ユーザーを無視 ユーザーを無視 警告: @@ -1120,8 +1120,8 @@ スキャンできません 断る 検証リクエスト - 通話の開始前に確認する - 意図しない通話を阻止する + 通話の開始前に確認 + 意図しない通話を阻止 お使いの端末は脆弱性のある古いTLSセキュリティープロトコルを使用しています、このセキュリティーでは接続できません SSLエラー。 SSLエラー:相手のアイデンティティが認証されていません。 @@ -1130,7 +1130,7 @@ このURLは検索結果に表示できません、ご確認ください この電話番号は既に使用されています。 復旧用のメールアドレスを設定します。後からオプションでメールアドレスや電話番号を使用して知人に見つけてもらえるようにできます。 - シングルサインオンを使用してサインインする + シングルサインオンを使用してサインイン HDを使用する HDを使用しない 背面 @@ -1186,10 +1186,10 @@ FCMトークンが正常に取得されました: \n%1$s Firebaseトークン - Playサービスを修正する + Playサービスを修正 GooglePlayサービスAPKは利用可能で最新の状態になっています。 Playサービスチェック - 設定を確認する + 設定を確認 カスタムルールの読み込みに失敗しました。再試行してください。 一部の通知はカスタム設定で無効になっています。 一部のメッセージがサイレントに設定されていることに注意してください(音を出さずに通知します)。 @@ -1197,7 +1197,7 @@ 1つ以上のテストが失敗しました。提案された修正を試してください。 基本的な診断はOKです。 それでも通知が届かない場合は、調査用の不具合報告を送信してください。 実行しています… (%1$dの %2$d) - テストを実行する + テストを実行 診断トラブルシューティング イベントごとの通知の優先順位 メールであなたに送ったリンクをクリックして確認してください。 @@ -1206,7 +1206,7 @@ パスワードを確認 暗号化されたルームでの検索はまだサポートされていません。 ブロックされたユーザーを絞り込む - トピックを変更する + トピックを変更 ルームをアップグレード m.room.server_acl eventsを送信 権限を変更 @@ -1220,7 +1220,7 @@ 他の人から送信されたメッセージの削除 ユーザーのブロック ユーザーの除去 - 設定を変更する + 設定を変更 招待されたユーザー メッセージを送る デフォルトルール @@ -1232,7 +1232,7 @@ ブロックを解除すると、ユーザーは再びルームに参加できるようになります。 禁止されたユーザー 禁止の理由 - ユーザーの禁止を解除する + ユーザーの禁止を解除 このユーザーはルームから除去されます。 \n \n再参加を防ぐためには、除去する代わりにブロックする必要があります。 @@ -1245,7 +1245,7 @@ このユーザーを無視すると、あなたが共有しているルームからそのユーザーのメッセージが削除されます。 \n \nこの動作は、設定からいつでも元に戻すことができます。 - ユーザーを無視する + ユーザーを無視 広角 あなたは自分自身を降格させようとしているため、今後、この変更を元に戻すことはできなくなります。あなたがルームの中で最後の特権ユーザーである場合、特権を再取得することはできません。 降格しますか? @@ -1262,7 +1262,7 @@ アクティブな通話(%s) あなたのホームサーバーがアシスト機能を提供しない場合、代わりに%sを使用します(IPアドレスは通話中に共有されます) ビデオ通話が行われています… - フォールバックコールアシストサーバーを許可する + フォールバックコールアシストサーバーを許可 有効な認証情報ではありません ${app_name} 呼び出し失敗 通話が確実に機能させるためには、ホームサーバー(%1$s)の管理者にTURNサーバーの設定を依頼してください。 @@ -1405,10 +1405,10 @@ \nサーバーからの応答を待っています… 空のルーム(%sでした) - %1$sと%2$sと%3$sそれに%4$dその他 + %1$sと%2$sと%3$sと%4$dなど - %1$sと%2$sと%3$sそれに%4$s - %1$sと%2$s それに%3$s + %1$sと%2$sと%3$sと%4$s + %1$sと%2$sと%3$s %1$sを%2$sから%3$sへ %2$sが%1$sの権限を変更しました。 %1$sの権限を変更しました。 @@ -1455,16 +1455,16 @@ これにより、現在のキーまたはフレーズが置き換えられます。 新しいセキュリティーキーを生成するか、既存のバックアップに新しいセキュリティーフレーズを設定します。 サーバー上の暗号化キーをバックアップすることにより、暗号化されたメッセージとデータへのアクセスが失われるのを防ぎます。 - メッセージ作成画面に絵文字キーボードを開くボタンを追加する - 絵文字キーボードを表示する + メッセージ作成画面に絵文字キーボードを開くボタンを追加 + 絵文字キーボードを表示 アバターと表示名の変更が含まれます。 - アカウントイベントを表示する + アカウントイベントを表示 招待、削除、ブロックは影響を受けません。 招待/参加/退出/削除/禁止イベントや、アバター/表示名の変更などを含む。 参加・退出イベントを表示 Use /confettiコマンドを使用するか、❄️または🎉を含むメッセージを送信します - チャットでエフェクトを表示する - ルームのメンバーのイベントを表示する + チャットでエフェクトを表示 + ルームのメンバーのイベントを表示 ホームサーバーがこの機能をサポートしている場合は、チャット内のリンクをプレビューします。 ボット、ブリッジ、ウィジェット、ステッカーパックの管理をします。 \nユーザーに代わり、構成データを受信しウィジェットを変更、ルーム招待の送信、権限の設定などができます。 @@ -1480,7 +1480,7 @@ 通話の通知を設定 うるさい通知を設定 アプリはバックグラウンドでホームサーバーに接続する必要がないためバッテリー使用量を減らすことができます - 最適化を無視する + 最適化を無視 画面をオフにした状態でデバイスのプラグを抜いて一定時間静止したままにすると、デバイスは機内モードになります。 これにより、アプリがネットワークにアクセスできなくなり、ジョブ、同期、および標準のアラームが防止されます。 ${app_name}に対してバックグラウンド制限が有効になっています。 \nアプリがバックグラウンドで実行しようとすると積極的に制限され、通知に影響を与える可能性があります。 @@ -1531,7 +1531,7 @@ %1$sや %2$sそれに%3$dに他の人も読みました %1$sや %2$sそれに%3$sが読みました - メッセージをマークダウンとして解釈せずにプレーンテキストとして送信する + メッセージをマークダウンとして解釈せずにプレーンテキストとして送信 ファイルとして保存 共有 完了 @@ -1539,7 +1539,7 @@ バックアップを作成中 パスフレーズを設定 手動でキーをエクスポート - キーバックアップを使って開始する + キーバックアップを使って開始 パスフレーズが弱すぎます パスフレーズを入力してください Google PlayサービスのAPKが見つかりませんでした。通知がうまく機能しない場合があります。 @@ -1555,7 +1555,7 @@ あなたのユーザーID あなたのアバターURL ブラウザーで開く - ウィジェットをロードする + ウィジェットをロード ウィジェット アクティブなウィジェット 自分 @@ -1571,22 +1571,22 @@ 選択 選択 詳細情報: %s - ローカルアドレスを追加する + ローカルアドレスを追加 このルームにはローカルアドレスがありません アドレス \"%1$s\" を削除しますか? メインアドレス これがメインアドレスです 電話番号の認証中にエラーが発生しました。 リンクを共有 - %s に招待する + %s に招待 Eメールで招待 詳細 - 人を招待する + 人を招待 とにかく参加 ルームを追加 %s はあなたを招待しています このルームでグループ通話をする権利がありません - オーディオミーティングを開始する + オーディオミーティングを開始 安全バックアップを設定 暗号鍵バックアップで管理 暗号鍵バックアップを使用 @@ -1760,7 +1760,7 @@ ルームへのアクセス 発信履歴閲覧権限の変更は今後送信されるメッセージにのみ適用されます。既存履歴の表示は影響されません。 無視して続行 - 毎回確認する + 毎回確認 招待 おすすめのルーム スペース @@ -1772,11 +1772,11 @@ 表示 このルーム内のメッセージはエンドツーエンド暗号化されています。 ダイレクトメッセージ - 新しいダイレクトメッセージを送信する + 新しいダイレクトメッセージを送信 メールアドレス(任意) メールアドレス アカウントを回復するためのメールを設定します。 後で、オプションで、あなたが知人にあなたのメールに見つけてもらえるようにできます。 - メールアドレスを設定する + メールアドレスを設定 メールアドレスを確認しました 検出可能なメールアドレス 続行するには条件に同意してください @@ -1799,7 +1799,7 @@ SSOを続行します サインイン サインアップ - Element Matrix Servicesに接続する + Element Matrix Servicesに接続 Matrix IDでサインイン Matrix IDでサインイン もっと詳しく知る @@ -1811,7 +1811,7 @@ メールと同じように、アカウントには1つのホームがありますが、誰とでも話すことができます サーバーを選択 始めましょう - エクスペリエンスを拡張およびカスタマイズする + エクスペリエンスを拡張およびカスタマイズ 暗号化して会話をプライベートに保つ 直接またはグループで人々とチャットする あなたの会話。 それを所有する。 @@ -1866,7 +1866,7 @@ ルーム管理者によってモデレートされたイベント リアクション リアクションを見る - リアクションを追加する + リアクションを追加 いいね 同意 リアクション @@ -1921,7 +1921,7 @@ 最大限のセキュリティーを確保するために、これを行うか、別の信頼できる通信手段を用いることをお勧めします。 短い文字列を比較して検証します。 認証が無効または期限切れのため、ログアウトされました。 - 構成を使用する + 構成を使用 ${app_name}がuserIdドメイン\"%1$s \"のカスタムサーバー構成を検出しました。 \n%2$s サーバーオプションをおまかせする @@ -1937,8 +1937,8 @@ %1$s: %2$s あなたが知らないかもしれない他のスペースやルーム このルームを見つけて参加できるか決める。 - タップしスペースを編集する - スペースを選択する + タップしスペースを編集 + スペースを選択 アクセス可能なスペース スペースのメンバーに発見とアクセスを許可します。 スペース%sのメンバーが検索、プレビュー、参加できます。 @@ -1984,7 +1984,7 @@ \nプライバシーの保護のため、データは送信前にハッシュ化されます。 メールと電話番号を送信 同意する - 同意を撤回する + 同意を撤回 あなたの連絡先から他のユーザーを発見するために、電子メールや電話番号をこのIDサーバーに送信することに同意していません。 あなたの連絡先から他のユーザーを発見するために、このIDサーバーにメールや電話番号を送信することに同意しています。 メールと電話番号を送信 @@ -1992,11 +1992,11 @@ %sに確認メールを送りました。まず、メールを確認してリンクをクリックしてください %sに確認のためのメールを送りました。メールにて確認リンクをクリックしてください 検出可能な電話番号 - IDサーバーとの接続を解除すると、他のユーザーから自分を発見できなくなり、メールや電話で他のユーザーを招待することができなくなります。 - 電話番号を追加すると、ディスカバリーオプションが表示されます。 - メールを追加すると、ディスカバリーオプションが表示されます。 - 現在、IDサーバーを使用していません。あなたの知っている連絡先を発見したり、その連絡先から発見されるようにするには、以下のように設定します。 - %1$sを使って知り合いを見つけたり、見つけられるようにしています。 + IDサーバーとの接続を解除すると、他のユーザーによって発見されなくなり、また、メールアドレスや電話で他のユーザーを招待することができなくなります。 + 電話番号を追加すると、発見可能に設定する電話番号を選択できるようになります。 + メールアドレスを追加すると、発見可能に設定するメールアドレスを選択できるようになります。 + 現在、IDサーバーを使用していません。あなたの知っている連絡先を発見したり、その連絡先から発見されるようにするには、以下を設定してください。 + あなたは現在 %1$sを使って連絡先を見つけたり、連絡先から見つけられるようにしています。 IDサーバーを変更 IDサーバーの設定 IDサーバーの切断 @@ -2035,7 +2035,7 @@ \n設定画面からパスワードとリカバリーキーを早急に変更することを推奨します。 Eメール アドレス - 継続する + 継続 ファイル このユーザーはスペースから除去されます。 \n From 3ad7701ad7c28382e681c8f8c0c7e14a329ec8aa Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 17 Feb 2022 15:14:08 +0100 Subject: [PATCH 148/302] Adding changelog entry --- changelog.d/5218.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5218.bugfix diff --git a/changelog.d/5218.bugfix b/changelog.d/5218.bugfix new file mode 100644 index 0000000000..93aece938c --- /dev/null +++ b/changelog.d/5218.bugfix @@ -0,0 +1 @@ +Fix crash during registration when redirecting to Web Browser From cee5ea03aeaa28a9c999a40f44ac2601d8bb7fb4 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Thu, 17 Feb 2022 16:42:24 +0100 Subject: [PATCH 149/302] Retrieve session in init method differently --- .../app/features/login/LoginWebFragment.kt | 1 + .../app/features/login2/LoginWebFragment2.kt | 1 + .../ftueauth/FtueAuthWebFragment.kt | 1 + .../signout/soft/SoftLogoutViewModel.kt | 29 ++++++++++++------- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt index ca21e96d20..fc3392df09 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt @@ -51,6 +51,7 @@ class LoginWebFragment @Inject constructor( private val assetReader: AssetReader ) : AbstractLoginFragment() { + // TODO confirm the need of this viewModel val softLogoutViewModel: SoftLogoutViewModel by activityViewModel() override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginWebBinding { diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt index ebe59ee1b9..6996cb552a 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt @@ -56,6 +56,7 @@ class LoginWebFragment2 @Inject constructor( return FragmentLoginWebBinding.inflate(inflater, container, false) } + // TODO confirm the need of this viewModel val softLogoutViewModel: SoftLogoutViewModel by activityViewModel() private var isWebViewLoaded = false diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthWebFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthWebFragment.kt index 879830a1c0..b1f6de9d49 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthWebFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthWebFragment.kt @@ -56,6 +56,7 @@ class FtueAuthWebFragment @Inject constructor( private val assetReader: AssetReader ) : AbstractFtueAuthFragment() { + // TODO confirm the need of this viewModel val softLogoutViewModel: SoftLogoutViewModel by activityViewModel() override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginWebBinding { diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt index 52986a1f3b..84b443a60f 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt @@ -16,7 +16,6 @@ package im.vector.app.features.signout.soft -import com.airbnb.mvrx.ActivityViewModelContext import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksViewModelFactory @@ -26,8 +25,10 @@ import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import dagger.hilt.EntryPoints import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.SingletonEntryPoint import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.hasUnsavedKeys import im.vector.app.core.platform.VectorViewModel @@ -56,15 +57,23 @@ class SoftLogoutViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { override fun initialState(viewModelContext: ViewModelContext): SoftLogoutViewState? { - val activity: SoftLogoutActivity = (viewModelContext as ActivityViewModelContext).activity() - val userId = activity.session.myUserId - return SoftLogoutViewState( - homeServerUrl = activity.session.sessionParams.homeServerUrl, - userId = userId, - deviceId = activity.session.sessionParams.deviceId ?: "", - userDisplayName = activity.session.getUser(userId)?.displayName ?: userId, - hasUnsavedKeys = activity.session.hasUnsavedKeys() - ) + val sessionHolder = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java) + .activeSessionHolder() + + return if (sessionHolder.hasActiveSession()) { + val session = sessionHolder.getActiveSession() + val userId = session.myUserId + + SoftLogoutViewState( + homeServerUrl = session.sessionParams.homeServerUrl, + userId = userId, + deviceId = session.sessionParams.deviceId.orEmpty(), + userDisplayName = session.getUser(userId)?.displayName ?: userId, + hasUnsavedKeys = session.hasUnsavedKeys() + ) + } else { + null + } } } From 8115b4b6e632b42284b9fb46032bc2f30a71296f Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Fri, 18 Feb 2022 14:22:38 +0100 Subject: [PATCH 150/302] Removing unused Session recovery action from onboarding --- .../app/features/onboarding/OnboardingAction.kt | 6 ------ .../features/onboarding/OnboardingViewModel.kt | 13 ------------- .../onboarding/ftueauth/FtueAuthWebFragment.kt | 15 +-------------- 3 files changed, 1 insertion(+), 33 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt index 2ca6a1f2fd..3ddea5ca2e 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt @@ -21,7 +21,6 @@ import im.vector.app.features.login.LoginConfig import im.vector.app.features.login.ServerType import im.vector.app.features.login.SignMode import org.matrix.android.sdk.api.auth.data.Credentials -import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider import org.matrix.android.sdk.api.auth.registration.RegisterThreePid import org.matrix.android.sdk.internal.network.ssl.Fingerprint @@ -71,11 +70,6 @@ sealed class OnboardingAction : VectorViewModelAction { // Homeserver history object ClearHomeServerHistory : OnboardingAction() - // For the soft logout case - data class SetupSsoForSessionRecovery(val homeServerUrl: String, - val deviceId: String, - val ssoIdentityProviders: List?) : OnboardingAction() - data class PostViewEvent(val viewEvent: OnboardingViewEvents) : OnboardingAction() data class UserAcceptCertificate(val fingerprint: Fingerprint) : OnboardingAction() diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index a125c57ac9..d279c5bbe9 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -143,7 +143,6 @@ class OnboardingViewModel @AssistedInject constructor( is OnboardingAction.ResetPasswordMailConfirmed -> handleResetPasswordMailConfirmed() is OnboardingAction.RegisterAction -> handleRegisterAction(action) is OnboardingAction.ResetAction -> handleResetAction(action) - is OnboardingAction.SetupSsoForSessionRecovery -> handleSetupSsoForSessionRecovery(action) is OnboardingAction.UserAcceptCertificate -> handleUserAcceptCertificate(action) OnboardingAction.ClearHomeServerHistory -> handleClearHomeServerHistory() is OnboardingAction.PostViewEvent -> _viewEvents.post(action.viewEvent) @@ -249,18 +248,6 @@ class OnboardingViewModel @AssistedInject constructor( } } - private fun handleSetupSsoForSessionRecovery(action: OnboardingAction.SetupSsoForSessionRecovery) { - setState { - copy( - signMode = SignMode.SignIn, - loginMode = LoginMode.Sso(action.ssoIdentityProviders), - homeServerUrlFromUser = action.homeServerUrl, - homeServerUrl = action.homeServerUrl, - deviceId = action.deviceId - ) - } - } - private fun handleRegisterAction(action: OnboardingAction.RegisterAction) { when (action) { is OnboardingAction.CaptchaDone -> handleCaptchaDone(action) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthWebFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthWebFragment.kt index b1f6de9d49..4c99a4d1d8 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthWebFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthWebFragment.kt @@ -30,7 +30,6 @@ import android.view.ViewGroup import android.webkit.SslErrorHandler import android.webkit.WebView import android.webkit.WebViewClient -import com.airbnb.mvrx.activityViewModel import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R import im.vector.app.core.utils.AssetReader @@ -40,8 +39,6 @@ import im.vector.app.features.login.SignMode import im.vector.app.features.onboarding.OnboardingAction import im.vector.app.features.onboarding.OnboardingViewEvents import im.vector.app.features.onboarding.OnboardingViewState -import im.vector.app.features.signout.soft.SoftLogoutAction -import im.vector.app.features.signout.soft.SoftLogoutViewModel import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.internal.di.MoshiProvider import timber.log.Timber @@ -56,15 +53,11 @@ class FtueAuthWebFragment @Inject constructor( private val assetReader: AssetReader ) : AbstractFtueAuthFragment() { - // TODO confirm the need of this viewModel - val softLogoutViewModel: SoftLogoutViewModel by activityViewModel() - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginWebBinding { return FragmentLoginWebBinding.inflate(inflater, container, false) } private var isWebViewLoaded = false - private var isForSessionRecovery = false override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -76,8 +69,6 @@ class FtueAuthWebFragment @Inject constructor( override fun updateWithState(state: OnboardingViewState) { setupTitle(state) - isForSessionRecovery = state.deviceId?.isNotBlank() == true - if (!isWebViewLoaded) { setupWebView(state) isWebViewLoaded = true @@ -240,11 +231,7 @@ class FtueAuthWebFragment @Inject constructor( } private fun notifyViewModel(credentials: Credentials) { - if (isForSessionRecovery) { - softLogoutViewModel.handle(SoftLogoutAction.WebLoginSuccess(credentials)) - } else { - viewModel.handle(OnboardingAction.WebLoginSuccess(credentials)) - } + viewModel.handle(OnboardingAction.WebLoginSuccess(credentials)) } override fun resetViewModel() { From 7df5372d4d67a6020289c59c54b1d1aed3c3140e Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Fri, 18 Feb 2022 14:22:51 +0100 Subject: [PATCH 151/302] Adding TODO to confirm --- .../java/im/vector/app/features/login/LoginWebFragment.kt | 6 ++++-- .../java/im/vector/app/features/login2/LoginWebFragment2.kt | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt index fc3392df09..e7c15445d0 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt @@ -51,8 +51,9 @@ class LoginWebFragment @Inject constructor( private val assetReader: AssetReader ) : AbstractLoginFragment() { - // TODO confirm the need of this viewModel - val softLogoutViewModel: SoftLogoutViewModel by activityViewModel() + // TODO I noticed in the Git history this variable was a local variable inside notifyViewModel method + // TODO was there any reason ? To be able to create this ViewModel we must be sure we will have a valid session + private val softLogoutViewModel: SoftLogoutViewModel by activityViewModel() override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginWebBinding { return FragmentLoginWebBinding.inflate(inflater, container, false) @@ -71,6 +72,7 @@ class LoginWebFragment @Inject constructor( override fun updateWithState(state: LoginViewState) { setupTitle(state) + // TODO check how it is possible to arrive in this case isForSessionRecovery = state.deviceId?.isNotBlank() == true if (!isWebViewLoaded) { diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt index 6996cb552a..17a271177a 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt @@ -56,8 +56,9 @@ class LoginWebFragment2 @Inject constructor( return FragmentLoginWebBinding.inflate(inflater, container, false) } - // TODO confirm the need of this viewModel - val softLogoutViewModel: SoftLogoutViewModel by activityViewModel() + // TODO I noticed in the Git history this variable was a local variable inside notifyViewModel method + // TODO was there any reason ? To be able to create this ViewModel we must be sure we will have a valid session + private val softLogoutViewModel: SoftLogoutViewModel by activityViewModel() private var isWebViewLoaded = false private var isForSessionRecovery = false @@ -72,6 +73,7 @@ class LoginWebFragment2 @Inject constructor( override fun updateWithState(state: LoginViewState2) { setupTitle(state) + // TODO check how it is possible to arrive in this case isForSessionRecovery = state.deviceId?.isNotBlank() == true if (!isWebViewLoaded) { From bfc6cd04a65134dc40b571bb49412d86667708cb Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Fri, 18 Feb 2022 14:23:31 +0100 Subject: [PATCH 152/302] Updating changelog entry --- changelog.d/5218.bugfix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/5218.bugfix b/changelog.d/5218.bugfix index 93aece938c..4f92338a4f 100644 --- a/changelog.d/5218.bugfix +++ b/changelog.d/5218.bugfix @@ -1 +1 @@ -Fix crash during registration when redirecting to Web Browser +Fix crash during account registration when redirecting to Web View From cb9df953fb46dc02dbd60de98607425497c1590c Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Fri, 18 Feb 2022 15:00:52 +0100 Subject: [PATCH 153/302] Removing some TODOs --- .../main/java/im/vector/app/features/login/LoginWebFragment.kt | 1 - .../main/java/im/vector/app/features/login2/LoginWebFragment2.kt | 1 - 2 files changed, 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt index e7c15445d0..f1558518f7 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt @@ -72,7 +72,6 @@ class LoginWebFragment @Inject constructor( override fun updateWithState(state: LoginViewState) { setupTitle(state) - // TODO check how it is possible to arrive in this case isForSessionRecovery = state.deviceId?.isNotBlank() == true if (!isWebViewLoaded) { diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt index 17a271177a..4e28d8e56c 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt @@ -73,7 +73,6 @@ class LoginWebFragment2 @Inject constructor( override fun updateWithState(state: LoginViewState2) { setupTitle(state) - // TODO check how it is possible to arrive in this case isForSessionRecovery = state.deviceId?.isNotBlank() == true if (!isWebViewLoaded) { From 66b30c33c83d6c58c0bedcafcae6072d62cb5352 Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Fri, 18 Feb 2022 14:38:22 +0000 Subject: [PATCH 154/302] Improve reliability of sanity tests. We add the permission so we can write to the external storage with the screenshots We rename the screenshots so they can be uploaded via the github action correctly We always do the upload even if the test build has failed. --- .github/workflows/sanity_test.yml | 3 ++- .../java/im/vector/app/espresso/tools/ScreenshotFailureRule.kt | 2 +- .../java/im/vector/app/ui/UiAllScreensSanityTest.kt | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sanity_test.yml b/.github/workflows/sanity_test.yml index 93e4686fe7..483926fa1f 100644 --- a/.github/workflows/sanity_test.yml +++ b/.github/workflows/sanity_test.yml @@ -69,9 +69,10 @@ jobs: touch emulator.log chmod 777 emulator.log adb logcat >> emulator.log & - ./gradlew $CI_GRADLE_ARG_PROPERTIES -PallWarningsAsErrors=false connectedGplayDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=im.vector.app.ui.UiAllScreensSanityTest || adb pull storage/emulated/0/Pictures/failure_screenshots + ./gradlew $CI_GRADLE_ARG_PROPERTIES -PallWarningsAsErrors=false connectedGplayDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=im.vector.app.ui.UiAllScreensSanityTest || (adb pull storage/emulated/0/Pictures/failure_screenshots && exit 1 ) - name: Upload Test Report Log uses: actions/upload-artifact@v2 + if: always() with: name: sanity-error-results path: | diff --git a/vector/src/androidTest/java/im/vector/app/espresso/tools/ScreenshotFailureRule.kt b/vector/src/androidTest/java/im/vector/app/espresso/tools/ScreenshotFailureRule.kt index 2e329ebb6b..2939dcf4e0 100644 --- a/vector/src/androidTest/java/im/vector/app/espresso/tools/ScreenshotFailureRule.kt +++ b/vector/src/androidTest/java/im/vector/app/espresso/tools/ScreenshotFailureRule.kt @@ -40,7 +40,7 @@ private val deviceLanguage = Locale.getDefault().language class ScreenshotFailureRule : TestWatcher() { override fun failed(e: Throwable?, description: Description) { - val screenShotName = "$deviceLanguage-${description.methodName}-${SimpleDateFormat("EEE-MMMM-dd-HH:mm:ss").format(Date())}" + val screenShotName = "$deviceLanguage-${description.methodName}-${SimpleDateFormat("EEE-MMMM-dd-HHmmss").format(Date())}" val bitmap = getInstrumentation().uiAutomation.takeScreenshot() storeFailureScreenshot(bitmap, screenShotName) } diff --git a/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt b/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt index bab397678e..417d28d625 100644 --- a/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt +++ b/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt @@ -16,10 +16,12 @@ package im.vector.app.ui +import android.Manifest import androidx.test.espresso.IdlingPolicies import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest +import androidx.test.rule.GrantPermissionRule import im.vector.app.R import im.vector.app.espresso.tools.ScreenshotFailureRule import im.vector.app.features.MainActivity @@ -43,6 +45,7 @@ class UiAllScreensSanityTest { @get:Rule val testRule = RuleChain .outerRule(ActivityScenarioRule(MainActivity::class.java)) + .around(GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE)) .around(ScreenshotFailureRule()) private val elementRobot = ElementRobot() From 95b3afd1488b046b3d36e99a8ed91d11a710778a Mon Sep 17 00:00:00 2001 From: ClaireG Date: Fri, 18 Feb 2022 16:45:01 +0100 Subject: [PATCH 155/302] #3771: When accepting an invite, expecting to see the room (#5247) Open the room when user accepts an invite from the room list --- changelog.d/3771.feature | 1 + .../home/room/detail/RoomDetailViewEvents.kt | 2 +- .../home/room/detail/RoomDetailViewState.kt | 2 ++ .../home/room/detail/TimelineFragment.kt | 8 +++++--- .../home/room/detail/TimelineViewModel.kt | 19 +++++++++++++++++-- .../room/detail/arguments/TimelineArgs.kt | 3 ++- .../home/room/list/RoomListFragment.kt | 6 +++--- .../home/room/list/RoomListViewEvents.kt | 2 +- .../home/room/list/RoomListViewModel.kt | 16 ++-------------- .../features/navigation/DefaultNavigator.kt | 5 +++-- .../app/features/navigation/Navigator.kt | 2 +- 11 files changed, 38 insertions(+), 28 deletions(-) create mode 100644 changelog.d/3771.feature diff --git a/changelog.d/3771.feature b/changelog.d/3771.feature new file mode 100644 index 0000000000..c480bb649d --- /dev/null +++ b/changelog.d/3771.feature @@ -0,0 +1 @@ +Open the room when user accepts an invite from the room list \ No newline at end of file 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 86240a5ffe..d08a27324c 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 @@ -29,7 +29,7 @@ import java.io.File * Transient events for RoomDetail */ sealed class RoomDetailViewEvents : VectorViewEvents { - data class Failure(val throwable: Throwable) : RoomDetailViewEvents() + data class Failure(val throwable: Throwable, val showInDialog: Boolean = false) : RoomDetailViewEvents() data class OnNewTimelineEvents(val eventIds: List) : RoomDetailViewEvents() data class ActionSuccess(val action: RoomDetailAction) : RoomDetailViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt index 22d5fc2a77..71a299e11b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewState.kt @@ -49,6 +49,7 @@ data class JitsiState( data class RoomDetailViewState( val roomId: String, val eventId: String?, + val isInviteAlreadyAccepted: Boolean, val myRoomMember: Async = Uninitialized, val asyncInviter: Async = Uninitialized, val asyncRoomSummary: Async = Uninitialized, @@ -77,6 +78,7 @@ data class RoomDetailViewState( constructor(args: TimelineArgs) : this( roomId = args.roomId, eventId = args.eventId, + isInviteAlreadyAccepted = args.isInviteAlreadyAccepted, // Also highlight the target event, if any highlightedEventId = args.eventId, switchToParentSpace = args.switchToParentSpace, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index ff392eaf1b..b6cbd538f3 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -448,7 +448,7 @@ class TimelineFragment @Inject constructor( timelineViewModel.observeViewEvents { when (it) { - is RoomDetailViewEvents.Failure -> showErrorInSnackbar(it.throwable) + is RoomDetailViewEvents.Failure -> displayErrorMessage(it) is RoomDetailViewEvents.OnNewTimelineEvents -> scrollOnNewMessageCallback.addNewTimelineEventIds(it.eventIds) is RoomDetailViewEvents.ActionSuccess -> displayRoomDetailActionSuccess(it) is RoomDetailViewEvents.ActionFailure -> displayRoomDetailActionFailure(it) @@ -623,6 +623,10 @@ class TimelineFragment @Inject constructor( ) } + private fun displayErrorMessage(error: RoomDetailViewEvents.Failure) { + if (error.showInDialog) displayErrorDialog(error.throwable) else showErrorInSnackbar(error.throwable) + } + private fun requestNativeWidgetPermission(it: RoomDetailViewEvents.RequestNativeWidgetPermission) { val tag = RoomWidgetPermissionBottomSheet::class.java.name val dFrag = childFragmentManager.findFragmentByTag(tag) as? RoomWidgetPermissionBottomSheet @@ -2374,12 +2378,10 @@ class TimelineFragment @Inject constructor( // VectorInviteView.Callback override fun onAcceptInvite() { - notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(timelineArgs.roomId) } timelineViewModel.handle(RoomDetailAction.AcceptInvite) } override fun onRejectInvite() { - notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(timelineArgs.roomId) } timelineViewModel.handle(RoomDetailAction.RejectInvite) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt index a404f9136b..0198c77280 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt @@ -53,6 +53,7 @@ import im.vector.app.features.home.room.detail.sticker.StickerPickerActionHandle import im.vector.app.features.home.room.detail.timeline.factory.TimelineFactory import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever import im.vector.app.features.home.room.typing.TypingHelper +import im.vector.app.features.notifications.NotificationDrawerManager import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import im.vector.app.features.session.coroutineScope import im.vector.app.features.settings.VectorDataStore @@ -123,6 +124,7 @@ class TimelineViewModel @AssistedInject constructor( private val analyticsTracker: AnalyticsTracker, private val activeConferenceHolder: JitsiActiveConferenceHolder, private val decryptionFailureTracker: DecryptionFailureTracker, + private val notificationDrawerManager: NotificationDrawerManager, timelineFactory: TimelineFactory, appStateHandler: AppStateHandler ) : VectorViewModel(initialState), @@ -190,6 +192,11 @@ class TimelineViewModel @AssistedInject constructor( prepareForEncryption() } + // If the user had already accepted the invitation in the room list + if (initialState.isInviteAlreadyAccepted) { + handleAcceptInvite() + } + if (initialState.switchToParentSpace) { // We are coming from a notification, try to switch to the most relevant space // so that when hitting back the room will appear in the list @@ -800,16 +807,24 @@ class TimelineViewModel @AssistedInject constructor( } private fun handleRejectInvite() { + notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(initialState.roomId) } viewModelScope.launch { - tryOrNull { session.leaveRoom(room.roomId) } + try { + session.leaveRoom(room.roomId) + } catch (throwable: Throwable) { + _viewEvents.post(RoomDetailViewEvents.Failure(throwable, showInDialog = true)) + } } } private fun handleAcceptInvite() { + notificationDrawerManager.updateEvents { it.clearMemberShipNotificationForRoom(initialState.roomId) } viewModelScope.launch { - tryOrNull { + try { session.joinRoom(room.roomId) analyticsTracker.capture(room.roomSummary().toAnalyticsJoinedRoom()) + } catch (throwable: Throwable) { + _viewEvents.post(RoomDetailViewEvents.Failure(throwable, showInDialog = true)) } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/arguments/TimelineArgs.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/arguments/TimelineArgs.kt index f22fe1b7df..a21567acb1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/arguments/TimelineArgs.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/arguments/TimelineArgs.kt @@ -28,5 +28,6 @@ data class TimelineArgs( val sharedData: SharedData? = null, val openShareSpaceForId: String? = null, val threadTimelineArgs: ThreadTimelineArgs? = null, - val switchToParentSpace: Boolean = false + val switchToParentSpace: Boolean = false, + val isInviteAlreadyAccepted: Boolean = false ) : Parcelable diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index b023c26590..28849204c4 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -121,7 +121,7 @@ class RoomListFragment @Inject constructor( when (it) { is RoomListViewEvents.Loading -> showLoading(it.message) is RoomListViewEvents.Failure -> showFailure(it.throwable) - is RoomListViewEvents.SelectRoom -> handleSelectRoom(it) + is RoomListViewEvents.SelectRoom -> handleSelectRoom(it, it.isInviteAlreadyAccepted) is RoomListViewEvents.Done -> Unit is RoomListViewEvents.NavigateToMxToBottomSheet -> handleShowMxToLink(it.link) }.exhaustive @@ -184,8 +184,8 @@ class RoomListFragment @Inject constructor( super.onDestroyView() } - private fun handleSelectRoom(event: RoomListViewEvents.SelectRoom) { - navigator.openRoom(requireActivity(), event.roomSummary.roomId) + private fun handleSelectRoom(event: RoomListViewEvents.SelectRoom, isInviteAlreadyAccepted: Boolean) { + navigator.openRoom(context = requireActivity(), roomId = event.roomSummary.roomId, isInviteAlreadyAccepted = isInviteAlreadyAccepted) } private fun setupCreateRoomButton() { diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewEvents.kt index df2ff58da6..15e16c464f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewEvents.kt @@ -27,7 +27,7 @@ sealed class RoomListViewEvents : VectorViewEvents { data class Loading(val message: CharSequence? = null) : RoomListViewEvents() data class Failure(val throwable: Throwable) : RoomListViewEvents() - data class SelectRoom(val roomSummary: RoomSummary) : RoomListViewEvents() + data class SelectRoom(val roomSummary: RoomSummary, val isInviteAlreadyAccepted: Boolean = false) : RoomListViewEvents() object Done : RoomListViewEvents() data class NavigateToMxToBottomSheet(val link: String) : RoomListViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt index a5977501d2..4a81a8b526 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt @@ -33,7 +33,6 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider import im.vector.app.features.analytics.AnalyticsTracker -import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom import im.vector.app.features.displayname.getBestName import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.settings.VectorPreferences @@ -174,7 +173,7 @@ class RoomListViewModel @AssistedInject constructor( // PRIVATE METHODS ***************************************************************************** private fun handleSelectRoom(action: RoomListAction.SelectRoom) = withState { - _viewEvents.post(RoomListViewEvents.SelectRoom(action.roomSummary)) + _viewEvents.post(RoomListViewEvents.SelectRoom(action.roomSummary, false)) } private fun handleToggleSection(roomSection: RoomsSection) { @@ -208,6 +207,7 @@ class RoomListViewModel @AssistedInject constructor( Timber.w("Try to join an already joining room. Should not happen") return@withState } + _viewEvents.post(RoomListViewEvents.SelectRoom(action.roomSummary, true)) // quick echo setState { @@ -221,18 +221,6 @@ class RoomListViewModel @AssistedInject constructor( } ) } - - viewModelScope.launch { - try { - session.joinRoom(roomId) - analyticsTracker.capture(action.roomSummary.toAnalyticsJoinedRoom()) - // We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data. - // Instead, we wait for the room to be joined - } catch (failure: Throwable) { - // Notify the user - _viewEvents.post(RoomListViewEvents.Failure(failure)) - } - } } private fun handleRejectInvitation(action: RoomListAction.RejectInvitation) = withState { state -> diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index b521710c1e..cc02687d93 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -147,13 +147,14 @@ class DefaultNavigator @Inject constructor( context: Context, roomId: String, eventId: String?, - buildTask: Boolean + buildTask: Boolean, + isInviteAlreadyAccepted: Boolean ) { if (sessionHolder.getSafeActiveSession()?.getRoom(roomId) == null) { fatalError("Trying to open an unknown room $roomId", vectorPreferences.failFast()) return } - val args = TimelineArgs(roomId, eventId) + val args = TimelineArgs(roomId = roomId, eventId = eventId, isInviteAlreadyAccepted = isInviteAlreadyAccepted) val intent = RoomDetailActivity.newIntent(context, args) startActivity(context, intent, buildTask) } diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt index b5e94241ce..a31dc8fb89 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt @@ -50,7 +50,7 @@ interface Navigator { fun softLogout(context: Context) - fun openRoom(context: Context, roomId: String, eventId: String? = null, buildTask: Boolean = false) + fun openRoom(context: Context, roomId: String, eventId: String? = null, buildTask: Boolean = false, isInviteAlreadyAccepted: Boolean = false) sealed class PostSwitchSpaceAction { object None : PostSwitchSpaceAction() From d29fc9f2d343f93c5a8c586743abd6a637ce54e7 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Fri, 18 Feb 2022 17:04:02 +0100 Subject: [PATCH 156/302] Replacing vctr_unread_room_badge by vctr_content_secondary --- library/ui-styles/src/main/res/values/colors.xml | 5 ----- library/ui-styles/src/main/res/values/theme_black.xml | 1 - library/ui-styles/src/main/res/values/theme_dark.xml | 1 - library/ui-styles/src/main/res/values/theme_light.xml | 1 - .../java/im/vector/app/features/home/HomeDetailFragment.kt | 2 +- vector/src/main/res/drawable/bg_unread_notification.xml | 4 ++-- 6 files changed, 3 insertions(+), 11 deletions(-) diff --git a/library/ui-styles/src/main/res/values/colors.xml b/library/ui-styles/src/main/res/values/colors.xml index 48ac48a8ca..770b001893 100644 --- a/library/ui-styles/src/main/res/values/colors.xml +++ b/library/ui-styles/src/main/res/values/colors.xml @@ -57,11 +57,6 @@ - - @color/palette_gray_200 - @color/palette_gray_250 - @color/palette_gray_250 - @android:color/white #FF181B21 diff --git a/library/ui-styles/src/main/res/values/theme_black.xml b/library/ui-styles/src/main/res/values/theme_black.xml index c472a4fae5..44d4206d43 100644 --- a/library/ui-styles/src/main/res/values/theme_black.xml +++ b/library/ui-styles/src/main/res/values/theme_black.xml @@ -7,7 +7,6 @@ - @color/vctr_unread_room_badge_black @color/vctr_fab_label_bg_black @color/vctr_fab_label_stroke_black @color/vctr_fab_label_color_black diff --git a/library/ui-styles/src/main/res/values/theme_dark.xml b/library/ui-styles/src/main/res/values/theme_dark.xml index b1d95c5439..100a07f41d 100644 --- a/library/ui-styles/src/main/res/values/theme_dark.xml +++ b/library/ui-styles/src/main/res/values/theme_dark.xml @@ -16,7 +16,6 @@ @color/element_system_dark - @color/vctr_unread_room_badge_dark @color/vctr_fab_label_bg_dark @color/vctr_fab_label_stroke_dark @color/vctr_fab_label_color_dark diff --git a/library/ui-styles/src/main/res/values/theme_light.xml b/library/ui-styles/src/main/res/values/theme_light.xml index dba39c97ca..39e78ee5b1 100644 --- a/library/ui-styles/src/main/res/values/theme_light.xml +++ b/library/ui-styles/src/main/res/values/theme_light.xml @@ -16,7 +16,6 @@ @color/element_system_light - @color/vctr_unread_room_badge_light @color/vctr_fab_label_bg_light @color/vctr_fab_label_stroke_light @color/vctr_fab_label_color_light diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt index a07409d063..ea03b833ac 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt @@ -457,7 +457,7 @@ class HomeDetailFragment @Inject constructor( backgroundColor = if (highlight) { ThemeUtils.getColor(requireContext(), R.attr.colorError) } else { - ThemeUtils.getColor(requireContext(), R.attr.vctr_unread_room_badge) + ThemeUtils.getColor(requireContext(), R.attr.vctr_content_secondary) } } diff --git a/vector/src/main/res/drawable/bg_unread_notification.xml b/vector/src/main/res/drawable/bg_unread_notification.xml index 7c9ea18eec..4926f588da 100644 --- a/vector/src/main/res/drawable/bg_unread_notification.xml +++ b/vector/src/main/res/drawable/bg_unread_notification.xml @@ -4,5 +4,5 @@ - - \ No newline at end of file + + From 4713fd96bf5e291b19f1cdfc4e8e4d677dbfbaf3 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Fri, 18 Feb 2022 17:05:29 +0100 Subject: [PATCH 157/302] Adding changelog entry --- changelog.d/5225.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5225.misc diff --git a/changelog.d/5225.misc b/changelog.d/5225.misc new file mode 100644 index 0000000000..799a3a4d81 --- /dev/null +++ b/changelog.d/5225.misc @@ -0,0 +1 @@ +Replacing color "vctr_unread_room_badge" by "vctr_content_secondary" From 468220cde7b9741fc3028203b557126e74a26f2d Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Fri, 18 Feb 2022 19:35:08 +0000 Subject: [PATCH 158/302] Translated using Weblate (Japanese) Currently translated at 77.4% (2158 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 91 ++++++++++++----------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index cd9eb82f92..24eb67c67a 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -183,9 +183,9 @@ 招待 このルームを退出 検索 - %sさんが文字入力しています… - %1$sさんと %2$sさんが文字入力しています… - %1$sさん、%2$sさん他が文字入力しています… + %sさんが文字を入力しています… + %1$sさんと %2$sさんが文字を入力しています… + %1$sさん、%2$sさん他が文字を入力しています… 暗号文を送信… 明るいテーマ 暗いテーマ @@ -214,7 +214,7 @@ 権限を司会者へ変更 権限を管理者へ変更 ここに送信文を入力 (暗号なし)… - サーバーとの接続が失われました. + サーバーとの接続が失われました。 全て再送信 未送信の文を再送信 未送信の文を削除 @@ -252,7 +252,7 @@ 画像等を一時保存する期間 利用者設定 通知 - 無視する相手 + 無視しているユーザー その他 拡張設定 暗号化 @@ -264,7 +264,7 @@ 全てのメッセージにタイムスタンプを表示 タイムスタンプを12時間形式で表示 セッションの詳細 - ID(端末固有番号) + ID(端末固有番号) 公開端末名 公開端末名の更新 最終接続日 @@ -302,7 +302,7 @@ 低優先度 なし 参加と可視範囲 - ルームの一覧へ公開 + ルームディレクトリへ公開 ルームへの参加 ルームの履歴の可視範囲 ルームの履歴を読める人は\? @@ -364,8 +364,8 @@ 端末の電話帳を${app_name}アプリが読み取ることは許可されていません 結果なし ルーム - ルーム一覧 - 利用者一覧 + ルームディレクトリ + ユーザーディレクトリ 送信 サインアウト アカウントを作成 @@ -402,7 +402,7 @@ 電子メールアドレスの確認に失敗しました: 電子メールのリンクをクリックしたことを確認してください パスワードがリセットされました。 \n -\n全てのセッションからログアウトしたため、プッシュ通知を受け取れなくなりました。通知を再び有効にするには、各デバイスで再ログインをお願いします。 +\n全てのセッションからログアウトしたため、プッシュ通知を受け取れなくなりました。通知を再び有効にするには、各端末で再ログインをお願いします。 登録ができません : 電子メールがあなた個人のものであるか確認できません 指定されたアクセストークンが認識されませんでした 不正な形式のJSON @@ -448,7 +448,7 @@ 参加者 ファイル ルーム - ルーム一覧を見る + ディレクトリを見る 会話から退出 会話 設定 @@ -479,7 +479,7 @@ このルームは暗号化されていません。 暗号化を有効にします \n(警告: 有効後にこれを無効にすることはできません!) - ルーム一覧 + ディレクトリ 外観 エンドツーエンド暗号化についての情報 公開端末名 @@ -537,13 +537,13 @@ \n続行する前に、各セッションの検証プロセスを進めることをおすすめしますが、検証せずにメッセージを再送信することもできます。 \n \n不明なセッション: - ルームに不明なデバイスが含まれています + ルームに不明な端末が含まれています キーが一致していることを確認 - 一致する場合は、下の確認ボタンを押します。そうでない場合は、他の誰かがこのデバイスを盗聴しているので、代わりにブロックボタンを押すことをおすすめします。今後この検証プロセスはより洗練されたものになるでしょう。 - デバイスの検証 - 不明なデバイス + 一致する場合は、下の確認ボタンを押します。そうでない場合は、他の誰かがこの端末を盗聴しているので、代わりにブロックボタンを押すことをおすすめします。今後この検証プロセスはより洗練されたものになるでしょう。 + 端末の検証 + 不明な端末 このセッションでは、未検証のセッションに対して暗号化されたメッセージを送信しない - 認証済みデバイスに対してのみ暗号化 + 認証済み端末に対してのみ暗号化 インポート ローカルファイルからキーをインポート ルームキーをインポート @@ -617,7 +617,7 @@ 復号エラー 発信者装置の情報 公開端末名 - デバイスキー + 端末キー Ed25519 フィンガープリント 未認証 ブラックリスト @@ -626,14 +626,14 @@ 認証を取り消す ブラックリスト ブラックリストから除外 - このデバイスが信頼できることを確認するために、その所有者に何らかの他の方法(直接会って、または、電話で)連絡し、以下のキーが、そのデバイスの「設定」で確認できるキーと一致するかお尋ねください: + この端末が信頼できることを確認するために、その所有者に何らかの他の方法(直接会って、または、電話で)連絡し、以下のキーが、その端末の「設定」で確認できるキーと一致するかお尋ねください: ルームのディレクトリを選択 公開のルームを表示するホームサーバーを入力してください サーバー名 %sサーバー上の全てのルーム 全てのローカルの %s ルーム メッセージが未送信です。今 %1$s または %2$s しますか? - 不明なデバイスが存在しているため、メッセージを送ることができませんでした。今 %1$s または %2$s しますか? + 不明な端末が存在しているため、メッセージを送ることができませんでした。今 %1$s または %2$s しますか? 要求されたフィンガープリントキー Ed25519 jitsiを用いて会議通話を始める 端末のカメラを使う @@ -739,10 +739,10 @@ \n追加しますか? 続行する… 申し訳ありません、この操作を完了するための外部アプリが見つかりません。 - 他のデバイスから 暗号鍵を再度要求 します。 + 他の端末から 暗号鍵を再度要求 します。 鍵のリクエストが送信されました。 リクエスト送信済 - 鍵をこのデバイスに送信できるように、メッセージを復号化できる他のデバイスで${app_name}を起動してください。 + 鍵をこの端末に送信できるように、メッセージを復号化できる他の端末で${app_name}を起動してください。 %d秒 @@ -877,7 +877,7 @@ サービスを初期化 鍵のバックアップ 鍵のバックアップを使用 - デバイスを認証 + 端末を認証 鍵のバックアップが終了していません。しばらくお待ちください… 会議通話中。 \n%1$s または %2$s として参加 @@ -890,7 +890,7 @@ バックグラウンド同期を行わない 優先同期間隔 %s -\n同期は、デバイスのリソース (バッテリ残量) または状態 (スリープ) に応じて延期される場合があります。 +\n同期は、端末のリソース (バッテリ残量) または状態 (スリープ) に応じて延期される場合があります。 文字入力中通知を送信 文字入力中であることを他の参加者に伝えます。 開封確認メッセージを表示 @@ -911,7 +911,7 @@ パスワード 今ここでサインアウトすると、あなたの暗号化されたメッセージは失われてしまいます 鍵のバックアップは現在処理中です。処理中にサインアウトすると暗号化されたメッセージにアクセスできなくなります。 - 暗号化されたメッセージにアクセスできなくなることを防ぐため、鍵の安全なバックアップはあなたのデバイス全てで有効化してください。 + 暗号化されたメッセージにアクセスできなくなることを防ぐため、鍵の安全なバックアップはあなたの端末全てで有効化してください。 暗号化されたメッセージは不要です 鍵をバックアップしています… 鍵のバックアップを使用 @@ -954,8 +954,8 @@ 名前 公開 誰でもこのルームに参加できるようになります - ルーム一覧 - ルームの一覧へ公開 + ルームディレクトリ + ルームディレクトリへ公開 一般 セキュリティーとプライバシー ヘルプと概要 @@ -1105,7 +1105,7 @@ 他の利用可能な言語 メッセージエディタ 環境設定 - このデバイスを設定 + この端末を設定 セキュアバックアップをリセット セキュアバックアップを設定 管理 @@ -1115,7 +1115,7 @@ %s からの招待 このセッションは正常に検証されました。 概ね完了しました。%s の画面にも同じシールドアイコンが表示されていますか? - 相手ユーザーのデバイスのコードをスキャンし、相互に安全性を検証します + 相手ユーザーの端末のコードをスキャンし、相互に安全性を検証 相手のコードをスキャン スキャンできません 断る @@ -1140,7 +1140,7 @@ ヘッドセット スピーカー 電話 - サウンドデバイスを選択 + サウンド端末を選択 リアルタイム接続を確立できませんでした。 \nホームサーバーの管理者に、通話が正常に動作するためにTURNを設定するようご連絡ください。 再び表示しない @@ -1268,7 +1268,7 @@ 通話が確実に機能させるためには、ホームサーバー(%1$s)の管理者にTURNサーバーの設定を依頼してください。 \n \n代わりに、%2$sのパブリックサーバーを使用することもできますが、信頼性は低く、あなたのIPアドレスがそのサーバーと共有されてしまいます。これは設定から管理することができます。 - ルームのディレクトリ内の全てのルームを表示(露骨なコンテンツのあるルームを含む)する。 + ルームディレクトリの全てのルームを表示(露骨なコンテンツのあるルームを含む)する。 露骨なコンテンツのあるルームを表示 ルームディレクトリ 新着情報 @@ -1473,28 +1473,28 @@ アプリがバックグラウンドにある場合、着信メッセージは通知されません。 ${app_name}は正確な時間に定期的にバックグラウンドで同期します(構成可能)。 \nこれはラジオとバッテリーの使用量に影響し$ {app_name}がイベントをリッスンしていることを示す永続的な通知が表示されます。 - ${app_name}は、デバイスの限られたリソース(バッテリー)を維持する方法でバックグラウンド同期をします。 -\nデバイスの状態によっては、OSによって同期が延期される場合があります。 + ${app_name}は、端末の限られたリソース(バッテリー)を維持する方法でバックグラウンド同期をします。 +\n端末の状態によっては、OSによって同期が延期される場合があります。 LEDの色、振動、音を選択してください… サイレント通知を設定 通話の通知を設定 うるさい通知を設定 アプリはバックグラウンドでホームサーバーに接続する必要がないためバッテリー使用量を減らすことができます 最適化を無視 - 画面をオフにした状態でデバイスのプラグを抜いて一定時間静止したままにすると、デバイスは機内モードになります。 これにより、アプリがネットワークにアクセスできなくなり、ジョブ、同期、および標準のアラームが防止されます。 + 画面をオフにした状態で端末のプラグを抜いて一定時間静止したままにすると、端末は機内モードになります。 これにより、アプリがネットワークにアクセスできなくなり、ジョブ、同期、および標準のアラームが防止されます。 ${app_name}に対してバックグラウンド制限が有効になっています。 \nアプリがバックグラウンドで実行しようとすると積極的に制限され、通知に影響を与える可能性があります。 \n%1$s ${app_name}のバックグラウンド制限は無効になっています。 このテストは、モバイル(WIFIでない)を使用して実行する必要があります。 \n%1$s - デバイスを再起動してもサービスは開始されません。${app_name}が一度開かれるまで通知は届きません。 + 端末を再起動してもサービスは開始されません。${app_name}が一度開かれるまで通知は届きません。 %1$s -\nこのエラーは${app_name}の管理外です。 これはいくつかの理由で発生する可能性があります。 後で再試行すればうまくいくかもしれません。システム設定でGoogle Play Serviceのデータ使用量が制限されていないか、デバイスの時刻が正しいかどうか、もしくはカスタムROMで起こることがあります。 +\nこのエラーは${app_name}の管理外です。 これはいくつかの理由で発生する可能性があります。 後で再試行すればうまくいくかもしれません。システム設定でGoogle Play Serviceのデータ使用量が制限されていないか、端末の時刻が正しいかどうか、もしくはカスタムROMで起こることがあります。 ${app_name}モバイルからこれを行うことはできません ${app_name}はバッテリー最適化の影響を受けません。 制限を無効にする 起動時の開始を有効にする - デバイスを再起動するとサービスが開始されます。 + 端末を再起動するとサービスが開始されます。 サービスの再起動に失敗しました サービスが強制終了され、自動的に再起動されました。 通知サービスの自動再起動 @@ -1514,7 +1514,7 @@ [%1$s] \nこのエラーは、${app_name}の管理外です。スマホにはGoogleアカウントがありません。アカウントマネージャーを開いて、Googleアカウントを追加してください。 %1$s -\nこのエラーは${app_name}の管理外であり、Googleによると、このエラーは、デバイスにFCMに登録されているアプリが多すぎることを示しています。 このエラーは、アプリの数が極端に多い場合にのみ発生するため、平均的なユーザーには影響しません。 +\nこのエラーは${app_name}の管理外であり、Googleによると、このエラーは、端末にFCMに登録されているアプリが多すぎることを示しています。 このエラーは、アプリの数が極端に多い場合にのみ発生するため、平均的なユーザーには影響しません。 ${app_name}はGoogle Playサービスを使用してプッシュメッセージを配信していますが、正しく設定されていないようです: \n%1$s FCMトークンの取得に失敗しました: @@ -1716,7 +1716,7 @@ %d件の招待 - 既にリストに載っているサーバーです + 既に一覧に載っているサーバーです サーバーまたはそのルーム一覧が見つかりません 検索される新しいサーバーの名前を入力します。 新しいサーバーを追加 @@ -1735,8 +1735,8 @@ 非公開 不明のアクセス設定(%s) 誰でもノックができ、メンバーがその参加を承認または拒否できます - 現在のルーム一覧の見え方を取得できません(%1$s)。 - このルームを%1$sのルーム一覧に公開しますか? + 現在のルームディレクトリの見え方を取得できません(%1$s)。 + このルームを%1$sのルームディレクトリに公開しますか? アドレスを非公開にする アドレスを公開 アドレスを設定すれば、他のユーザーがあなたのホームサーバー (%1$s) を通じてこのルームを見つけられるようになります。 @@ -1744,7 +1744,7 @@ 新しい公開アドレス(例: #alias:server) 他の公開アドレスはまだありません。以下から追加できます。 他の公開アドレスはまだありません。 - このルームを%1$sのルーム一覧に公開しますか? + このルームを%1$sのルームディレクトリに公開しますか? \"%1$s\"を非公開にしますか? 公開 手動で新しいアドレスを公開 @@ -1752,7 +1752,7 @@ 公開されたアドレスを通して、どのサーバーのどのユーザーでもこのルームに参加できます。アドレスを公開するには、まずローカルアドレスとして設定する必要があります。 公開アドレス ルームのアドレス - ルームのアドレス及びルーム一覧における可視性を管理できます。 + ルームのアドレス及びルームディレクトリにおける可視性を管理できます。 スペースのアドレスを管理できます。 スペースのアドレス ルームのアドレス @@ -1958,7 +1958,7 @@ 自分の表示名 グループチャットでのメッセージの暗号化 個別チャットでのメッセージの暗号化 - 通知してください + 以下がメッセージに含まれる場合に通知 その他 メンションとキーワード 通知のデフォルト @@ -2224,7 +2224,7 @@ 自分のみ スレッドでディスカッションを整理して管理 %sを待機しています… - このデバイスでスキャン + この端末でスキャン 検証を送信済 手動で検証 このセッションを検証 @@ -2356,4 +2356,5 @@ 復号エラーを自動的に報告する。 変更を有効にするにはアプリケーションの再起動が必要です。 LaTeXによる数学表記を有効にする + 以下が含まれる場合に通知 \ No newline at end of file From 0c1c65112a267fec48f68e3fc0cae605ecf1a4e3 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Fri, 18 Feb 2022 21:27:04 +0000 Subject: [PATCH 159/302] Translated using Weblate (Japanese) Currently translated at 77.5% (2159 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 267 +++++++++++----------- 1 file changed, 134 insertions(+), 133 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 24eb67c67a..7c9b8e9280 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1,6 +1,6 @@ - %1$s: %2$s + %1$s:%2$s %1$sが画像を送信しました。 %1$sがスタンプを送信しました。 %sの招待 @@ -36,17 +36,17 @@ ルームのメンバー全員。 誰でも。 不明 (%s)。 - %1$s がエンドツーエンド暗号化を有効にしました (%2$s) - %1$s がVoIP会議をリクエストしました + %1$sがエンドツーエンド暗号化を有効にしました (%2$s) + %1$sがVoIP会議をリクエストしました VoIP会議が開始されました VoIP会議が終了しました (アバターも変更されました) - %1$s がルーム名を削除しました - %1$s がルームトピックを削除しました - %1$s がプロフィール %2$s を更新しました - %1$s は %2$s にルームに参加するよう招待状を送りました + %1$sがルーム名を削除しました + %1$sがルームトピックを削除しました + %1$sがプロフィール %2$sを更新しました + %1$sは%2$sにルームに参加するよう招待状を送りました %1$sは%2$sの招待を受け入れました - ** 解読できません: %s ** + ** 解読できません:%s ** 送信者の端末からこのメッセージのキーが送信されていません。 修正できませんでした メッセージを送信できません @@ -164,7 +164,7 @@ ダウンロードを停止しますか? アップロードを停止しますか? %d秒 - %1$d分 %2$d秒 + %1$d分%2$d秒 昨日 今日 ルーム名 @@ -177,14 +177,14 @@ ルームを退出 このルームを退出してよろしいですか? 作成 - 接続中 - 切断中 - 待機中 + オンライン + オフライン + アイドル 招待 このルームを退出 検索 %sさんが文字を入力しています… - %1$sさんと %2$sさんが文字を入力しています… + %1$sさんと%2$sさんが文字を入力しています… %1$sさん、%2$sさん他が文字を入力しています… 暗号文を送信… 明るいテーマ @@ -205,7 +205,7 @@ このユーザー名は既に使用されています 削除 参加 - あなたは %s さんに、このルームへ招待されています + あなたは%sさんに、このルームへ招待されています 新しい会話 参加者を追加 1名 @@ -398,7 +398,7 @@ パスワードを初期化するには, アカウントに登録されている電子メールアドレスを入力してください: あなたのアカウントに登録された電子メールアドレスの入力が必要です. 新しいパスワードの入力が必要です。 - %s へ電子メールが送信されました. リンクをたどったら以下をクリックしてください. + %sへ電子メールが送信されました. リンクをたどったら以下をクリックしてください. 電子メールアドレスの確認に失敗しました: 電子メールのリンクをクリックしたことを確認してください パスワードがリセットされました。 \n @@ -555,12 +555,12 @@ ルームの暗号鍵をエクスポート 検証 通話 - 通知あり(音量大) - 通知あり(音量小) + 通知あり(音量大) + 通知あり(サイレント) 不具合の報告 開封確認メッセージのリスト ダウンロードファイルに保存しますか? - この招待はこのアカウントに関連付けられていない %s に送信されました。 + この招待はこのアカウントに関連付けられていない%sに送信されました。 \n別のアカウントでログインするか、このメールを自分のアカウントに追加してください。 あなたは%sにアクセスしようとしています。ディスカッションに参加しますか? ルーム @@ -571,7 +571,7 @@ ユーザーディレクトリ (%s) Matrixユーザーのみ ユーザーIDで招待 - 1つまたは複数のメールアドレスか、Matrix IDを入力してください + 1つまたは複数のメールアドレスか、Matrix IDを入力してください 信用する 信用しない フィンガープリント (%s): @@ -608,7 +608,7 @@ この通知の対象を削除してよろしいですか? %1$s %2$sを削除してよろしいですか? コード - %s はこのルームのタイムラインのある箇所を読み込もうとしましたが、見つかりませんでした。 + %sはこのルームのタイムラインのある箇所を読み込もうとしましたが、見つかりませんでした。 イベント情報 ユーザーID Curve25519 固有鍵 @@ -631,16 +631,16 @@ 公開のルームを表示するホームサーバーを入力してください サーバー名 %sサーバー上の全てのルーム - 全てのローカルの %s ルーム - メッセージが未送信です。今 %1$s または %2$s しますか? - 不明な端末が存在しているため、メッセージを送ることができませんでした。今 %1$s または %2$s しますか? + 全てのローカルの%sルーム + メッセージが未送信です。今%1$sまたは%2$sしますか? + 不明な端末が存在しているため、メッセージを送ることができませんでした。今%1$sまたは%2$sしますか? 要求されたフィンガープリントキー Ed25519 jitsiを用いて会議通話を始める - 端末のカメラを使う + 端末のカメラを使用 警告! ビデオ会議は開発中であり、確実でない可能性があります。 コマンドエラー - 認識されないコマンド: %s + 認識されないコマンド:%s 音量大 暗号化されたメッセージ @@ -657,7 +657,7 @@ ビデオ通話を開始してよろしいですか? グループリスト ユーザーをブロックすると、ユーザーはこのルームから削除され、二度と参加できなくなります。 - 全てのメッセージ (大音量) + 全てのメッセージ (音量大) 全てのメッセージ ミュート ホーム画面にショートカットを作成 @@ -691,7 +691,7 @@ 管理者はこのコミュニティーの詳細を規定していません。 あなたは%2$sによって%1$sから除外されました あなたは%2$sによって%1$sへの参加を禁止されました - 理由: %1$s + 理由:%1$s 再参加 端末を振って不具合を報告 @@ -713,7 +713,7 @@ %dルーム - %2$s に %1$s ルーム見つかりました + %2$sに%1$sルーム見つかりました ルームの履歴を消す アバター @@ -755,10 +755,10 @@ %d日 - 現在 %1$s - %2$s 前 %1$s + 現在%1$s + %2$sより%1$s "%1$s、 " - %1$s と %2$s + %1$sと%2$s %1$s %2$s 暗号化された返信を送信… 返信を送信 (未暗号化)… @@ -792,7 +792,7 @@ %dルーム - %2$s件 中 %1$s件 + %2$s件中%1$s件 %d個のウィジェットが使用中 @@ -820,7 +820,7 @@ %dルーム アバターを読み込み - %1$s ホームサーバーを使用し続けるには、利用規約を読み、同意する必要があります。 + %1$のホームサーバーを使用し続けるには、利用規約を読み、同意する必要があります。 エラー アバターに通知を表示 今すぐ見る @@ -845,8 +845,8 @@ このホームサーバーはリソース制限の1つを超過しています。 このホームサーバーは月間アクティブユーザー上限に達しているため、 ユーザーがログインできなくなることがあります このホームサーバーは月間アクティブユーザー上限に達しています。 - この上限を上げるには %s してください。 - このサービスを使い続けるには %s してください。 + この上限を上げるには%sしてください。 + このサービスを使い続けるには%sしてください。 最初にルームのメンバーのみを読み込むことでパフォーマンスを向上。 あなたのホームサーバーはルームのメンバーの簡易読み込みをサポートしていません。後で試してください。 ルームのメンバーの簡易読み込み @@ -859,7 +859,7 @@ 常に エラーの場合のみ %1$s: - %1$s: %2$s + %1$s:%2$s +%d %d+ 展開 @@ -869,7 +869,7 @@ 了承 このホームサーバーの方針を閲覧し承認してください: 通話設定画面 - 着信に${app_name}の既定の着信音を使う + 着信に${app_name}の既定の着信音を使用 着信音 着信音を選んでください: 追い出す @@ -880,7 +880,7 @@ 端末を認証 鍵のバックアップが終了していません。しばらくお待ちください… 会議通話中。 -\n%1$s または %2$s として参加 +\n%1$sまたは%2$sとして参加 音声 ビデオ 詳細な通知設定 @@ -891,7 +891,7 @@ 優先同期間隔 %s \n同期は、端末のリソース (バッテリ残量) または状態 (スリープ) に応じて延期される場合があります。 - 文字入力中通知を送信 + 入力中通知を送信 文字入力中であることを他の参加者に伝えます。 開封確認メッセージを表示 開封確認メッセージをクリックすると詳細なリストを確認できます。 @@ -903,7 +903,7 @@ メディア シャッター音を再生 公開端末名 (会話を行うユーザーに表示されます) - 音なし + サイレント パスワードを表示 パスワードを隠す 新しいパスワード @@ -964,7 +964,7 @@ 会話を検索… Matrix ID から追加 ユーザー名または ID で検索… - 全てのメッセージ (大音量) + 全てのメッセージ (音量大) 全てのメッセージ メンションのみ ミュート @@ -996,10 +996,10 @@ カスタム 招待者 ユーザー - %1$s の管理者 - %1$s のモデレーター - %1$s のデフォルトユーザー - %2$s のカスタム (%1$d) + %1$sの管理者 + %1$sのモデレーター + %1$sのデフォルトユーザー + %2$sのカスタム (%1$d) タイムライン エンドツーエンド暗号化を有効にする… 暗号化を有効にする @@ -1050,10 +1050,10 @@ レビュー 待機しています… サムネイルを暗号化しています… - サムネイルを送信しています (%1$s / %2$s) + サムネイルを送信しています (%1$s/%2$s) ファイルを暗号化しています… - ファイルを送信しています (%1$s / %2$s) - ファイル %1$s をダウンロードしています… + ファイルを送信しています (%1$s/%2$s) + ファイル %1$sをダウンロードしています… ファイル 連絡先 カメラ @@ -1112,16 +1112,16 @@ セキュアバックアップ ルームを作成しています… 招待されています - %s からの招待 + %sからの招待 このセッションは正常に検証されました。 - 概ね完了しました。%s の画面にも同じシールドアイコンが表示されていますか? + 概ね完了しました。%sの画面にも同じシールドアイコンが表示されていますか? 相手ユーザーの端末のコードをスキャンし、相互に安全性を検証 相手のコードをスキャン スキャンできません 断る 検証リクエスト 通話の開始前に確認 - 意図しない通話を阻止 + 意図しない通話を防止 お使いの端末は脆弱性のある古いTLSセキュリティープロトコルを使用しています、このセキュリティーでは接続できません SSLエラー。 SSLエラー:相手のアイデンティティが認証されていません。 @@ -1172,7 +1172,7 @@ QR コード QR コードによる追加 コードを共有 - ${app_name} で会話しましょう: %s + ${app_name} で会話しましょう:%s 友達を招待 既知のユーザー 無効なQRコード (無効な URI)! @@ -1196,7 +1196,7 @@ 1つ以上のテストが失敗しました。調査用の不具合報告を送信してください。 1つ以上のテストが失敗しました。提案された修正を試してください。 基本的な診断はOKです。 それでも通知が届かない場合は、調査用の不具合報告を送信してください。 - 実行しています… (%1$dの %2$d) + 実行しています…(%1$dの%2$d) テストを実行 診断トラブルシューティング イベントごとの通知の優先順位 @@ -1232,7 +1232,7 @@ ブロックを解除すると、ユーザーは再びルームに参加できるようになります。 禁止されたユーザー 禁止の理由 - ユーザーの禁止を解除 + ユーザーのブロックを解除 このユーザーはルームから除去されます。 \n \n再参加を防ぐためには、除去する代わりにブロックする必要があります。 @@ -1246,7 +1246,7 @@ \n \nこの動作は、設定からいつでも元に戻すことができます。 ユーザーを無視 - 広角 + 降格 あなたは自分自身を降格させようとしているため、今後、この変更を元に戻すことはできなくなります。あなたがルームの中で最後の特権ユーザーである場合、特権を再取得することはできません。 降格しますか? 招待をキャンセル @@ -1276,8 +1276,8 @@ 非公開 切り替える 加える - %1$sはエンドツーエンド暗号化 (認識されていないアルゴリズム%2$s) をオンにしました。 - エンドツーエンド暗号化 (認識されていないアルゴリズム%1$s) をオンにしました。 + %1$sはエンドツーエンド暗号化(認識されていないアルゴリズム %2$s)をオンにしました。 + エンドツーエンド暗号化(認識されていないアルゴリズム %1$s)をオンにしました。 会話を始める %1$sがエンドツーエンド暗号化をオンにしました。 エンドツーエンド暗号化をオンにしました。 @@ -1288,7 +1288,7 @@ ここへのゲストの入室を許可しました。 %1$sはここにゲストが参加することを許可しました。 ゲストにルームへの参加を許可しました。 - %1$s がゲストにルームへの参加を許可しました。 + %1$sがゲストにルームへの参加を許可しました。 システムデフォルト このルームのメインおよび代替のアドレスを変更しました。 このルームの代替アドレスを変更しました。 @@ -1304,10 +1304,10 @@ このルームのアドレスの%1$sを削除しました。 - %1$sの招待を取り消しました。理由:%2$s - %1$sの招待を受諾しました%2$。理由:%2$s - %1$sのルームへの招待を取り消しました。理由:%2$s - %1$sにルームへの招待状を送りました。理由:%2$s + %1$sの招待を取り消しました。理由:%2$s + %1$sの招待を受諾しました%2$。理由:%2$s + %1$sのルームへの招待を取り消しました。理由:%2$s + %1$sにルームへの招待状を送りました。理由:%2$s VoIPカンファレンスをリクエストしました このルームのサーバーのアクセス制御リストを変更しました。 このルームのサーバーアクセス制御リストを設定しました。 @@ -1317,28 +1317,28 @@ 通話に応答しました。 通話を設定するためのデータを送信しました。 このルームのアドレスを変更しました。 - %1$s はこのルームのメインおよび代替アドレスを変更しました。 - %1$s がこのルームのアドレスを変更しました。 + %1$sはこのルームのメインおよび代替アドレスを変更しました。 + %1$sがこのルームのアドレスを変更しました。 %1$sはこのルームの代替アドレスを変更しました。 - %1$s がこのルームの代替アドレス%2$sを削除しました。 + %1$sがこのルームの代替アドレス%2$sを削除しました。 - %1$s はこのルームの代替アドレス%2$sを追加しました。 + %1$sはこのルームの代替アドレス%2$sを追加しました。 %1$sがこのルームのメインアドレスを削除しました。 %1$sがこのルームのメインアドレスを%2$sに設定しました。 - %1$sはこのルームのアドレスとして %2$sを追加し%3$sを削除しました。 + %1$sはこのルームのアドレスとして%2$sを追加し%3$sを削除しました。 - %1$s はこのルームのアドレスの%2$sを削除しました。 + %1$sはこのルームのアドレスの%2$sを削除しました。 このルームのアドレスとして%1$sが追加されました。 - %1$sが%2$s にルームへの招待を送りました。理由:%3$s - %1$sが%2$sのルームへの招待を取り消しました。理由:%3$s - %1$sが %2$sの招待を承諾しました。理由:%3$s - %1$sは%2$sの招待を取り下げました。理由:%3$s + %1$sが%2$sにルームへの招待を送りました。理由:%3$s + %1$sが%2$sのルームへの招待を取り消しました。理由:%3$s + %1$sが %2$sの招待を承諾しました。理由:%3$s + %1$sは%2$sの招待を取り下げました。理由:%3$s %1$sはこのルームのアドレスとして%2$sを追加しました。 @@ -1350,25 +1350,25 @@ ・%sに一致するサーバーは禁止されています。 %sがこのルームのサーバーアクセス制御リストを設定しました。 %sがここをアップグレードしました。 - %s がこのルームをアップグレードしました。 + %sがこのルームをアップグレードしました。 エンドツーエンド暗号化をオンにしました (%1$s) あなたは今後のメッセージを%1$sに見えるように設定しました 今後のルーム履歴を%1$sに見えるように設定しました - %1$s は今後のメッセージを %2$sに見えるように設定しました + %1$sは今後のメッセージを%2$sに見えるように設定しました %sが通話を設定するためのデータを送信しました。 通話をしました。 ビデオ通話をしました。 - あなたが%1$sを永久追放しました。理由: %2$s - %1$sが%2$sを永久追放しました。理由: %3$s - あなたが%1$sの禁止を解除しました。理由: %2$s - %1$sが%2$sの禁止を解除しました。理由: %3$s - あなたは%1$sを除去しました。理由: %2$s - %1$sが%2$sを除去しました。理由: %3$s - あなたは招待を拒否しました。理由: %1$s - %1$s は招待を拒否しました。理由: %2$s - 退出しました。理由: %1$s - %1$sが退出しました。理由: %2$s - あなたがこのルームを退出しました。理由: %1$s + あなたが%1$sをブロックしました。理由:%2$s + %1$sが%2$sをブロックしました。理由:%3$s + あなたが%1$sのブロックを解除しました。理由:%2$s + %1$sが%2$sのブロックを解除しました。理由:%3$s + あなたは%1$sを除去しました。理由:%2$s + %1$sが%2$sを除去しました。理由:%3$s + あなたは招待を拒否しました。理由:%1$s + %1$sは招待を拒否しました。理由:%2$s + 退出しました。理由:%1$s + %1$sが退出しました。理由:%2$s + あなたがこのルームを退出しました。理由:%1$s 初期同期: \n退出したルームをインポートしています 初期同期: @@ -1376,16 +1376,16 @@ 初期同期: \n会話を読み込んでいます \n多くのルームに参加している場合、読み込みに時間がかかるかもしれません - %1$sがこのルームを退出しました。理由: %2$s - あなたがこのルームに参加しました。理由: %1$s - %1$sがこのルームに参加しました。理由: %2$s - あなたがこのルームに参加しました。理由: %1$s - %1$sがこのルームに参加しました。理由: %2$s - %1$sがあなたを招待しました。 理由: %2$s - あなたが%1$sを招待しました。 理由: %2$s - %1$sが%2$sを招待しました。 理由: %3$s - あなたの招待です。理由: %1$s - %1$sの招待です。理由: %2$s + %1$sがこのルームを退出しました。理由:%2$s + あなたがこのルームに参加しました。理由:%1$s + %1$sがこのルームに参加しました。理由:%2$s + あなたがこのルームに参加しました。理由:%1$s + %1$sがこのルームに参加しました。理由:%2$s + %1$sがあなたを招待しました。 理由:%2$s + あなたが%1$sを招待しました。 理由:%2$s + %1$sが%2$sを招待しました。 理由:%3$s + あなたの招待です。理由:%1$s + %1$sの招待です。理由:%2$s 送信キューのクリア メッセージを送っています… メッセージを送りました @@ -1426,11 +1426,11 @@ あなたは%1$sウィジェットを変更しました %1$sは%2$sウィジェットを変更しました あなたは%1$sウィジェットを削除しました - %1$sが %2$sウィジェットを削除しました + %1$sが%2$sウィジェットを削除しました あなたは%1$sウィジェットを追加しました - あなたは %1$sの招待を受けました - %1$sが %2$sウィジェットを追加しました - ルーム名を変更しました: %1$s + あなたは%1$sの招待を受けました + %1$sが%2$sウィジェットを追加しました + ルーム名を変更しました:%1$s あなたは%1$sの招待を取り消しました %1$sが%2$sの招待を取り消しました あなたは%1$sを招待しました @@ -1438,12 +1438,12 @@ %1$sが%2$sのルームへの招待を取り消しました %1$sが%2$sを招待しました あなたは%1$sにルームへの招待を送りました - メッセージが%1$sによって削除されました [理由: %2$s] - メッセージが削除されました [理由: %1$s] + メッセージが%1$sによって削除されました[理由:%2$s] + メッセージが削除されました[理由:%1$s] %1$sがメッセージを削除しました メッセージを削除 ルームのアバターを削除しました - %1$s がルームのアバターを削除しました + %1$sがルームのアバターを削除しました ルームのトピックを削除しました ルーム名を削除しました 許可を与える @@ -1476,9 +1476,9 @@ ${app_name}は、端末の限られたリソース(バッテリー)を維持する方法でバックグラウンド同期をします。 \n端末の状態によっては、OSによって同期が延期される場合があります。 LEDの色、振動、音を選択してください… - サイレント通知を設定 + 通知(サイレント)を設定 通話の通知を設定 - うるさい通知を設定 + 通知(音量大)を設定 アプリはバックグラウンドでホームサーバーに接続する必要がないためバッテリー使用量を減らすことができます 最適化を無視 画面をオフにした状態で端末のプラグを抜いて一定時間静止したままにすると、端末は機内モードになります。 これにより、アプリがネットワークにアクセスできなくなり、ジョブ、同期、および標準のアラームが防止されます。 @@ -1528,9 +1528,9 @@ • %sに一致するサーバーが禁止リストから削除されました。 • %sに一致するサーバーは禁止されています。 - %1$sや %2$sそれに%3$dに他の人も読みました + %1$s、%2$s、他%3$d人のユーザーが読みました - %1$sや %2$sそれに%3$sが読みました + %1$s、%2$s、%3$sが読みました メッセージをマークダウンとして解釈せずにプレーンテキストとして送信 ファイルとして保存 共有 @@ -1564,13 +1564,13 @@ 新しいイベント 不明なIP - キー %1$dと%2$dのインポートに成功。 + キー%1$dと%2$dのインポートに成功。 キーバックアップを管理 キーのエクスポートに成功しました 選択 選択 - 詳細情報: %s + 詳細情報:%s ローカルアドレスを追加 このルームにはローカルアドレスがありません アドレス \"%1$s\" を削除しますか? @@ -1578,13 +1578,13 @@ これがメインアドレスです 電話番号の認証中にエラーが発生しました。 リンクを共有 - %s に招待 + %sに招待 Eメールで招待 詳細 人を招待 とにかく参加 ルームを追加 - %s はあなたを招待しています + %sはあなたを招待しています このルームでグループ通話をする権利がありません オーディオミーティングを開始 安全バックアップを設定 @@ -1678,12 +1678,12 @@ ”%s”とのコマンドはいくつかのパラメータが欠けているか不正です。 この機能はメッセージを録音するために第三者のアプリを必要とします。 新しいセッションが暗号鍵を要請しています。 -\nセッション名: %1$s -\n最後のオンライン時刻: %2$s +\nセッション名:%1$s +\n最後のオンライン時刻:%2$s \n新たにログインして新しいセッションを開始しなかった場合、この要求を無視してください。 未検証のセッションが暗号鍵を要請しています。 -\nセッション名: %1$s -\n最後のオンライン時刻: %2$s +\nセッション名:%1$s +\n最後のオンライン時刻:%2$s \n新たにログインして新しいセッションを開始しなかった場合、この要求を無視してください。 暗号鍵共有要請 カスタムカメラ画面の代わりにシステムカメラを使用します。 @@ -1706,12 +1706,12 @@ **送信に失敗 - ルームを開いてください 新しい招待 %1$sと%2$s - %1$s に %2$s と %3$s + %1$sに%2$sと%3$s %d件の通知 - %1$s: %2$d件のメッセージ + %1$s:%2$d件のメッセージ %d件の招待 @@ -1767,7 +1767,7 @@ ホームサーバーAPIのURL 復旧用のメールアドレスを設定します。後からオプションでメールアドレスや電話番号を使用して知人に見つけてもらえるようにできます。 電話番号を設定して、後からオプションで知人に見つけてもらえるようにできます。 - %s を使用してみてください + %sを使用してみてください アクセスを取り消す 表示 このルーム内のメッセージはエンドツーエンド暗号化されています。 @@ -1819,7 +1819,7 @@ ここが%sとのダイレクトメッセージのスタート地点です。 変更履歴はありません メッセージの変更履歴 - ファイル %1$s をダウンロードしました! + ファイル %1$sをダウンロードしました! ビデオの圧縮%d%% 画像を圧縮しています… 暗号化されたルームで完全な履歴を表示 @@ -1847,7 +1847,7 @@ ファイル\"%1$s\"からe2eキーをインポートします。 キーのバックアップデータの取得中にエラーが発生しました 信頼情報の取得中にエラーが発生しました - ルームが作成されましたが、一部の招待が送信されていません。理由: + ルームが作成されましたが、一部の招待が送信されていません。理由: \n \n%s ルームの設定 @@ -1899,7 +1899,7 @@ このルームを含むスペースを知る このルームにアクセスできるスペースを決定します。スペースが選択されるとそのメンバーはルーム名を見つけて参加できます。 検証がキャンセルされました。 -\n理由:%s +\n理由:%s 相手が検証をキャンセルしました。 \n%s リクエストはキャンセルされました @@ -1922,7 +1922,7 @@ 短い文字列を比較して検証します。 認証が無効または期限切れのため、ログアウトされました。 構成を使用 - ${app_name}がuserIdドメイン\"%1$s \"のカスタムサーバー構成を検出しました。 + ${app_name}がuserIdドメイン\"%1$s\"のカスタムサーバー構成を検出しました。 \n%2$s サーバーオプションをおまかせする 無効なホームサーバーディスカバリーレスポンス @@ -1932,9 +1932,9 @@ 暗号化されたメッセージを失いません バックアップ (%s) のtrust infoの取得に失敗しました。 セッションの暗号化が有効になっていません - これを使用するとデータを %sと共有します。 - %1$s: %2$s %3$s - %1$s: %2$s + これを使用するとデータを%sと共有します。 + %1$s:%2$s %3$s + %1$s:%2$s あなたが知らないかもしれない他のスペースやルーム このルームを見つけて参加できるか決める。 タップしスペースを編集 @@ -1996,12 +1996,12 @@ 電話番号を追加すると、発見可能に設定する電話番号を選択できるようになります。 メールアドレスを追加すると、発見可能に設定するメールアドレスを選択できるようになります。 現在、IDサーバーを使用していません。あなたの知っている連絡先を発見したり、その連絡先から発見されるようにするには、以下を設定してください。 - あなたは現在 %1$sを使って連絡先を見つけたり、連絡先から見つけられるようにしています。 + あなたは現在%1$sを使って連絡先を見つけたり、連絡先から見つけられるようにしています。 IDサーバーを変更 IDサーバーの設定 IDサーバーの切断 IDサーバー - ボット、ブリッジ、ウィジェット、ステッカーパックを使う + ボット、ブリッジ、ウィジェット、ステッカーパックを使用 他の人が見つけられるように 規約を確認 利用規約 @@ -2056,7 +2056,7 @@ %sとのビデオ通話 呼び出しています… ホームサーバーを選択 - %s のURLにあるホームサーバーに接続できません。リンクをチェックするか、手動でホームサーバーを選択してください。 + %sのURLにあるホームサーバーに接続できません。リンクをチェックするか、手動でホームサーバーを選択してください。 後で スペース スレッドから @@ -2069,14 +2069,14 @@ コンテンツが報告されました ヘルプとサポート ヘルプ - ${app_name} ポリシー + ${app_name}のポリシー ここ キーワードを追加 自分のスレッド 全てのスレッド ユーザーを自動的に招待 ユーザー - このユーザーの禁止を解除すると、そのユーザーはスペースに再び参加できるようになります。 + このユーザーのブロックを解除すると、そのユーザーはスペースに再び参加できるようになります。 このルームを招待者のみ参加可能に設定しました。 低優先度から削除 低優先度に追加 @@ -2216,9 +2216,9 @@ 添付ファイルの取得中にエラーが発生しました。 キーバックアップのバナーを閉じる キーワードに「%s」を含めることはできません - %sへのメール通知を有効にする - ヒント:メッセージを長押しして「%s」を使う。 - スレッドを使うと、会話のテーマを保ったり、会話を追跡したりするのが容易になります。 + %s へのメール通知を有効にする + ヒント:メッセージを長押しして「%s」を選択。 + スレッドを用いると、会話のテーマを保ったり、会話を追跡したりするのが容易になります。 あなたの非公開スペース あなたの公開スペース 自分のみ @@ -2341,7 +2341,7 @@ 連絡先を発見するには、連絡先のデータをあなたのIDサーバーに送信する必要があります。 \n \nプライバシーの保護のため、データは送信前にハッシュ化されます。この情報を送信することに同意しますか? - メールアドレスと電話番号を %s に送信 + メールアドレスと電話番号を%sに送信 このIDサーバーはポリシーを提供していません IDサーバーのポリシーを隠す IDサーバーのポリシーを表示 @@ -2357,4 +2357,5 @@ 変更を有効にするにはアプリケーションの再起動が必要です。 LaTeXによる数学表記を有効にする 以下が含まれる場合に通知 + アップグレードすると、このルームの新しいバージョンが作成されます。今ある全てのメッセージは、アーカイブしたルームに残ります。 \ No newline at end of file From 0b0ca4f92f8968942f05af2b3bcd6adf65e4937d Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 10:25:19 +0000 Subject: [PATCH 160/302] Translated using Weblate (Japanese) Currently translated at 77.5% (2159 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 7c9b8e9280..9517c5aedc 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -386,7 +386,7 @@ 電話番号が入力されていません 電子メールアドレスまたは電話番号が入力されていません 接続先サーバーを指定する(追加設定) - トークンが正しくありません + 不正なトークン メールと電話番号の同時登録はまだシステムが対応できませんが、電話番号だけの登録は可能です。 \n \n設定からプロフィールにメールアドレスを追加できます。 @@ -761,7 +761,7 @@ %1$sと%2$s %1$s %2$s 暗号化された返信を送信… - 返信を送信 (未暗号化)… + 返信を送る(未暗号化)… %d個選択済 From 540a410941a5d8819a332ddf3fc4204eea9a208f Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 12:51:40 +0000 Subject: [PATCH 161/302] Translated using Weblate (Japanese) Currently translated at 77.6% (2162 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 79 ++++++++++++----------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 9517c5aedc..4ca27087e7 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -207,10 +207,10 @@ 参加 あなたは%sさんに、このルームへ招待されています 新しい会話 - 参加者を追加 + メンバーを追加 1名 端末 - 権限を一般参加者へ変更 + 権限を一般メンバーへ変更 権限を司会者へ変更 権限を管理者へ変更 ここに送信文を入力 (暗号なし)… @@ -221,7 +221,7 @@ ファイルが見つかりません あなたはこのルームで発言する権限がありません。 ルームの詳細 - 参加者 + メンバー ファイル 設定 お気に入り @@ -306,15 +306,15 @@ ルームへの参加 ルームの履歴の可視範囲 ルームの履歴を読める人は\? - ルームへ参加できる人は\? + 誰がルームにアクセスできますか? 誰でも - 参加者のみ (この設定を選択した時点から) - 参加者のみ (招待を送った時点から) - 参加者のみ (参加した時点から) - このルームに招待された人だけ - ルームのリンクを知る人なら誰でも(ゲストユーザーを除く) - ルームのリンクを知る人なら誰でも(ゲストユーザーも含む) - 再入室禁止された参加者 + メンバーのみ(この設定を選択した時点から) + メンバーのみ(招待を送った時点から) + メンバーのみ(参加した時点から) + 招待された人のみ + ルームのリンクを知っている人なら誰でも(ゲストユーザーを除く) + ルームのリンクを知っている人なら誰でも(ゲストユーザーを含む) + 再入室禁止されたメンバー 拡張設定 このルームのサーバー内識別ID ラボ @@ -322,13 +322,13 @@ エンドツーエンド暗号化 エンドツーエンド暗号化を使用中 暗号を有効にするためにはログアウトする必要があります. - 認証された端末のみで暗号化 + 検証済のセッションに対してのみ暗号化 このセッションでは、このルームの未検証のセッションに対して暗号化されたメッセージを送信しない。 新しいアドレス (記入例 #foo:matrix.org) このルームにはローカルアドレスがありません 住所表記 - 住所表記が正しくありません - \'%s\' は正しくない形式の住所表記です + エイリアスのフォーマットが正しくありません + \'%s\'はエイリアスの正しいフォーマットではありません このルームのメインアドレスが設定されていません。 メインアドレスの警告 メインアドレスとして設定 @@ -430,8 +430,8 @@ ダイレクトメッセージ 再入室禁止 再入室禁止解除 - この参加者の発言を全て非表示 - この参加者の発言を全て表示 + このメンバーの発言を全て非表示 + このメンバーの発言を全て表示 指名して呼掛け ユーザーID, 表示名, 電子メールアドレス 接続端末一覧を表示 @@ -442,10 +442,10 @@ ログアウト 無視 招待中 - 参加者 - 参加者を検索 + メンバー + メンバーを検索 結果なし - 参加者 + メンバー ファイル ルーム ディレクトリを見る @@ -477,7 +477,7 @@ このルームへのリンクを作成するには、アドレスが必要です。 このルームは暗号化されています。 このルームは暗号化されていません。 - 暗号化を有効にします + 暗号化を有効にする \n(警告: 有効後にこれを無効にすることはできません!) ディレクトリ 外観 @@ -543,7 +543,7 @@ 端末の検証 不明な端末 このセッションでは、未検証のセッションに対して暗号化されたメッセージを送信しない - 認証済み端末に対してのみ暗号化 + 認証済端末に対してのみ暗号化 インポート ローカルファイルからキーをインポート ルームキーをインポート @@ -680,7 +680,7 @@ コミュニティーID ホーム - 参加者 + メンバー ルーム ユーザーがいません ルーム @@ -697,11 +697,11 @@ %dメンバーシップの変更 - 参加者を表示 + メンバーを表示 見出しを開く 同期しています… - %d名の参加者 + %d名のメンバー %d名 @@ -814,7 +814,7 @@ Markdown書式の入/切 Matrixアプリの管理を修正するには - %d名の参加者 + %d名のメンバー %dルーム @@ -892,7 +892,7 @@ %s \n同期は、端末のリソース (バッテリ残量) または状態 (スリープ) に応じて延期される場合があります。 入力中通知を送信 - 文字入力中であることを他の参加者に伝えます。 + 文字入力中であることを他のメンバーに伝えます。 開封確認メッセージを表示 開封確認メッセージをクリックすると詳細なリストを確認できます。 エンター入力でメッセージを送信 @@ -939,8 +939,8 @@ とどまる 編集 返信 - 削除済みのメッセージ - 削除済みのメッセージを表示 + メッセージが削除されました + 削除済のメッセージを表示 削除されたメッセージの代わりに削除されたという通知を表示します。 ユーザーによって削除されたイベント 新しいルームを作成 @@ -960,7 +960,7 @@ セキュリティーとプライバシー ヘルプと概要 ダイレクトメッセージ - (編集済み) + (編集済) 会話を検索… Matrix ID から追加 ユーザー名または ID で検索… @@ -986,7 +986,7 @@ ルームの設定 通知 - %1$d 人の参加者 + %1$d 人のメンバー アップロード ルームを退出 @@ -1725,9 +1725,9 @@ セッションの公開名は会話中の相手に閲覧できます ルームのバージョン - banされたユーザー%d人 + ブロックされたユーザー%d人 - このルームのあるスペースの参加者は誰でも発見し参加できます。ルームをスペースに追加できるのは、ルームの管理者だけです。 + このルームのあるスペースのメンバーは誰でも発見し参加できます。ルームをスペースに追加できるのは、ルームの管理者だけです。 スペースのメンバーのみ 誰でもルームを発見し参加できます 公開 @@ -1896,7 +1896,7 @@ セッションはそのトランザクションについて知りません 検証プロセスがタイムアウトしました ユーザーが検証をキャンセルしました - このルームを含むスペースを知る + このルームを含む参加済のスペース このルームにアクセスできるスペースを決定します。スペースが選択されるとそのメンバーはルーム名を見つけて参加できます。 検証がキャンセルされました。 \n理由:%s @@ -1914,8 +1914,8 @@ 検証リクエストを受信しました。 相手の画面に次の番号が表示されていることを確認して、このセッションを確認します 相手の画面に次の絵文字が表示されることを確認して、このセッションを確認します - このセッションを検証すると、信頼済みとしてマークされ、自分も相手に信頼済みとしてマークされます。 - このセッションを検証して、信頼済みとしてマークします。やり取りの前に検証することで、より安全にメッセージすることができます。 + このセッションを検証すると、信頼済としてマークされ、自分も相手に信頼済としてマークされます。 + このセッションを検証して、信頼済としてマークします。相手のセッションを信頼すると、さらに安心してエンドツーエンド暗号化を使用することができます。 入力された検証要求 検証を開始します 最大限のセキュリティーを確保するために、これを行うか、別の信頼できる通信手段を用いることをお勧めします。 @@ -1936,12 +1936,12 @@ %1$s:%2$s %3$s %1$s:%2$s あなたが知らないかもしれない他のスペースやルーム - このルームを見つけて参加できるか決める。 + 誰がこのルームを検索し、参加できるか決める。 タップしスペースを編集 スペースを選択 アクセス可能なスペース スペースのメンバーに発見とアクセスを許可します。 - スペース%sのメンバーが検索、プレビュー、参加できます。 + スペース %s のメンバーが検索、プレビュー、参加できます。 非公開(招待のみ) デフォルトのメディアソース デフォルトの圧縮 @@ -1971,7 +1971,7 @@ デフォルトで使いもう尋ねない キー共有リクエストの履歴を送信 結果がありません - 自分で電話をかけることはできません。参加者が招待を受け入れるのを待ちます + 自分で電話をかけることはできません。メンバーが招待を受け入れるのを待ちます ミーティングはJitsiのセキュリティーとパーミッションポリシーを使用します。会議中は、現在ルームにいる全ての人に招待状が表示されます。 権限がありません 音声メッセージを送信するには、マイクの権限を許可してください。 @@ -2358,4 +2358,7 @@ LaTeXによる数学表記を有効にする 以下が含まれる場合に通知 アップグレードすると、このルームの新しいバージョンが作成されます。今ある全てのメッセージは、アーカイブしたルームに残ります。 + 誰がアクセスできますか? + 通知は%1$sで管理できます。 + 暗号化されたルームでのメンションとキーワードによる通知は、携帯端末では利用できません。 \ No newline at end of file From 821913788d8609f564970a3b72b7c23198f73a60 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 13:18:34 +0000 Subject: [PATCH 162/302] Translated using Weblate (Japanese) Currently translated at 77.7% (2165 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 4ca27087e7..99988c650b 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -303,7 +303,7 @@ なし 参加と可視範囲 ルームディレクトリへ公開 - ルームへの参加 + ルームへのアクセス ルームの履歴の可視範囲 ルームの履歴を読める人は\? 誰がルームにアクセスできますか? From 22369717b5f11493719d0c48661a2accaa99b822 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sat, 19 Feb 2022 13:17:20 +0000 Subject: [PATCH 163/302] Translated using Weblate (Japanese) Currently translated at 77.7% (2165 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 99988c650b..0ce844ca66 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2358,7 +2358,10 @@ LaTeXによる数学表記を有効にする 以下が含まれる場合に通知 アップグレードすると、このルームの新しいバージョンが作成されます。今ある全てのメッセージは、アーカイブしたルームに残ります。 - 誰がアクセスできますか? + 誰にアクセスさせますか? 通知は%1$sで管理できます。 暗号化されたルームでのメンションとキーワードによる通知は、携帯端末では利用できません。 + ユーザーを無視し、そのメッセージを非表示にします + %sとのコマンドは認識されていますが、スレッドではサポートされていません。 + 誰でもこのスペースを発見し参加できます \ No newline at end of file From 0da00efa8ac7fee7f29b09ca55f853c38486db7d Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sat, 19 Feb 2022 13:33:48 +0000 Subject: [PATCH 164/302] Translated using Weblate (Japanese) Currently translated at 78.3% (2181 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 0ce844ca66..d64895bc74 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2364,4 +2364,9 @@ ユーザーを無視し、そのメッセージを非表示にします %sとのコマンドは認識されていますが、スレッドではサポートされていません。 誰でもこのスペースを発見し参加できます + 法律関連 + ユーザーに関する情報を表示します + この部屋においてのみアバターを変更します + この部屋においてのみ表示名を変更します + ユーザーの無視を解除し、これからのメッセージを表示します \ No newline at end of file From e3ca25c4f5c75186fdd31e21383f5b4f13126e55 Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Sat, 19 Feb 2022 13:32:11 +0000 Subject: [PATCH 165/302] Translated using Weblate (Japanese) Currently translated at 78.3% (2181 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index d64895bc74..85c7ebd817 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2369,4 +2369,7 @@ この部屋においてのみアバターを変更します この部屋においてのみ表示名を変更します ユーザーの無視を解除し、これからのメッセージを表示します + 続行するには%sを入力してください + リカバリーパスフレーズ + 有効なリカバリーキーではありません \ No newline at end of file From e9c10d719d12d16a20b3393ca85fea61a9f9867d Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 13:31:48 +0000 Subject: [PATCH 166/302] Translated using Weblate (Japanese) Currently translated at 78.3% (2181 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 85c7ebd817..9d008725a4 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2358,7 +2358,7 @@ LaTeXによる数学表記を有効にする 以下が含まれる場合に通知 アップグレードすると、このルームの新しいバージョンが作成されます。今ある全てのメッセージは、アーカイブしたルームに残ります。 - 誰にアクセスさせますか? + 誰がアクセスできますか? 通知は%1$sで管理できます。 暗号化されたルームでのメンションとキーワードによる通知は、携帯端末では利用できません。 ユーザーを無視し、そのメッセージを非表示にします @@ -2372,4 +2372,12 @@ 続行するには%sを入力してください リカバリーパスフレーズ 有効なリカバリーキーではありません + リカバリーキーを入力してください + 投票の種類 + 実施中の投票 + 投票する + 投票した人には、投票の際に即座に結果が表示されます + 終了した投票 + 結果は投票を終了した後でのみ明らかにされます + 以下で開く \ No newline at end of file From e3243f7fc1694aeff8857d2f1e97ff8d2999ba6e Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Sat, 19 Feb 2022 13:50:20 +0000 Subject: [PATCH 167/302] Translated using Weblate (Japanese) Currently translated at 78.9% (2200 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 9d008725a4..acbb77a455 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2380,4 +2380,5 @@ 終了した投票 結果は投票を終了した後でのみ明らかにされます 以下で開く + 暗号化のアップグレードが利用できます \ No newline at end of file From 681fd3d97c1e995157370bc176a3b678203754b6 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 13:49:56 +0000 Subject: [PATCH 168/302] Translated using Weblate (Japanese) Currently translated at 78.9% (2200 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index acbb77a455..cdcf6197c2 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2364,7 +2364,7 @@ ユーザーを無視し、そのメッセージを非表示にします %sとのコマンドは認識されていますが、スレッドではサポートされていません。 誰でもこのスペースを発見し参加できます - 法律関連 + 法的情報 ユーザーに関する情報を表示します この部屋においてのみアバターを変更します この部屋においてのみ表示名を変更します @@ -2381,4 +2381,22 @@ 結果は投票を終了した後でのみ明らかにされます 以下で開く 暗号化のアップグレードが利用できます + SSSSキーをリカバリーキーから生成しています + ${app_name} iOS +\n${app_name} Android + ${app_name}ウェブ版 +\n${app_name}デスクトップ版 + リカバリーキーを選択、直接入力、あるいはクリップボードからペースト + リカバリーキーを使用 + 暗号化されたルームでのみサポート + メディアファイルを保存できませんでした + メディアファイルをギャラリーに追加できませんでした + このスペースへの招待が、アカウントに関連付けられていないメールアドレス %s に送られました + + %1$d個の投票 + + 投票を締め切り、投票の最終結果を表示します。 + 招待者のみ参加可能。個人やチームに最適 + スペースを作成 + スペースに招待 \ No newline at end of file From 44b1f2f955b28da0d4ce20c7fa894bc295199ed7 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sat, 19 Feb 2022 13:46:27 +0000 Subject: [PATCH 169/302] Translated using Weblate (Japanese) Currently translated at 78.9% (2200 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index cdcf6197c2..5d329abd4e 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2399,4 +2399,8 @@ 招待者のみ参加可能。個人やチームに最適 スペースを作成 スペースに招待 + IDサーバーは利用規約がありません + あなたの連絡先はプライベートです。端末の連絡先からユーザーを発見できるように、連絡先の情報をIDサーバーへ送信する許可が必要です。 + ディスカバリー設定を開く + 既読時間 \ No newline at end of file From 9019edb04598ee6ff469c082c4972373e5991e36 Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Sat, 19 Feb 2022 13:50:43 +0000 Subject: [PATCH 170/302] Translated using Weblate (Japanese) Currently translated at 79.0% (2201 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 5d329abd4e..7c1607e344 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2403,4 +2403,5 @@ あなたの連絡先はプライベートです。端末の連絡先からユーザーを発見できるように、連絡先の情報をIDサーバーへ送信する許可が必要です。 ディスカバリー設定を開く 既読時間 + クロスサイニングを有効にする \ No newline at end of file From 73e51e3efcd3d4aad4497aad1d5f30f23399f25a Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 13:50:30 +0000 Subject: [PATCH 171/302] Translated using Weblate (Japanese) Currently translated at 79.0% (2201 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 7c1607e344..9600b36733 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2380,7 +2380,7 @@ 終了した投票 結果は投票を終了した後でのみ明らかにされます 以下で開く - 暗号化のアップグレードが利用できます + 暗号化のアップグレードが利用可能です SSSSキーをリカバリーキーから生成しています ${app_name} iOS \n${app_name} Android From 96a6793d7b8e2ad4c6ea8f23007bc7232bee86eb Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Sat, 19 Feb 2022 13:51:33 +0000 Subject: [PATCH 172/302] Translated using Weblate (Japanese) Currently translated at 79.0% (2202 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 9600b36733..c4053b34f0 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2404,4 +2404,5 @@ ディスカバリー設定を開く 既読時間 クロスサイニングを有効にする + トピックを追加する \ No newline at end of file From c1e0b4d1f5699e77c98cadcc1c17da0dcd428f0a Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 13:50:51 +0000 Subject: [PATCH 173/302] Translated using Weblate (Japanese) Currently translated at 79.0% (2202 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index c4053b34f0..00d18e951a 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2403,6 +2403,6 @@ あなたの連絡先はプライベートです。端末の連絡先からユーザーを発見できるように、連絡先の情報をIDサーバーへ送信する許可が必要です。 ディスカバリー設定を開く 既読時間 - クロスサイニングを有効にする + クロス証明を有効にする トピックを追加する \ No newline at end of file From ed4634acf0f96dce952f8660ee7508a893827754 Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Sat, 19 Feb 2022 13:55:29 +0000 Subject: [PATCH 174/302] Translated using Weblate (Japanese) Currently translated at 79.2% (2208 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 00d18e951a..8674aa6d09 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2405,4 +2405,7 @@ 既読時間 クロス証明を有効にする トピックを追加する + %sが部屋を作成し構成しました。 + 参加しました。 + %sが参加しました。 \ No newline at end of file From 4e12ab1a06244dc49363ea084e4a65485d070097 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 13:54:46 +0000 Subject: [PATCH 175/302] Translated using Weblate (Japanese) Currently translated at 79.2% (2208 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 8674aa6d09..03cf2312cc 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1031,7 +1031,7 @@ このイベントを削除してよろしいですか?ルーム名やトピックの変更を削除すると、変更が元に戻る点にご注意ください。 暗号化は有効です このルーム内でのメッセージはエンドツーエンド暗号化されます。詳細の確認や検証はユーザーのプロフィールをご確認ください。 - 暗号化が有効化されていません + 暗号化が有効になっていません 通知設定 切断 ログアウトしますか? @@ -2404,8 +2404,10 @@ ディスカバリー設定を開く 既読時間 クロス証明を有効にする - トピックを追加する + トピックを追加 %sが部屋を作成し構成しました。 参加しました。 %sが参加しました。 + このルームで使用されている暗号化はサポートされていません + 暗号化が正しく設定されていません \ No newline at end of file From 56d1dd29050709b620277d6c89611236bc0b2340 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sat, 19 Feb 2022 13:53:56 +0000 Subject: [PATCH 176/302] Translated using Weblate (Japanese) Currently translated at 79.2% (2208 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 03cf2312cc..0eae3a46e1 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2410,4 +2410,6 @@ %sが参加しました。 このルームで使用されている暗号化はサポートされていません 暗号化が正しく設定されていません + %sにテキストメッセージを送信しました。メッセージに含まれた確認コードを入力してください。 + 選択したIDサーバーは利用規約がありません。サービス提供者を信頼しなければ続行しないほうがいいです \ No newline at end of file From 12f503932e2bb73e791400eb2eb24cba4335eb17 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sat, 19 Feb 2022 13:55:51 +0000 Subject: [PATCH 177/302] Translated using Weblate (Japanese) Currently translated at 79.3% (2210 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 0eae3a46e1..90d786a8e6 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2412,4 +2412,5 @@ 暗号化が正しく設定されていません %sにテキストメッセージを送信しました。メッセージに含まれた確認コードを入力してください。 選択したIDサーバーは利用規約がありません。サービス提供者を信頼しなければ続行しないほうがいいです + 現在IDさーバー%1$sにメールアドレスや電話番号を共有しています。共有を停止させるためには%2$sに再接続する必要があります。 \ No newline at end of file From 4e494e53cded5269afa4800ab1b1f0059a7edd1a Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Sat, 19 Feb 2022 13:55:49 +0000 Subject: [PATCH 178/302] Translated using Weblate (Japanese) Currently translated at 79.3% (2210 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 90d786a8e6..109a38cc3d 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2413,4 +2413,5 @@ %sにテキストメッセージを送信しました。メッセージに含まれた確認コードを入力してください。 選択したIDサーバーは利用規約がありません。サービス提供者を信頼しなければ続行しないほうがいいです 現在IDさーバー%1$sにメールアドレスや電話番号を共有しています。共有を停止させるためには%2$sに再接続する必要があります。 + 部屋を作成し構成しました。 \ No newline at end of file From e6398d6b750a60a1341df55422e51e82ff04b125 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 13:55:43 +0000 Subject: [PATCH 179/302] Translated using Weblate (Japanese) Currently translated at 79.3% (2210 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 109a38cc3d..748f3d3360 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2405,7 +2405,7 @@ 既読時間 クロス証明を有効にする トピックを追加 - %sが部屋を作成し構成しました。 + %sはルームを作成し設定しました。 参加しました。 %sが参加しました。 このルームで使用されている暗号化はサポートされていません From c6a0ccf3688069c0fd8db9928979d8afabe9c508 Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Sat, 19 Feb 2022 13:58:21 +0000 Subject: [PATCH 180/302] Translated using Weblate (Japanese) Currently translated at 79.4% (2212 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 748f3d3360..96126a5760 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2414,4 +2414,6 @@ 選択したIDサーバーは利用規約がありません。サービス提供者を信頼しなければ続行しないほうがいいです 現在IDさーバー%1$sにメールアドレスや電話番号を共有しています。共有を停止させるためには%2$sに再接続する必要があります。 部屋を作成し構成しました。 + QRコードを読み取り新しいダイレクトメッセージを作成する + キーのインポートに失敗しました \ No newline at end of file From 24acbcccc686f6ef98365d02fc6bf75170b47c48 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 13:57:32 +0000 Subject: [PATCH 181/302] Translated using Weblate (Japanese) Currently translated at 79.4% (2212 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 96126a5760..2ce27cec31 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2412,8 +2412,8 @@ 暗号化が正しく設定されていません %sにテキストメッセージを送信しました。メッセージに含まれた確認コードを入力してください。 選択したIDサーバーは利用規約がありません。サービス提供者を信頼しなければ続行しないほうがいいです - 現在IDさーバー%1$sにメールアドレスや電話番号を共有しています。共有を停止させるためには%2$sに再接続する必要があります。 - 部屋を作成し構成しました。 + 現在IDサーバー %1$s でメールアドレスや電話番号を共有しています。共有を停止するには %2$s に再接続する必要があります。 + ルームを作成し設定しました。 QRコードを読み取り新しいダイレクトメッセージを作成する キーのインポートに失敗しました \ No newline at end of file From df72019e1d58f90f7575111ddc2313f76e5333bd Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Sat, 19 Feb 2022 14:10:11 +0000 Subject: [PATCH 182/302] Translated using Weblate (Japanese) Currently translated at 79.8% (2223 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 2ce27cec31..f8a0521922 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2416,4 +2416,5 @@ ルームを作成し設定しました。 QRコードを読み取り新しいダイレクトメッセージを作成する キーのインポートに失敗しました + Matrix IDで新しいダイレクトメッセージを作成する \ No newline at end of file From c78c20c06e077f52b6d6473ee9bdefccfb3ee5aa Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sat, 19 Feb 2022 14:09:49 +0000 Subject: [PATCH 183/302] Translated using Weblate (Japanese) Currently translated at 79.8% (2223 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index f8a0521922..8ff8eeb66f 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2417,4 +2417,8 @@ QRコードを読み取り新しいダイレクトメッセージを作成する キーのインポートに失敗しました Matrix IDで新しいダイレクトメッセージを作成する + 新しいダイレクトメッセージを作成 + 部屋作成メニューを閉じる… + 部屋作成メニューを開く + サーバーの応答に時間がかかりすぎています。おそらく接続が遅すぎるからか、サーバー側でエラーが発生しているからです。後で再試行してください。 \ No newline at end of file From 53061be8719151fe93312357cea168d686c25ed1 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 14:09:46 +0000 Subject: [PATCH 184/302] Translated using Weblate (Japanese) Currently translated at 79.8% (2223 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 8ff8eeb66f..a4957dc68e 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -362,7 +362,7 @@ ホーム 会話なし 端末の電話帳を${app_name}アプリが読み取ることは許可されていません - 結果なし + 結果がありません ルーム ルームディレクトリ ユーザーディレクトリ @@ -2414,11 +2414,17 @@ 選択したIDサーバーは利用規約がありません。サービス提供者を信頼しなければ続行しないほうがいいです 現在IDサーバー %1$s でメールアドレスや電話番号を共有しています。共有を停止するには %2$s に再接続する必要があります。 ルームを作成し設定しました。 - QRコードを読み取り新しいダイレクトメッセージを作成する + QRコードを読み取り、新しいダイレクトメッセージを作成 キーのインポートに失敗しました Matrix IDで新しいダイレクトメッセージを作成する 新しいダイレクトメッセージを作成 部屋作成メニューを閉じる… 部屋作成メニューを開く サーバーの応答に時間がかかりすぎています。おそらく接続が遅すぎるからか、サーバー側でエラーが発生しているからです。後で再試行してください。 + このルームを%1$sから%2$sにアップグレードします。 + スライドしてキャンセル + 音声メッセージを録音しています + 録音を削除 + 音声メッセージがアクティブの間は返信や編集はできません + この投票を削除してよろしいですか?一度削除すると復元することはできません。 \ No newline at end of file From 28d0daf8755eb5ec314f0033daeea36358466fbb Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sat, 19 Feb 2022 14:13:51 +0000 Subject: [PATCH 185/302] Translated using Weblate (Japanese) Currently translated at 80.2% (2236 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index a4957dc68e..c9718663c3 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2416,7 +2416,7 @@ ルームを作成し設定しました。 QRコードを読み取り、新しいダイレクトメッセージを作成 キーのインポートに失敗しました - Matrix IDで新しいダイレクトメッセージを作成する + Matrix IDで新しいダイレクトメッセージを作成 新しいダイレクトメッセージを作成 部屋作成メニューを閉じる… 部屋作成メニューを開く @@ -2427,4 +2427,6 @@ 録音を削除 音声メッセージがアクティブの間は返信や編集はできません この投票を削除してよろしいですか?一度削除すると復元することはできません。 + 共有データをの取扱に失敗しました + 回転とクロップ \ No newline at end of file From da8d102ccad8d14c9d5262b495e8d621a294cfbb Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 14:13:24 +0000 Subject: [PATCH 186/302] Translated using Weblate (Japanese) Currently translated at 80.2% (2236 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index c9718663c3..12c446428c 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2429,4 +2429,15 @@ この投票を削除してよろしいですか?一度削除すると復元することはできません。 共有データをの取扱に失敗しました 回転とクロップ + ルームを探す + 既存のルームとスペースを追加 + スレッドのメッセージを有効にする + おすすめに追加 + おすすめから除外 + ルームとスペースを管理 + ホームに全てのルームを表示 + おすすめ + 実験したい気分ですか? +\n既存のスペースを別のスペースに追加できます。 + あなたのホームサーバーはまだスペースをサポートしていないようです \ No newline at end of file From 002246801839dc63557c3c29f66ff62332a690f9 Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Sat, 19 Feb 2022 14:11:06 +0000 Subject: [PATCH 187/302] Translated using Weblate (Japanese) Currently translated at 80.2% (2236 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 12c446428c..3bc7a1593a 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2440,4 +2440,5 @@ 実験したい気分ですか? \n既存のスペースを別のスペースに追加できます。 あなたのホームサーバーはまだスペースをサポートしていないようです + 画像を追加 \ No newline at end of file From dc6fba26d87a6c081227ea2bf1366267cd545aed Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sat, 19 Feb 2022 14:20:50 +0000 Subject: [PATCH 188/302] Translated using Weblate (Japanese) Currently translated at 80.6% (2247 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 3bc7a1593a..fb9f2fdf2f 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2441,4 +2441,14 @@ \n既存のスペースを別のスペースに追加できます。 あなたのホームサーバーはまだスペースをサポートしていないようです 画像を追加 + このコンテンツは不適切な投稿として報告されています。 +\n +\nこのユーザーのコンテンツをこれ以上見たくなければ、ユーザーを無視してそのメッセージを非表示にできます。 + このコンテンツはスパムとして報告されています。 +\n +\nこのユーザのコンテンツをこれ以上見たくなければ、ユーザーを無視してそのメッセージを非表示にできます。 + このコンテンツが報告されています。 +\n +\nこのユーザーのコンテンツをこれ以上見たくなければ、ユーザーを無視してそのメッセージを非表示にできます。 + %1$s%2$s \ No newline at end of file From cc779b8ce5c3dbc653ce5d7a1647bdfbc24168b6 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 14:20:04 +0000 Subject: [PATCH 189/302] Translated using Weblate (Japanese) Currently translated at 80.6% (2247 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index fb9f2fdf2f..0a05eb95fe 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2427,7 +2427,7 @@ 録音を削除 音声メッセージがアクティブの間は返信や編集はできません この投票を削除してよろしいですか?一度削除すると復元することはできません。 - 共有データをの取扱に失敗しました + 共有データの取り扱いに失敗しました 回転とクロップ ルームを探す 既存のルームとスペースを追加 @@ -2451,4 +2451,12 @@ \n \nこのユーザーのコンテンツをこれ以上見たくなければ、ユーザーを無視してそのメッセージを非表示にできます。 %1$s%2$s + 質問あるいはトピック + 投票の質問あるいはトピック + スペースのメンバーが非公開のルームを発見できるよう手伝う + 少々お待ちください。少し時間がかかるかもしれません。 + ルームのバージョン 👓 + 不安定 + 安定 + スポイラー \ No newline at end of file From b9558bdf910858bd8a430d42d5d58a9d722d99fa Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 14:34:15 +0000 Subject: [PATCH 190/302] Translated using Weblate (Japanese) Currently translated at 81.8% (2279 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 37 ++++++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 0a05eb95fe..7649295cd1 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -314,7 +314,7 @@ 招待された人のみ ルームのリンクを知っている人なら誰でも(ゲストユーザーを除く) ルームのリンクを知っている人なら誰でも(ゲストユーザーを含む) - 再入室禁止されたメンバー + ブロックされたユーザー 拡張設定 このルームのサーバー内識別ID ラボ @@ -347,7 +347,7 @@ 発言更新を確認 暗号解除されたソースコードを表示 名前変更 - 切断中 + オフライン 会話を開始 音声通話を開始 ビデオ通話を開始 @@ -2418,8 +2418,8 @@ キーのインポートに失敗しました Matrix IDで新しいダイレクトメッセージを作成 新しいダイレクトメッセージを作成 - 部屋作成メニューを閉じる… - 部屋作成メニューを開く + ルーム作成メニューを閉じる… + ルーム作成メニューを開く サーバーの応答に時間がかかりすぎています。おそらく接続が遅すぎるからか、サーバー側でエラーが発生しているからです。後で再試行してください。 このルームを%1$sから%2$sにアップグレードします。 スライドしてキャンセル @@ -2446,7 +2446,7 @@ \nこのユーザーのコンテンツをこれ以上見たくなければ、ユーザーを無視してそのメッセージを非表示にできます。 このコンテンツはスパムとして報告されています。 \n -\nこのユーザのコンテンツをこれ以上見たくなければ、ユーザーを無視してそのメッセージを非表示にできます。 +\nこのユーザーのコンテンツをこれ以上見たくなければ、ユーザーを無視してそのメッセージを非表示にできます。 このコンテンツが報告されています。 \n \nこのユーザーのコンテンツをこれ以上見たくなければ、ユーザーを無視してそのメッセージを非表示にできます。 @@ -2459,4 +2459,31 @@ 不安定 安定 スポイラー + 生体認証を有効にする + %1$sによりブロック + 招待を取り消す + サーバーのバージョン + サーバー名 + 電話番号が正しくありません。確認してください + カスタムホームサーバーを選択 + Element Matrix Servicesを選択 + 再送信 + コードを入力 + 電話番号 + 退席中 + オフライン + オンライン + 一般 + 転送 + 信頼済 + 検証済 + 未送信のメッセージを削除 + カスタムイベントを送信 + ルームの状態を調べる + 開封確認メッセージを表示 + 通知しない + ファイルから鍵をインポート + 未確認 + 制限は不明です。 + サーバーのファイルアップロードの制限 \ No newline at end of file From 376057b7989e8782e7c25474c318f623538459e7 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sat, 19 Feb 2022 14:31:14 +0000 Subject: [PATCH 191/302] Translated using Weblate (Japanese) Currently translated at 81.8% (2279 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 7649295cd1..75d5a5341f 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2458,7 +2458,7 @@ ルームのバージョン 👓 不安定 安定 - スポイラー + ネタバレ 生体認証を有効にする %1$sによりブロック 招待を取り消す @@ -2486,4 +2486,11 @@ 未確認 制限は不明です。 サーバーのファイルアップロードの制限 + 自分の会話は自分のものにしましょう。 + %1$sが部屋を招待されたユーザーにのみアクセスできるように設定しました。 + %1$sが部屋をリンクを持っているユーザーにアクセスできるように設定しました。 + 選択したメッセージをネタバレとして送信 + ${app_name} がE2E暗号鍵をディスクに保存する許可を要求しています。 +\n +\n暗号鍵を手動でエクスポートできるように、次のポップアップでアクセスを許可してください。 \ No newline at end of file From 4dc15f99a86e04b33eb8d288e4c323a15d67a71e Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 14:34:18 +0000 Subject: [PATCH 192/302] Translated using Weblate (Japanese) Currently translated at 81.8% (2279 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 75d5a5341f..fd2e153059 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2493,4 +2493,5 @@ ${app_name} がE2E暗号鍵をディスクに保存する許可を要求しています。 \n \n暗号鍵を手動でエクスポートできるように、次のポップアップでアクセスを許可してください。 + %1$sがルームをリンクを持っているユーザーにアクセスできるように設定しました。 \ No newline at end of file From 1a5b0d2e825d8144c3d29342a230ea541cbee964 Mon Sep 17 00:00:00 2001 From: metatek Date: Sat, 19 Feb 2022 14:56:44 +0000 Subject: [PATCH 193/302] Translated using Weblate (Japanese) Currently translated at 82.1% (2289 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index fd2e153059..d83ddcdd30 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2494,4 +2494,5 @@ \n \n暗号鍵を手動でエクスポートできるように、次のポップアップでアクセスを許可してください。 %1$sがルームをリンクを持っているユーザーにアクセスできるように設定しました。 + まず、設定でIDサーバーの条件に同意してください。 \ No newline at end of file From 21401430b22e9f1fd90839a249f158cd42a1b8ad Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 14:56:23 +0000 Subject: [PATCH 194/302] Translated using Weblate (Japanese) Currently translated at 82.1% (2289 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index d83ddcdd30..525e481b68 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2316,7 +2316,7 @@ 私たちは情報を第三者と共有することはありません 私たちはアカウントのデータを記録したり分析したりすることはありません Elementの改善を手伝う - リンクを知っている人を対象に、このルームを公開しました。 + リンクを知っている人がアクセスできるようにこのルームを設定しました。 どのユーザーも無視していません キーワードを入力するとリアクションを検索できます。 変更を加えませんでした @@ -2366,8 +2366,8 @@ 誰でもこのスペースを発見し参加できます 法的情報 ユーザーに関する情報を表示します - この部屋においてのみアバターを変更します - この部屋においてのみ表示名を変更します + このルームにおいてのみアバターを変更します + このルームにおいてのみ表示名を変更します ユーザーの無視を解除し、これからのメッセージを表示します 続行するには%sを入力してください リカバリーパスフレーズ @@ -2487,12 +2487,22 @@ 制限は不明です。 サーバーのファイルアップロードの制限 自分の会話は自分のものにしましょう。 - %1$sが部屋を招待されたユーザーにのみアクセスできるように設定しました。 + %1$sは、このルームを招待者のみ参加可能に設定しました。 %1$sが部屋をリンクを持っているユーザーにアクセスできるように設定しました。 選択したメッセージをネタバレとして送信 ${app_name} がE2E暗号鍵をディスクに保存する許可を要求しています。 \n \n暗号鍵を手動でエクスポートできるように、次のポップアップでアクセスを許可してください。 - %1$sがルームをリンクを持っているユーザーにアクセスできるように設定しました。 + %1$sはリンクを知っている人がアクセスできるようにこのルームを設定しました。 まず、設定でIDサーバーの条件に同意してください。 + 初めにIDサーバーを設定してください。 + + %1$d個の投票があります。結果を見るには投票してください + + 信頼済としてマーク + 未検証の端末で暗号化 + メッセージを紙吹雪と共に送る + メッセージを降雪と共に送る + 紙吹雪🎉を送る + 降雪❄️を送る \ No newline at end of file From c6e712ee7b15f54b2e2cfb0cfd5a0de80eae0dca Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sat, 19 Feb 2022 14:49:25 +0000 Subject: [PATCH 195/302] Translated using Weblate (Japanese) Currently translated at 82.1% (2289 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 525e481b68..c0b1141a72 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2505,4 +2505,11 @@ メッセージを降雪と共に送る 紙吹雪🎉を送る 降雪❄️を送る + あなたのチームのメッセージングに。 + エンドツーエンド暗号化され、電話番号不要。広告やデータマイニング無し。 + 会話の保存先を自分で決められ、自分で管理できる独立したコミュニケーション。Matrixを基に。 + お宅での対面会話と同じぐらいのプライバシーを提供する、セキュアで独立したコミュニケーション。 + チームワークを効率よくしましょう。 + セキュアメッセージング + 管理権を握るのはあなたです。 \ No newline at end of file From 7083d7dd7263ee788d16943944f39c4278fcea1c Mon Sep 17 00:00:00 2001 From: Vladyslav Stepanov Date: Fri, 11 Feb 2022 18:54:32 +0000 Subject: [PATCH 196/302] Translated using Weblate (Russian) Currently translated at 100.0% (2785 of 2785 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 | 650 +++++++++++----------- 1 file changed, 325 insertions(+), 325 deletions(-) diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index 1ec34777db..f164afc11b 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -298,14 +298,14 @@ Поделиться Позже Переслать - Копировать ссылку + Постоянная ссылка Просмотр исходного кода Просмотр расшифрованного исходного кода Удалить Переименовать Пожаловаться на содержимое Активный вызов - Ongoing conference call. + Текущая конференц-звонок. \nПрисоединиться как %1$s или %2$s Голос Видео @@ -335,10 +335,10 @@ Избранные Люди Комнаты - Фильтр названия комнаты + Фильтр названий комнат Фильтр избранного Фильтр людей - Фильтр названия комнаты + Фильтр названий комнат Приглашения Маловажные Беседы @@ -348,7 +348,7 @@ Вы не дали доступ ${app_name} к внутренним контактам Нет результатов Комнаты - Список комнат + Каталог комнат Нет комнат Публичные комнаты недоступны @@ -359,12 +359,12 @@ Отправить логи Отправить журналы ошибок - Отправить скриншот + Отправить снимок экрана Сообщить об ошибке - Пожалуйста опишите ошибку. Что вы делали? Что вы ожидали получить? Что произошло? + Пожалуйста опишите ошибку. Что вы делали\? Что вы хотели получить\? Что на самом деле произошло\? Опишите проблему здесь Для диагностики проблемы журналы работы приложения будут приложены к отчету об ошибке. Этот отчет, включая журналы и скриншот, не будет доступен публично. Если вы предпочитаете отправить только текст, то снимите отметку: - Похоже вы разочарованы, раз трясёте телефоном. Хотите сообщить об ошибке? + Вы, наверное, трясете телефон в отчаянии. Хотите открыть экран отчета об ошибке\? Отчет об ошибке успешно отправлен Сбой отправки отчета об ошибке (%s) Прогресс (%s%%) @@ -386,65 +386,65 @@ Камера Вход Создать аккаунт - Отправить + Подать Пропустить Выслать письмо для сброса Вернуться на экран входа - Электронная почта или логин + Электронная почта или имя пользователя Пароль Новый пароль - Логин + Имя пользователя Адрес электронной почты Адрес электронной почты (не обязательно) Номер телефона - Номер телефона (по желанию) + Номер телефона (необязательно) Повтор пароля Подтвердите ваш новый пароль - Неверный логин и/или пароль + Неправильный логин и/или пароль Логин может содержать только буквы, цифры, точки, дефис и подчеркивание Короткий пароль (минимум 6 символов) Отсутствует пароль - Это не похоже на адрес электронной почты - Введен некорректный номер телефона + Это не похоже на действительный адрес электронной почты + Это не похоже на действительный номер телефона Этот адрес электронной почты уже используется. - Отсутствует email + Отсутствует адрес электронной почты Отсутствует номер телефона - Отсутствует номер телефона или email + Отсутствует номер телефона или электронной почты Токен не действителен Пароли не совпадают Забыли пароль? - Использовать особые параметры сервера - Проверьте email для продолжения регистрации - Регистрация одновременно по email и номеру телефона пока не поддерживается. Только номер телефона будет связан с аккаунтом. + Использовать пользовательские параметры сервера(расширенный) + Проверьте адрес электронной почты для продолжения регистрации + Регистрация одновременно по электронной почте и номеру телефона пока не поддерживается. Только номер телефона будет связан с аккаунтом. \n -\nВы можете добавить свой email в настройках профиля. +\nВы можете добавить свой электронный адрес в настройках профиля. Этот домашний сервер хочет убедиться, что вы не робот Логин уже используется Домашний сервер: - Сервер идентификации: - Я проверил мой email адрес - Для сброса пароля введите email привязанный к учетной записи: - Должен быть введен email привязанный к учетной записи. + Сервер опознавания: + Я проверил мой адрес электронной почты + Для сброса пароля введите адрес электронной почты привязанный к учетной записи: + Должен быть введен адрес электронной почты привязанный к учетной записи. Должен быть введен новый пароль. На адрес %s было отправлено письмо. После перехода по ссылке в письме, нажмите ниже. - Не удалось проверить email: убедитесь, что вы перешли по присланной ссылке - Ваш пароль сброшен. + Не удалось проверить адрес электронной почты: убедитесь, что вы перешли по ссылке из сообщения + Ваш пароль сброшен. \n -\nОсуществлен выход на всех сессиях - вы не будете получать push уведомления. Для включения push уведомлений заново войдите на каждом из ваших устройств. +\nОсуществлен выход на всех сессиях - вы не будете получать всплывающие уведомления. Для включения всплывающие уведомлений заново войдите на каждом из ваших устройств. URL должен начинаться с http[s]:// Сбой входа: сетевая ошибка Сбой входа Сбой регистрации: сетевая ошибка Сбой регистрации - Сбой регистрации: ошибка проверки email + Сбой регистрации: ошибка проверки электронного ящика Пожалуйста, введите корректный URL Неверное имя пользователя или пароль - Указанный токен доступа не распознан - Поврежденный JSON - Не JSON + Указанный токен доступа не был распознан + Неверный формат JSON + Не содержит допустимого JSON Отправлено слишком много запросов Логин уже используется - Вы не перешли по высланной в email ссылке + Вы еще не перешли по высланной ссылке Чтение списка вступивших Отправить как Оригинал @@ -459,21 +459,21 @@ Сегодня Название комнаты Тема комнаты - Вызов соединён + Вызов установлен Устанавливается соединение… - Вызов закончен - Звонок… + Вызов завершен + Звоним… Входящий вызов Входящий видеовызов Входящий голосовой вызов Идёт разговор… - Вызываемый абонент не отвечает. + Вызываемый абонент не смог ответить. Медиавызов не удался Невозможно инициализировать камеру Звонок принят на другом устройстве Снять фото или видео" Не удалось записать видео" - Element Информация + Информация ${app_name} нуждается в разрешении на доступ к вашей фото-и видеотеке для отправки и сохранения вложений. \n \nПожалуйста, разрешите доступ в следующем всплывающем окне, чтобы иметь возможность отправлять файлы с вашего устройства. @@ -488,7 +488,7 @@ ${app_name} может проверить Вашу адресную книгу, чтобы найти других пользователей сети по email или телефонному номеру. \n \nСогласны ли вы поделиться своей адресной книгой для этой цели\? - Извините. Действие не выполнено из-за недостаточных разрешений + Извините. Действие не выполнено из-за отсутствия на него разрешений Сохранено Сохранить в загрузки? ДА @@ -501,10 +501,10 @@ Перейти к непрочитанному %s пригласил вас присоединиться к этой комнате Приглашение пришло на адрес %s, который не связан с этим аккаунтом. -\nВозможно, вы захотите войти в систему с другим аккаунтом или добавить этот email в свою учетную запись. +\nВозможно, вы захотите войти в систему с другим аккаунтом или добавить этот электронный ящик в свою учетную запись. Вы пытаетесь получить доступ к %s. Хотите присоединиться к обсуждению? комната - Это пред. просмотр комнаты. Вы в режиме только чтения. + Это предпросмотр комнаты. Вы в режиме только чтения. Новый чат Добавить участника 1 пользователь @@ -516,7 +516,7 @@ Покой АДМИНИСТРИРОВАНИЕ ВЫЗОВ - ПРЯМЫЕ ЧАТЫ + ПРЯМЫЕ СООБЩЕНИЯ СЕССИИ Пригласить Покинуть этот чат @@ -527,25 +527,25 @@ Сделать администратором Скрыть все сообщения этого пользователя Отобразить все сообщения этого пользователя - ID пользователя, имя или email + ID пользователя, имя или электронный адрес Упомянуть Отобразить список сессий Вы не сможете отменить это действие, поскольку пользователь получит такой же уровень доступа, как и у вас. \nВы уверены\? "Вы уверены что хотите пригласить %s в этот чат?" Пригласить по ID - Локальные Контакты (%d) - Только зарегистрированные + ЛОКАЛЬНЫЕ КОНТАКТЫ (%d) + Только пользователи Matrix Пригласить пользователя по ID - Пожалуйста, введите один или несколько адресов email или Matrix ID - Email или Matrix ID + Пожалуйста, введите один или несколько электронных адресов или Matrix ID + Электронный почтовый ящик или Matrix ID Поиск %s печатает… %1$s & %2$s печатают… %1$s & %2$s & и другие печатают… Отправить зашифрованное сообщение… - Отправить сообщение… - Соединение с сервером потеряно. + Отправить сообщение(не зашифрованное)… + Связь с сервером утеряна. Сообщения не отправлены. %1$s или %2$s сейчас? Сообщения, не отправлены из-за присутствия неизвестных сессий. %1$s или %2$s сейчас\? Повторить отправку @@ -553,7 +553,7 @@ Отправить неотправленные сообщения Удалить неотправленные сообщения Файл не найден - У вас нет прав писать сообщения в этом чате. + У вас нет разрешения писать сообщения в этой комнате. Доверять Не доверять Выйти @@ -561,8 +561,8 @@ Отпечаток (%s): Не удалось проверить сертификат удаленного сервера. Это может означать, что кто-то злонамеренно перехватывает ваш трафик или что ваш телефон не доверяет сертификату, предоставленному удаленным сервером. - Если администратор сервера сказал, что это ожидается, убедитесь, что отпечаток сертификата ниже соответствует отпечатку сертификата, предоставленному администратором. - Сертификат сервера изменился и ваш телефон теперь ему не доверяет. Это ОЧЕНЬ ПОДОЗРИТЕЛЬНО. Рекомендуется, НЕ ДОВЕРЯТЬ этому новому сертификату. + Если администратор сервера сказал, что это ожидалось, убедитесь, что отпечаток сертификата ниже совпадает с отпечатком сертификата предоставленным администратором. + Сертификат был изменен с того, которому доверял ваш телефон. Это ОЧЕНЬ НЕОБЫЧНО. Рекомендуется НЕ ПРИНИМАТЬ этот новый сертификат. Сертификат изменился с ранее доверенного на недействительный. Возможно, сервер обновил свой сертификат. Свяжитесь с администратором сервера для получения ожидаемого отпечатка сертификата. Примите сертификат только если администратор сервера опубликовал отпечаток сертификата, который соответствует указанному выше. Подробности комнаты @@ -572,7 +572,7 @@ Некорректный ID. Используйте email или Matrix ID вида \'@localpart:domain\' ПРИГЛАШЕНЫ ПРИСОЕДИНИЛИСЬ - Причина отчета о контенте + Причина жалобы об этом содержимом Вы хотите скрыть все сообщения этого пользователя\? \n \nУчтите, что это действие перезапустит приложение и может занять некоторое время. @@ -601,8 +601,8 @@ Политика конфиденциальности Аватар Отображаемое имя - Email - Добавить email + Электронный ящик + Добавить электронный адрес Телефон Добавить телефон Системные настройки приложения. @@ -615,7 +615,7 @@ Когда меня приглашают в комнату Вызовы Сообщения от бота - Синхронизация + Фоновая синхронизация Включить фоновую синхронизацию Таймаут синхронизации Задержка между каждой синхронизацией @@ -635,7 +635,7 @@ Устройства для уведомлений Локальные контакты Доступ к контактам - Страна для контактов + Страна контактов Домашний экран Прикрепить комнаты с отключенными уведомлениями Прикрепить комнаты с непрочитанными сообщениями @@ -644,16 +644,16 @@ ID Публичное имя Обновить публичное имя - Последнее подключение + Недавно %1$s @ %2$s Для этой операции требуется дополнительная проверка подлинности. \nЧтобы продолжить, введите пароль. Аутентификация Пароль: - Отправить + Подать Авторизован как Домашний сервер - Сервер идентификации + Сервер опознавания Ожидается подтверждение Проверьте электронную почту и перейдите по высланной ссылке. Затем нажмите продолжить. Не удалось подтвердить адрес электронной почты. Проверьте электронную почту и нажмите на содержащуюся ссылку. После этого нажмите продолжить. @@ -699,11 +699,11 @@ Только участники (с момента выбора этой опции) Только участники (с момента приглашения) Только участники (с момента присоединения) - Для генерации ссылки команда должна иметь адрес. - Только приглашенные + Чтобы подключиться к комнате, у нее должен быть адрес. + Только те, кого пригласили Все у кого есть ссылка на комнату, кроме гостей Все у кого есть ссылка на комнату, включая гостей - Забаненные пользователи + Заблокированные пользователи Дополнительно Внутренний ID комнаты Адреса @@ -770,8 +770,8 @@ Блокировать Разрешить Проверить сессию - Чтобы убедиться, что этой сессии можно доверять, обратитесь к его владельцу, используя другие способы (например, лично или по телефону), и спросите, соответствует ли ключ, который он видит в настройках для этой сессии: - Если совпадает, то нажмите кнопку подтвердить ниже. Если не совпадает, возможно кто-то пытается перехватить сессию и вы захотите добавить его в черный список. В будущем данный процесс будет улучшен. + Чтобы убедиться, что этой сессии можно доверять, обратитесь к ее владельцу, используя другие способы (например, лично или по телефону), и спросите, соответствует ли ключ, который он видит в настройках для этой сессии: + Если они не совпадают, безопасность вашего общения может быть поставлена под угрозу. Я проверил, что ключи совпадают Комната содержит неизвестные сессии Эта комната содержит неизвестные сессии, которые не были подтверждены. @@ -779,7 +779,7 @@ \nПеред продолжением рекомендуем вам пройти процесс проверки для каждой сессии, но вы можете отправить сообщение повторно, не проверяя. \n \nНеизвестные сессии: - Выбор списка комнат + Выбор каталога комнат Сервер возможно недоступен или перегружен Введите домашний сервер для отображения списка публичных комнат Имя сервера @@ -794,7 +794,7 @@ 3 дня 1 неделя 1 месяц - Постоянно + Навсегда Очистить медиа кэш Недоступен Каталог пользователей @@ -832,7 +832,7 @@ Мониторинг событий Вызов Сообщения, содержащие мое имя пользователя - Вы добавили новою сессию \'%s\', запрашивающая ключи шифрования. + Вы добавили новою сессию \'%s\', запрашивающую ключи шифрования. Ваше непроверенная сессия \'%s\' запрашивает ключи шифрования. Сообщения, содержащие мое отображаемое имя Начать проверку @@ -845,7 +845,7 @@ Аналитика Использовать встроенную камеру Сообщить об ошибке - Внимание! + Предупреждение! Конференц-связь находится в разработке и может быть ненадежной. Ошибка команды Нераспознанная команда: %s @@ -856,7 +856,7 @@ Загрузка… Закрыть приложение Сообщества - Поиск сообществ + Фильтр сообществ Пригласить Сообщества Нет групп @@ -864,13 +864,13 @@ Вы уверены, что хотите начать голосовой вызов? Вы уверены, что хотите начать видеовызов? Список групп - Блокировка пользователя удалит его из этой комнаты и не позволит ему присоединиться к ней снова. + Блокировка пользователя удалит его из этой комнаты и не позволит ему присоединиться вновь. Все сообщения (громко) Все сообщения Только упоминания Без звука Добавить на главный экран - Предпросмотр URL-адресов + Предпросмотр встроенных URL-адресов Вибрация при упоминании пользователя Уведомления Новый ID сообщества (например +foo:matrix.org) @@ -878,22 +878,22 @@ \'%s\' недействительный ID сообщества Создать Создать сообщество - Имя сообщества + Название сообщества Пример ID сообщества пример Начало Люди Комнаты - Нет пользователей + Пользователей нет Комнаты Присоединился Приглашен Фильтр участников группы Фильтр комнат группы - Администратор сообщества не предоставил подробного описания этого сообщества. + Администратор сообщества не предоставил подробного описания для этого сообщества. Вас выгнал %2$s из %1$s - Вас забанил %2$s в %1$s + Вас заблокировал %2$s в %1$s Причина: %1$s Присоединиться снова Забыть комнату @@ -966,7 +966,7 @@ Получить аватар Заметка аватара - Сообщества + Чутье Эта комната не показывает любые сообщества Конфиденциальность уведомлений Нормальный @@ -994,17 +994,17 @@ Да, я хочу помочь! Обязательный параметр отсутствует. Параметр недействителен. - Для продолжения использования этого сервера %1$s вы должны ознакомиться и принять Условия использования. - Ознакомиться сейчас + Для продолжения использования %1$s вы должны ознакомиться и согласиться с условиями и правилами использования этого домашнего сервера. + Посмотреть сейчас Деактивировать аккаунт - Пожалуйста, удалите все сообщения, которые я отправил, после деактивации моего аккаунта (предупреждение: будущие участники увидят неполную историю разговоров) + Пожалуйста, удалите все сообщения, которые я отправил, после деактивации моего аккаунта (Предупреждение: будущие участники увидят неполную историю разговоров) Чтобы продолжить, введите пароль: Деактивировать аккаунт - Это действие сделает вашу учетную запись непригодной для дальнейшего использования. Вы не сможете войти в систему и никто другой не сможет заново зарегистрировать учетную запись с вашим идентификатором. Также, это приведет к тому, что вы покинете все комнаты, в которых участвовали и данные о вашей учетной записи будут удалены с сервера идентификации. Это действие необратимо. + Это действие сделает вашу учетную запись навсегда непригодной для дальнейшего использования. Вы не сможете войти в систему и никто другой не сможет заново зарегистрировать учетную запись с вашим идентификатором. Также, это приведет к тому, что вы покинете все комнаты, в которых участвовали и данные о вашей учетной записи будут удалены с сервера идентификации. Это действие необратимо. \n -\nПо умолчанию, деактивация вашей учетной записи не удаляет отправленные вами сообщения. Если вы хотите, чтобы мы удалили все ваши сообщения - поставьте отметку в поле ниже. +\nПо умолчанию, деактивация вашей учетной записи не удаляет отправленные вами сообщения. Если вы хотите, чтобы мы удалили все ваши сообщения - поставьте отметку в поле ниже. \n -\nВидимость сообщений в Matrix похожа на электронную почту. Удаление ваших сообщений означает, что отправленные вами сообщения не будут показаны новым или не зарегистрированным пользователям, но те пользователи, которые уже получили эти сообщения - по прежнему будут их видеть. +\nВидимость сообщений в Matrix похожа на электронную почту. Удаление ваших сообщений означает, что отправленные вами сообщения не будут показаны новым или не зарегистрированным пользователям, но те пользователи, которые уже получили эти сообщения - по прежнему будут видеть их копии. Лицензии сторонних производителей Скачать Говорить @@ -1016,7 +1016,7 @@ Введите здесь… Отправить голосовое сообщение продолжить с… - К сожалению, для выполнения этого действия не найдено внешнее приложение. + К сожалению, внешнее приложение для выполнения этого действия не найдено. Отправлять голосовые сообщения Пожалуйста, введите ваш пароль. Если возможно, добавьте описание на английском языке. @@ -1024,17 +1024,17 @@ Отправить ответ (незашифрованный)… Предварительный просмотр медиа перед отправкой В настоящее время вы не являетесь участником каких-либо сообществ. - Использовать клавишу Enter для отправки сообщения + Использовать клавишу ввода для отправки сообщения Отображает действие - Банит пользователя с указанным ID - Разбанит пользователя с указанным ID + Блокирует пользователя с данным ID + Разблокирует пользователя с данным ID Определение уровня доступа пользователя Сбросить уровень доступа для пользователя с данным ID Пригласить пользователя с данным ID в текущую комнату Покинуть комнату Задать тему комнаты - Выкинуть пользователя с заданным ID - Изменить ваш псевдоним + Выгнать пользователя с заданным ID из этой комнаты + Изменить ваше отображаемое имя Вкл/выкл markdown Эта комната была заменена и больше не активна. Этот разговор продолжается здесь @@ -1113,10 +1113,10 @@ свернуть Всё равно позвонить Пароль - Пожалуйста ознакомьтесь и подтвердите согласие с политикой этого сервера: + Пожалуйста, ознакомьтесь и примите правила этого домашнего сервера: Вызовы Использовать стандартную мелодию ${app_name} для входящих звонков - Мелодия звонка + Мелодия входящего вызова Выберите мелодию звонка: Идёт видеозвонок … Удалить из чата @@ -1130,7 +1130,7 @@ Произошла ошибка при подтверждении вашего номера телефона. Дополнительная информация: %s Эта опция требует стороннего приложения для записи сообщений. - Команде \"%s\" нужно больше параметров, или некоторые параметры неверны. + Команде \"%s\" нужно либо больше параметров, либо некоторые из них неверны. Markdown включен. Markdown выключен. Всегда @@ -1199,7 +1199,7 @@ Показывать события аккаунта Включает изменения аватара и отображаемого имени. Необходимо минимизировать влияние на фоновое соединение для надёжности уведомлений. -\nНа следующем экране вам будет предложено разрешить ${app_name} всегда работать в фоновом режиме, пожалуйста, примите. +\nНа следующем экране вам будет предложено разрешить ${app_name} всегда работать в фоновом режиме, пожалуйста, согласитесь. Использовать системную камеру вместо камеры Element. Показать информацию %1$s: @@ -1207,7 +1207,7 @@ +%d %d+ Не найден APK сервисов Google Play. Уведомления могут работать неправильно. - Не влияет на приглашения, удаления и запреты. + Не влияет на приглашения, изгнания и блокировки. Резервное копирование ключей Используйте резервную копию ключа Резервное копирование ключей не завершено, пожалуйста, подождите… @@ -1253,7 +1253,7 @@ Чтобы использовать резервную копию ключа в этой сессии, восстановите его с помощью своей парольной фразы или ключа восстановления. Резервная копия имеет недействительную подпись из подтвержденной сессии %s Резервная копия имеет действительную подпись из неподтвержденной сессии %s - Резервная копия имеет действительно подпись из подтверждённой сессии %s. + Резервная копия имеет действительную подпись из подтверждённой сессии %s. Резервная копия имеет действительную подпись с этой сессии. Резервная копия подписана сессией с идентификатором %s. Резервные копии ключей этой сессии не сохраняются. @@ -1261,7 +1261,7 @@ Резервное копирование ключей успешно настроено для этой сессии. Удалить резервную копию Восстановить из резервной копии - Сессионное шифрование не активировано + Шифрование сессии не активировано Пожалуйста, введите ключ восстановления Разблокировать историю Восстановление резервной копии: @@ -1271,7 +1271,7 @@ Если вы не знаете вашу парольную фразу для восстановления, вы можете %s. используйте ключ восстановления Вы можете потерять доступ к сообщениям, если выйдете из системы или потеряете это устройство. - Запрашивает версию резервной копии… + Получение версии резервной копии… Используйте парольную фразу для разблокировки истории зашифрованных сообщений Потеряли ключ восстановления? В настройках вы можете создать новый. Ошибка сети: проверьте соединение и повторите попытку. @@ -1281,9 +1281,9 @@ Не удалось получить последнюю версию ключей восстановления (%s). %d новый ключ был добавлен к этому устройству. - %d новых ключа были добавлены к этому устройству. - %d новых ключей были добавлены к этому устройству. - + %d новых ключа были добавлены к этим устройствам. + %d новых ключей были добавлены к этим устройствам. + %d новых ключей были добавлены к этим устройствам. Восстановлена резервная копия с %d ключом. @@ -1291,7 +1291,7 @@ Восстановлены резервные копии с %d ключами. Невозможно расшифровать резервную копию с помощью этого ключа восстановления: убедитесь, что вы ввели правильный ключ. - Невозможно расшифровать резервную копию с помощью данного пароля: убедитесь, что вы ввели верный пароль. + Невозможно расшифровать резервную копию с помощью этого пароля: убедитесь, что вы ввели правильный пароль. Ключи шифрования копируются на сервер в фоновом режиме. Первое копирование может занять несколько минут. Генерация ключей восстановления с использованием парольной фразы может занять несколько секунд. Ключ восстановления был сохранен в \'%s\'. @@ -1392,7 +1392,7 @@ Мне Использовать настройку Проверить сессию - Ваше устройство использует устаревший TLS протокол, уязвимый для атак, для вашей же безопасности вам отказано в подключении + Ваше устройство использует устаревший протокол безопасности TLS, уязвимый для атак, в целях безопасности вы не сможете подключиться Приложениям не нужно подключаться к домашнему серверу в фоновом режиме, это должно снизить расход заряда батареи Клавиша Ввод отправит сообщение вместо переноса строки Воспроизвести звук затвора @@ -1428,7 +1428,7 @@ В ожидании партнера, чтобы подтвердить … Проверено! Вы успешно подтвердили эту сессию. - Защищенные сообщения от этого пользователя шифруются end-to-end и не могут быть прочитаны третьими лицами. + Сообщения от этого пользователя защищены сквозным шифрованием и не могут быть прочитаны третьими лицами. Понял Ничего не появляется\? Не все клиенты пока поддерживают интерактивную проверку. Используйте устаревшую проверку. Используйте устаревшую проверку. @@ -1440,11 +1440,11 @@ \nПричина: %s Интерактивное подтверждение сессии Запрос на подтверждение - %s желает подтвердить ваше устройство + %s желает подтвердить вашу сессию Пользователь отменил проверку Время проверки истекло - Сессия не знает об этой транзакции - Сессия не может договориться о выработке общего ключе, хэше, MAC или методе SAS + Сессия не знает об этой сделке + Сессия не может договориться о выработке общего ключа, хэша, MAC или метод SAS Полученный хеш не соответствует SAS не соответствует Сессия получила неожиданное сообщение @@ -1458,18 +1458,18 @@ Стоп Проверка состояния резервного копирования Вы вышли из системы из-за недействительных или истекших учетных данных. - Редактировать + Изменить Ответить Повторить - Присоединитесь к комнате, чтобы начать использовать приложение. + Присоединитесь к комнате, чтобы начать пользоваться приложением. Отправил вам приглашение Приглашен %s - Вы в курсе! + Вы в теме! У вас больше нет непрочитанных сообщений Добро пожаловать домой! - Узнайте больше о непрочитанных сообщениях здесь - Беседа - Здесь будут отображаться ваши диалоги. Нажмите + внизу справа, чтобы начать. + Следите за непрочитанными сообщениями здесь + Беседы + Здесь будут отображаться ваши диалоги. Нажмите + внизу справа, чтобы начать что-то. Комнаты Здесь будут отображаться ваши комнаты. Коснитесь + внизу справа, чтобы найти существующие или создать свои. Реакции @@ -1481,11 +1481,11 @@ Менеджер интеграции не настроен. Реакции Событие удалено пользователем - Мероприятие, модерируемое администратором помещения + Событие модерируется администратором комнаты Последнее изменение %1$s %2$s - Некорректное событие, не может быть отображено + Некорректное событие, не могу отобразить Создать новую комнату - Сети нет. Пожалуйста, проверьте подключение к Интернету. + Нет сети. Пожалуйста, проверьте подключение к Интернету. Изменить Изменить сеть Пожалуйста, подождите… @@ -1497,18 +1497,18 @@ СОЗДАТЬ Имя Публичная - Любой сможет присоединиться к этой комнате - Каталог номеров - Опубликовать эту комнату в каталоге номеров + Каждый сможет присоединиться к этой комнате + Каталог комнат + Опубликовать эту комнату в каталоге комнат Произошла ошибка при получении информации о доверии Произошла ошибка при получении ключей резервного копирования данных - Импорт ключей e2e из файла \"%1$s\". + Импорт ключей сквозного шифрования из файла \"%1$s\". Версия Matrix SDK - Другие уведомления третьих сторон + Другие уведомления третьих лиц Вы уже просмотрели эту комнату! - Быстрое реагирование + Быстрые Реакции Общее - Параметры + Предпочтения Безопасность и конфиденциальность Профессионал Правила push-уведомлений @@ -1525,7 +1525,7 @@ Пожалуйста, напишите ваше предложение ниже. Опишите ваше предложение здесь Спасибо, предложение было успешно отправлено - Предложение не было отправлено (%s) + Не удалось отправить предложение (%s) Показать скрытые события в ленте сообщений Предварительный просмотр открытой комнаты в ${app_name} пока не поддерживается Диалоги @@ -1537,18 +1537,18 @@ Файл %1$s загружается… Файл %1$s был загружен! (изменено) - Редактирование сообщений + Изменение сообщения Изменения не найдены Отфильтровывать разговоры… Не можете найти то, что ищете\? Создать новую комнату - Отправить новое прямое сообщение - Просмотр список комнат + Отправить новое сообщение в диалог + Просмотр каталога комнат Имя или ID (#example:matrix.org) Включить жест смахивания для ответа в ленте сообщений Ссылка скопирована в буфер обмена Добавить по Matrix ID - Создание комнаты… + Создаем комнату… Результатов не найдено, используйте \"Добавить по matrix ID\" для поиска на сервере. Начните печатать, чтобы получить результат Фильтр по имени пользователя или ID… @@ -1556,13 +1556,13 @@ История изменений Обзор Отклонить - Для продолжения Вам необходимо принять Условия данного сервиса. + Для продолжения Вам необходимо принять Условия этого сервиса. Правила push-уведомлений не определены Нет зарегистрированных push-шлюзов - Условия предоставления услуг - Условия просмотра - Быть доступным для других - Используйте ботов, мосты, виджеты и стикеры + Условия использования + Условия отзыва + Быть видимым для других + Используйте ботов, мосты, виджеты и наборы стикеров Читать в Никто Отмена @@ -1587,7 +1587,7 @@ Предпочтительный интервал синхронизации Обнаружение Будет использовать %s в качестве помощника, если ваш домашний сервер не предлагает его (ваш IP-адрес будет доступен во время разговора) - Добавьте идентификационный сервер в свои настройки, чтобы выполнить это действие. + Добавьте сервер обнаружения в свои настройки, чтобы выполнить это действие. Режим фоновой синхронизации ${app_name} будет синхронизироваться в фоновом режиме таким образом, чтобы сохранить ограниченные ресурсы устройства (батарея). \nВ зависимости от состояния ресурса вашего устройства, синхронизация может быть отложена операционной системой. @@ -1599,35 +1599,35 @@ Изменить настройки обнаружения. Публичное имя (видимое для людей, с которыми вы общаетесь) Публичное имя сессии видны людям, с которыми вы общаетесь - Вы не используете какой-либо сервер идентификации - Идентификационный сервер не настроен, требуется сброс пароля. + Вы не используете какой-либо сервер обнаружения + Сервер обнаружения не настроен, требуется сброс пароля. Похоже, вы пытаетесь подключиться к другому домашнему серверу. Вы хотите выйти\? - Сервер идентификации - Отключить идентификационный сервер - Настроить идентификационный сервер - Изменить идентификационный сервер - В настоящее время вы используете %1$s для обнаружения и быть найденным вашими контактами. - Вы в настоящее время не используете идентификационный сервер. Чтобы обнаружить и быть найденным вашими существующими контактами, настройте один из них ниже. + Сервер обнаружения + Отключить сервер обнаружения + Настроить сервер обнаружения + Изменить сервер обнаружения + В настоящее время вы используете %1$s для обнаружения и доступны для обнаружения существующими знакомыми вам контактам. + Вы в настоящее время не используете сервер обнаружения. Чтобы обнаружить и быть найденным вашими существующими контактами, настройте один из них ниже. Видимые адреса электронной почты - Доступные номера телефонов + Видимые номера телефонов В ожидании - Введите адрес сервера идентификации - Не удалось подключиться к серверу идентификации - Пожалуйста, введите URL сервера идентификации - Сервер идентификации не имеет условий предоставления услуг + Введите адрес сервера обнаружения + Не удалось подключиться к серверу обнаружения + Пожалуйста, введите URL сервера обнаружения + Сервер обнаружения не имеет условий использования Параметры обнаружения появятся после добавления электронной почты. Параметры поиска появятся после добавления номера телефона. - Отключение от сервера идентификации будет означать, что другие пользователи не смогут обнаружить вас, и вы не сможете приглашать других по электронной почте или по телефону. + Отключение от сервера обнаружения будет означать, что другие пользователи не смогут обнаружить вас, и вы не сможете приглашать других по электронной почте или по телефону. Мы отправили вам электронное письмо с подтверждением на %s, проверьте вашу электронную почту и нажмите на ссылку для подтверждения - Выбранный сервер идентификации не имеет условий обслуживания. Продолжить, только если вы доверяете владельцу службы + Выбранный сервер обнаружения не имеет условий использования. Продолжайте, только если вы доверяете его владельцу Текстовое сообщение отправлено %s. Введите код проверки, который он содержит. - В настоящее время вы делитесь адресами электронной почты или телефонными номерами на сервере идентификации %1$s. Вам нужно повторно подключиться к %2$s, чтобы прекратить делиться ими. - Примите Условия обслуживания сервера идентификации (%s), чтобы разрешить обнаружение по адресу электронной почты или номеру телефона. + В настоящее время вы делитесь адресами электронной почты или телефонными номерами на сервере обнаружения %1$s. Вам нужно повторно подключиться к %2$s, чтобы прекратить делиться ими. + Примите Условия использования сервера обнаружения (%s), чтобы разрешить обнаружение по адресу электронной почты или номеру телефона. Включить подробные логи. Отправить вложение - Откройте навигационный ящик - Открыть меню создания комнаты - Неверный адрес сервера Matrix + Откройте панель навигации + Откройте меню создания комнаты + Это недействительный адрес сервера Matrix Подтвердите пароль Требуется аутентификация Интеграции @@ -1637,10 +1637,10 @@ Перезагрузить виджет Открыть в браузере ID виджета - Принять + Позволить Вы это не можете делать на мобильном ${app_name} Этот виджет был добавлен: - Ваши тема + Ваша тема ID комнаты Используйте менеджер интеграций чтобы управлять ботами, мостами, виджетами и наборами стикеров. \nМенеджеры интеграций получают данные о конфигурации, могут изменять виджеты, отправлять приглашения в комнаты и устанавливать права от вашего имени. @@ -1667,21 +1667,21 @@ Это спам Игнорировать пользователя Все сообщения - Только при упоминаниях + Только упоминания Настройки Покинуть комнату %1$s сделал(а) комнату доступной для всех, у кого есть ссылка. %1$s сделал(а) комнату доступной только по приглашению. - Подробные логи помогут разработчикам, предоставив больше информации, когда вы отправляете RageShake. Даже когда они разрешены, приложение не логирует ваши сообщения и другие приватные данные. - Отменить создание комнаты… + Подробные логи помогут разработчикам, предоставив больше информации, когда вы отправляете ВзмахЯрости. Даже когда они разрешены, приложение не записывает ваши сообщения и другие приватные данные. + Закройте меню создание комнаты… Вниз Контакт Стикер - Причина жалобы на контент - Пожаловаться + Причина жалобы на это содержимое + ЖАЛОБА ИГНОРИРОВАТЬ ПОЛЬЗОВАТЕЛЯ Все сообщения (громко) - Без звука + Заглушить Отправить данное сообщение под спойлером Спойлер Введите ключевые слова, чтобы найти реакцию. @@ -1689,9 +1689,9 @@ Непрочитанные сообщения Это ваш разговор. Владейте им. Общайтесь с людьми напрямую или в группах - Начать + Начнем Выберите сервер - Как и у электронной почты, у учётных записей один дом, хотя вы можете общаться с кем угодно + Как и у электронной почты, у учётных записей один дом, не смотря на это вы можете общаться с кем угодно Премиум-хостинг для организаций Узнать больше Другой @@ -1703,12 +1703,12 @@ Зарегистрироваться Войти в систему Продолжить с SSO - Модульный адрес + Element Matrix Services Адрес Адрес Премиум-хостинг для организаций - Введите адрес Modular Element или сервера, который вы хотите использовать + Введите адрес Modular Element или Сервер, который вы хотите использовать Произошла ошибка при загрузке страницы: %1$s (%2$d) - Приложение не может войти на этот сервер, так как он поддерживает следующие типы входа: %1$s. + Приложение не может войти на этот домашний сервер. Домашний сервер поддерживает следующие типы входа: %1$s. \n \nВы хотите войти с помощью веб-клиента\? Извините, этот сервер не принимает новые учётные записи. @@ -1718,15 +1718,15 @@ Этот адрес электронной почты не связан ни с одной учетной записью. Сбросить пароль на %1$s Далее - Email + Электронная почта Новый пароль - Внимание! + Предупреждение! Смена пароля приведёт к сбросу всех сквозных ключей шифрования во всех ваших сессиях, что сделает зашифрованную историю разговоров нечитаемой. Настройте резервное копирование ключей или экспортируйте ключи от комнаты из другой сессии, прежде чем сбрасывать пароль. Продолжить - Данный email не связан ни с одним аккаунтом + Данный электронный ящик не связан ни с одним аккаунтом Проверьте свою почту Письмо с подтверждением было отправлено на %1$s. - Нажмите на ссылку, чтобы подтвердить свой новый пароль. Как только вы перейдете по ссылке, которую он содержит, нажмите ниже. + Нажмите на ссылку, чтобы подтвердить свой новый пароль. Как только вы перейдете по ссылке нажмите ниже. Успешно! Ваш пароль был сброшен. Вы вышли из всех сессий и больше не будете получать push-уведомления. Чтобы возобновить уведомления, войдите снова на каждом устройстве. @@ -1737,10 +1737,10 @@ \nОстановить процесс смены пароля\? Задать адрес электронной почты Электронная почта - Электронная почта (по желанию) + Электронная почта (необязательно) Далее Установить номер телефона - Укажите номер своего телефона, чтобы разрешить знакомым найти вас. + Укажите номер своего телефона, чтобы разрешить людям найти вас. Пожалуйста, используйте международный формат. Номер телефона Номер телефона (необязательно) @@ -1751,9 +1751,9 @@ Отправить повторно Далее Международные телефонные номера должны начинаться с \'+\' - Номер телефона кажется недействительным. Пожалуйста, проверьте его + Номер телефона выглядит недействительным. Пожалуйста, проверьте его Зарегистрироваться в %1$s - Имя пользователя или email + Имя пользователя или электронная почта Имя пользователя Пароль Далее @@ -1764,11 +1764,11 @@ \nОстановить процесс регистрации\? Выбрать matrix.org Выбрать Element Matrix Services - Выбрать другой сервер + Выбрать пользовательский домашний сервер Пожалуйста, пройдите проверку капчей Примите условия для продолжения - Пожалуйста, проверьте ваш email - Мы только что отправили email на %1$s. + Пожалуйста, проверьте ваш электронный почтовый ящик + Мы только что отправили письмо на %1$s. \nПожалуйста, нажмите на содержащуюся в нём ссылку, чтобы продолжить создание аккаунта. Домашний сервер устарел Этот домашний сервер использует слишком старую версию для подключения. Попросите администратора обновить домашний сервер. @@ -1804,7 +1804,7 @@ Очистить данные Текущая сессия предназначена для пользователя %1$s, а вы предоставляете учётные данные для пользователя %2$s. Это не поддерживается в ${app_name}. \nПожалуйста, сначала очистите данные, а затем снова войдите под другим аккаунтом. - Ваша ссылка на matrix.to неверна + Ваша ссылка на matrix.to была испорчена Описание слишком короткое Посмотреть все мои сессии Дополнительные настройки @@ -1838,9 +1838,9 @@ В этой комнате нет медиафайлов ФАЙЛЫ В этой комнате нет файлов - Это недопустимо + Это неуместно Другая причина… - Пожаловаться на контент + Пожаловаться на это содержимое Безопасность Ещё QR-код @@ -1891,30 +1891,30 @@ Произошла ошибка при загрузке вложения. %1$s %2$s Жалоба отправлена - Жалоба на контент отправлена. -\n -\nЕсли вы не хотите видеть контент этого пользователя, вы можете его игнорировать, чтобы скрыть его сообщения. + Жалоба на контент отправлена. +\n +\nЕсли вы больше не хотите видеть от этого пользователя любого содержимого, вы можете его игнорировать, чтобы скрыть его сообщения. Отмечено как спам - Этот контент был отмечен как спам. -\n -\nЕсли вы не хотите видеть контент этого пользователя, вы можете его игнорировать, чтобы скрыть его сообщения. - Жалоба на неприемлемое содержание отправлена - Этот контент был отмечен как неприемлемый. -\n -\nЕсли вы не хотите видеть контент этого пользователя, вы можете его игнорировать, чтобы скрыть его сообщения. + Это содержимое было отмечен как спам. +\n +\nЕсли вы больше не хотите видеть любое содержимое этого пользователя, вы можете его игнорировать, чтобы скрыть его сообщения. + Жалоба на неуместное содержание отправлена + Этот контент был отмечен как неприемлемый. +\n +\nЕсли вы больше не хотите видеть от этого пользователя любого содержимого, вы можете его игнорировать, чтобы скрыть его сообщения. Они совпадают Они не совпадают - Закрыть окно бэкапа ключей + Закрыть окно резервного копирования ключей %s прочитано Не удалось обработать данные - ${app_name} требуются права для сохранения ваших ключей шифрования на диск. + ${app_name} требуются права для сохранения ваших ключей сквозного шифрования на диск. \n \nПожалуйста, разрешите доступ в следующем всплывающем окне, чтобы экспортировать ключи вручную. - Нет подключения к сети + Сейчас нет подключения к сети Воспроизвести Приостановить Копировать - Выполнено + Удачно Уведомления Звонок не состоялся Не удалось установить соединение реального времени. @@ -1936,7 +1936,7 @@ Отменить приглашение Снизить собственные полномочия\? Отклонить - Вы не сможете отменить это изменение, поскольку вы понижаете себя в должности, а если вы последний привилегированный пользователь в комнате, то восстановить привилегии будет невозможно. + Вы не сможете отменить это изменение, поскольку вы понижаете собственный полномочия, а если вы последний привилегированный пользователь в комнате, то восстановить привилегии будет невозможно. Понизить Игнорировать пользователя Игнорирование этого пользователя приведет к удалению его сообщений из общих комнат. @@ -1948,13 +1948,13 @@ Вы уверены, что хотите отменить приглашение для этого пользователя\? Выгнать пользователя Причина гонения - Выгнанный пользователь будет удалён из этой комнаты. + Пользователь будет выгнан из этой комнаты. \n -\nЧтобы предотвратить его повторное присоединение, вы должны забанить его. +\nЧтобы предотвратить его повторное присоединение, вы должны заблокировать его. Заблокировать пользователя Причина блокировки Разблокировать пользователя - Разблокирование пользователя позволит ему снова присоединиться к комнате. + Разблокирование пользователя позволит ему присоединиться к комнате опять. Безопасное резервное копирование Управление Настройка безопасного резервного копирования @@ -1977,7 +1977,7 @@ Безопасное резервное копирование Защита от потери доступа к зашифрованным сообщениям и данным Настроить безопасное резервное копирование - Добавьте специальную вкладку для непрочитанных уведомлений на главном экране. + Добавьте отдельную вкладку для непрочитанных уведомлений на главном экране. Прочитал %d пользователь Прочитано %d пользователями @@ -1991,35 +1991,35 @@ Вы не игнорируете никаких пользователей Вы сделали комнату доступной для всех, у кого есть ссылка. Вы сделали комнату только по приглашению. - Сохраняйте приватность ваших переписок с помощью шифрования + Сохраняйте конфиденциальность разговоров с помощью шифрования Расширьте и персонализируйте свой опыт использования Присоединяйтесь к миллионам бесплатно на крупнейшем публичном сервере Войти в %1$s Введите адрес сервера, который вы хотите использовать - На ваш почтовый ящик будет отправлено письмо с подтверждением установки нового пароля. + На ваш почтовый ящик будет отправлено письмо для подтверждения установки нового пароля. Я подтвердил свою электронную почту Установите адрес электронной почты для восстановления вашей учетной записи. Позже вы можете дополнительно разрешить людям, которых вы знаете, обнаружить вас по электронной почте. Введенный код неверен. Пожалуйста, проверьте. Кроме того, если у вас уже есть учетная запись и вы знаете свой идентификатор Matrix и пароль, вы можете использовать этот метод: - Войти с помощью Matrix ID - Войти с помощью Matrix ID + Войти с Matrix ID + Войти с Matrix ID Если вы создаете учетную запись на домашнем сервере, используйте свой матричный идентификатор (например, @user:domain.com) и пароль ниже. Matrix ID Если вы не знаете свой пароль, вернитесь, чтобы сбросить его. Это недопустимый идентификатор пользователя. Ожидаемый формат: \'@user:homeserver.org\' Не удалось найти действительный домашний сервер. Пожалуйста, проверьте свой идентификатор - Первичная синхронизация… - Rageshake + Начальная синхронизация… + СотрясениеЯрости Порог обнаружения Встряхните телефон, чтобы проверить порог обнаружения - Тряска зафиксирована! + Обнаружено потрясение! Показываем только первые результаты, наберите больше букв… Раннее падение ${app_name} может падать чаще, когда происходит непредвиденная ошибка Добавляет смайл ¯\\_(ツ)_/¯ в начало сообщения - После включения шифрования оно не может быть отключено. + После включения шифрования его нельзя отключить. Ваш почтовый домен не имеет права регистрироваться на этом сервере - Проверьте этого пользователя, подтвердив, что следующие уникальные смайлики появляются на его экране в том же порядке. + Проверьте этого пользователя, подтвердив, что следующие уникальные эмодзи появляются на его экране в том же порядке. Для максимальной безопасности используйте другое надежное средство связи или сделайте это лично. Ищите зеленый щит, чтобы убедиться, что пользователь доверенный. Доверяйте всем пользователям в комнате, чтобы обеспечить безопасность комнаты. Не безопасно @@ -2027,8 +2027,8 @@ \n \n— Ваш домашний сервер \n— Домашний сервер, к которому подключен пользователь, которого вы проверяете -\n— Ваше или подключение к интернету других пользователей -\n— Ваше или устройство других пользователей +\n— Ваше подключение к интернету или других пользователей +\n— Ваше устройство или других пользователей Видео. Изображение. Аудио @@ -2044,26 +2044,26 @@ Подтвердите эту сессию Подтверждение вручную Вы - Сканируйте код с помощью устройства другого пользователя, чтобы надежно проверить друг друга + Сканируйте код с помощью устройства другого пользователя, чтобы безопасно проверить друг друга Сканировать их код Невозможно сканировать - Если вы не можете лично, сравните эмодзи в таком случае + Если вы не можете лично, сравните вместо этого эмодзи Подтвердить при помощи сравнения эмодзи Подтверждение с помощью эмодзи - Если вы не можете отсканировать приведенный выше код, проверьте это, сравнив короткий уникальный набор эмодзи. + Если вы не можете отсканировать приведенный выше код, проверьте сравнивая короткий уникальный набор эмодзи. Изображение QR-кода Подтверждено %s Подтверждённых %s - Ожидание для %s… - Для дополнительной безопасности проверьте %s, проверив одноразовый код на обоих ваших устройствах. + Ожидаем %s… + Для особой безопасности проверьте %s, проверив одноразовый код на обоих ваших устройствах. \n \nДля максимальной безопасности сделайте это лично. - Сообщения в этой комнате не шифруются сквозным шифрованием. - Сообщения в этой комнате шифруются сквозным шифрованием. + Сообщения в этой комнате не защищены сквозным шифрованием. + Сообщения в этой комнате защищены сквозным шифрованием. \n -\nВаши сообщения защищены замками, и только у вас и получателя есть уникальные ключи, чтобы разблокировать их. +\nВаши сообщения защищены замками и только вы и получатель имеете уникальные ключи для их разблокировки. Действия Администратора - Покинуть комнату… + Покидаем комнату… Пользовательский Приглашения Администратор в %1$s @@ -2080,32 +2080,32 @@ Посылает сообщение, окрашенное в цвет радуги Посылает данную эмоцию, окрашенную в цвет радуги Редактор сообщений - Включить сквозное шифрование… + Включаем сквозное шифрование… После включения шифрования оно не может быть отключено. - Активировать шифрование\? - После включения шифрование для комнаты не может быть отключено. Сообщения, отправленные в зашифрованном помещении, не могут быть замечены сервером, только участниками помещения. Включение шифрования может помешать правильной работе многих ботов и мостов. - Активировать шифрование - Чтобы быть в безопасности, проверьте %s, проверив одноразовый код. - Чтобы обезопасить себя, сделайте это лично или используйте другой способ общения. + Включить шифрование\? + После включения шифрование для комнаты нельзя отключить. Сообщения отправленные в зашифрованной комнате не будут видны серверу, только участникам комнаты. Включение шифрования может помешать правильной работе многих ботов и мостов. + Включить шифрование + В целях безопасности, подтвердите %s, проверив одноразовый код. + В целях безопасности, сделайте это лично или используйте другой способ общения. Сравните уникальные эмодзи, убедившись, что они появились в том же порядке. Сравните код с тем, который отображается на экране другого пользователя. - Сообщения с этим пользователем полностью зашифрованы и не могут быть прочитаны третьими лицами. - Ваша новая сессия теперь подтверждена. Она имеет доступ к вашим зашифрованным сообщениям, и другие пользователи будут считать её надежной. - Кросс-подпись - Кросс-подпись включена -\nПриватные ключи хранятся на устройстве. - Кросс-подпись включена -\nКлючи являются надёжными. -\nПриватные ключи неизвестны - Кросс-подпись включена. -\nКлючи являются ненадёжными - Кросс-подпись выключена + Сообщения от этого пользователя зашифрованы сквозным шифрованием и не смогут быть прочитаны третьими лицами. + Ваша новая сессия подтверждена. У нее есть доступ к вашим зашифрованным сообщениям, а другие пользователи увидят его как доверенное. + Перекрестная подпись + Перекрестная подпись включена +\nЛичные ключи хранятся на устройстве. + Перекрестная подпись включена +\nКлючи являются доверенными. +\nЛичные ключи неизвестны + Перекрестная подпись включена. +\nКлючи не являются доверенными + Перекрестная подпись выключена Администратор вашего сервера отключил сквозное шифрование по умолчанию в приватных комнатах и диалогах. Активные сессии Показать все сессии Управление сессиями Выйти из этой сессии - Нет доступного шифрования информации + Нет доступной криптографической информации %d сессия активна %d сессии активны @@ -2129,19 +2129,19 @@ Сообщения, содержащие @room Отладка Настройки важности уведомлений для событий - Используйте последнюю версию ${app_name} на других ваших устройствах, веб-клиент ${app_name}, ${app_name} для ПК, ${app_name} для iOS, ${app_name} для Android или другой клиент Matrix, поддерживающий кросс-подпись + Используйте последнюю версию ${app_name} на других ваших устройствах, веб-клиент ${app_name}, ${app_name} для ПК, ${app_name} для iOS, ${app_name} для Android или другой клиент Matrix, поддерживающий перекрестную подпись Используйте последнюю версию ${app_name} на других ваших устройствах: Подтвердите новую сессию вашей учетной записи: %1$s Настроить безопасное резервное копирование Безопасное резервное копирование - Эта сессия является доверенной для безопасного обмена сообщениями, потому что вы проверили её: + Эта сессия является надежной для безопасного обмена сообщениями, поскольку вы подтвердили ее: Подтвердите эту сессию, чтобы пометить её доверенной и предоставить ей доступ к зашифрованным сообщениям. Если вы не входили в эту сессию, ваша учетная запись может быть скомпрометирована: Другие пользователи могут не доверять ему Завершите настройку безопасности - Верифицировать - Верифицировано - Внимание - Ошибка получения списка сессий + Проверить + Проверено + Предупреждение + Не удалось получить список сессий Сессии Доверенные Недоверенные @@ -2150,7 +2150,7 @@ Создать простой опрос Новый вход Пока этот пользователь не доверяет этой сессии, сообщения, отправленные в обе стороны, помечаются предупреждениями. Кроме того, вы можете подтвердить сессию вручную. - Инициализировать кросс-подпись + Начать перекрестную подпись Сбросить ключи Почти готово! Показывает ли %s галочку\? Да @@ -2159,7 +2159,7 @@ Не удалось найти данные в хранилище Введите парольную фразу для секретного хранилища Предупреждение: - Вы должны получать доступ к секретному хранилищу только с доверенного устройства + Вам следует получать доступ к секретному хранилищу только с доверенного устройства Вы хотите отправить это вложение в %1$s\? Отправить изображение в оригинальном размере @@ -2168,7 +2168,7 @@ Подтвердите удаление Вы уверены, что хотите скрыть (удалить) это событие\? Обратите внимание, что если вы удалите название комнаты или измените тему, это может отменить изменение. - Указать причину + Укажите причину Причина редактирования Событие удалено пользователем, Причина: %1$s Событие модерируется администратором комнаты, Причина: %1$s @@ -2179,10 +2179,10 @@ Нажмите, чтобы просмотреть и проверить Это был не я Ваш аккаунт может оказаться под угрозой - Если вы прервёте процедуру, то не сможете читать зашифрованные сообщения на этом устройстве, а другие пользователи не будут доверять ему - Если вы прервёте процедуру, то не сможете читать зашифрованные сообщения на своем новом устройстве, а другие пользователи не будут доверять ему + Если вы прервёте процедуру, то не сможете читать зашифрованные сообщения на этом устройстве, а другие пользователи не захотят доверять ему + Если вы прервёте процедуру, то не сможете читать зашифрованные сообщения на своем новом устройстве, а другие пользователи не захотят доверять ему Если вы прервёте процедуру, пользователь %1$s (%2$s) не будет подтверждён. Начните заново в профиле этого пользователя. - Что-то из этого может быть скомпрометировано: + Что-то из этого может быть поставлено под угрозу: \n \n- Ваш пароль \n- Ваш домашний сервер @@ -2212,7 +2212,7 @@ Синхронизация ключа пользователя Синхронизация ключа самоподписи Настройка резервного копирования ключей - Сохраните на USB-флешку или резервный диск + Сохраните на USB-ключ или резервное хранилище Скопируйте в персональное облачное хранилище Вы не можете сделать это с телефона Шифрование этой комнаты не поддерживается @@ -2227,7 +2227,7 @@ Посылает сообщение в виде простого текста, не интерпретируя его как разметку Неверное имя пользователя и/или пароль. Введенный пароль начинается или заканчивается пробелами, пожалуйста, проверьте. Эта учётная запись была деактивирована. - Активировать кросс-подпись + Включить перекрестную подпись Введите %s, чтобы продолжить Использовать файл Введите %s @@ -2250,7 +2250,7 @@ \n${app_name} для ПК ${app_name} для iOS \n${app_name} для Android - или другой, поддерживаемый кросс-подпись Matrix клиент + или другой клиент Matrix поддерживающий перекрестную подпись Принудительно отбрасывает текущую групповую сессию для отправки сообщений в зашифрованную комнату Чтобы продолжить, используйте ваш %1$s или используйте ваш %2$s. Используйте ключ восстановления @@ -2259,7 +2259,7 @@ Не удалось получить доступ к защищенному хранилищу данных Не зашифровано Зашифровано неподтверждённой сессией - Проверьте, где вы вошли + Посмотрите, где вы вошли Подтвердите все свои сессии, чтобы убедиться в безопасности вашей учетной записи и сообщений Ручная проверка с помощью текста Пометить как надежный @@ -2292,7 +2292,7 @@ Для вашей приватности, ${app_name} поддерживает отправку адреса электронной почты и номера телефона только в хэшированном виде. Привязка не удалась. Текущая взаимосвязь с этим идентификатором отсутствует. - Ваш домашний сервер (%1$s) предлагает использовать %2$s для вашего сервера идентификации + Ваш домашний сервер (%1$s) предлагает использовать %2$s для вашего сервера обнаружения Использовать %1$s Кроме того, вы можете ввести любой другой URL-адрес сервера идентификации Введите URL-адрес сервера идентификации @@ -2322,7 +2322,7 @@ Вы успешно изменили настройки комнаты У вас нет доступа к этому сообщению Расшифровка этого сообщения может занять некоторое время - Не удалось расшифровать + Не могу расшифровать Из-за сквозного шифрования вам, возможно, придется ждать прибытие чьего-либо сообщения, потому что ключи шифрования не были отправлены вам должным образом. Вы не можете получить доступ к этому сообщению, потому что вы были заблокированы отправителем Нет доступа к этому сообщению, так как отправитель не доверяет вашей сессии @@ -2358,7 +2358,7 @@ Для сброса PIN-кода нажмите Забыл(а) PIN-код, чтобы выйти из сессии и сбросить его. Подтвердите PIN-код, чтобы отключить PIN-код Предотвращение случайных звонков - Спрашивать подтверждение перед звонком + Запрашивать подтверждение перед началом звонка У вас нет разрешения на запуск конференции в этой комнате Конференция уже идет! Начать видеовстречу @@ -2390,7 +2390,7 @@ Предупреждение! Последняя оставшаяся попытка перед выходом из системы! Слишком много ошибок, вы вышли из системы - Этот номер телефона уже определён. + Этот номер телефона уже используется. В ваш аккаунт не добавлен номер телефона Адрес электронной почты В ваш аккаунт не добавлен адрес электронной почты @@ -2410,7 +2410,7 @@ %d секунд Показать события статуса участников комнаты - Включает в себя события приглашения/ присоединения/выхода/удаления/блокировки и изменение аватара/отображаемого имени. + Включает в себя события приглашения/присоединения/выхода/удаления/события блокировки и изменение аватара/изменения отображаемого имени. Опрос Отреагировал: %s Результат проверки @@ -2441,10 +2441,10 @@ Сообщения в этой комнате зашифрованы сквозным шифрованием. Покинуть Настройки - Сообщения здесь зашифрованы. + Сообщения здесь защищены сквозным шифрованием. \n \nВаши сообщения защищены замками, и только у вас и получателя есть уникальные ключи для их разблокировки. - Сообщения здесь не зашифрованы. + Сообщения здесь не прошли сквозного шифрования. На этом домашнем сервере работает старая версия. Попросите администратора вашего домашнего сервера выполнить обновление. Вы можете продолжить, но некоторые функции могут работать некорректно. Вы сделали доступ только по приглашению. %1$s сделал(а) доступ только по приглашению. @@ -2477,17 +2477,17 @@ Приложение ожидает push-уведомление Тестирование push-уведомлений Есть несохраненные изменения. Отменить изменения\? - Удалить из низкого приоритета + Удалить из маловажного Повернуть и обрезать Настройки комнаты - Тема комнаты (опционально) + Тема комнаты (необязательно) Отменить изменения Комната ещё не создана. Отменить создание комнаты\? - Добавить к низкому приоритету + Добавить к маловажному Добавить изображение из Тема Название комнаты - Вы дали свое согласие на отправку электронных писем и телефонных номеров на этот сервер идентификации для обнаружения других пользователей из ваших контактов. + Вы дали свое согласие на отправку электронных писем и телефонных номеров на этот сервер обнаружения для обнаружения других пользователей из ваших контактов. Добавить по QR-коду Разрешить доступ к вашим контактам. Чтобы отсканировать QR-код, вам нужно разрешить доступ к камере. @@ -2523,12 +2523,12 @@ Скрыть дополнительные настройки Показать дополнительные настройки %1$d из %2$d - Согласны ли вы на отправку своих контактных данных (номера телефонов и/или электронную почту) на настроенный сервер идентификации (%1$s) для обнаружения контактов\? + Согласны ли вы на отправку своих контактных данных (номера телефонов и/или электронной почты) на настроенный сервер идентификации (%1$s) для обнаружения контактов\? \n \nДля большей конфиденциальности отправленные данные перед отправкой будут хешированы. Дать согласие Отозвать моё согласие - Вы не дали свое согласие на отправку электронной почты и номеров телефонов на этот сервер идентификации для обнаружения других пользователей из ваших контактов. + Вы не дали свое согласие на отправку электронной почты и номеров телефонов на этот сервер обнаружения для обнаружения других пользователей из ваших контактов. Больше никаких результатов Предложения Контакты @@ -2613,8 +2613,8 @@ У вас нет права доступа на обновление ролей, необходимых для изменения различных параметров комнаты Выберите роли, которые смогут менять различные параметры комнаты Просматривайте и обновляйте роли, необходимые для изменения различных параметров комнаты. - Права доступа - Права доступа комнаты + Разрешения + Разрешения комнаты Эта комната не публичная. Вы не сможете повторно присоединиться без приглашения. Системная тема Не удалось пройти аутентификацию @@ -2698,14 +2698,14 @@ Изображение Импорт ключа из файла Открытые виджеты - Скриншот + Снимок экрана %d запись %d записи %d записей %d записей - Лимит неизвестен. + Предел неизвестен. Ваш домашний сервер принимает вложения (файлы, медиа и т.д.) размером до %s. Лимит загрузки файла сервера Версия сервера @@ -2713,9 +2713,9 @@ Настройки комнаты Покинуть текущую конференцию и перейти к другой\? Версия комнаты - Показать все комнаты в списке комнат, в том числе с чувствительным содержанием. - Показать комнаты с деликатным содержанием - Список комнат + Показать все комнаты в списке комнат, в том числе с откровенным содержанием. + Показать комнаты с откровенным содержанием + Каталог комнат Новое значение Сменить Начальная синхронизация: @@ -2738,18 +2738,18 @@ Модернизировать публичную комнату Обновление Пожалуйста, будьте терпеливы, это может занять некоторое время. - Присоединиться к изменённой комнате + Присоединиться к замещенной комнате В настоящее время люди не могут присоединиться к созданным вами приватным комнатам. \n \nМы улучшим это в рамках бета-версии, но мы просто хотели сообщить вам об этом. Пространства для членов команды еще не совсем готовы, но вы все еще можете их попробовать - Комната без названия + Безымянная Комната Некоторые комнаты могут быть скрыты, потому что они приватные, и вам нужно приглашение. Некоторые комнаты могут быть скрыты, потому что они приватные, и вам нужно приглашение. \nУ вас нет разрешения на добавление комнат. В этом пространстве нет комнат - Для получения дополнительной информации обратитесь к администратору домашнего сервера - Похоже, что ваш домашний сервер пока не поддерживает пространства + Для получения дополнительной информации обратитесь к администратору вашего домашнего сервера + Похоже, что ваш домашний сервер пока не поддерживает Пространства Чувствуете себя экспериментатором\? \nВы можете добавить существующие пространства в пространство. Управление комнатами и пространствами @@ -2770,12 +2770,12 @@ Вы здесь единственный человек. Если вы уйдёте, никто не сможет присоединиться в будущем, включая вас. Покинуть пространство Добавить комнаты - Список комнат + Исследуйте комнаты %d человек, которого вы знаете, уже присоединился - %d человека, которых вы знаете, уже присоединились - %d человек, которых вы знаете, уже присоединились - %d человек, которых вы знаете, уже присоединились + %d людей, которых вы знаете, уже присоединились + %d людей, которых вы знаете, уже присоединились + %d людей, которых вы знаете, уже присоединились Добро пожаловать в %1$s, %2$s. Вы ещё не находитесь ни в одной комнате. Ниже приведены некоторые предлагаемые комнаты, но вы можете посмотреть другие с помощью зелёной кнопки внизу справа. @@ -2806,7 +2806,7 @@ Мы создадим для них комнаты. Позже вы сможете добавить и другие. Какие обсуждения вы хотите провести в %s\? Дайте ему название, чтобы продолжить. - Добавьте некоторые детали, чтобы помочь людям идентифицировать его. Вы сможете изменить их в любой момент. + Добавьте некоторые детали, чтобы помочь людям распознать его. Вы сможете изменить их в любой момент. Добавьте некоторые детали, чтобы помочь ему выделиться. Вы сможете изменить их в любой момент. Создание пространства Только по приглашениям, лучше для себя или команды @@ -2859,9 +2859,9 @@ Сжатие видео %d%% Сжатие изображения… Дать отзыв - Отзыв не отправлен (%s) + Не удалось отправить отзыв (%s) Спасибо, ваш отзыв успешно отправлен - Вы можете связаться со мной, если у вас возникнут какие-либо последующие вопросы + Вы можете связаться со мной, если у вас есть дополнительные вопросы Вы используете бета-версию пространств. Ваши отзывы помогут при разработке следующих версий. Ваша платформа и имя пользователя будут отмечены, чтобы мы могли максимально использовать ваш отзыв. Отзыв Извините, при попытке присоединиться к конференции произошла ошибка @@ -2872,12 +2872,12 @@ Ваш сервер Любой человек в пространстве с этой комнатой может найти её и присоединиться к ней. Только администраторы этой комнаты могут добавить её в пространство. Только участники пространства - Любой желающий может найти комнату и присоединиться + Каждый может найти комнату и присоединиться Публичный Только приглашенные люди могут найти и присоединиться Приватный Неизвестная настройка доступа (%s) - Любой может постучаться в комнату, участники могут принять или отклонить его + Любой может постучаться в комнату, а участники могут принять или отклонить его Просмотреть и управлять адресами этого пространства. Разрешить гостям присоединяться Продолжить в любом случае @@ -2951,9 +2951,9 @@ Свяжите этот адрес электронной почты с вашей учетной записью Приглашение в эту комнату было отправлено на %s, который не связан с вашей учетной записью Приглашение в это пространство было отправлено на %s, который не связан с вашей учетной записью - Чтобы помочь участникам пространства найти и присоединиться к приватной комнате, перейдите в настройки этой комнаты, нажав на аватар. - Помогите участникам пространства в поиске приватных комнат - Это позволяет комнатам оставаться приватными для пространства, в то же время позволяя людям в пространстве находить их и присоединяться к ним. Все новые комнаты в пространстве будут иметь эту опцию. + Чтобы помочь участникам пространства найти и присоединиться к частной комнате, перейдите в настройки этой комнаты, нажав на ее аватар. + Помогите участникам пространства в поиске частных комнат + Это позволяет комнатам оставаться приватными для пространства, в то же время позволяя людям в пространстве находить их и присоединяться к ним. Все новые комнаты в пространстве будут иметь эту возможность. Помогите людям в пространствах самим находить и присоединяться к приватным комнатам, без необходимости вручную приглашать всех. Новое: Позволяет людям в пространствах находить и присоединяться к приватным комнатам Начался групповой вызов @@ -2963,7 +2963,7 @@ %1$s Нажмите, чтобы вернуться Активный вызов (%1$s) · - Активный вызов · + %1$d Активный вызов · %1$d активных вызова · %1$d активных вызовов · %1$d активных вызовов · @@ -3016,7 +3016,7 @@ Завершение настройки Приглашение по электронной почте, поиск контактов и многое другое… Завершите настройку обнаружения. - В настоящее время вы не используете сервер идентификации. Чтобы приглашать членов команды и быть доступным для них, настройте один из них ниже. + В настоящее время вы не используете сервер обнаружения. Чтобы приглашать членов команды и быть доступным для них, настройте один из них ниже. Приглашение по имени пользователя или по почте Убедитесь, что нужные люди имеют доступ к %s. Вы можете пригласить больше людей позже. Кто ваши члены команды\? @@ -3028,36 +3028,36 @@ Открыть настройки обнаружения Поиск по имени, ID или почте Создать новое пространство - Любой желающий может найти это пространство и присоединиться + Каждый может найти это пространство и присоединиться Доступ к пространству Кто имеет к этому доступ\? Включить уведомления по электронной почте для %s Чтобы получать уведомления по электронной почте, пожалуйста, привяжите электронную почту к вашей учетной записи Matrix Уведомление по эл. почте - Обновление пространства + Обновить пространство Изменить название пространства Включить шифрование пространства Изменить основной адрес для пространства Изменить аватар пространства - У вас нет разрешения на обновление ролей, необходимых для изменения различных частей этого пространства - Выберите роли, необходимые для изменения различных частей этого пространства + У вас нет разрешения на обновление ролей, необходимых для изменения различных параметров этого пространства + Выберите роли, необходимые для изменения различных параметров этого пространства Просмотр и обновление ролей, необходимых для изменения различных частей пространства. Разрешения пространства - Разблокирование пользователя позволит ему снова присоединиться к пространству. - Блокировка пользователя удалит его из этого пространства и не позволит ему присоединиться снова. - Выгнанный пользователь будет удалён из этого пространства. -\n + Разблокирование пользователя позволит ему присоединиться к пространству опять. + Блокировка пользователя удалит его из этого пространства и не позволит ему присоединиться вновь. + Пользователь будет выгнан из этого пространства. +\n \nЧтобы предотвратить его повторное присоединение, вы должны заблокировать его. Остановить запись - Добавляет ( ͡° ͜ʖ ͡°) к текстовому сообщению + Добавляет ( ͡° ͜ʖ ͡°) в начало сообщения Правила - Нет правил, предоставляемых сервером идентификации - Скрыть правила сервера идентификации - Показать правила сервера идентификации + Нет правил, предоставляемых сервером обнаружения + Скрыть правила сервера обнаружения + Показать правила сервера обнаружения Отображает информацию о пользователе Изменяет ваш аватар только в этой текущей комнате Меняет аватар текущей комнаты - Изменяет ваш отображаемый псевдоним только в текущей комнате + Изменяет ваш отображаемое имя только в текущей комнате Устанавливает имя комнаты Прекращение игнорирования пользователя, показывает его сообщения в дальнейшем Игнорирует пользователя, скрывая его сообщения от вас @@ -3071,7 +3071,7 @@ Загрузить файл Отправить изображения и видео Открыть камеру - Отображать местоположения пользователя на временной шкале + Показывать местоположения пользователя в ленте сообщений После включения вы сможете отправить свое местоположение в любую комнату Включить отправку местоположения Открыть с помощью @@ -3145,27 +3145,27 @@ Шифрование неправильно настроено Изменить цвет ника Восстановить шифрование - Пожалуйста, свяжитесь с администратором для восстановления шифрования в рабочее состояние. - Шифрование неправильно настроено. + Обратитесь к администратору, чтобы восстановить шифрование до рабочего состояния. + Шифрование настроено неправильно. Поделились своим местоположением У меня уже есть учетная запись Создать учетную запись - Общение вашей команды. - Со сквозным шифрованием и без требования номера телефона. Без рекламы или анализа данных. - Выберите, где общаться, что даст вам контроль и независимость. Подключено через Matrix. + Обмен сообщениями для вашей команды. + Сквозное шифрование не требующее номера телефона. Нет рекламы или сбора данных. + Выбор где хранятся ваши разговоры дает вам власть и независимость. Подключено с помощью Matrix. Безопасное и независимое общение, обеспечивающее вам такой же уровень конфиденциальности, как при личном общении в вашем собственном доме. - Усовершенствуйте общение в команде. - Защищенное общение. - Вы контролируете всё. - Владейте своими разговорами. + Удалите шлак из команд. + Безопасный обмен сообщениями. + Ваше управление. + Ваши собственные разговоры. Местоположение Вы согласны отправить эту информацию\? - Чтобы обнаружить существующие контакты, необходимо отправить контактную информацию (электронную почту и номера телефонов) на сервер идентификации. Мы хэшируем ваши данные перед отправкой для обеспечения конфиденциальности. - Чтобы обнаружить существующие контакты, необходимо отправить контактную информацию на сервер идентификации. + Чтобы обнаружить существующие контакты, необходимо отправить контактную информацию (электронную почту и номера телефонов) на сервер обнаружения. Мы хешируем ваши данные перед отправкой для обеспечения конфиденциальности. + Чтобы обнаружить существующие контакты, необходимо отправить контактную информацию на сервер обнаружения. \n -\nМы хэшируем ваши данные перед отправкой для обеспечения конфиденциальности. Согласны ли вы отправить эту информацию\? +\nМы хешируем ваши данные перед отправкой для обеспечения конфиденциальности. Вы согласны отправить эту информацию\? Отправить электронные адреса и номера телефонов %s - Ваши контакты приватны. Чтобы обнаружить пользователей из ваших контактов, нам необходимо ваше разрешение на отправку контактной информации на ваш сервер идентификации. + Ваши контакты приватны. Чтобы обнаружить пользователей из ваших контактов, нам необходимо ваше разрешение на отправку контактной информации на ваш сервер обнаружения. Системные настройки Версии Получите помощь в использовании Element @@ -3174,7 +3174,7 @@ Правовые положения Этот сервер не предоставляет никакой политики. Сторонние библиотеки - Политика вашего сервера идентификации + Политика вашего сервера опознавания Политика вашего домашнего сервера Политика ${app_name} Вы можете отключить это в любое время в настройках @@ -3185,10 +3185,10 @@ \n \nВы можете ознакомиться со всеми нашими условиями %s. Помогите улучшить Element - Сессия была завершена! + Сессия завершена! Комната покинута! - Шифрование было неправильно настроено, поэтому вы не можете отправлять сообщения. Нажмите, чтобы открыть настройки. - Шифрование было неправильно настроено, поэтому вы не можете отправлять сообщения. Пожалуйста, обратитесь к администратору, чтобы восстановить работу шифрования. + Шифрование неправильно настроено, поэтому вы не можете отправлять сообщения. Нажмите, чтобы открыть настройки. + Шифрование настроено неправильно, поэтому вы не можете отправлять сообщения. Пожалуйста, обратитесь к администратору, чтобы восстановить работу шифрования. Выберите домашний сервер Не могу связаться с домашним сервером на URL %s. Пожалуйста, проверьте вашу ссылку или выберите домашний сервер вручную. Не сейчас @@ -3199,7 +3199,7 @@ Показать все потоки в которых вы участвуете Все Потоки Просмотр Потоков - Вид в комнате + Посмотреть в комнате Показать всплывающие сообщения Не удалось загрузить карту Карта @@ -3215,12 +3215,12 @@ Мы поможем вам подключится. С кем вы будете общаться больше всего\? Вы уже просматриваете этот Поток! - Вид в Комнате + Просмотр в Комнате Ответить в Поток Команда «%s» распознается, но не поддерживается в потоках. Из Потока Совет: нажмите и удерживайте сообщение и используйте «%s». - Потоки помогают вести ваши разговоры тематически и легко отслеживающимися + Потоки помогают хранить ваши разговоры по темам и легко отслеживать их. Мои Потоки Показать все потоки в текущей комнате Фильтр From 98f339fed91e7770893ccdd8b3b3a10327e76f9d Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Fri, 18 Feb 2022 18:24:08 +0000 Subject: [PATCH 197/302] Translated using Weblate (Slovak) Currently translated at 97.7% (2723 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/ --- vector/src/main/res/values-sk/strings.xml | 189 ++++++++++++++-------- 1 file changed, 123 insertions(+), 66 deletions(-) diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml index 88cf02d87d..dd410031a8 100644 --- a/vector/src/main/res/values-sk/strings.xml +++ b/vector/src/main/res/values-sk/strings.xml @@ -28,7 +28,7 @@ pre všetkých členov. pre každého. neznámym (%s). - %1$s povolil/a E2E šifrovanie (%2$s) + %1$s povolil/a end-to-end šifrovanie (%2$s) %1$s požiadal/a o VoIP konferenciu Začala sa VoIP konferencia Skončila sa VoIP konferencia @@ -39,7 +39,7 @@ %1$s pozval/a %2$s vstúpiť do miestnosti %1$s prijal/a pozvanie pre %2$s ** Nie je možné dešifrovať: %s ** - Zo zariadenia odosieľateľa nebolo možné získať kľúče potrebné na dešifrovanie tejto správy. + Zariadenie odosielateľa nám neposlalo kľúče pre túto správu. Nie je možné vymazať Nie je možné odoslať správu Nepodarilo sa nahrať obrázok @@ -138,7 +138,7 @@ Prijali ste hovor. Ukončili ste hovor. Sprístupnili ste budúcu históriu miestnosti %1$s - Povolili ste E2E šifrovanie (%1$s) + Povolili ste end-to-end šifrovanie (%1$s) Aktualizovali ste túto miestnosť. Požiadali ste o VoIP konferenciu Odstránili ste názov miestnosti @@ -191,12 +191,12 @@ Povolili ste hosťom///návštevníkom prístup do tejto miestnosti. %1$s zakázal/a hosťom///návštevníkom prístup do tejto miestnosti. Zakázali ste hosťom///návštevníkom prístup do tejto miestnosti. - %1$s povolil/a E2E šifrovanie. - Povolili ste E2E šifrovanie. - %1$s povolil/a E2E šifrovanie (Nerozpoznaný algorytmus %2$s). - Povolili ste E2E šifrovanie (Nerozpoznaný algorytmus %1$s). - nastavili ste na servery pravidlá ACL tejto miestnosti. - %s nastavil(a) na servery pravidlá ACL tejto miestnosti. + %1$s povolil/a end-to-end šifrovanie. + Zapli ste end-to-end šifrovanie. + %1$s zapol end-to-end šifrovanie (nerozpoznaný algoritmus %2$s). + Zapli ste end-to-end šifrovanie (nerozpoznaný algoritmus %1$s). + Nastavili ste ACL servera pre túto miestnosť. + %s nastavil/a na serveri pravidlá ACL pre túto miestnosť. Aktualizovali ste sem. %s aktualizoval(a) sem. %1$s sprístupnil(a) budúce správy %2$s @@ -297,7 +297,7 @@ Nahlásiť chybu Prosím, Napíšte text hlásenia. Čo ste práve robili? Čo ste očakávali? Čo sa v skutočnosti udialo? Tu popíšte váš problém - S cieľom lepšej diagnostiky problému sa spolu s vašim hlásením odošlú záznami o činnosti programu Element. Toto hlásenie vrátane priložených záznamov a snímky obrazovky nebude verejne dostupné. Ak si želáte odoslať len text hlásenia, odškrtnite niektoré z nasledujúcich polí: + Za účelom diagnostiky problémov budú spolu s týmto hlásením o chybe odoslané záznamy z tohto klienta. Toto hlásenie o chybe, vrátane záznamov a snímku obrazovky, nebude verejne viditeľné. Ak chcete radšej odoslať len vyššie uvedený text, zrušte označenie: Zdá sa, že v zlosti trasiete zariadením. Chceli by ste odoslať hlásenie o chybe? Posledné spustenie aplikácie skončilo pádom. Chceli by ste odoslať hlásenie o chybe? Hlásenie o chybe bolo úspešne odoslané @@ -364,7 +364,7 @@ Nepodarilo sa overiť emailovú adresu: Uistite sa, že ste správne klikli na odkaz v emailovej správe Vaše heslo bolo obnovené. \n -\nBoli ste odhlásení na všetkých reláciach a nebudete viac dostávať okamžité oznámenia. Oznámenia znovu povolíte tak, že sa opätovne prihlásite na každom zariadení. +\nBoli ste odhlásení zo všetkých relácií a už nebudete dostávať okamžité oznámenia. Ak chcete opätovne povoliť oznámenia, znovu sa prihláste na každom zariadení. URL adresa musí začínať http[s]:// Nie je možné sa prihlásiť: Chyba siete Nie je možné sa prihlásiť @@ -472,7 +472,7 @@ Túto zmenu nebudete môcť vrátiť späť, pretože tomuto používateľovi udeľujete rovnakú úroveň moci, akú máte vy. \nSte si istí\? Ste si istí, že chcete pozvať používateľa %s do tejto miestnosti? - Pozvať zadaním používateľského ID + Pozvať pomocou ID LOKÁLNE KONTAKTY (%d) ADRESÁR POUŽÍVATEĽOV (%s) Len Matrix používatelia @@ -501,15 +501,15 @@ Odtlačok (%s): Nie je možné overiť totožnosť servera. Vaše zariadenie nedôveruje certifikátu poskytnutému serverom alebo sa niekto môže pokúšať odpočúvať vašu komunikáciu. - Ak vám aj správca servera môže potvrdiť, že certifikát nie je dôverihodný, uistite sa, že odtlačok zobrazený nižšie sa zhoduje s odtlačkom získaným od správcu. - Certifikát sa zmenil na taký, ktorý nie je viac dôverovaný vašim zariadením. Takáto zmena je veľmi nezvičajná. Navrhujeme, aby ste NEDÔVEROVALI tomuto novému certifikátu. - Vami overený certifikát sa zmenil na taký, ktorý nie je viac dôverovaný vašim zariadením. Je pravdepodobné, že správca servera obnovil certifikát. Na účel ručného overenia si prosím vyžiadajte nový odtlačok. + Ak správca servera uviedol, že sa to očakáva, skontrolujte, či sa odtlačok uvedený nižšie zhoduje s odtlačkom, ktorý poskytol. + Certifikát sa zmenil na iný, ktorému tento telefón dôveroval. Toto je VEĽMI NEZVYČAJNÉ. Odporúča sa, aby ste tento nový certifikát NEPRIJALI. + Certifikát sa zmenil z predtým dôveryhodného na nedôveryhodný. Server mohol obnoviť svoj certifikát. Obráťte sa na správcu servera, aby vám poskytol očakávaný odtlačok. Dôverujte certifikátu len v prípade, že správca servera zverejnil odtlačok zhodný s odtlačkom zobrazeným vyššie. Podrobnosti o miestnosti Ľudia Súbory Nastavenia - Nesprávny formát ID. Mali by ste zadať emailovú adresu alebo Matrix ID ako napríklad \'@lokálnaČasť:doména\' + Chybné ID. Mala by to byť emailová adresa alebo Matrix ID ako napríklad \"@lokalnacast:domena\" POZVANÍ VSTÚPILI Dôvod, prečo chcete ohlásiť tento obsah @@ -555,7 +555,7 @@ Správy obsahujúce moje používateľské meno Správy v priamych konverzáciách Správy v skupinových konverzáciách - Pozvania vstúpiť do miestnosti + Keď ma pozvú do miestnosti Audio / Video hovory Správy odosielané robotmi Spustiť po reštarte zariadenia @@ -623,11 +623,11 @@ \nUpozorňujeme, že táto akcia spôsobí reštart aplikácie a môže chvíľu trvať. Ste si istí, že chcete odstrániť tento cieľ oznámení? Ste si istí, že chcete odstrániť %1$s %2$s? - Vyberte krajnu - Krajnu - Prosím, vyberte krajnu + Vyberte si krajinu + Krajina + Prosím, vyberte si krajinu Telefónne číslo - Zadané číslo nie je správne pre vybratú krajnu + Neplatné telefónne číslo pre vybranú krajinu Overenie telefónneho čísla Odoslali sme vám SMS správu, ktorá obsahuje overovací kód. Prosím zadajte ho nižšie. Zadajte aktivačný kód @@ -665,11 +665,11 @@ Adresy Experimenty Tieto funkcie sú experimentálne a môžu sa nečakane pokaziť. Pri používaní buďte opatrní. - E2E šifrovanie - E2E šifrovanie je povolené + End-to-end šifrovanie + End-to-end šifrovanie je povolené Ak si želáte povoliť šifrovanie, musíte sa odhlásiť a následne prihlásiť znovu. - Šifrovať len známym reláciam - Nikdy neposielajte šifrované správy neovereným reláciam v tejto miestnosti z tejto relácie. + Šifrovať len pre overené relácie + Z tejto relácie nikdy neposielať šifrované správy neovereným reláciám v tejto miestnosti. Pre túto miestnosť nie sú žiadne lokálne adresy Nová adresa (napr. #foo:matrix.org) Nesprávny formát aliasu @@ -680,18 +680,18 @@ Zrušiť nastavenie ako hlavnej adresy Kopírovať ID miestnosti Kopírovať adresu miestnosti - V tejto miestnosti je povolené šifrovanie. - V tejto miestnosti nie je povolené šifrovanie. + V tejto miestnosti je zapnuté šifrovanie. + V tejto miestnosti vypnuté šifrovanie. Povoliť šifrovanie \n(Pozor: nie je možné ho znova vypnúť!) Adresár Vzhľad %s sa pokúšal zobraziť konkrétny bod v histórii tejto miestnosti, no zodpovedajúcu udalosť sa nepodarilo nájsť. - Informácie o E2E šifrovaní + Informácie o end-to-end šifrovaní Informácie o udalosti - Používateľské id + ID používateľa Kľúč totožnosti curve25519 - Údajne kľúč s odtlačkom prsta Ed25519 + Deklarovaný kľúč odtlačku Ed25519 Algoritmus ID relácie Chyba dešifrovania @@ -701,7 +701,7 @@ ID relácie Kľúč relácie Overenie - Odtlačok prsta Ed25519 + Odtlačok Ed25519 Exportovať šifrovacie kľúče miestnosti Exportovať kľúče miestnosti Exportovať kľúče do lokálneho súboru @@ -715,8 +715,8 @@ Importovať kľúče miestnosti Importovať kľúče z lokálneho súboru Importovať - Šifrovať len známym reláciam - Nikdy neposielať šifrované správy neovereným reláciam z tejto relácie. + Šifrovať len pre overené relácie + Nikdy neposielať šifrované správy neovereným reláciám z tejto relácie. Neoverené Overené Na čiernej listine @@ -989,7 +989,7 @@ Vykáže zadaného používateľa z miestnosti Mení vaše zobrazované meno / prezývku Zapnutie/vypnutie formátovanie textu markdown - Užitočné na opravu spravovania aplikácií matrix + Užitočné na opravu spravovania Matrix aplikácií 1 člen %d členovia @@ -1095,7 +1095,7 @@ Deaktivovať obmedzenia Optimalizácia batérie Chod ${app_name} nie je ovplyvnený nastavením optimalizácie batérie. - Ak používateľ na nejaký čas ponechá zariadenie s vypnutou obrazovkou odložené odpojené od napájania, na zariadení sa použije režim Doze. Toto aplikáciám zabráni pristupovať k sieti, pozastaví ich naplánované úlohy, synchronizáciu aj bežné signály. + Ak používateľ nechá zariadenie na určitý čas odpojené od siete a nehybné s vypnutou obrazovkou, zariadenie prejde do režimu Doze. Tým sa aplikáciám zabráni v prístupe k sieti a oddialia sa ich úlohy, synchronizácia a štandardné alarmy. Ignorovať optimalizáciu Zobraziť náhľady odkazov v konverzáciách (ak sú podporované domovským serverom). Odosielať oznámenia pri písaní @@ -1166,7 +1166,7 @@ Vybrať farbu upozornení LED, vibrácie, zvuky… Správa šifrovacích kľúčov Odoslanie správy pomocou enter - Stlačením klávesu enter na dotykovej klávesnici odošlete správu namiesto odriadkovania + Tlačidlo Enter na softvérovej klávesnici odošle správu namiesto pridania zalomenia riadku Režim šetrenia údajov aplikuje filter, ktorý potlačí aktualizácie prítomnosti a oznámenia pri písaní. Aktualizovať heslo Heslo nie je platné @@ -1201,7 +1201,7 @@ Žiadny Zrušiť Odpojiť sa - Náhlad + Skontrolovať Odmietnuť Nebol nakonfigurovaný server totožnosti. Hovor zlyhal z dôvodu nesprávne nastaveného servera @@ -1283,14 +1283,14 @@ ${app_name} sa bude synchronizovať na pozadí s cieľom ušetriť limitované zdroje (batériu). \nV závislosti od kapacity prostriedkov zariadenia môže byť synchronizácia odložená operačným systémom na neskôr. Optimalizovaný na používanie v reálnom čase - ${app_name} sa bude pravideľne synchronizovať na pozadí v presne stanovenom čase (nastaviteľné). -\nToto ovplyvní využívanie batérie a prenos údajov, v oznamovacej oblasti sa bude neustále zobrazovať upozornenie, že ${app_name} spracúva udalosti. + ${app_name} sa bude pravidelne synchronizovať na pozadí v presne stanovenom čase (nastaviteľné). +\nBude to mať vplyv na používanie rádia a batérie, bude sa zobrazovať trvalé oznámenie, že ${app_name} počúva udalosti. Žiadna synchronizácia na pozadí Nebudete dostávať oznámenia o prichádzajúcich správach, keď aplikácia pracuje na pozadí. Nepodarilo sa aktualizovať nastavenia. Uprednostňovaný interval synchronizácie %s -\nSynchronizácia môže byť odložená vzávislosti od kapacity zariadenia (batéria a režim spánku). +\nSynchronizácia môže byť odložená v závislosti od zdrojov (batéria) alebo stavu zariadenia (režim spánok). Integrácie Použite správcu integrácií na nastavenie botov, premostení, widgetov a balíčkov s nálepkami. \nSprávcovia integrácie dostávajú konfiguračné údaje a môžu vo vašom mene upravovať widgety, posielať pozvánky do miestnosti a nastavovať úrovne oprávnení. @@ -1368,7 +1368,7 @@ Zadajte prosím prístupovú frázu Prístupová fráza je príliš slabá Ak chcete, aby ${app_name} vygeneroval kľúč na obnovenie, odstráňte prístupovú frázu. - Nie je dostupná žiadna relácia matrix + Nie je dostupná žiadna relácia Matrix Nikdy nepríďte o šifrované správy Správy v šifrovaných miestnostiach sú zabezpečené end-to-end šifrovaním. Kľúče na čítanie týchto správ máte len vy a príjemca (príjemcovia). \n @@ -1447,12 +1447,12 @@ Zálohovanie kľúčov nie je aktívne v tejto relácii. Kľúče z tejto relácie nie sú zálohované. Záloha je podpísaná kľúčom z neznámej relácie, ID %s. - Záloha je podpísana platným kľúčom z tejto relácie. - Záloha je podpísana platným kľúčom z overenej relácie %s. - Záloha je podpísana platným kľúčom z neoverenej relácie %s - Záloha je podpísana neplatným kľúčom z overenej relácie %s - Záloha je podpísana neplatným kľúčom z neoverenej relácie %s - Nepodarilo sa zistiť stav dôverihodnosti zálohy (%s). + Záloha má platný podpis z tejto relácie. + Záloha má platný podpis z overenej relácie %s. + Záloha má platný podpis z neoverenej relácie %s + Záloha má neplatný podpis z overenej relácie %s + Záloha má neplatný podpis z neoverenej relácie %s + Nepodarilo sa získať informácie o dôveryhodnosti pre zálohu (%s). Ak chcete použiť zálohovanie kľúčov v tejto relácii, obnovte ju teraz pomocou svojej prístupovej frázy alebo pomocou kľúča na obnovenie. Mazanie zálohy… Nepodarilo sa vymazať zálohu (%s) @@ -1460,9 +1460,9 @@ Vymazať zálohu Vymazať vaše zálohované šifrovacie kľúče z domovského servera\? Na čítanie histórie zašifrovaných správ už nebudete môcť použiť kľúč na obnovenie. Nová záloha kľúčov - Bola zistená nová bezpečná záloha šifrovacích kľúčov. + Bola zistená nová záloha kľúča zabezpečenej správy. \n -\nAk ste si nenastavili nový spôsob obnovenia kľúčov, útočník sa môže pokúšať pristupovať k vášmu účtu. V nastaveniach si prosím hneď zmente prihlasovacie heslo účtu a nastavte zálohovanie kľúčov. +\nAk ste nenastavili nový spôsob obnovy, útočník sa môže pokúsiť získať prístup k vášmu účtu. Okamžite zmeňte vaše heslo k účtu a nastavte novú metódu obnovy v Nastaveniach. Bol(a) som to ja Nikdy neprídete o šifrované správy Začnite používať zálohovanie kľúčov @@ -1493,7 +1493,7 @@ Z dôvodu dodržania maximálnej bezpečnosti odporúčame, aby ste toto urobili osobne alebo použili iný dôveryhodný komunikačný kanál. Spustiť overenie Prichádzajúca žiadosť o overenie - Overte túto reláciu, aby ste ju mohli označiť za dôveryhodnú. Dôverovanie reláciám vašich komunikačných partnerov vám pridáva pokoj na duši pri používaní E2E šifrovaných správ. + Overte túto reláciu a označte ju ako dôveryhodnú. Dôveryhodnosť relácií partnerov vám poskytuje pokoj na duši pri používaní end-to-end šifrovaných správ. Overením tejto relácie si ju označíte ako dôveryhodnú a tiež označíte vašu reláciu ako dôveryhodnú pre protistranu. Overte túto reláciu potvrdením, že na obrazovke protistrany sa zobrazia nasledujúce emoji Overte túto reláciu potvrdením, že na obrazovke protistrany sa zobrazia nasledujúce čísla @@ -1502,7 +1502,7 @@ Čakanie na potvrdenie protistrany… Overené! Úspešne ste overili túto reláciu. - Šifrované správy s týmto používateľom sú zabezpečené E2E šifrou a nik okrem vás ich nemôže čítať. + Zabezpečené správy s týmto používateľom sú end-to-end šifrované a tretie strany ich nemôžu čítať. Rozumiem Nič sa neobjavuje\? Ešte nie všetci klienti podporujú interaktívne overenie. Použite pôvodný spôsob overenia. Použiť starší spôsob overenia. @@ -1578,7 +1578,7 @@ \n%s Pri získavaní stavu dôveryhodnosti nastala chyba Pri získavaní údajov o zálohe kľúčov nastala chyba - Importovať E2E kľúče zo súboru \"%1$s\". + Importovať šifrovacie kľúče zo súboru \"%1$s\". Verzia Matrix SDK Ďalšie poznámky tretích strán Už máte túto miestnosť zobrazenú! @@ -1621,21 +1621,21 @@ Vytvoriť novú miestnosť Poslať priamu správu Zobraziť adresár miestností - Názov alebo ID (#priklad:matrix.org) + Názov alebo ID (#napriklad:matrix.org) Povoliť posunutím odpovedať na časovej osi Zobrazovať záložku oznámenia na hlavnej obrazovke. Odkaz skopírovaný do schránky - Pridať matrix ID + Pridať pomocou Matrix ID Vytváranie miestnosti… - Nenájdený žiadny výsledok, ak chcete hľadať na servery, klepnite na pridať Matrix ID. + Nenašiel sa žiadny výsledok, na vyhľadávanie na serveri použite Pridať pomocou Matrix ID. Začnite písať a uvidíte výsledky hneď - Filtrovať zadaním používateľskeho mena alebo ID… + Filtrovať pomocou používateľského mena alebo ID… Vstupovanie do miestnosti… Zobraziť históriu úprav Podmienky poskytovania služby Prečítať podmienky Umožnite ostatným vás nájsť - Používajte botov, mosty, widgety a balíčky s nálepkami + Použiť boty, premostenia, widgety a balíčky s nálepkami Prečítajte si na adrese Server totožností Odpojiť server totožností @@ -1835,7 +1835,7 @@ Zverejniť túto adresu Ďalšie zverejnené adresy: Nemôžete napísať priamu správu sebe! - Pridať tému + Pridajte tému %1$d z %2$d Žiadne ďalšie výsledky Téma miestnosti (voliteľné) @@ -2109,7 +2109,7 @@ Nemáte oprávnenie na začatie hovoru v tejto miestnosti Nemáte oprávnenie na začatie konferenčného hovoru Chýbajúce oprávnenia - Abyste mohli posielať hlasové správy, udeľte prosím oprávnenie používať mikrofón. + Aby ste mohli posielať hlasové správy, udeľte prosím oprávnenie používať mikrofón. Na vykonanie tejto akcie, prosím udeľte oprávnenie na používanie fotoaparátu cez systémové nastavenia. Chýbajú niektoré oprávnenia potrebné na vykonanie tejto akcie, prosím udeľte ich cez systémové nastavenia. Čakanie na upozornenia @@ -2236,8 +2236,8 @@ Udržujte konverzácie súkromné pomocou šifrovania Komunikujte s ľuďmi priamo alebo v skupinách Je to vaša konverzácia. Vlastnite ju. - Vytvorili ste miestnosť len pre pozvaných. - %1$s vytvoril miestnosť len na pozvanie. + Nastavili ste miestnosť len pre pozvaných. + %1$s nastavil miestnosť len na pozvanie. Miestnosť ste zverejnili pre každého, kto pozná odkaz. %1$s zverejnil miestnosť pre každého, kto pozná odkaz. Dlhým kliknutím na miestnosť zobrazíte ďalšie možnosti @@ -2284,8 +2284,8 @@ Je nám ľúto, ale tento server neprijíma nové účty. Prihlásiť sa cez %s Prihlásiť sa cez %s - Ste ju vytvorili len na pozvanie. - %1$s ju vytvoril len na pozvanie. + Ste ju nastavili len na pozvanie. + %1$s ju nastavil/a len na pozvanie. Otočiť a orezať Pridať obrázok z Súbor je príliš veľký na odoslanie. @@ -2490,7 +2490,7 @@ Kvôli end-to-end šifrovaniu sa môže stať, že budete musieť chvíľu počkať, kým vám od niekoho príde správa, pretože vám neboli správne odoslané šifrovacie kľúče. Správy v tejto miestnosti sú šifrované od vás až k príjemcovi. Správy v tejto miestnosti sú end-to-end šifrované. Zistite viac a overte používateľov v ich profile. - Správca vášho servera predvolene vypol šifrovanie end-to-end v súkromných miestnostiach a priamych správach. + Správca vášho servera predvolene vypol end-to-end šifrovanie v súkromných miestnostiach a v priamych správach. Správy s týmto používateľom sú end-to-end šifrované a tretie strany ich nemôžu čítať. Správy sú tu end-to-end šifrované . \n @@ -2557,7 +2557,7 @@ Nastaviť nové heslo k účtu… Nepoužívajte heslo k svojmu účtu. Zadajte svoje %s pre pokračovanie. - Ak ste si vytvorili účet na domovskom serveri, použite svoje Matrix ID (napr. @user:domain.com) a heslo uvedené nižšie. + Ak ste si vytvorili účet na domovskom serveri, použite svoje Matrix ID (napr. @pouzivatel:domena.sk) a heslo. Ak už máte účet a poznáte svoj identifikátor Matrix a heslo, môžete použiť aj túto metódu: Tento e-mail nie je prepojený so žiadnym účtom Vyzerá to, že váš domovský server zatiaľ nepodporuje Priestory @@ -2828,7 +2828,7 @@ Nemáte oprávnenie povoliť šifrovanie v tejto miestnosti. Odošle daný emotív sfarbený ako dúha Odošle danú správu vo farbe dúhy - Táto relácia nemôže zdieľať toto overenie s ostatnými reláciami. + Táto relácia nemôže zdieľať toto overenie s vašimi ostatnými reláciami. \nOverenie bude uložené lokálne a zdieľané v budúcej verzii aplikácie. Akcie správcu V záujme zvýšenia bezpečnosti overte %s kontrolou jednorazového kódu na oboch zariadeniach. @@ -3070,4 +3070,61 @@ Vyzváňanie hovoru… Kopírovať odkaz na vlákno Zobraziť v miestnosti + Zobraziť potvrdenia o prečítaní + Importovať kľúč zo súboru + Odmietli ste tento hovor %s + Do galérie sa nepodarilo pridať mediálny súbor + Kľúč obnovy zálohy kľúča + Získavanie kľúča krivky + Adresa služby Element Matrix Services + Spojler + Odošle danú správu ako spojler + Nahlásené ako nevhodné + + %d používateľ prečítal + %d používatelia prečítali + %d používatelia prečítali + + %1$s a %2$s prečítali + %1$s, %2$s a %3$s prečítali + + %1$s, %2$s a %3$d ďalší prečítal + %1$s, %2$s a %3$d ďalší prečítali + %1$s, %2$s a %3$d ďalší prečítali + + Ste pozvaní + Dôveryhodná úroveň + Predvolená úroveň dôveryhodnosti + Niektoré správy neboli odoslané + Existujú neuložené zmeny. Chcete zrušiť tieto zmeny\? + Odkaz na Matrix + Túto miestnosť nie je možné nájsť. Uistite sa, že existuje. + Nemôžete otvoriť miestnosť, do ktorej máte zákaz vstupu. + Nie je možné nájsť tajné údaje v úložisku + Tento obsah bol nahlásený ako nevhodný. +\n +\nAk nechcete vidieť ďalší obsah od tohto používateľa, môžete ho ignorovať a skryť jeho správy. + Známi používatelia + Túto miestnosť nie je možné zobraziť v náhľade. Chcete sa k nej pripojiť\? + Otvoriť výber emotikonov + Zatvoriť výber emotikonov + Správa nebola odoslaná kvôli chybe + Oznámiť bez zvuku + Neoznamovať + Obsah udalosti + Žiadny obsah + Udalosť odoslaná! + ${app_name} nespracováva správy typu \'%1$s\' + ${app_name} nespracováva udalosti typu \'%1$s\' + Hľadať názov + Spätnú väzbu sa nepodarilo odoslať (%s) + Zobraziť informácie o ladení chýb na obrazovke + Nahradiť farbu prezývky + Chcete sa pripojiť k existujúcemu serveru\? + Udalosť bola upravená administrátorom miestnosti, dôvod: %1$s + Táto miestnosť je momentálne neprístupná. +\nSkúste to neskôr alebo požiadajte správcu miestnosti, aby skontroloval, či máte prístup. + Presmerovať na používateľa %1$s + Počas presmerovania hovoru došlo k chybe + Presmerovať \ No newline at end of file From ed3c04ab6725e70c9f9d8dc4808f26eb6febdec7 Mon Sep 17 00:00:00 2001 From: Ernesto AV Date: Thu, 17 Feb 2022 05:58:06 +0000 Subject: [PATCH 198/302] Translated using Weblate (Spanish) Currently translated at 95.6% (2665 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/es/ --- vector/src/main/res/values-es/strings.xml | 57 ++++++++++++++++------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/vector/src/main/res/values-es/strings.xml b/vector/src/main/res/values-es/strings.xml index 42054e3c0e..6392d243fe 100644 --- a/vector/src/main/res/values-es/strings.xml +++ b/vector/src/main/res/values-es/strings.xml @@ -62,14 +62,14 @@ Mensaje eliminado [motivo: %1$s] Mensaje eliminado por %1$s [motivo: %2$s] %1$s ha revocado la invitación a unirse a la sala para %2$s - Sincronización Inicial + Sincronización inicial \nImportando cuenta… - Sincronización Inicial: -\nImportando Salas - Sincronización Inicial: -\nImportando Comunidades - Sincronización Inicial: -\nImportando Datos de la Cuenta + Sincronización inicial: +\nImportando salas + Sincronización inicial: +\nImportando comunidades + Sincronización inicial: +\nImportando datos de la cuenta Enviando mensaje… Borrar cola de envío %1$s ha invitado a %2$s. Razón: %3$s @@ -82,14 +82,15 @@ %1$s ha aceptado la invitación para %2$s. Razón: %3$s %1$s ha eliminado la dirección principal para esta sala. %s ha actualizado la sala. - Sincronización Inicial: + Sincronización inicial: \nImportando criptografía Sincronización Inicial: -\nImportando Salas a las que te has unido +\nCargando tus conversaciones +\nEsto puede tomar un tiempo si te has unido a muchas salas Sincronización Inicial: -\nImportando Salas a las que has sido invitada - Sincronización Inicial: -\nImportando Salas Abandonadas +\nImportando salas a las que te han invitado + Sincronización inicial: +\nImportando salas abandonadas Invitación de %1$s. Razón: %2$s %1$s ha desbaneado a %2$s. Razón: %3$s %1$s envió una invitación a %2$s para que se una a la sala. Razón: %3$s @@ -504,7 +505,7 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua SESIONES Invitar Salir de esta sala - Vetar + Banear Quitar Veto Restablecer a usuario normal Convertir a moderador @@ -848,7 +849,7 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua ¿Seguro que quieres iniciar una llamada de voz? ¿Seguro que quieres iniciar una llamada de vídeo? Lista de Grupos - El usuario baneado lo echará de esta sala y evitará que se unan nuevamente. + Vetar un usuario lo echará de esta sala y evitará que se una nuevamente. Todos los mensajes (ruidoso) Todos los mensajes Solo menciones @@ -1185,7 +1186,7 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua Mostrar recibos de lectura Hacer click en los recibos de lectura para mostrar una lista detallada. Mostrar notificaciones de entrada y salida - Invitaciones, expulsiones y prohibiciones no se ven afectadas. + Invitaciones, expulsiones y vetos no se ven afectadas. Mostrar notificaciones de la cuenta Incluye cambios en el avatar y en el nombre. Enviar mensaje con intro @@ -2413,7 +2414,7 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua %d invitación %d invitaciones - Incluye invitar/unirse/expulsar/prohibir/mostrar cambios de nombre. + Incluye los eventos de invitar/unirse/abandonar/eliminar/vetar y los cambios de avatar/nombre. Mostrar eventos de los miembros de la sala ¡La notificación ha sido cliqueada! Tema del sistema @@ -2921,7 +2922,7 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua Vea y actualice los roles necesarios para cambiar varias partes del espacio. Permisos de espacio Quitar la prohibición al usuario le permitirá unirse al espacio nuevamente. - La prohibición del usuario lo expulsara de este espacio y evitará que se una nuevamente. + Vetar un usuario lo expulsará de este espacio y evitará que se una nuevamente. Patear al usuario lo eliminará de este espacio. \n \nPara evitar que se unan nuevamente, debe prohibirlos. @@ -2970,4 +2971,26 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua Todas las salas en las que se encuentra se mostraran en inicio. Mostrar todas las salas en inicio Agregar un espacio a cualquier espacio que administre. + Añadir espacios existentes + ¡Se ha cerrado la sesión! + ¡Se ha abandonado la sala! + Consejo: Pulse prolongadamente un mensaje y use \"%s\" . + Mantén las conversaciones organizadas con hilos + Muestra todos los hilos en que has participado + Mis Hilos + Muestra todos los hilos de la sala actual + Todos los Hilos + Hilos + Hilo + Filtrar Hilos en la sala + El cifrado está mal configurado por lo que no puedes enviar mensajes. Haz clic para abrir los ajustes. + El cifrado está mal configurado, por lo que no puedes enviar mensajes. Por favor, contacta un administrador para que restablezca el cifrado a un estado válido. + Elegir servidor doméstico + No se puede acceder al servidor con la URL %s. Por favor revisa el enlace o elige otro servidor manualmente. + Ahora no + Ver Hilos + Captando notificaciones + Ver en la sala + Habilitar + No estás autorizado a unirte a esta sala \ No newline at end of file From 3bae8c9d7a501bd743a24e8131da0fcb2b77403c Mon Sep 17 00:00:00 2001 From: Retired Lawyer Date: Thu, 17 Feb 2022 22:59:09 +0000 Subject: [PATCH 199/302] Translated using Weblate (Turkish) Currently translated at 76.1% (2122 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/tr/ --- vector/src/main/res/values-tr/strings.xml | 64 +++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/vector/src/main/res/values-tr/strings.xml b/vector/src/main/res/values-tr/strings.xml index e7e9fd0e8c..d42e2532a1 100644 --- a/vector/src/main/res/values-tr/strings.xml +++ b/vector/src/main/res/values-tr/strings.xml @@ -2322,4 +2322,68 @@ Yalnızca geçerli odadaki görünen takma adınızı değiştirir Oda adını ayarlar Bir kullanıcıyı görmezden gelmeyi durdurur, mesajlarını ileriye doğru gösterir + Yine de Katıl + Alana Katıl + Alan Oluştur + Şimdilik atla + Sadece bu odaya + Link paylaş + Kullanıcı adı veya mail ile davet et + Kullanıcı adı ile davet et + Mail ile davet et + %syi davet et + İnsanları davet et + Alanınıza insanları davet edin + Açıklama + Alan Oluşturuluyor… + Rastgele + Genel + Takım arkadaşların kimler\? + Alan oluştur + Yalnızca davet edin, kendiniz veya ekipleriniz için en iyisi + Özel + Herkese açık, topluluklar için en iyisi + Halka açık + Ben ve takım arkadaşlarım + Yalnızca ben + Kiminle çalışıyorsun\? + Konum paylaş + Bu odadaki mesajlar uçtan uca şifrelenir. +\n +\nMesajlarınız şifrelerle korunur ve yalnızca siz ve alıcı, mesajların kilidini açmak için benzersiz anahtarlara sahip olursunuz. + Buradaki mesajlar uçtan uca şifrelenmez. + Bu odadaki mesajlar uçtan uca şifrelenmez. + Ekstra güvenlik için, her iki cihazınızda da tek seferlik bir kodu kontrol ederek %s\'yi doğrulayın. +\n +\nMaksimum güvenlik için bunu bizzat yapın. + %s bekleniyor… + %s doğrulandı + %s\'yi doğrula + QR kod resmi + Yukarıdaki kodu tarayamıyorsanız, kısa, benzersiz bir emoji seçimini karşılaştırarak doğrulayın. + Emojiyi doğrula + Emojileri karşılaştırarak doğrulayın + Sunucuya bağlan + Mevcut bir sunucuya katılmak mı istiyorsun\? + bu soruyu atla + Henüz emin değil misin\? %s yapabilirsin + Topluluklar + Takımlar + Arkadaşlar ve aile + Bağlanmanıza yardımcı olacağız. + Bu konuyu zaten görüntülüyorsun! + Odada Görüntüle + Bir Konudan + İpucu: Bir mesaja uzun dokunun ve “%s” kullanın. + Katıldığın tüm konuları göster + Konularım + Geçerli odadaki tüm konuları göster + Tüm Konular + Filtre + Konular + Konu + Odadaki Konuları Filtrele + Konu bağlantısını kopyala + Odada görüntüle + Konuları Görüntüle \ No newline at end of file From 81706b2f7fd6470cbdcc8351aae7f63915fe68cd Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Sat, 12 Feb 2022 18:38:25 +0000 Subject: [PATCH 200/302] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2785 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/ --- vector/src/main/res/values-pt-rBR/strings.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index 973a82ebfb..9eabb09e69 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -324,7 +324,7 @@ Filtrar pessoas Filtrar nomes de salas Convites - Baixa prioridade + Prioridade baixa Conversas Agenda de endereços local Contatos de Matrix somente @@ -673,7 +673,7 @@ Etiqueta da Sala Etiquetada como: Favoritar - Baixa prioridade + Prioridade baixa Nenhuma Acesso e visibilidade Listar esta sala em diretório de salas @@ -2404,8 +2404,8 @@ %d convite %d convites - Remover de baixa prioridade - Adicionar a baixa prioridade + Remover de prioridade baixa + Adicionar a prioridade baixa Adicionar imagem de Descartar mudanças Existem mudanças não-salvas. Descartar as mudanças\? @@ -2896,7 +2896,7 @@ Configurações de conta Você pode gerenciar notificações em %1$s. Por favor note que notificações de menções & palavrachave não estão disponíveis em salas encriptadas no celular. - Notifique-me por + Notifique-me para Você não vai ter notificações para menções & palavrachaves em salas encriptadas no celular. Palavrachaves \@room From 05690c66e01e2018758aede76a7d53cb464441eb Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Tue, 15 Feb 2022 16:11:41 +0000 Subject: [PATCH 201/302] Translated using Weblate (Swedish) Currently translated at 99.9% (2784 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/ --- vector/src/main/res/values-sv/strings.xml | 34 +++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index c0d4b757e4..45e3b55007 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -76,7 +76,7 @@ Meddelande borttaget av %1$s Meddelande borttaget [anledning: %1$s] Meddelande borttaget av %1$s [anledning: %2$s] - %1$s uppdaterade sim profil %2$s + %1$s uppdaterade sin profil %2$s Du uppdaterade din profil %1$s %1$s bjöd in %2$s att gå med i rummet Du bjöd in %1$s att gå med i rummet @@ -582,7 +582,7 @@ Fortsätt Ta bort Gå med - Förhandsvisning + Förhandsgranskning Avslå Lista medlemmar Öppna rubrik @@ -593,7 +593,7 @@ \nDu kanske vill logga in på ett annat konto eller lägga till den här e-postadressen till det här kontot. Du försöker komma åt %s. Skulle du vilja gå med för att delta i diskussionen\? ett rum - Det här är en förhandsvisning av det här rummet. Rumsinteraktioner har blivit inaktiverade. + Det här är en förhandsgranskning av det här rummet. Rumsinteraktioner har blivit inaktiverade. Lägg till en identitetsserver i dina inställningar för att utföra den här handlingen. Ny chatt Lägg till medlem @@ -740,7 +740,7 @@ Lagra din återställningsnyckel på något säkert ställe, t.ex. en lösenordshanterare (eller ett kassaskåp) En ny säker säkerhetskopia för meddelandenycklar har hittats. \n -\nOm det inte var du som satte upp den nya återställningsmetoden så kan det vara en angripare som försöker komma åt ditt konto. Ändra ditt kontolösenord och sätt en ny återställningsmetod omedelbart i inställningarna. +\nOm det inte var du som satte upp den nya återställningsmetoden så kan det vara en angripare som försöker komma åt ditt konto. Byt ditt kontolösenord och sätt en ny återställningsmetod omedelbart i inställningarna. Ingen identitetsserver är konfigurerad, vilket krävs för att återställa ditt lösenord. Byt nätverk Alla gemenskaper @@ -1469,7 +1469,7 @@ Om du har skapat ett konto på en hemserver så kan du använda ditt Matrix-ID (t.ex. @användare:domän.com) och lösenord nedan. Detta kan bero på flera orsaker: \n -\n• Du har ändrat ditt lösenord från en annan session. +\n• Du har bytt ditt lösenord från en annan session. \n \n• Du har tagit bort den här sessionen från en annan session. \n @@ -1533,7 +1533,7 @@ \n- Den här enheten, eller den andra enheten \n- Internetuppkopplingen en av enheterna använder \n -\nVi rekommenderar att du ändrar ditt lösenord och återställningsnyckel i inställningarna omedelbart. +\nVi rekommenderar att du byter ditt lösenord och återställningsnyckel i inställningarna omedelbart. Sätter upp nyckelsäkerhetskopiering Spara den på ett USB-minne eller en säkerhetskopieringsenhet Nästan färdigt! Visar den andra enheten en bock\? @@ -1771,7 +1771,7 @@ Går med i rummet med den angivna adressen Sätt ett rumsämne Sparkar ut användaren med det angivna ID:t - Ändrar ditt visningsnamn + Byter ditt visningsnamn För att fixa Matrixapphantering Skapa Skapa gemenskap @@ -2034,9 +2034,9 @@ Ditt lösenord har återställts. Tillbaka till inloggning Varning - Ditt lösenord har inte ändrats än. + Ditt lösenord har inte bytts än. \n -\nVill du avbryta återställningsprocessen\? +\nStoppa lösenordsbytesprocessen\? Nästa Sätt telefonnummer Vänligen använd internationellt format. @@ -2179,7 +2179,7 @@ Skicka bilder i originalstorlek Bekräfta borttagning - Är du säker på att du vill ta bort (radera) den här händelsen\? Observera att om du raderar ett rumsnamn eller ämnesändring så kan det upphäva ändringen. + Är du säker på att du vill ta bort (radera) den här händelsen\? Observera att om du raderar ett rumsnamns- eller ämnesbyte så kan det upphäva ändringen. Inkludera en anledning Anledning för borttagning Händelsen raderades av användaren, anledning: %1$s @@ -2429,7 +2429,7 @@ Ogiltig QR-kod (ogiltig URI)! Kan inte DMa dig själv! Dela med text - Ändra din nuvarande PIN-kod + Byt din nuvarande PIN-kod Ändra PIN-kod Sök efter kontakter på Matrix Sätt avatar @@ -2520,7 +2520,7 @@ Visa emojitangentbord Använda /confetti för att skicka meddelanden som innehåller ❄️ eller 🎉 Visa chatteffekter - Ändra ämnet + Byta ämnet Uppgradera rummet Skicka m.room.server_acl-händelser Ändra behörigheter @@ -2645,7 +2645,7 @@ Skickar Rumskatalog Meddelande skickat - Lägg till några detaljer för att hjälpa det satt sticka ut. Du kan ändra dessa när som helst. + Lägg till några detaljer för att hjälpa det att sticka ut. Du kan ändra dessa när som helst. Skapa ett utrymme Endast inbjudan, bäst för dig själv eller grupper Privat @@ -2782,7 +2782,7 @@ För att utföra detta, vänligen ge kameraåtkomst från systeminställningarna. Vissa behörigheter saknas för att utföra detta, vänligen ge behörighet från systeminställningarna. Observera att uppgradering kommer att göra en ny version av rummet. Alla nuvarande meddelanden kommer att vara kvar i det här arkiverade rummet. - em som helst i föräldrautrymmet kommer kunna hitta och gå med i det här rummen - du behöver inte bjuda in alla. Du kommer kunna ändra detta i rumsinställningarna när som helst. + Vem som helst i föräldrautrymmet kommer kunna hitta och gå med i det här rummen - du behöver inte bjuda in alla. Du kommer kunna ändra detta i rumsinställningarna när som helst. Vem som helst i %s kommer kunna hitta och gå med i det här rummen - du behöver inte bjuda in alla. Du kommer kunna ändra detta i rumsinställningarna när som helst. Röstmeddelande (%1$s) Kan inte svara eller redigera när röstmeddelande är aktivt @@ -2947,10 +2947,10 @@ För att få e-post med aviseringar, vänligen associera en e-postadress med ditt Matrixkonto E-postavisering Uppgradera utrymmet - Byt utrymmets namn + Byta utrymmets namn Aktivera utrymmeskryptering - Byt huvudadress för det här utrymmet - Byt utrymmets avatar + Byta huvudadress för det här utrymmet + Byta utrymmets avatar Du är inte behörig att uppdatera rollerna som krävs för att ändra diverse delar av det här utrymmet Välj de roller som krävs för att ändra diverse delar av det här utrymmet Se och uppdatera rollerna som krävs för att ändra diverse delar av utrymmet. From a62365d2b0ae04d5d69d27e69dbc58e4d447a2ff Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 15:01:18 +0000 Subject: [PATCH 202/302] Translated using Weblate (Japanese) Currently translated at 82.1% (2289 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index c0b1141a72..25d5a0517d 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1167,7 +1167,7 @@ 未読メッセージ タイムラインでのスワイプによる返信を有効にする タイムラインで非表示のイベントを表示 - QR コードをスキャン + QRコードをスキャン QR コード画像 QR コード QR コードによる追加 @@ -2494,7 +2494,7 @@ \n \n暗号鍵を手動でエクスポートできるように、次のポップアップでアクセスを許可してください。 %1$sはリンクを知っている人がアクセスできるようにこのルームを設定しました。 - まず、設定でIDサーバーの条件に同意してください。 + まず、設定画面でIDサーバーの利用規約に同意してください。 初めにIDサーバーを設定してください。 %1$d個の投票があります。結果を見るには投票してください From cdea53b096acfbfc8f58e48a8884a536279feead Mon Sep 17 00:00:00 2001 From: JokerGermany Date: Fri, 18 Feb 2022 12:59:23 +0000 Subject: [PATCH 203/302] Translated using Weblate (German) Currently translated at 99.7% (2779 of 2785 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 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 622db6324d..ab83dd07b9 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2900,8 +2900,8 @@ Auf deinem Mobilgerät wirst du keine Benachrichtigungen für Erwähnungen und Schlüsselwörter in verschlüsselten Räumen erhalten. Existierende Spaces hinzufügen Existierende Räume hinzufügen - Ausgewählte Räume oder Spaces verlassen… - Keine Räume und Spaces verlassen + Ausgewählte Räume oder Subspaces verlassen… + Keine Räume und Subspaces verlassen Du wirst alle Räume und Spaces in %s verlassen. Alle Räume und Spaces verlassen Willst du %s wirklich verlassen\? From 6ef8b71d911885c32ca184a70ef052d6f14cc3be Mon Sep 17 00:00:00 2001 From: noantiq Date: Sat, 12 Feb 2022 13:08:05 +0000 Subject: [PATCH 204/302] Translated using Weblate (German) Currently translated at 99.7% (2779 of 2785 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 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index ab83dd07b9..5852e2de31 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -154,7 +154,7 @@ %1$s hat das %2$s Widget modifiziert Du hast das %1$s Widget modifiziert Admin - Moderator + Moderation Standard Benutzerdefiniert (%1$d) Benutzerdefiniert @@ -505,8 +505,8 @@ Verbannen Verbannung aufheben Zum normalen Benutzer herabstufen - Zum Moderator machen - Zum Admin machen + Moderationsrechte vergeben + Administrationsrechte vergeben Blockieren Alle Nachrichten dieses Nutzers anzeigen Nutzer-ID, Name oder E-Mail-Adresse @@ -845,7 +845,7 @@ Sicher, dass du einen Sprachanruf starten möchtest\? Sicher, dass du einen Videoanruf starten möchtest\? Gruppenliste - Ein Bann schließt die Person aus dem Raum aus und verhindert einen erneuten Beitritt. + Die Verbannung einer Person entfernt sie aus diesem Raum und hindert sie am erneuten Beitritt. Alle Nachrichten (laut) Alle Nachrichten Nur Erwähnungen @@ -1076,7 +1076,7 @@ Formatiere Nachrichten mittels Markdown-Syntax, bevor sie gesendet werden. Dies erlaubt erweiterte Formatierungen wie Sternchen (*), um kursiven Text anzuzeigen. Lesebestätigungen zeigen Klicke auf die Lesebestätigungen für eine detailliertere Liste. - Einladungen, Kicks und Banns werden weiterhin angezeigt. + Einladungen, Entfernungen und Verbannungen bleiben sichtbar. Passwort Starte die System-Kamera anstelle der angepassten Kamera. Diese Option erfordert eine externe Anwendung um Sprachnachrichten aufzuzeichnen. @@ -1864,7 +1864,7 @@ Raum verlassen Verlasse den Raum… Administratoren - Moderatoren + Moderationen Benutzerdefiniert Eingeladen Nutzer @@ -2273,7 +2273,7 @@ Einladung zurücknehmen Einladung zu %1$s zurücknehmen\? Gebannt von %1$s - Aufheben des Banns fehlgeschlagen + Aufhebung der Verbannung fehlgeschlagen Push-Benachrichtigungen sind deaktiviert Gehe zu deinen Einstellungen um Push-Benachrichtigungen zu aktivieren Nutze eine PIN für mehr Sicherheit @@ -2337,7 +2337,7 @@ %d Sekunden Status-Ereignisse der Raummitglieder zeigen - Bezieht Einladungs-/Beitritts-/Verlassen-/Entfernen-/Verbannen-Ereignisse und Avatar-/Anzeigenamen-Wechsel mit ein. + Bezieht Einladungs-/Beitritts-/Verlassen-/Entfernungs-/Verbannungs-Ereignisse und Wechsel des Avatar/Anzeigenamen mit ein. Umfrage Reagierte mit: %s Der Link war fehlerhaft @@ -2926,7 +2926,7 @@ Du hast nicht die Berechtigung, Rollenrechte zu bearbeiten Space-Berechtigungen Wenn du die Person entbannst, kann sie wieder beitreten. - Wenn du eine Person bannst, kann sie nicht erneut beitreten. + Die Verbannung einer Person entfernt sie aus diesem Space und hindert sie am erneuten Beitritt. Kicken entfernt die Person aus dem Space \n \nUm sie für immer zu entfernen, solltest du sie bannen. From e42945518364de6ecb147cb1321933f7b8e5cf93 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Fri, 18 Feb 2022 15:36:43 +0000 Subject: [PATCH 205/302] Translated using Weblate (Japanese) Currently translated at 38.7% (19 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/ja/ --- .../android/ja-JP/changelogs/40100100.txt | 2 +- .../android/ja-JP/changelogs/40100110.txt | 2 +- .../android/ja-JP/changelogs/40100120.txt | 2 +- .../android/ja-JP/changelogs/40100130.txt | 2 +- .../android/ja-JP/changelogs/40100140.txt | 2 +- .../android/ja-JP/changelogs/40100150.txt | 2 +- .../android/ja-JP/changelogs/40100160.txt | 2 +- .../android/ja-JP/changelogs/40100170.txt | 2 +- .../android/ja-JP/changelogs/40101000.txt | 2 +- .../android/ja-JP/changelogs/40101010.txt | 2 +- .../android/ja-JP/changelogs/40101020.txt | 2 +- .../android/ja-JP/changelogs/40101030.txt | 2 +- .../android/ja-JP/changelogs/40101160.txt | 2 +- .../android/ja-JP/changelogs/40103160.txt | 2 + .../android/ja-JP/changelogs/40103170.txt | 2 + .../android/ja-JP/changelogs/40103180.txt | 2 + .../android/ja-JP/full_description.txt | 41 ++++++++++--------- 17 files changed, 41 insertions(+), 32 deletions(-) create mode 100644 fastlane/metadata/android/ja-JP/changelogs/40103160.txt create mode 100644 fastlane/metadata/android/ja-JP/changelogs/40103170.txt create mode 100644 fastlane/metadata/android/ja-JP/changelogs/40103180.txt diff --git a/fastlane/metadata/android/ja-JP/changelogs/40100100.txt b/fastlane/metadata/android/ja-JP/changelogs/40100100.txt index 8359a12964..48af96d216 100644 --- a/fastlane/metadata/android/ja-JP/changelogs/40100100.txt +++ b/fastlane/metadata/android/ja-JP/changelogs/40100100.txt @@ -1,2 +1,2 @@ 今回の新バージョンでは、主にバグの修正と改善が行われています。メッセージの送信がより速くなりました。 -すべての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.10 +全ての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.10 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40100110.txt b/fastlane/metadata/android/ja-JP/changelogs/40100110.txt index c93db421af..b8b9798fcd 100644 --- a/fastlane/metadata/android/ja-JP/changelogs/40100110.txt +++ b/fastlane/metadata/android/ja-JP/changelogs/40100110.txt @@ -1,2 +1,2 @@ 今回の新バージョンでは、主にUI(ユーザーインターフェース)とUX(ユーザーエクスペリエンス)の向上が図られています。友達を招待したり、QRコードを読み取って素早くDMを作成できるようになりました。 -すべての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.11 +全ての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.11 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40100120.txt b/fastlane/metadata/android/ja-JP/changelogs/40100120.txt index aace2ef79f..01c33c5d52 100644 --- a/fastlane/metadata/android/ja-JP/changelogs/40100120.txt +++ b/fastlane/metadata/android/ja-JP/changelogs/40100120.txt @@ -1,2 +1,2 @@ このバージョンの主な変更点: URLプレビュー、新しい絵文字、新しいルーム設定機能、それにクリスマスには雪が! -すべての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.12 +全ての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.12 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40100130.txt b/fastlane/metadata/android/ja-JP/changelogs/40100130.txt index 97633621c5..941a052239 100644 --- a/fastlane/metadata/android/ja-JP/changelogs/40100130.txt +++ b/fastlane/metadata/android/ja-JP/changelogs/40100130.txt @@ -1,2 +1,2 @@ このバージョンの主な変更点: URLプレビュー、新しい絵文字、新しいルーム設定機能、それにクリスマスには雪が! -すべての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.13 +全ての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.13 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40100140.txt b/fastlane/metadata/android/ja-JP/changelogs/40100140.txt index c340663127..6dc536cdcf 100644 --- a/fastlane/metadata/android/ja-JP/changelogs/40100140.txt +++ b/fastlane/metadata/android/ja-JP/changelogs/40100140.txt @@ -1,2 +1,2 @@ このバージョンの主な変更点: 部屋の許可、自動のテーマ切替、そして多くのバグを修正しました。 -すべての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.14 +全ての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.14 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40100150.txt b/fastlane/metadata/android/ja-JP/changelogs/40100150.txt index 42f28c7bea..caded1b8ed 100644 --- a/fastlane/metadata/android/ja-JP/changelogs/40100150.txt +++ b/fastlane/metadata/android/ja-JP/changelogs/40100150.txt @@ -1,2 +1,2 @@ このバージョンの主な変更点: ソーシャルログインに対応しました。 -すべての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.15 +全ての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.15 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40100160.txt b/fastlane/metadata/android/ja-JP/changelogs/40100160.txt index 8b5196998a..1b1a2092b0 100644 --- a/fastlane/metadata/android/ja-JP/changelogs/40100160.txt +++ b/fastlane/metadata/android/ja-JP/changelogs/40100160.txt @@ -1,2 +1,2 @@ このバージョンの主な変更点: パフォーマンスの向上とバグの修正! -すべての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.15 and https://github.com/vector-im/element-android/releases/tag/v1.0.16 +全ての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.15 and https://github.com/vector-im/element-android/releases/tag/v1.0.16 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40100170.txt b/fastlane/metadata/android/ja-JP/changelogs/40100170.txt index 586b01cb2b..a0cc7b107d 100644 --- a/fastlane/metadata/android/ja-JP/changelogs/40100170.txt +++ b/fastlane/metadata/android/ja-JP/changelogs/40100170.txt @@ -1,2 +1,2 @@ このバージョンの主な変更点: バグの修正! -すべての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.17 +全ての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.0.17 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40101000.txt b/fastlane/metadata/android/ja-JP/changelogs/40101000.txt index 25bbd7ab87..d0900f38c2 100644 --- a/fastlane/metadata/android/ja-JP/changelogs/40101000.txt +++ b/fastlane/metadata/android/ja-JP/changelogs/40101000.txt @@ -1,2 +1,2 @@ このバージョンの主な変更点: パフォーマンスの向上とバグの修正! -すべての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.1.0 +全ての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.1.0 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40101010.txt b/fastlane/metadata/android/ja-JP/changelogs/40101010.txt index 35ba933069..cb204e5696 100644 --- a/fastlane/metadata/android/ja-JP/changelogs/40101010.txt +++ b/fastlane/metadata/android/ja-JP/changelogs/40101010.txt @@ -1,2 +1,2 @@ このバージョンの主な変更点: パフォーマンスの向上とバグの修正! -すべての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.1.1 +全ての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.1.1 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40101020.txt b/fastlane/metadata/android/ja-JP/changelogs/40101020.txt index 88e3c79ca8..bb6ab66525 100644 --- a/fastlane/metadata/android/ja-JP/changelogs/40101020.txt +++ b/fastlane/metadata/android/ja-JP/changelogs/40101020.txt @@ -1,2 +1,2 @@ このバージョンの主な変更点: パフォーマンスの向上とバグの修正! -すべての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.1.2 +全ての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.1.2 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40101030.txt b/fastlane/metadata/android/ja-JP/changelogs/40101030.txt index 87d191b226..e7ecc05a0f 100644 --- a/fastlane/metadata/android/ja-JP/changelogs/40101030.txt +++ b/fastlane/metadata/android/ja-JP/changelogs/40101030.txt @@ -1,2 +1,2 @@ このバージョンの主な変更点: パフォーマンスの向上とバグの修正! -すべての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.1.3 +全ての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.1.3 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40101160.txt b/fastlane/metadata/android/ja-JP/changelogs/40101160.txt index a498487f46..985ea10510 100644 --- a/fastlane/metadata/android/ja-JP/changelogs/40101160.txt +++ b/fastlane/metadata/android/ja-JP/changelogs/40101160.txt @@ -1,2 +1,2 @@ このバージョンの主な変更点:ルームにて誰かがログアウトした際に発生するエラーを修正しました。 -すべての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.1.16 +全ての変更履歴はこちら: https://github.com/vector-im/element-android/releases/tag/v1.1.16 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40103160.txt b/fastlane/metadata/android/ja-JP/changelogs/40103160.txt new file mode 100644 index 0000000000..5475828623 --- /dev/null +++ b/fastlane/metadata/android/ja-JP/changelogs/40103160.txt @@ -0,0 +1,2 @@ +このバージョンの主な変更点:ルームへのロケーションの送信。投票機能の変更。 +更新履歴:https://github.com/vector-im/element-android/releases/tag/v1.3.16 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40103170.txt b/fastlane/metadata/android/ja-JP/changelogs/40103170.txt new file mode 100644 index 0000000000..61b91b54c0 --- /dev/null +++ b/fastlane/metadata/android/ja-JP/changelogs/40103170.txt @@ -0,0 +1,2 @@ +このバージョンの主な変更点:ルームへのロケーションの送信。投票機能の変更。 +更新履歴:https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/ja-JP/changelogs/40103180.txt b/fastlane/metadata/android/ja-JP/changelogs/40103180.txt new file mode 100644 index 0000000000..ae4f1a0a0f --- /dev/null +++ b/fastlane/metadata/android/ja-JP/changelogs/40103180.txt @@ -0,0 +1,2 @@ +このバージョンの主な変更点:ルームへのロケーションの送信。投票機能の変更。 +更新履歴:https://github.com/vector-im/element-android/releases/tag/v1.3.18 diff --git a/fastlane/metadata/android/ja-JP/full_description.txt b/fastlane/metadata/android/ja-JP/full_description.txt index 4e7b01cce3..6014938cce 100644 --- a/fastlane/metadata/android/ja-JP/full_description.txt +++ b/fastlane/metadata/android/ja-JP/full_description.txt @@ -1,39 +1,42 @@ -Elementはセキュアなメッセンジャーであると同時に、リモートワークでのグループチャットにも最適です。エンドツーエンドの暗号化を使用して、強力なビデオ会議、ファイル共有、音声通話を提供します。 +Elementは、安全なメッセンジャー、リモートワーク中のグループチャットに適したチームコラボレーションアプリです。エンドツーエンドの暗号化を使用して、強力なビデオ会議、ファイル共有、音声通話を提供します。 Elementの特徴 - 高度なオンラインコミュニケーションツール -- 完全に暗号化されたメッセージ +- 完全に暗号化されたメッセージにより、リモートワーカーでも、より安全な企業コミュニケーションが可能 - Matrixオープンソースフレームワークをベースにした分散型のチャット - プロジェクトを管理しながら、暗号化されたデータで安全にファイル共有 - Voice over IPによるビデオチャットと画面共有 -- お気に入りのオンラインコラボレーションツール、プロジェクト管理ツール、VoIPサービス、その他のチームメッセージングアプリと統合可能 +- お気に入りのオンラインコラボレーションツール、プロジェクト管理ツール、VoIPサービス、その他のチームメッセージングアプリと簡単に統合可能 -Elementは他のメッセージングアプリやコラボレーションアプリとは異なります。安全なメッセージングと分散型(非中央集権)コミュニケーションのためのオープンネットワークであるMatrixで動作します。また、ユーザーが自分のデータやメッセージを最大限にコントロールできるように、セルフホスティングも可能です。 +Elementは他のメッセージングアプリやコラボレーションアプリとは全く異なります。安全なメッセージングと分散型(非中央集権)コミュニケーションのためのオープンネットワークであるMatrixで動作します。ユーザーが自分のデータやメッセージを最大限にコントロールできるように、セルフホスティングも可能です。 -プライバシーと暗号化されたやりとり -Elementは、望ましくない広告、データマイニング、ウォールドガーデンからユーザーを保護します。また、エンド・ツー・エンドの暗号化と相互署名されたデバイスの検証により、すべてのデータ、1対1のビデオおよび音声通信を保護します。 +プライバシーと暗号化されたコミュニケーション +Elementは、望ましくない広告、データマイニング、ウォールドガーデンからユーザーを保護します。また、エンド・ツー・エンドの暗号化と相互署名された端末の検証により、全てのデータ、1対1のビデオおよび音声通信を保護します。 -Elementは、Slackなどのアプリと統合することで、Matrixネットワーク上の誰とでも安全にコミュニケーションをとることができると同時に、プライバシーをコントロールすることができます。 +Elementは、Slackなどのアプリと統合することで、Matrixネットワーク上の誰とでも安全にコミュニケーションを取ることができると同時に、プライバシーをコントロールすることができます。 Elementはセルフホスティングが可能 -機密データや会話の管理を強化するために、Elementはセルフホスティングが可能で、オープンソースの分散型コミュニケーションの標準であるマトリックスベースのホストを選択することもできます。Elementは、プライバシー、セキュリティコンプライアンス、および統合の柔軟性を提供します。 +機密データや会話の管理を強化するために、Elementはセルフホスティングが可能です。または、オープンソースの分散型コミュニケーションの標準であるMatrixベースのホストを選択することもできます。Elementは、プライバシー、セキュリティーコンプライアンス、および統合の柔軟性を提供します。 -データを所有する -データやメッセージをどこに保管するかは、お客様が決めることができます。データマイニングやサードパーティからのアクセスされません。 +自分のデータを所有する +データやメッセージをどこに保管するかは、ユーザー自身が決めることができます。データマイニングやサードパーティからのアクセスのリスクはありません。 -Elementではどのサーバーを使うか決めることができます。さまざまな方法で選択できます。 +Elementでは、どのサーバーを使うかを、ご自身で決めることができます。 1. 開発者がホストする matrix.org のパブリックサーバーで無料アカウントを取得するか、ボランティアがホストしているパブリックサーバーから選択する。 -2. 自分でサーバを実行することにより、アカウントをセルフホストする。 -3. Element Matrix Servicesのホスティングプラットフォームに加入しカスタムサーバー上でアカウントを作る。 +2. あなた自身がサーバーを運営し、アカウントを管理する。 +3. Element Matrix Servicesのホスティングプラットフォームに加入し、カスタムサーバー上でアカウントを作る。 オープンなメッセージングとコラボレーション -Matrixネットワーク上の誰とでも、相手がElementを使っているか、他のMatrixアプリを使っていてもコミュニケーションすることができます。 +Matrixネットワーク上の誰とでも、相手がElementや他のMatrixアプリを使っているか、さらには他のメッセージングアプリを使っているかに関わらず、チャットをすることができます。 -すごく安全 -本物のエンド・ツー・エンドの暗号化(会話に参加している人だけがメッセージを復号化できる)と、相互署名されたデバイスの検証を行います。 +非常に安全 +本物のエンド・ツー・エンドの暗号化(会話に参加している人だけがメッセージを復号化できる)と、相互署名された端末の検証を行います。 包括的なコミュニケーションと統合 -メッセージング、音声およびビデオ通話、ファイル共有、画面共有、その他多くの統合、ボット、ウィジェットを提供します。部屋やコミュニティを作り、連絡を取り合い、物事を成し遂げることができます。 +メッセージング、音声およびビデオ通話、ファイル共有、画面共有、その他多くのインテグレーション、ボット、ウィジェットを提供します。ルームやコミュニティーを立ち上げて連絡を取り合い、物事をスムーズに成し遂げることができます。 -中断からの再開は -すべてのデバイスとウェブで完全に同期されたメッセージにより、どこにいても連絡を取り合うことができます。https://app.element.io +中断からの再開 +メッセージの履歴は全ての端末とウェブ(https://app.element.io)で完全に同期されるので、どこからでも連絡を取り合うことができます。 + +オープンソース +Element AndroidはGitHubで開発されているオープンソースのプロジェクトです。 バグの報告や開発への貢献は https://github.com/vector-im/element-android にて受け付けています。 From d5bb908f032afc9e8d0a3a364bbe64726ca992a0 Mon Sep 17 00:00:00 2001 From: Linerly Date: Fri, 18 Feb 2022 15:46:17 +0000 Subject: [PATCH 206/302] Translated using Weblate (Indonesian) Currently translated at 100.0% (49 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/id/ --- fastlane/metadata/android/id/changelogs/40100100.txt | 2 +- fastlane/metadata/android/id/changelogs/40100110.txt | 2 +- fastlane/metadata/android/id/changelogs/40100120.txt | 2 +- fastlane/metadata/android/id/changelogs/40100130.txt | 2 +- fastlane/metadata/android/id/changelogs/40100140.txt | 2 +- fastlane/metadata/android/id/changelogs/40100150.txt | 2 +- fastlane/metadata/android/id/changelogs/40100160.txt | 2 +- fastlane/metadata/android/id/changelogs/40100170.txt | 2 +- fastlane/metadata/android/id/changelogs/40101000.txt | 2 +- fastlane/metadata/android/id/changelogs/40101010.txt | 2 +- fastlane/metadata/android/id/changelogs/40101020.txt | 2 +- fastlane/metadata/android/id/changelogs/40101030.txt | 2 +- fastlane/metadata/android/id/changelogs/40101040.txt | 2 +- fastlane/metadata/android/id/changelogs/40101050.txt | 2 +- fastlane/metadata/android/id/changelogs/40101060.txt | 2 +- fastlane/metadata/android/id/changelogs/40101070.txt | 2 +- fastlane/metadata/android/id/changelogs/40101080.txt | 2 +- fastlane/metadata/android/id/changelogs/40101090.txt | 2 +- fastlane/metadata/android/id/changelogs/40101100.txt | 2 +- fastlane/metadata/android/id/changelogs/40101110.txt | 2 +- fastlane/metadata/android/id/changelogs/40101120.txt | 2 +- fastlane/metadata/android/id/changelogs/40101130.txt | 2 +- fastlane/metadata/android/id/changelogs/40101140.txt | 2 +- fastlane/metadata/android/id/changelogs/40101150.txt | 2 +- fastlane/metadata/android/id/changelogs/40101160.txt | 2 +- fastlane/metadata/android/id/changelogs/40102000.txt | 2 +- fastlane/metadata/android/id/changelogs/40102010.txt | 2 +- fastlane/metadata/android/id/changelogs/40103000.txt | 2 +- fastlane/metadata/android/id/changelogs/40103020.txt | 2 +- fastlane/metadata/android/id/changelogs/40103030.txt | 2 +- fastlane/metadata/android/id/changelogs/40103040.txt | 2 +- fastlane/metadata/android/id/changelogs/40103050.txt | 2 +- fastlane/metadata/android/id/changelogs/40103060.txt | 2 +- fastlane/metadata/android/id/changelogs/40103100.txt | 2 +- fastlane/metadata/android/id/changelogs/40103110.txt | 2 +- fastlane/metadata/android/id/changelogs/40103120.txt | 2 +- fastlane/metadata/android/id/changelogs/40103130.txt | 2 +- fastlane/metadata/android/id/changelogs/40103140.txt | 2 +- fastlane/metadata/android/id/changelogs/40103150.txt | 2 +- fastlane/metadata/android/id/changelogs/40103160.txt | 4 ++-- fastlane/metadata/android/id/changelogs/40103170.txt | 4 ++-- fastlane/metadata/android/id/changelogs/40103180.txt | 4 ++-- 42 files changed, 45 insertions(+), 45 deletions(-) diff --git a/fastlane/metadata/android/id/changelogs/40100100.txt b/fastlane/metadata/android/id/changelogs/40100100.txt index 96a8f506b3..d4294758d8 100644 --- a/fastlane/metadata/android/id/changelogs/40100100.txt +++ b/fastlane/metadata/android/id/changelogs/40100100.txt @@ -1,2 +1,2 @@ Versi baru ini terutama berisi perbaikan bug dan peningkatan. Mengirim pesan sekarang jauh lebih cepat. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.10 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.10 diff --git a/fastlane/metadata/android/id/changelogs/40100110.txt b/fastlane/metadata/android/id/changelogs/40100110.txt index 9f86005d8b..07e969581c 100644 --- a/fastlane/metadata/android/id/changelogs/40100110.txt +++ b/fastlane/metadata/android/id/changelogs/40100110.txt @@ -1,2 +1,2 @@ Versi baru ini terutama berisi antarmuka pengguna dan peningkatan pengalaman pengguna. Sekarang Anda dapat mengundang teman, dan membuat sebuah DM sangat cepat dengan memindai kode QR. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.11 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.11 diff --git a/fastlane/metadata/android/id/changelogs/40100120.txt b/fastlane/metadata/android/id/changelogs/40100120.txt index 3067b6367d..18adabfdcd 100644 --- a/fastlane/metadata/android/id/changelogs/40100120.txt +++ b/fastlane/metadata/android/id/changelogs/40100120.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Pratinjau URL, keyboard Emoji baru, kemampuan pengaturan ruangan baru, dan salju untuk Natal! -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.12 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.12 diff --git a/fastlane/metadata/android/id/changelogs/40100130.txt b/fastlane/metadata/android/id/changelogs/40100130.txt index df52988b6c..f94db4d7cd 100644 --- a/fastlane/metadata/android/id/changelogs/40100130.txt +++ b/fastlane/metadata/android/id/changelogs/40100130.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Pratinjau URL, keyboard Emoji baru, kemampuan pengaturan ruangan baru, dan salju untuk Natal! -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.13 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.13 diff --git a/fastlane/metadata/android/id/changelogs/40100140.txt b/fastlane/metadata/android/id/changelogs/40100140.txt index 5243adc1a8..e1ef504cd9 100644 --- a/fastlane/metadata/android/id/changelogs/40100140.txt +++ b/fastlane/metadata/android/id/changelogs/40100140.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Edit izin ruangan, tema cahaya/gelap otomatis, dan banyak perbaikan bug. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.14 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.14 diff --git a/fastlane/metadata/android/id/changelogs/40100150.txt b/fastlane/metadata/android/id/changelogs/40100150.txt index 54c307b9b6..eaf8e1a715 100644 --- a/fastlane/metadata/android/id/changelogs/40100150.txt +++ b/fastlane/metadata/android/id/changelogs/40100150.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Dukungan login sosial. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.15 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.15 diff --git a/fastlane/metadata/android/id/changelogs/40100160.txt b/fastlane/metadata/android/id/changelogs/40100160.txt index 3e357db352..0a6d42f8f6 100644 --- a/fastlane/metadata/android/id/changelogs/40100160.txt +++ b/fastlane/metadata/android/id/changelogs/40100160.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Dukungan login sosial. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.15 dan https://github.com/vector-im/element-android/releases/tag/v1.0.16 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.15 dan https://github.com/vector-im/element-android/releases/tag/v1.0.16 diff --git a/fastlane/metadata/android/id/changelogs/40100170.txt b/fastlane/metadata/android/id/changelogs/40100170.txt index 77f638a7fd..a2bd48f2c3 100644 --- a/fastlane/metadata/android/id/changelogs/40100170.txt +++ b/fastlane/metadata/android/id/changelogs/40100170.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: perbaikan bug! -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.17 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.0.17 diff --git a/fastlane/metadata/android/id/changelogs/40101000.txt b/fastlane/metadata/android/id/changelogs/40101000.txt index acfe661354..737f9b63ac 100644 --- a/fastlane/metadata/android/id/changelogs/40101000.txt +++ b/fastlane/metadata/android/id/changelogs/40101000.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: perbaikan VoIP (panggilan audio dan video dalam DM) dan perbaikan bug! -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.0 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.0 diff --git a/fastlane/metadata/android/id/changelogs/40101010.txt b/fastlane/metadata/android/id/changelogs/40101010.txt index a9903a90bd..be22d21c32 100644 --- a/fastlane/metadata/android/id/changelogs/40101010.txt +++ b/fastlane/metadata/android/id/changelogs/40101010.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: peningkatan kinerja dan perbaikan bug! -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.1 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.1 diff --git a/fastlane/metadata/android/id/changelogs/40101020.txt b/fastlane/metadata/android/id/changelogs/40101020.txt index d654bda4fe..394f48c171 100644 --- a/fastlane/metadata/android/id/changelogs/40101020.txt +++ b/fastlane/metadata/android/id/changelogs/40101020.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: peningkatan kinerja dan perbaikan bug! -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.2 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.2 diff --git a/fastlane/metadata/android/id/changelogs/40101030.txt b/fastlane/metadata/android/id/changelogs/40101030.txt index 283c201b2f..aa1e725b46 100644 --- a/fastlane/metadata/android/id/changelogs/40101030.txt +++ b/fastlane/metadata/android/id/changelogs/40101030.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: peningkatan kinerja dan perbaikan bug! -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.3 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.3 diff --git a/fastlane/metadata/android/id/changelogs/40101040.txt b/fastlane/metadata/android/id/changelogs/40101040.txt index fdb94db53d..97eddf643d 100644 --- a/fastlane/metadata/android/id/changelogs/40101040.txt +++ b/fastlane/metadata/android/id/changelogs/40101040.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: peningkatan kinerja dan perbaikan bug! -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.4 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.4 diff --git a/fastlane/metadata/android/id/changelogs/40101050.txt b/fastlane/metadata/android/id/changelogs/40101050.txt index 856530c703..fe745e06d1 100644 --- a/fastlane/metadata/android/id/changelogs/40101050.txt +++ b/fastlane/metadata/android/id/changelogs/40101050.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: perbaikan hot-fix untuk 1.1.4 -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.5 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.5 diff --git a/fastlane/metadata/android/id/changelogs/40101060.txt b/fastlane/metadata/android/id/changelogs/40101060.txt index 1810ecc3aa..2e01d640f7 100644 --- a/fastlane/metadata/android/id/changelogs/40101060.txt +++ b/fastlane/metadata/android/id/changelogs/40101060.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: perbaikan hot-fix untuk 1.1.5 -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.6 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.6 diff --git a/fastlane/metadata/android/id/changelogs/40101070.txt b/fastlane/metadata/android/id/changelogs/40101070.txt index 0087d51703..7449ef81c2 100644 --- a/fastlane/metadata/android/id/changelogs/40101070.txt +++ b/fastlane/metadata/android/id/changelogs/40101070.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: dukungan beta untuk Spaces. Kompres video sebelum mengirim. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.7 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.7 diff --git a/fastlane/metadata/android/id/changelogs/40101080.txt b/fastlane/metadata/android/id/changelogs/40101080.txt index cb98796449..737298a081 100644 --- a/fastlane/metadata/android/id/changelogs/40101080.txt +++ b/fastlane/metadata/android/id/changelogs/40101080.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: perbaikan untuk Spaces. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.8 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.8 diff --git a/fastlane/metadata/android/id/changelogs/40101090.txt b/fastlane/metadata/android/id/changelogs/40101090.txt index f6f535fe64..040cbac3b0 100644 --- a/fastlane/metadata/android/id/changelogs/40101090.txt +++ b/fastlane/metadata/android/id/changelogs/40101090.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: menambahkan dukungan untuk jaringan gitter.im. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.9 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.9 diff --git a/fastlane/metadata/android/id/changelogs/40101100.txt b/fastlane/metadata/android/id/changelogs/40101100.txt index 121d84ca50..2c13314610 100644 --- a/fastlane/metadata/android/id/changelogs/40101100.txt +++ b/fastlane/metadata/android/id/changelogs/40101100.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: pembaruan tema dan gaya dan fitur-fitur baru untuk Spaces. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.10 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.10 diff --git a/fastlane/metadata/android/id/changelogs/40101110.txt b/fastlane/metadata/android/id/changelogs/40101110.txt index 63c97253c4..7930471cb9 100644 --- a/fastlane/metadata/android/id/changelogs/40101110.txt +++ b/fastlane/metadata/android/id/changelogs/40101110.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: pembaruan tema dan gaya dan fitur baru untuk spaces (perbaikan bug untuk 1.1.10) -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.11 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.11 diff --git a/fastlane/metadata/android/id/changelogs/40101120.txt b/fastlane/metadata/android/id/changelogs/40101120.txt index b8f23c530b..6fd0e25502 100644 --- a/fastlane/metadata/android/id/changelogs/40101120.txt +++ b/fastlane/metadata/android/id/changelogs/40101120.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: pembaruan tema dan gaya dan perbaiki crash setelah panggilan video -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.12 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.12 diff --git a/fastlane/metadata/android/id/changelogs/40101130.txt b/fastlane/metadata/android/id/changelogs/40101130.txt index 51c532725b..0fca5b3563 100644 --- a/fastlane/metadata/android/id/changelogs/40101130.txt +++ b/fastlane/metadata/android/id/changelogs/40101130.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: terutama pembaruan stabilitas dan perbaikan bug. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.13 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.13 diff --git a/fastlane/metadata/android/id/changelogs/40101140.txt b/fastlane/metadata/android/id/changelogs/40101140.txt index af1e203dde..60b041b8e7 100644 --- a/fastlane/metadata/android/id/changelogs/40101140.txt +++ b/fastlane/metadata/android/id/changelogs/40101140.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: memperbaiki masalah tentang pesan terenkripsi. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.14 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.14 diff --git a/fastlane/metadata/android/id/changelogs/40101150.txt b/fastlane/metadata/android/id/changelogs/40101150.txt index f3aec557d0..2411b62b5f 100644 --- a/fastlane/metadata/android/id/changelogs/40101150.txt +++ b/fastlane/metadata/android/id/changelogs/40101150.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: implementasi pesan suara dalam pengaturan labs. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.15 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.1.15 diff --git a/fastlane/metadata/android/id/changelogs/40101160.txt b/fastlane/metadata/android/id/changelogs/40101160.txt index 19209bacf2..0a829a9262 100644 --- a/fastlane/metadata/android/id/changelogs/40101160.txt +++ b/fastlane/metadata/android/id/changelogs/40101160.txt @@ -1,2 +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 +Catatan perubahan 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 index f7d93e2e4f..745c46dc18 100644 --- a/fastlane/metadata/android/id/changelogs/40102000.txt +++ b/fastlane/metadata/android/id/changelogs/40102000.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Pesan Suara diaktifkan secara default -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.2.0 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.2.0 diff --git a/fastlane/metadata/android/id/changelogs/40102010.txt b/fastlane/metadata/android/id/changelogs/40102010.txt index e77f0327b0..e68a571226 100644 --- a/fastlane/metadata/android/id/changelogs/40102010.txt +++ b/fastlane/metadata/android/id/changelogs/40102010.txt @@ -1,2 +1,2 @@ Perubahan utama di versi ini: Banyak perbaikan di VoIP dan Space (masih beta). -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.2.1 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.2.1 diff --git a/fastlane/metadata/android/id/changelogs/40103000.txt b/fastlane/metadata/android/id/changelogs/40103000.txt index bf7b5d8d5d..7192c3ba30 100644 --- a/fastlane/metadata/android/id/changelogs/40103000.txt +++ b/fastlane/metadata/android/id/changelogs/40103000.txt @@ -1,2 +1,2 @@ Perubahan utama di versi ini: Organisir ruangan Anda menggunakan sebuah Space! -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.0 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/id/changelogs/40103020.txt b/fastlane/metadata/android/id/changelogs/40103020.txt index 4f46881d68..2eb358b980 100644 --- a/fastlane/metadata/android/id/changelogs/40103020.txt +++ b/fastlane/metadata/android/id/changelogs/40103020.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Penambahan dukungan untuk Android Auto. Banyak perbaikan bug! -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.2 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.2 diff --git a/fastlane/metadata/android/id/changelogs/40103030.txt b/fastlane/metadata/android/id/changelogs/40103030.txt index 630593a107..9324b44a3a 100644 --- a/fastlane/metadata/android/id/changelogs/40103030.txt +++ b/fastlane/metadata/android/id/changelogs/40103030.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Membuat kebijakan server identitas terlihat di pengaturan. Menghilangkan dukungan Android Auto untuk sementara. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.3 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/id/changelogs/40103040.txt b/fastlane/metadata/android/id/changelogs/40103040.txt index 0641f72ffd..00987013ac 100644 --- a/fastlane/metadata/android/id/changelogs/40103040.txt +++ b/fastlane/metadata/android/id/changelogs/40103040.txt @@ -1,2 +1,2 @@ Perubahan utama di versi ini: Tambahkan dukungan presensi, untuk ruangan Pesan Langsung (diingat bahwa presensi dinonaktifkan di matrix.org). Tambahkan lagi dukungan Android Auto. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.4 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.4 diff --git a/fastlane/metadata/android/id/changelogs/40103050.txt b/fastlane/metadata/android/id/changelogs/40103050.txt index ec7c9423bf..dbca8cc0db 100644 --- a/fastlane/metadata/android/id/changelogs/40103050.txt +++ b/fastlane/metadata/android/id/changelogs/40103050.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Tambahkan dukungan presensi, untuk ruangan Pesan Langsung (diingat bahwa presensi dinonaktifkan di matrix.org). Tambahkan lagi dukungan Android Auto. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.5 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.5 diff --git a/fastlane/metadata/android/id/changelogs/40103060.txt b/fastlane/metadata/android/id/changelogs/40103060.txt index 4265699d2f..18f81838ff 100644 --- a/fastlane/metadata/android/id/changelogs/40103060.txt +++ b/fastlane/metadata/android/id/changelogs/40103060.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Tambahkan dukungan presensi, untuk ruangan Pesan Langsung (catatan: presensi dinonaktifkan di matrix.org). Tambahkan lagi dukungan Android Auto. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.6 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.6 diff --git a/fastlane/metadata/android/id/changelogs/40103100.txt b/fastlane/metadata/android/id/changelogs/40103100.txt index 39d127cd93..0254c176ee 100644 --- a/fastlane/metadata/android/id/changelogs/40103100.txt +++ b/fastlane/metadata/android/id/changelogs/40103100.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Dukungan untuk fitur poll (dalam Uji Coba), dan desain tampilan URL baru. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.10 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.10 diff --git a/fastlane/metadata/android/id/changelogs/40103110.txt b/fastlane/metadata/android/id/changelogs/40103110.txt index 725e58d957..3b325f7f03 100644 --- a/fastlane/metadata/android/id/changelogs/40103110.txt +++ b/fastlane/metadata/android/id/changelogs/40103110.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Perbaikan bug! -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.11 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.11 diff --git a/fastlane/metadata/android/id/changelogs/40103120.txt b/fastlane/metadata/android/id/changelogs/40103120.txt index 9a5dc8026c..c765575ad7 100644 --- a/fastlane/metadata/android/id/changelogs/40103120.txt +++ b/fastlane/metadata/android/id/changelogs/40103120.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Perbaikan bug! -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.12 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.12 diff --git a/fastlane/metadata/android/id/changelogs/40103130.txt b/fastlane/metadata/android/id/changelogs/40103130.txt index de10de53d5..2b81855beb 100644 --- a/fastlane/metadata/android/id/changelogs/40103130.txt +++ b/fastlane/metadata/android/id/changelogs/40103130.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Perubahan pertama di layar permulaan, termasuk analitik opt-in. Dukungan untuk Peristiwa dengan Matematika ditambahkan di Uji Coba. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.13 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.13 diff --git a/fastlane/metadata/android/id/changelogs/40103140.txt b/fastlane/metadata/android/id/changelogs/40103140.txt index dfefff307f..cabf0750e0 100644 --- a/fastlane/metadata/android/id/changelogs/40103140.txt +++ b/fastlane/metadata/android/id/changelogs/40103140.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Perubahan pertama di layar permulaan, termasuk analitik opt-in. Dukungan untuk Peristiwa dengan Matematika ditambahkan di Uji Coba. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.14 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.14 diff --git a/fastlane/metadata/android/id/changelogs/40103150.txt b/fastlane/metadata/android/id/changelogs/40103150.txt index c46e661d47..27fc93215b 100644 --- a/fastlane/metadata/android/id/changelogs/40103150.txt +++ b/fastlane/metadata/android/id/changelogs/40103150.txt @@ -1,2 +1,2 @@ Perubahan utama dalam versi ini: Perubahan pertama di layar permulaan, termasuk analitik opt-in. Dukungan untuk Peristiwa dengan Matematika ditambahkan di Uji Coba. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.15 +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.15 diff --git a/fastlane/metadata/android/id/changelogs/40103160.txt b/fastlane/metadata/android/id/changelogs/40103160.txt index 8a6e62be0c..418853bb2c 100644 --- a/fastlane/metadata/android/id/changelogs/40103160.txt +++ b/fastlane/metadata/android/id/changelogs/40103160.txt @@ -1,2 +1,2 @@ -Perubahan utama dalam versi ini: Kirim lokasi Anda ke ruangan apa saja. Edit poll. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.16 +Perubahan utama dalam versi ini: Kirim lokasi Anda ke ruangan apa saja. Pengeditan pemungutan suara. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.16 diff --git a/fastlane/metadata/android/id/changelogs/40103170.txt b/fastlane/metadata/android/id/changelogs/40103170.txt index 04197b674d..eebdcf5858 100644 --- a/fastlane/metadata/android/id/changelogs/40103170.txt +++ b/fastlane/metadata/android/id/changelogs/40103170.txt @@ -1,2 +1,2 @@ -Perubahan utama dalam versi ini: kirim lokasi Anda ke ruangan apa saja. Edit poll. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.17 +Perubahan utama dalam versi ini: kirim lokasi Anda ke ruangan apa saja. Pengeditan pemungutan suara. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/id/changelogs/40103180.txt b/fastlane/metadata/android/id/changelogs/40103180.txt index 655fbd562a..6ec4c2c1bc 100644 --- a/fastlane/metadata/android/id/changelogs/40103180.txt +++ b/fastlane/metadata/android/id/changelogs/40103180.txt @@ -1,2 +1,2 @@ -Perubahan utama dalam versi ini: kirim lokasi Anda ke ruangan apa saja. Edit poll. -Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.18 +Perubahan utama dalam versi ini: kirim lokasi Anda ke ruangan apa saja. Pengeditan pemungutan suara. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.18 From 162973c8df79c021f3f7c174dafb7a8b733c3160 Mon Sep 17 00:00:00 2001 From: Edward Gera Date: Wed, 16 Feb 2022 15:09:02 +0000 Subject: [PATCH 207/302] Translated using Weblate (Hebrew) Currently translated at 73.7% (2055 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/he/ --- vector/src/main/res/values-iw/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-iw/strings.xml b/vector/src/main/res/values-iw/strings.xml index 50cace2348..a245b14b9d 100644 --- a/vector/src/main/res/values-iw/strings.xml +++ b/vector/src/main/res/values-iw/strings.xml @@ -2408,4 +2408,7 @@ %1$s שלח מדבקה. %1$s שלח תמונה‮. %1$s: %2$s + כל חברי החדר, מהנקודה בה הם הוזמנו. + את/ה הפכת הודעות עתידיות לגלויות בפני %1$s + %1$s הפך הודעות עתידיות לגלויות בפני %2$s \ No newline at end of file From 3731fdce0e1dd8a81e2ef7c3a81f4679756bcae9 Mon Sep 17 00:00:00 2001 From: Edward Gera Date: Wed, 16 Feb 2022 15:00:11 +0000 Subject: [PATCH 208/302] Translated using Weblate (Hebrew) Currently translated at 10.2% (5 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/he/ --- fastlane/metadata/android/iw-IL/changelogs/40103180.txt | 2 ++ fastlane/metadata/android/iw-IL/full_description.txt | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 fastlane/metadata/android/iw-IL/changelogs/40103180.txt diff --git a/fastlane/metadata/android/iw-IL/changelogs/40103180.txt b/fastlane/metadata/android/iw-IL/changelogs/40103180.txt new file mode 100644 index 0000000000..9649c6839c --- /dev/null +++ b/fastlane/metadata/android/iw-IL/changelogs/40103180.txt @@ -0,0 +1,2 @@ +שינויים עיקריים בגרסה זו: שלח את המיקום שלך לכל חדר. ערוך סקר. +יומן שינויים מלא: https://github.com/vector-im/element-android/releases/tag/v1.3.18 diff --git a/fastlane/metadata/android/iw-IL/full_description.txt b/fastlane/metadata/android/iw-IL/full_description.txt index fe3bc16661..1545634b33 100644 --- a/fastlane/metadata/android/iw-IL/full_description.txt +++ b/fastlane/metadata/android/iw-IL/full_description.txt @@ -28,3 +28,6 @@ תקשורת מלאה : הודעות, שיחות קול ווידאו, שיתוף קבצים, שיתוף מסך וחבורה שלמה של אינטגרציות, בוטים ווידג'טים. לבנות חדרים, קהילות, לשמור על קשר ולעשות דברים. בכל מקום שאתה נמצא : הישאר בקשר בכל מקום שאתה נמצא עם היסטוריית הודעות מסונכרנת לחלוטין בכל המכשירים שלך באינטרנט בכתובת https://app.element.io. + +קוד פתוח: +Element Android הוא פרויקט קוד פתוח, המתארח על ידי GitHub. נא לדווח על באגים ו/או לתרום לפיתוחה בכתובת https://github.com/vector-im/element-android From e8b79e6e3b8176c28e7c473c4baeced235374aa3 Mon Sep 17 00:00:00 2001 From: Linerly Date: Fri, 18 Feb 2022 16:06:41 +0000 Subject: [PATCH 209/302] Translated using Weblate (Indonesian) Currently translated at 100.0% (2785 of 2785 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 | 36 +++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index afe1638b0f..5677c283a4 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -43,7 +43,7 @@ Direktori ruang Kirim log Deskripsikan kendala Anda di sini - Laporan bug telah berhasil dikirimkan + Laporan kutu telah berhasil dikirimkan Baca Daftar Masuk @@ -75,7 +75,7 @@ Tidak dapat memulai panggilan, coba lagi nanti Tidak dapat memulai panggilan Keluar - Offline + Luring Pencarian global Tandai semua sudah dibaca Orang @@ -86,7 +86,7 @@ Prioritas rendah Hanya kontak Matrix Ruangan - Laporan bug + Laporan kutu Aplikasi gagal saat terakhir digunakan. Apakah Anda ingin membuka halaman laporan kegagalan\? Gabung di Ruangan URL server identitas @@ -136,7 +136,7 @@ Nanti Kirim Saja ${app_name} belum diizinkan untuk mengakses kontak lokal - Kirim log gangguan + Kirim catat gangguan Raksasa Kecil Normal @@ -169,10 +169,10 @@ %d pengguna Kirim tampilan layar - Mohon uraikan bug tersebut. Apa yang Anda lakukan? Apa yang Anda harapkan terjadi? Apa yang sebenarnya terjadi? - Log dari klien akan dikirim bersama laporan gangguan ini untuk mendalami kendala yang Anda temukan. Laporan gangguan ini, termasuk log dan rekalayar, tidak akan dilihat oleh khalayak umum. Jika Anda hanya ingin mengirimkan tulisan di atas, silahkan hapus centang: - Sepertinya Anda mengguncang telepon akibat frustrasi. Apakah Anda ingin membuka halaman laporan bug? - Pengiriman laporan bug gagal (%s) + Mohon uraikan kutu tersebut. Apa yang Anda lakukan\? Apa yang Anda harapkan terjadi\? Apa yang sebenarnya terjadi\? + Catat dari klien akan dikirim bersama laporan gangguan ini untuk mendalami kendala yang Anda temukan. Laporan gangguan ini, termasuk catat dan tangkapan layar, tidak akan terlihat secara umum. Jika Anda hanya ingin mengirimkan tulisan di atas, silakan hapus centang: + Sepertinya Anda mengguncang ponsel akibat frustrasi. Apakah Anda ingin membuka halaman laporan kutu\? + Pengiriman laporan kutu gagal (%s) Kemajuan (%s%%) Kirim ke Nama Pengguna @@ -320,8 +320,8 @@ Ijinkan akses lewat halaman selanjutnya untuk menemukan pengguna ${app_name} yan Tinggalkan ruang Apa benar Anda ingin meninggalkan ruangan ini\? Buat - Online - Offline + Daring + Luring Berdiam Diri %1$s sekarang %1$s %2$s yang lalu @@ -795,9 +795,9 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Hasil diagnosa pemeriksaan keadaan Lansungkan Ujicoba Berlangsung… (%1$d of %2$d) - Diagnosa dasar berlangsung lancar. Apabila Anda masih belum dapat menerima pemberitahuan, mohon kirim laporan bug untuk kami selidiki. + Diagnosa dasar berlangsung lancar. Apabila Anda masih belum dapat menerima pemberitahuan, mohon kirim laporan kutu untuk kami selidiki. Satu atau beberapa ujicoba gagal, coba sugesti yang kami tawarkan. - Satu atau beberapa ujicoba gagal, mohon kirim laporan bug untuk kami selidiki. + Satu atau beberapa ujicoba gagal, mohon kirim laporan kutu untuk kami selidiki. Pengaturan Sistem. Pemberitahuan diperbolehkan dalam pengaturan sistem. Notifikasi dinonaktifkan dalam pengaturan sistem. @@ -1710,8 +1710,8 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. 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. + Log verbose akan membantu pengembang dengan menyediakan lebih banyak catat saat Anda mengirim RageShake. Bahkan ketika diaktifkan, aplikasi tidak mencatat isi pesan atau data pribadi lainnya. + Aktifkan catat verbose. Kode verifikasi salah. Kode Sebuah pesan teks telah dikirim ke %s. Silakan masukkan kode verifikasi yang ada di dalamnya. @@ -2330,7 +2330,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Otomatis memperbarui induk space Otomatis undang pengguna Anda akan meningkatkan ruangan ini dari %1$s ke %2$s. - Meningkatkan ruangan adalah aksi lanjutan dan hanya disarankan ketika ruangan tidak stabil karena bug yang ada, fitur yang kurang atau rentanan keamanan. + Meningkatkan ruangan adalah aksi lanjutan dan hanya disarankan ketika ruangan tidak stabil karena kutu yang ada, fitur yang kurang atau rentanan keamanan. \nIni biasanya hanya mempengaruhi bagaimana ruangan itu diproses di servernya. Tingkatkan ruangan privat Tingkatkan ruangan publik @@ -2924,8 +2924,8 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Mengubah avatar Anda di ruangan saat ini saja Menampilkan Tidak Tersedia - Offline - Online + Luring + Daring Pilih homeserver Tidak dapat menjangkau homeserver di URL %s. Silakan periksa tautan Anda atau pilih sebuah homeserver secara manual. Mendengarkan notifikasi @@ -2995,7 +2995,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Mulai ulang aplikasi ini untuk menerapkan perubahan. Aktifkan matematika LaTeX Anda tidak diperbolehkan untuk bergabung ke ruangan ini - Sistem Anda akan mengirimkan log secara otomatis ketika sebuah kesalahan dekripsi terjadi + Sistem Anda akan mengirimkan catat secara otomatis ketika sebuah kesalahan dekripsi terjadi Buat poll Buka kontak Kirim stiker From d43b699e1af63761170a903d35e57c166ab5252c Mon Sep 17 00:00:00 2001 From: Retired Lawyer Date: Thu, 17 Feb 2022 22:35:58 +0000 Subject: [PATCH 210/302] Translated using Weblate (Turkish) Currently translated at 59.1% (29 of 49 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/tr/ --- fastlane/metadata/android/tr-TR/changelogs/40103000.txt | 2 ++ fastlane/metadata/android/tr-TR/changelogs/40103010.txt | 2 ++ fastlane/metadata/android/tr-TR/changelogs/40103020.txt | 2 ++ fastlane/metadata/android/tr-TR/changelogs/40103030.txt | 2 ++ 4 files changed, 8 insertions(+) create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103000.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103010.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103020.txt create mode 100644 fastlane/metadata/android/tr-TR/changelogs/40103030.txt diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103000.txt b/fastlane/metadata/android/tr-TR/changelogs/40103000.txt new file mode 100644 index 0000000000..bb66b40193 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103000.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Spaces kullanarak odalarınızı düzenleyin! +Tam değişiklik günlüğü: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103010.txt b/fastlane/metadata/android/tr-TR/changelogs/40103010.txt new file mode 100644 index 0000000000..3fea80054e --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103010.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Spaces kullanarak odalarınızı düzenleyin! v1.3.1, v1.3.0'da meydana gelen bir kilitlenme düzeltildi. +Tam değişiklik günlüğü: https://github.com/vector-im/element-android/releases/tag/v1.3.1 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103020.txt b/fastlane/metadata/android/tr-TR/changelogs/40103020.txt new file mode 100644 index 0000000000..ef8271c6c2 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103020.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Android Auto desteği eklendi. Birçok hata düzeltmesi! +Tam değişiklik günlüğü: https://github.com/vector-im/element-android/releases/tag/v1.3.2 diff --git a/fastlane/metadata/android/tr-TR/changelogs/40103030.txt b/fastlane/metadata/android/tr-TR/changelogs/40103030.txt new file mode 100644 index 0000000000..b771e53f96 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Bu sürümdeki ana değişiklikler: Ayarlarda kimlik sunucusu politika(lar)ını görünür yapın. Android Auto desteğini geçici olarak kaldırın. +Tam değişiklik günlüğü: https://github.com/vector-im/element-android/releases/tag/v1.3.3 From b133de8961a86362e01554aa7c6a4c248cbd1202 Mon Sep 17 00:00:00 2001 From: Arusekk Date: Sun, 13 Feb 2022 19:28:44 +0000 Subject: [PATCH 211/302] Translated using Weblate (Polish) Currently translated at 95.1% (2651 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/ --- vector/src/main/res/values-pl/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index f25ad75c73..f3b3888a20 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -2425,7 +2425,7 @@ Kto powinien mieć dostęp \? Ustawienia konta Możesz zarządzać notyfikacjami w %1$s. - Proszę zwrócić uwagę, że notyfikacje o wzmiankach i słowach kluczowych nie są dostępne w zaszyfrowanych pokojach na urządzeniach mobilnych. + Proszę zwrócić uwagę, że powiadomienia o wzmiankach i słowach kluczowych nie są dostępne w zaszyfrowanych pokojach na urządzeniach mobilnych. Powiadamiaj mnie o Zresetuj bezpieczną kopię zapasową Skonfiguruj bezpieczną kopię zapasową @@ -2440,7 +2440,7 @@ Powiadomienie email Żadne Tylko wzmianki i słowa kluczowe - Oczekiwanie na notyfikacje + Oczekiwanie na powiadomienia %1$s zmienił(a) adresy tego pokoju. Zmieniłeś(aś) głowny i alternatywny adres tego pokoju. %1$s zmienił(a) główny i alternatywny adres tego pokoju. @@ -3072,8 +3072,8 @@ Jedno aktywne połączenie (%1$s) - Jedno wstrzymane połączenie Jedno aktywne połączenie (%1$s) - Kilka wstrzymanych połączeń - - + + Odkrywanie (%s) Dokończ konfigurację odkrywania. From b595fa061e591f0bd39131a313c9138733a41425 Mon Sep 17 00:00:00 2001 From: notramo Date: Sun, 13 Feb 2022 14:02:42 +0000 Subject: [PATCH 212/302] Translated using Weblate (Hungarian) Currently translated at 100.0% (2785 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/hu/ --- vector/src/main/res/values-hu/strings.xml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index 0a6b6d9a97..5a21a5a5eb 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -1225,9 +1225,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Aláírás A Kulcs Mentés munkamenetben való felhasználáshoz, állítsd vissza jelmondattal vagy Visszaállítási Kulccsal. Új Kulcs Mentés - Új biztonságos üzenet kulcs mentés észlelve. - -Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó próbál hozzáférni a fiókodhoz. Azonnal cseréld le a felhasználói fiókod jelszavát és állítsál be új visszaállítási metódust a Beállításokban. + Egy új biztonságos kulcs mentés észlelve. Ha nem te állítottad be a visszaállítási módot, akkor egy támadó próbál hozzáférni a fiókodhoz. Azonnal cseréld le a felhasználói fiókod jelszavát és állíts be új visszaállítási módot a Beállításokban. Én voltam Visszaállítási kulcs kiszámítása… Kulcsok letöltése… @@ -2656,7 +2654,7 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró \n \nAz üzeneteidet zárolással vannak biztosítva és csak neked és a címzetteknek van meg a kulcs hozzá. Itt az üzenetek nincsenek végponttól végpontig titkosítva. - Azonosítás eredménye + Hitelesítés eredménye Szavazás Szoba létrehozása… Néhány karakter nem engedélyezett @@ -3068,8 +3066,8 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró A beállítás után bármelyik szobában megoszthatod a földrajzi helyzetedet Földrajzi hely megosztás engedélyezése Megnyitás ezzel - ${app_name} nem fér hozzá a helyadatodhoz. Próbáld újra később. - ${app_name} nem fér hozzá a földrajzi helyzetedhez + Az ${app_name} nem fér hozzá a tartózkodási helyedhez. Próbáld újra később. + Az ${app_name} nem tudott hozzáférni a tartózkodási helyedhez Tartózkodási hely megosztása Tartózkodási hely megosztása Földrajzi helyzet From 491233b6f7090b351d9ab9277c62db2ae0547bc2 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Sun, 13 Feb 2022 09:25:57 +0000 Subject: [PATCH 213/302] Translated using Weblate (Hungarian) Currently translated at 100.0% (2785 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/hu/ --- vector/src/main/res/values-hu/strings.xml | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index 5a21a5a5eb..b206744119 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -3094,4 +3094,37 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Földrajzi helyzet A titkosítás beállítása hibás így nem lehet üzenetet küldeni. Kattints a beállításokért. A titkosítás beállítása hibás így nem lehet üzenetet küldeni. Kérjük vedd fel a kapcsolatot az adminisztrátorral a titkosítás helyreállításához. + Üzenet buborékok megjelenítése + Térkép betöltése sikertelen + Térkép + Figyelem: az alkalmazás újraindul + Üzenetszálak engedélyezése + Szerverhez csatlakozás + Csatlakoznál egy már meglévő szerverhez\? + kérdés kihagyása + Még nem vagy biztos\? Tudhatsz ilyent: %s + Közösségek + Csoportok + Barátok és család + Segítünk a kapcsolatteremtésben. + Kivel beszélgetnék leginkább\? + Már nézed ezt az üzenetszálat! + Megjelenítés szobában + Válasz az üzenetszálban + „%s” parancs ismert, de üzenetszálban nem támogatott. + Az üzenetszálból + Tipp: Koppints hosszan az üzenetre és használd ezt: %s. + Az üzenetszálak segítenek a különböző témájú beszélgetések figyelemmel kísérésében. + Beszélgetések üzenetszálakba való rendezése + Minden üzenetszál megjelenítése ahol szerepel + Üzenetszálaim + A szobában lévő összes szál mutatása + Minden üzenetszál + Szűrés + Üzenetszálak + Üzenetszál + Üzenetszálak szűrése a szobában + Üzenetszálra mutató hivatkozás másolása + Megjelenítés szobában + Üzenetszálak megtekintése \ No newline at end of file From 539d2e732299e0785ad75ae67cb63e1aa39ac9e2 Mon Sep 17 00:00:00 2001 From: Johan Smits Date: Tue, 15 Feb 2022 18:42:04 +0000 Subject: [PATCH 214/302] Translated using Weblate (Dutch) Currently translated at 100.0% (2785 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/nl/ --- vector/src/main/res/values-nl/strings.xml | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index abe647b39e..819958feb3 100644 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -3097,4 +3097,37 @@ Locatie De versleuteling is verkeerd geconfigureerd, zodat u geen berichten kunt verzenden. Klik om instellingen te openen. De versleuteling is verkeerd geconfigureerd, zodat u geen berichten kunt verzenden. Neem contact op met een beheerder om de versleuteling in een geldige staat te herstellen. + Toon bericht bubbels + Kan kaart niet laden + Kaart + Let op: app wordt opnieuw gestart + Discussieberichten inschakelen + Verbinding maken met server + Wilt u lid worden van een bestaande server\? + sla deze vraag over + Nog niet zeker\? U kunt %s + Gemeenschappen + Teams + Vrienden en familie + We helpen u om verbinding te maken. + Met wie gaat u het meest chatten\? + U bekijkt deze discussie al! + Bekijk in kamer + Reageren in discussie + Het commando \"%s\" wordt herkend maar niet ondersteund in discussies. + Van een discussie + Tip: Tik lang op een bericht en gebruik \"%s\". + Discussies helpen je gesprekken on-topic te houden en gemakkelijk bij te houden. + Houd discussies georganiseerd met discussielijnen + Toont alle discussies waaraan u heeft deelgenomen + Mijn discussies + Toont alle discussies van de huidige kamer + Alle discussies + Filter + Discussies + Discussie + Discussies in de kamer filteren + Kopieer link naar discussie + Bekijk in kamer + Discussies bekijken \ No newline at end of file From b80ab1e5190fa09061baadd959d36e9385cf677f Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sat, 19 Feb 2022 18:10:23 +0000 Subject: [PATCH 215/302] Translated using Weblate (Japanese) Currently translated at 82.3% (2294 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 25d5a0517d..73e326956b 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2512,4 +2512,6 @@ チームワークを効率よくしましょう。 セキュアメッセージング 管理権を握るのはあなたです。 + Elementの使用に関するヘルプ + 詳細なログはRageShakeのときにもっと詳しいログを提供し開発者を助けてくれます。有効にした場合でも、メッセージの内容などのプライベートな情報は記録されません。 \ No newline at end of file From ba269b244a9273eb9beb2b6a74f816436224ed71 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 18:09:55 +0000 Subject: [PATCH 216/302] Translated using Weblate (Japanese) Currently translated at 82.3% (2294 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 73e326956b..36aeba76f2 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -122,10 +122,10 @@ 不具合の内容と状況の説明をお願いします。何をしましたか?何が起こるべきでしたか?実際に起こった事象は何でしょうか? ここに不具合の内容を記述 スクリーンショットの画像を送信 - クラッシュ時の動作記録を送信 - 動作記録を送信 - 開発者が問題を診断するために、このクライアントの動作記録が不具合報告と一緒に送信されます。不具合報告は、動作記録とスクリーンショットを含めて、公開されることはありません。上記の説明文だけを送信したい場合は、以下のチェックを解除してください。 - あなたは不満で端末を振っているようです。不具合報告の画面を開きますか? + クラッシュ時のログを送信 + ログを送信 + 開発者が問題を診断するために、このクライアントのログがバグレポートと一緒に送信されます。バグレポートは、ログとスクリーンショットを含めて、公開されることはありません。上記の説明文だけを送信したい場合は、以下のチェックを解除してください。 + あなたは不満で端末を振っているようです。バグレポートの画面を開きますか? 前回アプリケーションは正常に停止しませんでした。クラッシュ報告の画面を開きますか? 不具合を報告しました 不具合の報告の送信に失敗しました (%s) @@ -1193,9 +1193,9 @@ カスタムルールの読み込みに失敗しました。再試行してください。 一部の通知はカスタム設定で無効になっています。 一部のメッセージがサイレントに設定されていることに注意してください(音を出さずに通知します)。 - 1つ以上のテストが失敗しました。調査用の不具合報告を送信してください。 + 1つ以上のテストが失敗しました。調査用のバグレポートを送信してください。 1つ以上のテストが失敗しました。提案された修正を試してください。 - 基本的な診断はOKです。 それでも通知が届かない場合は、調査用の不具合報告を送信してください。 + 基本的な診断はOKです。 それでも通知が届かない場合は、調査用のバグレポートを送信してください。 実行しています…(%1$dの%2$d) テストを実行 診断トラブルシューティング @@ -1536,7 +1536,7 @@ 共有 完了 成功! - バックアップを作成中 + バックアップを作成しています パスフレーズを設定 手動でキーをエクスポート キーバックアップを使って開始 @@ -1659,7 +1659,7 @@ リカバリーキーはパスワードマネージャー(もしくは金庫)のような、非常に安全な場所で保管してください リカバリーキーはセーフティーネットとなります。パスフレーズを忘れた場合でも、リカバリーキーを使えば、暗号化されたメッセージにアクセスすることができます。 \nリカバリーキーは、パスワードマネージャー(もしくは金庫)のような、非常に安全な場所で保管してください。 - 暗号鍵がバックアップ中です。 + 暗号鍵をバックアップしています。 (高度)リカバリーキーを使用して設定 または、リカバリーキーでバックアップを保護し、安全な場所に保存してください。 暗号鍵のコピーを暗号化してホームサーバーに保存します。バックアップを保護するためにパスフレーズを設定してください。 @@ -2411,7 +2411,7 @@ このルームで使用されている暗号化はサポートされていません 暗号化が正しく設定されていません %sにテキストメッセージを送信しました。メッセージに含まれた確認コードを入力してください。 - 選択したIDサーバーは利用規約がありません。サービス提供者を信頼しなければ続行しないほうがいいです + 選択したIDサーバーには利用規約がありません。サービス提供者を信頼している場合にのみ続行してください 現在IDサーバー %1$s でメールアドレスや電話番号を共有しています。共有を停止するには %2$s に再接続する必要があります。 ルームを作成し設定しました。 QRコードを読み取り、新しいダイレクトメッセージを作成 @@ -2514,4 +2514,7 @@ 管理権を握るのはあなたです。 Elementの使用に関するヘルプ 詳細なログはRageShakeのときにもっと詳しいログを提供し開発者を助けてくれます。有効にした場合でも、メッセージの内容などのプライベートな情報は記録されません。 + ルームのアップグレードは高度な作業であり、不具合や不足する機能、セキュリティー上の脆弱性がある場合に推奨されます。 +\nアップグレードは普通、ルームがサーバー上で処理される仕方にだけ影響します。 + 一度有効にしたルームの暗号化は無効にすることはできません。暗号化されたルームで送信されたメッセージは、サーバーからは見ることができず、そのルームのメンバーだけが見ることができます。暗号化を有効にすると、多くのボットやブリッジが正常に動作しなくなる場合があります。 \ No newline at end of file From cea16719e85452c53d131e1bcc168037f1cf2169 Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Sat, 19 Feb 2022 20:59:37 +0000 Subject: [PATCH 217/302] Translated using Weblate (Japanese) Currently translated at 84.3% (2349 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 36aeba76f2..c3606e4b56 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2517,4 +2517,5 @@ ルームのアップグレードは高度な作業であり、不具合や不足する機能、セキュリティー上の脆弱性がある場合に推奨されます。 \nアップグレードは普通、ルームがサーバー上で処理される仕方にだけ影響します。 一度有効にしたルームの暗号化は無効にすることはできません。暗号化されたルームで送信されたメッセージは、サーバーからは見ることができず、そのルームのメンバーだけが見ることができます。暗号化を有効にすると、多くのボットやブリッジが正常に動作しなくなる場合があります。 + %sでこの部屋について人々に知らせます。 \ No newline at end of file From 47f45f42cce7ce633835546adba08d903fdd00cf Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sat, 19 Feb 2022 20:59:12 +0000 Subject: [PATCH 218/302] Translated using Weblate (Japanese) Currently translated at 84.3% (2349 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 83 ++++++++++++++++++++--- 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index c3606e4b56..12ffe05406 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -142,9 +142,9 @@ 電話番号 電話番号 (任意で) ユーザー名かパスワードが正しくありません - ユーザー名は半角英数字、ドット、ハイフン、アンダスコアのみで記して下さい + ユーザー名は半角英数字、ドット、ハイフン、アンダースコアのみで記して下さい パスワードが短すぎます(最小6文字) - 正しくない電子メールアドレスのようです + 正しくないメールアドレスのようです 正しくない電話番号のようです 既に登録されている電子メールアドレスです。 パスワードが一致しません @@ -385,7 +385,7 @@ メールアドレスがありません 電話番号が入力されていません 電子メールアドレスまたは電話番号が入力されていません - 接続先サーバーを指定する(追加設定) + 接続先サーバーを指定(高度) 不正なトークン メールと電話番号の同時登録はまだシステムが対応できませんが、電話番号だけの登録は可能です。 \n @@ -581,7 +581,7 @@ 証明書はあなたの電話に信頼されていたものから変更されています。これはきわめて異常な事態です。この新しい証明書は承認しないことを強く推奨します。 証明書は以前信頼されていたものから信頼されていないものへと変更されています。サーバーがその証明書を更新した可能性があります。予測されるフィンガープリントを取得するために、サーバーの管理者に連絡してください。 サーバーの管理者が上のフィンガープリントと一致するものを発行した場合に限り、証明書を承認してください。 - 不正な形式のIDです。メールアドレスまたは\'@localpart:domain\'のようなMatrix IDを入力してください + 不正な形式のIDです。メールアドレスまたは\'@localpart:domain\'という形式のMatrix IDを入力してください このコンテンツを報告する理由 このユーザーによる全てのメッセージを非表示にしますか? \n @@ -978,7 +978,7 @@ 現在のセッション その他のセッション 暗号化を有効にする - 有効にすると、あとで無効にすることはできません。 + いったん有効にすると、暗号化を無効にすることはできません。 セキュリティー 詳細 その他の設定 @@ -1063,7 +1063,7 @@ スパムメッセージです 不適切なメッセージです その他の報告… - コンテンツの報告 + コンテンツを報告 このコンテンツを報告する理由 報告 ユーザーを無視 @@ -1581,7 +1581,7 @@ %sに招待 Eメールで招待 詳細 - 人を招待 + 連絡先を招待 とにかく参加 ルームを追加 %sはあなたを招待しています @@ -1861,7 +1861,7 @@ このルームはプレビューできません お待ち下さい… ネットワークがありません。インターネット接続を確認してください。 - 不正な形式のイベント、表示できません + 不正な形式のイベントです。表示できません %2$sに%1$sによって最後に編集されました ルーム管理者によってモデレートされたイベント リアクション @@ -2398,7 +2398,7 @@ 投票を締め切り、投票の最終結果を表示します。 招待者のみ参加可能。個人やチームに最適 スペースを作成 - スペースに招待 + 連絡先をスペースに招待 IDサーバーは利用規約がありません あなたの連絡先はプライベートです。端末の連絡先からユーザーを発見できるように、連絡先の情報をIDサーバーへ送信する許可が必要です。 ディスカバリー設定を開く @@ -2506,16 +2506,77 @@ 紙吹雪🎉を送る 降雪❄️を送る あなたのチームのメッセージングに。 - エンドツーエンド暗号化され、電話番号不要。広告やデータマイニング無し。 + エンドツーエンドで暗号化され、電話番号不要。広告やデータマイニング無し。 会話の保存先を自分で決められ、自分で管理できる独立したコミュニケーション。Matrixを基に。 お宅での対面会話と同じぐらいのプライバシーを提供する、セキュアで独立したコミュニケーション。 チームワークを効率よくしましょう。 セキュアメッセージング 管理権を握るのはあなたです。 Elementの使用に関するヘルプ - 詳細なログはRageShakeのときにもっと詳しいログを提供し開発者を助けてくれます。有効にした場合でも、メッセージの内容などのプライベートな情報は記録されません。 + 詳細なログは、イライラシェイクでログを送信する際に、より多くのログを提供することで、開発者にとっての助けになります。有効にした場合でも、メッセージの内容やその他のプライベートな情報は記録されません。 ルームのアップグレードは高度な作業であり、不具合や不足する機能、セキュリティー上の脆弱性がある場合に推奨されます。 \nアップグレードは普通、ルームがサーバー上で処理される仕方にだけ影響します。 一度有効にしたルームの暗号化は無効にすることはできません。暗号化されたルームで送信されたメッセージは、サーバーからは見ることができず、そのルームのメンバーだけが見ることができます。暗号化を有効にすると、多くのボットやブリッジが正常に動作しなくなる場合があります。 %sでこの部屋について人々に知らせます。 + このコードを連絡先と共有し、スキャンして追加してもらい、会話を始めましょう。 + 正当な参加者が%sにアクセスできることを確認してください。これは後から変更できます。 + 新規:スペースの参加者が非公開のルームを検索し、参加できるようになりました + 参加者を追加 + スペースは、ルームや連絡先をグループ化する新しい方法です + + %d人の連絡先がすでに参加しています + + %sに招待 + ユーザー名かメールアドレスで招待 + どのルームやスペースからも退出しない + 退出するルームとスペースを選択 + %sにある全てのルームとスペースから退出しようとしています。 + %1$sにようこそ、%2$sさん。 + %sを退出してよろしいですか? + スペースは、ルームや連絡先をグループ化する新しい方法です。 + 招待されています + 新しいスペースを、あなたが管理するスペースに追加。 + 注意:アプリケーションは再起動します + ホームサーバーの管理者にお問い合わせください + あなたが参加している全てのルームがホームに表示されます。 + 親のスペースを自動的に更新 + 残り%1$d秒 + %sに属する人は、誰でもこのルームを検索し、参加することができます。手動で全員を招待する必要はありません。これはルームの設定からいつでも変更できます。 + 親のスペースに属する人は、誰でもこのルームを検索し、参加することができます。手動で全員を招待する必要はありません。これはルームの設定からいつでも変更できます。 + + %1$d個の投票に基づく + + + %1$d個の投票に基づく最終結果 + + 最近のルーム + 新しいセッションが認証されました。セッションは暗号化されたメッセージにアクセスでき、他のユーザーには信頼済として表示されます。 + いったん有効にすると、暗号化を無効にすることはできません。 + このルームを、あなたのホームサーバーで、組織内のチームとのコラボレーションにのみ使用するなら、このオプションを有効にするといいかもしれません。これは後から変更できません。 + %sに属していない人がこのルームに今後参加するのを防ぐ + プレーンテキストメッセージの前に ( ͡° ͜ʖ ͡°) を付ける + このメールアドレスのドメインの登録は許可されていません + スペースを作成しています… + ルームを作成しています… + 高度な設定を表示しない + 高度な設定を表示 + プレーンテキストメッセージの前に ¯\\_(ツ)_/¯ を付ける + アプリケーションのデバッグを手伝うのに役立つ情報を表示 + デバッグ用の情報を画面に表示 + 初期同期を行っています… + 説明文が短すぎます + サインインして暗号化の鍵を復元しない限り、暗号化されたメッセージにアクセスすることはできなくなります。 + 再サインイン + 正しいホームサーバーを発見できません。識別子を確認してください + ホームサーバーでアカウントを設定したら、以下でMatrix ID(例:@user:domain.com)とパスワードを使用してください。 + 入力したコードは正しくありません。確認してください。 + これは正しいユーザー識別子ではありません。期待されるフォーマットは「@user:homeserver.org」となります。 + パスワードが分からなければ、戻ってパスワードをリセットしてください。 + 電子メールを確認してください + カスタムサーバーに接続 + 既にアカウントを持っています + 既存のサーバーに参加しますか? + この質問をスキップ + 友達と家族 + %1$sは、これを招待者のみ参加可能に設定しました。 \ No newline at end of file From cbca800f16484a5e814c23f2c8b7f1969c568d4d Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sun, 20 Feb 2022 07:03:44 +0000 Subject: [PATCH 219/302] Translated using Weblate (Japanese) Currently translated at 85.0% (2369 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 95 ++++++++++++++--------- 1 file changed, 58 insertions(+), 37 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 12ffe05406..f1ed804e63 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -105,11 +105,11 @@ クリップボードへコピー 警告 お気に入り - 会話 + 知人 ルーム ルーム名で絞り込む お気に入りで絞り込む - ユーザーで絞り込む + 連絡先で絞り込む ルーム名で絞り込む 招待中 低優先度 @@ -130,7 +130,7 @@ 不具合を報告しました 不具合の報告の送信に失敗しました (%s) ルームに参加 - 通話が開始できません + 通話を開始できません 音声通話 ビデオ通話 全体検索 @@ -221,7 +221,7 @@ ファイルが見つかりません あなたはこのルームで発言する権限がありません。 ルームの詳細 - メンバー + 参加者 ファイル 設定 お気に入り @@ -381,8 +381,8 @@ 電子メールアドレス (任意で) パスワード再確認 新しいパスワードを再確認 - パスワードが違います - メールアドレスがありません + パスワードが入力されていません + メールアドレスが入力されていません 電話番号が入力されていません 電子メールアドレスまたは電話番号が入力されていません 接続先サーバーを指定(高度) @@ -394,21 +394,21 @@ ユーザー名は既に使用されています ホームサーバー: IDサーバー: - メールアドレスを確認しました + メールアドレスを認証しました パスワードを初期化するには, アカウントに登録されている電子メールアドレスを入力してください: - あなたのアカウントに登録された電子メールアドレスの入力が必要です. + あなたのアカウントに登録されたメールアドレスの入力が必要です。 新しいパスワードの入力が必要です。 %sへ電子メールが送信されました. リンクをたどったら以下をクリックしてください. 電子メールアドレスの確認に失敗しました: 電子メールのリンクをクリックしたことを確認してください パスワードがリセットされました。 \n \n全てのセッションからログアウトしたため、プッシュ通知を受け取れなくなりました。通知を再び有効にするには、各端末で再ログインをお願いします。 - 登録ができません : 電子メールがあなた個人のものであるか確認できません + 登録できません:メールアドレスの所有権が確認できません 指定されたアクセストークンが認識されませんでした 不正な形式のJSON 有効なJSONを含んでいませんでした ログイン要求が多すぎてサーバーが対応できません - まだクリックされていないeメールのリンク + まだクリックされていない電子メールのリンク 以下の容量で画像を送信 ルームの説明 通話が接続されました @@ -437,15 +437,15 @@ 接続端末一覧を表示 %sさんをこのルームに招待してよろしいですか? ユーザーIDで招待 - 電子メールまたはMatrixユーザーID + メールアドレスまたはMatrix ID 全て中止 ログアウト 無視 招待中 - メンバー + 参加者 メンバーを検索 結果なし - メンバー + 参加者 ファイル ルーム ディレクトリを見る @@ -483,7 +483,7 @@ 外観 エンドツーエンド暗号化についての情報 公開端末名 - ルームのEnd-to-end暗号鍵を出力 + ルームのエンドツーエンド暗号化の鍵をエクスポート 認証 履歴を検索 あなたはこのルームに参加していません。 @@ -569,9 +569,9 @@ \nよろしいですか? 端末の連絡先 (%d) ユーザーディレクトリ (%s) - Matrixユーザーのみ + Matrixのユーザーのみ ユーザーIDで招待 - 1つまたは複数のメールアドレスか、Matrix IDを入力してください + メールアドレスかMatrix IDを入力してください 信用する 信用しない フィンガープリント (%s): @@ -680,7 +680,7 @@ コミュニティーID ホーム - メンバー + 参加者 ルーム ユーザーがいません ルーム @@ -902,7 +902,7 @@ パスワードが無効です メディア シャッター音を再生 - 公開端末名 (会話を行うユーザーに表示されます) + 公開セッション名(あなたとやり取りする人々に対して表示されます) サイレント パスワードを表示 パスワードを隠す @@ -986,7 +986,7 @@ ルームの設定 通知 - %1$d 人のメンバー + %1$d人の参加者 アップロード ルームを退出 @@ -1126,10 +1126,10 @@ SSLエラー。 SSLエラー:相手のアイデンティティが認証されていません。 このURLからホームサーバーに接続できませんでした、ご確認ください - 有効なMatrixサーバーアドレスではありません + 有効なMatrixサーバーのアドレスではありません このURLは検索結果に表示できません、ご確認ください この電話番号は既に使用されています。 - 復旧用のメールアドレスを設定します。後からオプションでメールアドレスや電話番号を使用して知人に見つけてもらえるようにできます。 + アカウント復旧用のメールアドレスを設定します。後からオプションでメールアドレスや電話番号を使用して知人に見つけてもらえるようにできます。 シングルサインオンを使用してサインイン HDを使用する HDを使用しない @@ -1175,7 +1175,7 @@ ${app_name} で会話しましょう:%s 友達を招待 既知のユーザー - 無効なQRコード (無効な URI)! + 無効なQRコード(無効なURI)! パスワードが一致しません メールアドレスの確認中にエラーが発生しました。 これを行うには設定からインテグレーションを許可を有効にしてください。 @@ -1263,7 +1263,7 @@ あなたのホームサーバーがアシスト機能を提供しない場合、代わりに%sを使用します(IPアドレスは通話中に共有されます) ビデオ通話が行われています… フォールバックコールアシストサーバーを許可 - 有効な認証情報ではありません + 有効な認証情報がないため、権限がありません ${app_name} 呼び出し失敗 通話が確実に機能させるためには、ホームサーバー(%1$s)の管理者にTURNサーバーの設定を依頼してください。 \n @@ -1512,7 +1512,7 @@ トークンの登録 アカウントを追加 [%1$s] -\nこのエラーは、${app_name}の管理外です。スマホにはGoogleアカウントがありません。アカウントマネージャーを開いて、Googleアカウントを追加してください。 +\nこのエラーは、${app_name}の管理外です。このスマートフォンにはGoogleアカウントが登録されていません。アカウントマネージャーを開いて、Googleアカウントを追加してください。 %1$s \nこのエラーは${app_name}の管理外であり、Googleによると、このエラーは、端末にFCMに登録されているアプリが多すぎることを示しています。 このエラーは、アプリの数が極端に多い場合にのみ発生するため、平均的なユーザーには影響しません。 ${app_name}はGoogle Playサービスを使用してプッシュメッセージを配信していますが、正しく設定されていないようです: @@ -1722,7 +1722,7 @@ 新しいサーバーを追加 あなたのサーバー 暗号化されたメッセージの復元 - セッションの公開名は会話中の相手に閲覧できます + セッションの公開名は、あなたとやり取りする人々に対して表示されます ルームのバージョン ブロックされたユーザー%d人 @@ -1765,8 +1765,8 @@ おすすめのルーム スペース ホームサーバーAPIのURL - 復旧用のメールアドレスを設定します。後からオプションでメールアドレスや電話番号を使用して知人に見つけてもらえるようにできます。 - 電話番号を設定して、後からオプションで知人に見つけてもらえるようにできます。 + アカウント復旧用のメールアドレスを設定します。後からオプションでメールアドレスや電話番号を使用して知人に見つけてもらえるようにできます。 + 電話番号を設定します。後からオプションで知人に見つけてもらえるようにできます。 %sを使用してみてください アクセスを取り消す 表示 @@ -1775,7 +1775,7 @@ 新しいダイレクトメッセージを送信 メールアドレス(任意) メールアドレス - アカウントを回復するためのメールを設定します。 後で、オプションで、あなたが知人にあなたのメールに見つけてもらえるようにできます。 + アカウント復旧用のメールアドレスを設定します。後からオプションで知人に見つけてもらえるようにできます。 メールアドレスを設定 メールアドレスを確認しました 検出可能なメールアドレス @@ -1807,15 +1807,15 @@ カスタムと高度な設定 組織向けのプレミアムホスティング 組織向けのプレミアムホスティング - 最大のパブリックサーバーで数百万人に無料で参加 + 最大のパブリックサーバーで、数百万人に無料で参加 メールと同じように、アカウントには1つのホームがありますが、誰とでも話すことができます サーバーを選択 始めましょう エクスペリエンスを拡張およびカスタマイズ 暗号化して会話をプライベートに保つ - 直接またはグループで人々とチャットする + 直接またはグループで連絡先とチャット あなたの会話。 それを所有する。 - アカウントの復旧用のメールアドレスを設定して、後からオプションで知人に見つけてもらえるようにできます。 + アカウント復旧用のメールアドレスを設定します。後からオプションで知人に見つけてもらえるようにできます。 ここが%sとのダイレクトメッセージのスタート地点です。 変更履歴はありません メッセージの変更履歴 @@ -2486,7 +2486,7 @@ 未確認 制限は不明です。 サーバーのファイルアップロードの制限 - 自分の会話は自分のものにしましょう。 + 自分の会話は、自分のものに。 %1$sは、このルームを招待者のみ参加可能に設定しました。 %1$sが部屋をリンクを持っているユーザーにアクセスできるように設定しました。 選択したメッセージをネタバレとして送信 @@ -2511,20 +2511,20 @@ お宅での対面会話と同じぐらいのプライバシーを提供する、セキュアで独立したコミュニケーション。 チームワークを効率よくしましょう。 セキュアメッセージング - 管理権を握るのはあなたです。 + 管理権を握るのは、あなたです。 Elementの使用に関するヘルプ 詳細なログは、イライラシェイクでログを送信する際に、より多くのログを提供することで、開発者にとっての助けになります。有効にした場合でも、メッセージの内容やその他のプライベートな情報は記録されません。 - ルームのアップグレードは高度な作業であり、不具合や不足する機能、セキュリティー上の脆弱性がある場合に推奨されます。 + ルームのアップグレードは高度な作業であり、不具合や欠けている機能、セキュリティー上の脆弱性がある場合に推奨されます。 \nアップグレードは普通、ルームがサーバー上で処理される仕方にだけ影響します。 一度有効にしたルームの暗号化は無効にすることはできません。暗号化されたルームで送信されたメッセージは、サーバーからは見ることができず、そのルームのメンバーだけが見ることができます。暗号化を有効にすると、多くのボットやブリッジが正常に動作しなくなる場合があります。 - %sでこの部屋について人々に知らせます。 - このコードを連絡先と共有し、スキャンして追加してもらい、会話を始めましょう。 + %sして、このルームを皆に紹介しましょう。 + このコードを皆と共有し、スキャンして追加してもらい、会話を始めましょう。 正当な参加者が%sにアクセスできることを確認してください。これは後から変更できます。 新規:スペースの参加者が非公開のルームを検索し、参加できるようになりました 参加者を追加 スペースは、ルームや連絡先をグループ化する新しい方法です - %d人の連絡先がすでに参加しています + %d人の知り合いがすでに参加しています %sに招待 ユーザー名かメールアドレスで招待 @@ -2579,4 +2579,25 @@ この質問をスキップ 友達と家族 %1$sは、これを招待者のみ参加可能に設定しました。 + メッセージを送信できませんでした + ウィジェットを開く + %1$sに転送 + 通話は終了しました + 自分自身にダイレクトメッセージを送信することはできません! + %1$sは通話を開始しました + あなたは通話を開始しました + 電話番号(任意) + 電話番号を確認 + 電話番号を設定 + パスワードがリセットされました。 + %1$sでパスワードをリセット + Element Matrix Servicesのアドレス + %1$sにサインイン + 誰と最もよく会話しますか? + 特定のルームとスペースから退出… + 非公開で招待が必要なルームは表示されていません。 +\nルームを追加する権限はありません。 + 非公開で招待が必要なルームは表示されていません。 + 勝者 + 電話番号を設定します。オプションで知人に見つけてもらえるようにできます。 \ No newline at end of file From 70a65d9fd489115e37a46c5625b51e018668ae58 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sun, 20 Feb 2022 08:34:47 +0000 Subject: [PATCH 220/302] Translated using Weblate (Japanese) Currently translated at 86.2% (2402 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 42 +++++++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index f1ed804e63..d84cda8709 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1020,7 +1020,7 @@ %d 件の有効なセッション このログインを検証 - QR コード + QRコード はい いいえ 機内モードが有効です @@ -1070,7 +1070,7 @@ ユーザーを無視 警告: - 元の大きさのまま画像を送信する + 元の大きさのまま画像を送信 自分自身には通話できません マークダウン書式 @@ -1168,7 +1168,7 @@ タイムラインでのスワイプによる返信を有効にする タイムラインで非表示のイベントを表示 QRコードをスキャン - QR コード画像 + QRコード画像 QR コード QR コードによる追加 コードを共有 @@ -1632,9 +1632,9 @@ リカバリーキーを喪失しましたか? 設定で新しいリカバリーキーを設定できます。 メッセージの復元 バックアップのバージョンを取得しています… - 暗号化されたメッセージ履歴のロックを解除するには、復元パスフレーズを使用してください - 復元パスフレーズをご存知でなければ、%sができます。 - リカバリーキーを使用して暗号化されたメッセージ履歴をアンロックします + 暗号化されたメッセージ履歴のロックを解除するには、復旧用のパスフレーズを使用してください + 復旧用のパスフレーズが分からなければ、%sできます。 + リカバリーキーを使用して暗号化されたメッセージ履歴をアンロックする リカバリーキーを入力 リカバリーキーを使用 ログアウトしたりこの端末を失くしたりすればメッセージへのアクセスを失う可能性があります。 @@ -1653,7 +1653,7 @@ リカバリーキーが保存されました。 リカバリーキーが%sに保存されました。 \n -\n注意: アプリケーションを削除した場合、ファイルは削除される可能性があります。 +\n注意: アプリケーションを削除した場合、リカバリーキーが削除される可能性があります。 リカバリーキーを保存 コピーをしました リカバリーキーはパスワードマネージャー(もしくは金庫)のような、非常に安全な場所で保管してください @@ -2600,4 +2600,32 @@ 非公開で招待が必要なルームは表示されていません。 勝者 電話番号を設定します。オプションで知人に見つけてもらえるようにできます。 + メッセージキー + 復旧用のパスフレーズ + ニックネームの色を変更 + 上記のコードをスキャンできなければ、絵文字の並び方を比較して検証してください。 + パスワードは変更されていません。 +\n +\n変更作業を中止しますか? + 確認メールが%1$sに送信されました。 + メールボックスを確認してください + サインインに戻る + 元の大きさのままメディアファイルを送信 + + 元の大きさのまま動画を送信 + + サーバーとの接続が失われました + リカバリーパスフレーズか、リカバリーキーを使用 + 新しいサインイン + クロス署名を開始 + 信頼されていません + セキュリティーを確認 + 検証リクエスト + %sがキャンセルしました + 閲覧済: + 検証 + 正しくないメールアドレスのようです + 国際電話番号の形式を使用してください。 + 国際電話番号は「+」から始まる必要があります + コードを%1$sに送信しました。以下に入力して認証してください。 \ No newline at end of file From c0f3e9707ecec7695a166b45f408feb8439ad900 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sun, 20 Feb 2022 08:33:52 +0000 Subject: [PATCH 221/302] Translated using Weblate (Japanese) Currently translated at 86.2% (2402 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index d84cda8709..e8499a6730 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2628,4 +2628,20 @@ 国際電話番号の形式を使用してください。 国際電話番号は「+」から始まる必要があります コードを%1$sに送信しました。以下に入力して認証してください。 + このメールアドレスはどのアカウントにも属していません + パスワードの変更はすべてのセッションでエンドツーエンド暗号鍵をリセットし、暗号化されたメッセージ履歴が読めなくなります。パスワードを再設定する前に、暗号鍵のバックアップを設定するか他のセッションからエクスポートしてください。 + パスワードの再設定を確認するために認証メールを送信しました。 + このメールアドレスはどのアカウントにも属していません。 + このアプリではこのホームサーバーにアカウントを作成できません。 +\n +\nウェブクライエントを使用してアカウント登録しますか? + 申し訳ありません。このサーバーはアカウントの新規登録を認めていません。 + このアプリではこのホームサーバーにサインインできません。このホームサーバーは次のサインイン方法に対応しています: %1$s +\n +\nウェブクライエントを使用してサインインしますか? + %1$sを読み込み中にエラーが発生しました(%2$d) + 利用したいサーバーのアドレスを入力してください + 利用したいModular Elementまたはサーバーのアドレスを入力してください + 迷っていますか?%sしてもいいです + みんなと繋がる手助けをいたします。 \ No newline at end of file From c11cede1d03058c379f11c1147a750545b86aed0 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sun, 20 Feb 2022 11:19:18 +0000 Subject: [PATCH 222/302] Translated using Weblate (Japanese) Currently translated at 88.8% (2474 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 85 ++++++++++++++++++----- 1 file changed, 68 insertions(+), 17 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index e8499a6730..e934210978 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -216,8 +216,8 @@ ここに送信文を入力 (暗号なし)… サーバーとの接続が失われました。 全て再送信 - 未送信の文を再送信 - 未送信の文を削除 + 未送信のメッセージを再送信 + 未送信のメッセージを削除 ファイルが見つかりません あなたはこのルームで発言する権限がありません。 ルームの詳細 @@ -803,7 +803,7 @@ 動作を表示 指定したIDのユーザーをブロック 指定したIDのユーザーのブロックを解除 - ユーザーの権限レベルを決める + ユーザーの権限レベルを規定 指定したIDのユーザーの管理者権限を取り消す 指定したユーザーを現在のルームに招待 指定されたアドレスのルームに参加 @@ -1105,7 +1105,7 @@ 他の利用可能な言語 メッセージエディタ 環境設定 - この端末を設定 + この端末で設定 セキュアバックアップをリセット セキュアバックアップを設定 管理 @@ -1220,9 +1220,9 @@ 他の人から送信されたメッセージの削除 ユーザーのブロック ユーザーの除去 - 設定を変更 - 招待されたユーザー - メッセージを送る + 設定の変更 + ユーザーの招待 + メッセージの送信 デフォルトルール ルームに関する変更を行うために必要な役割を更新する権限がありません ルームに関する変更を行うために必要な役割を選択 @@ -1409,9 +1409,9 @@ %1$sと%2$sと%3$sと%4$s %1$sと%2$sと%3$s - %1$sを%2$sから%3$sへ - %2$sが%1$sの権限を変更しました。 - %1$sの権限を変更しました。 + %1$sの権限レベルを%2$sから%3$sへ変更しました。 + %1$sが + あなたは カスタム カスタム (%1$d) デフォルト @@ -1462,7 +1462,7 @@ 招待、削除、ブロックは影響を受けません。 招待/参加/退出/削除/禁止イベントや、アバター/表示名の変更などを含む。 参加・退出イベントを表示 - Use /confettiコマンドを使用するか、❄️または🎉を含むメッセージを送信します + /confettiコマンドを使用するか、❄️または🎉を含むメッセージを送信 チャットでエフェクトを表示 ルームのメンバーのイベントを表示 ホームサーバーがこの機能をサポートしている場合は、チャット内のリンクをプレビューします。 @@ -1620,7 +1620,7 @@ %d個のキーが含まれたバックアップを復元しました。 バックアップが復元されました %s! - このリカバリーキーではバックアップを復号できませんでした。正しいリカバリーキーを入力したことを確認してください。 + このリカバリーキーではバックアップを復号化できませんでした。正しいリカバリーキーを入力したことを確認してください。 リカバリーキーを入力してください 履歴をアンロック 鍵をインポートしています… @@ -2370,7 +2370,7 @@ このルームにおいてのみ表示名を変更します ユーザーの無視を解除し、これからのメッセージを表示します 続行するには%sを入力してください - リカバリーパスフレーズ + 復旧用のパスフレーズ 有効なリカバリーキーではありません リカバリーキーを入力してください 投票の種類 @@ -2410,7 +2410,7 @@ %sが参加しました。 このルームで使用されている暗号化はサポートされていません 暗号化が正しく設定されていません - %sにテキストメッセージを送信しました。メッセージに含まれた確認コードを入力してください。 + %sにテキストメッセージを送信しました。メッセージにある確認コードを入力してください。 選択したIDサーバーには利用規約がありません。サービス提供者を信頼している場合にのみ続行してください 現在IDサーバー %1$s でメールアドレスや電話番号を共有しています。共有を停止するには %2$s に再接続する必要があります。 ルームを作成し設定しました。 @@ -2450,7 +2450,7 @@ このコンテンツが報告されています。 \n \nこのユーザーのコンテンツをこれ以上見たくなければ、ユーザーを無視してそのメッセージを非表示にできます。 - %1$s%2$s + %1$sにより%2$sに 質問あるいはトピック 投票の質問あるいはトピック スペースのメンバーが非公開のルームを発見できるよう手伝う @@ -2615,7 +2615,7 @@ 元の大きさのまま動画を送信 サーバーとの接続が失われました - リカバリーパスフレーズか、リカバリーキーを使用 + 復旧用のパスフレーズか、リカバリーキーを使用 新しいサインイン クロス署名を開始 信頼されていません @@ -2629,7 +2629,7 @@ 国際電話番号は「+」から始まる必要があります コードを%1$sに送信しました。以下に入力して認証してください。 このメールアドレスはどのアカウントにも属していません - パスワードの変更はすべてのセッションでエンドツーエンド暗号鍵をリセットし、暗号化されたメッセージ履歴が読めなくなります。パスワードを再設定する前に、暗号鍵のバックアップを設定するか他のセッションからエクスポートしてください。 + パスワードを変更すると、すべてのセッションでのエンドツーエンド暗号鍵がリセットされ、暗号化されたメッセージ履歴が読めなくなります。パスワードを再設定する前に、暗号鍵のバックアップを設定するか、他のセッションからエクスポートしておいてください。 パスワードの再設定を確認するために認証メールを送信しました。 このメールアドレスはどのアカウントにも属していません。 このアプリではこのホームサーバーにアカウントを作成できません。 @@ -2644,4 +2644,55 @@ 利用したいModular Elementまたはサーバーのアドレスを入力してください 迷っていますか?%sしてもいいです みんなと繋がる手助けをいたします。 + 自分のコード + + 招待を%1$sと他%2$d人に送信しました + + 招待を%1$sに送信しました + 招待を%1$sと%2$sに送信しました + 正しいMatrixのQRコードではありません + スペースを追加 + このルームの全ての未送信のメッセージを削除してよろしいですか? + メッセージの送信をキャンセルしますか? + IDを指定してルームから退出(指定しない場合は現在のルームから退出) + IDを指定してスペースに参加 + 開発者ツール + 音を出さずに通知 + 音を出して通知 + 既定の信頼レベル + いくつかのメッセージは送信されませんでした + 保存されていない変更があります。変更を破棄しますか? + このルームはまだ作成されていません。キャンセルしますか? + テキストメッセージで共有 + 保護を設定 + このルームのみ + 誰でも参加可能。コミュニティーに最適 + 既存のスペースに参加するには、招待が必要です。 + これは後から変更できます + 接続できませんでした + 変更を破棄 + このリンクは不正な形式です + QRコードがスキャンされていません! + 内容を通知に表示 + プッシュ通知は無効になっています + ユーザーのブロックを解除できませんでした + %1$sへの招待を取り消しますか? + 連絡先を取得しています… + 連絡先を検索 + 電話帳 + RiotはElementになりました! + このメッセージにアクセスできません + アバターを設定 + IDサーバーのURLを入力 + マイクのミュートを解除 + マイクをミュート + %1$sを使用 + 役割を設定 + 設定 + セキュリティーキーを保存 + セキュリティーキーを使用 + カメラを開始 + カメラを停止 + セキュリティーキーを保存 + リカバリーキー \ No newline at end of file From 9c7cae4b9663c059d401bcf3aac7b4e46ba4cc42 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sun, 20 Feb 2022 10:06:17 +0000 Subject: [PATCH 223/302] Translated using Weblate (Japanese) Currently translated at 88.8% (2474 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 89 ++++++++++++++++++----- 1 file changed, 70 insertions(+), 19 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index e934210978..fcd2e966a2 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2464,7 +2464,7 @@ 招待を取り消す サーバーのバージョン サーバー名 - 電話番号が正しくありません。確認してください + 電話番号が正しくないようです。確認してください カスタムホームサーバーを選択 Element Matrix Servicesを選択 再送信 @@ -2552,27 +2552,27 @@ 最近のルーム 新しいセッションが認証されました。セッションは暗号化されたメッセージにアクセスでき、他のユーザーには信頼済として表示されます。 いったん有効にすると、暗号化を無効にすることはできません。 - このルームを、あなたのホームサーバーで、組織内のチームとのコラボレーションにのみ使用するなら、このオプションを有効にするといいかもしれません。これは後から変更できません。 - %sに属していない人がこのルームに今後参加するのを防ぐ + この部屋を同じホームサーバー上で組織内のチームとのコラボレーションにのみ使用するなら、このオプションを有効にするといいかもしれません。これは後から変更できません。 + %sに属していないユーザーによるこの部屋への参加を今後永久的に拒否する プレーンテキストメッセージの前に ( ͡° ͜ʖ ͡°) を付ける このメールアドレスのドメインの登録は許可されていません スペースを作成しています… ルームを作成しています… - 高度な設定を表示しない + 高度な設定を非表示にする 高度な設定を表示 プレーンテキストメッセージの前に ¯\\_(ツ)_/¯ を付ける - アプリケーションのデバッグを手伝うのに役立つ情報を表示 + アプリケーションのデバッグに役立つ情報を表示 デバッグ用の情報を画面に表示 - 初期同期を行っています… + 初期同期中… 説明文が短すぎます - サインインして暗号化の鍵を復元しない限り、暗号化されたメッセージにアクセスすることはできなくなります。 + サインインして暗号鍵を取り戻さななければ、暗号化されたメッセージがアクセスできなくなります。 再サインイン - 正しいホームサーバーを発見できません。識別子を確認してください - ホームサーバーでアカウントを設定したら、以下でMatrix ID(例:@user:domain.com)とパスワードを使用してください。 - 入力したコードは正しくありません。確認してください。 - これは正しいユーザー識別子ではありません。期待されるフォーマットは「@user:homeserver.org」となります。 - パスワードが分からなければ、戻ってパスワードをリセットしてください。 - 電子メールを確認してください + 有効なホームサーバーを発見できません。識別子を確認してください + どこかのホームサーバーで既にアカウントを登録している場合、以下でMatrix ID(例:@user:domain.com)とパスワードを使用してください。 + 入力したコードが正しくありません。確認してください。 + これは正しいユーザー識別子ではありません。正しいフォーマットは「@user:homeserver.org」です。 + パスワードをお忘れの場合、戻ってパスワードをリセットしてください。 + メールボックスを確認してください カスタムサーバーに接続 既にアカウントを持っています 既存のサーバーに参加しますか? @@ -2589,7 +2589,7 @@ 電話番号(任意) 電話番号を確認 電話番号を設定 - パスワードがリセットされました。 + パスワードをリセットしました。 %1$sでパスワードをリセット Element Matrix Servicesのアドレス %1$sにサインイン @@ -2599,15 +2599,15 @@ \nルームを追加する権限はありません。 非公開で招待が必要なルームは表示されていません。 勝者 - 電話番号を設定します。オプションで知人に見つけてもらえるようにできます。 + 知人に見つけてもらえるように電話番号を設定できます。任意です。 メッセージキー 復旧用のパスフレーズ ニックネームの色を変更 上記のコードをスキャンできなければ、絵文字の並び方を比較して検証してください。 - パスワードは変更されていません。 + パスワードはまだ変更されていません。 \n \n変更作業を中止しますか? - 確認メールが%1$sに送信されました。 + %1$sに認証メールを送信しました。 メールボックスを確認してください サインインに戻る 元の大きさのままメディアファイルを送信 @@ -2622,9 +2622,9 @@ セキュリティーを確認 検証リクエスト %sがキャンセルしました - 閲覧済: + 既読 検証 - 正しくないメールアドレスのようです + メールアドレスが正しくないようです 国際電話番号の形式を使用してください。 国際電話番号は「+」から始まる必要があります コードを%1$sに送信しました。以下に入力して認証してください。 @@ -2695,4 +2695,55 @@ カメラを停止 セキュリティーキーを保存 リカバリーキー + 位置を共有しました + %sとリアクションしました + 検証終了 + 次のいずれかのセキュリティが破られている可能性があります。 +\n +\n - あなたのホームサーバー +\n - 検証している相手のホームサーバー +\n - あなたか相手のインターネット接続 +\n - あなたか相手の端末 + セキュアではない + この緑の盾のシンボルが信頼できるユーザーの印です。部屋のセキュリティを確認するには、全ての参加者に信頼できることを確認してください。 + セキュリティを最大限に高めるには、対面で行うか他の信頼できる通信媒体を利用してください。 + 次の絵文字が相手の画面にも同じ順番で現れるのを確認し、このユーザーを検証してください。 + 信頼できないサインイン + 使用できない文字が含まれています + Elementの改善と課題抽出のために、匿名の使用分析データを収集させてくださいませんか?複数の端末での使用を解析するために、あなたの全端末共通のランダムな識別子を生成します。 +\n +\n%sで利用規約を閲覧できます。 + 最初の検索結果のみ表示中、文字をもっと入力してください… + matrix.toリンクのフォーマットが正しくありませんでした + 注意!この端末には未だ暗号鍵を含む個人情報が保存されています。 +\n +\nこの端末での使用を終了したり、他のアカウントにサインインしたい場合、このデータをクリアしてください。 + この端末に現在保存されているすべてのデータをクリアしますか? +\nアカウントデータとメッセージにアクセスするにはもう一度サインインしてください。 + 現在のセッションはユーザー%1$sのものなのに、あなたが提供している資格情報はユーザー%2$sのものです。この操作は${app_name}にサポートされていません。 +\nまずはデータをクリアしてから別のアカウントにサインインしてください。 + 暗号化されたメッセージが読めるように、サインインしてこの端末にのみ保存されている暗号鍵を取り戻してください。 + あなたのホームサーバー(%1$s)の管理者があなたを%2$sのアカウントからサインアウトしています。(%3$s) + いくつかの原因が考えられます: +\n +\n• 他のセッションでパスワードを変更している。 +\n +\n• 他のセッションでこのセッションを削除している。 +\n +\n• サーバーの管理者がセキュリティ上の理由であなたのアクセスを取り消している。 + 代理手段として、既にアカウントをお持ちでMatrix IDとパスワードをご存知なら、この方法が使用できます。 + + リクエストが多すぎます。%1$d秒後に再試行できます… + + このホームサーバーが古いバージョンで運営しています。管理者にアップグレードを要請してください。続行できますが、いくつかの機能が正しく作動しない可能性があります。 + このホームサーバーが古すぎるバージョンで運営しており、接続できません。管理者にアップグレードを要請してください。 + ホームサーバーのバージョンが古すぎます + ただいま%1$sにメールを送信しました。 +\nアカウント登録を続けるにはメールに含まれたリンクをクリックしてください。 + CAPTCHA認証を行ってください + アカウントがまだ登録されていません。 +\n +\n登録を中止しますか? + %1$sにアカウント登録 + あなたはすべてのセッションからログアウトしており、これ以上プッシュ通知を受け取れません。通知をもう一度有効にするには、各端末でサインインしてください。 \ No newline at end of file From ff63ae0e73c1156877ce6cd1570ed5b1b3e82152 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sun, 20 Feb 2022 12:52:22 +0000 Subject: [PATCH 224/302] Translated using Weblate (Japanese) Currently translated at 89.4% (2490 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 120 ++++++++++++---------- 1 file changed, 67 insertions(+), 53 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index fcd2e966a2..4a10ef383d 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -47,7 +47,7 @@ %1$sは%2$sにルームに参加するよう招待状を送りました %1$sは%2$sの招待を受け入れました ** 解読できません:%s ** - 送信者の端末からこのメッセージのキーが送信されていません。 + 送信者の端末からこのメッセージの鍵が送信されていません。 修正できませんでした メッセージを送信できません 画像のアップロードに失敗しました @@ -94,7 +94,7 @@ 削除 共有 削除 - 端末情報 + セッションの情報 暗号化されたルームでのグループ通話はサポートされていません 招待 全ての発言を既読にする @@ -209,7 +209,7 @@ 新しい会話 メンバーを追加 1名 - 端末 + セッション 権限を一般メンバーへ変更 権限を司会者へ変更 権限を管理者へ変更 @@ -236,7 +236,7 @@ 電話番号を追加 通知音 このアカウントで通知を許可 - この端末で通知を許可 + このセッションで通知を許可 1対1のチャットでのメッセージ グループチャットでのメッセージ ルームへ招待されたとき @@ -322,7 +322,7 @@ エンドツーエンド暗号化 エンドツーエンド暗号化を使用中 暗号を有効にするためにはログアウトする必要があります. - 検証済のセッションに対してのみ暗号化 + 認証済のセッションに対してのみ暗号化 このセッションでは、このルームの未検証のセッションに対して暗号化されたメッセージを送信しない。 新しいアドレス (記入例 #foo:matrix.org) このルームにはローカルアドレスがありません @@ -434,7 +434,7 @@ このメンバーの発言を全て表示 指名して呼掛け ユーザーID, 表示名, 電子メールアドレス - 接続端末一覧を表示 + セッション一覧を表示 %sさんをこのルームに招待してよろしいですか? ユーザーIDで招待 メールアドレスまたはMatrix ID @@ -483,7 +483,7 @@ 外観 エンドツーエンド暗号化についての情報 公開端末名 - ルームのエンドツーエンド暗号化の鍵をエクスポート + ルームのエンドツーエンド暗号鍵をエクスポート 認証 履歴を検索 あなたはこのルームに参加していません。 @@ -537,21 +537,21 @@ \n続行する前に、各セッションの検証プロセスを進めることをおすすめしますが、検証せずにメッセージを再送信することもできます。 \n \n不明なセッション: - ルームに不明な端末が含まれています - キーが一致していることを確認 - 一致する場合は、下の確認ボタンを押します。そうでない場合は、他の誰かがこの端末を盗聴しているので、代わりにブロックボタンを押すことをおすすめします。今後この検証プロセスはより洗練されたものになるでしょう。 - 端末の検証 - 不明な端末 - このセッションでは、未検証のセッションに対して暗号化されたメッセージを送信しない - 認証済端末に対してのみ暗号化 + ルームに不明なセッションが含まれています + 鍵が一致していることを確認 + 一致していない場合は、あなたのコミュニケーションの安全性が損なわれている可能性があります。 + セッションを認証 + 不明なセッション + このセッションでは、未検証のセッションに対して暗号化されたメッセージを送信しない。 + 認証済のセッションに対してのみ暗号化 インポート - ローカルファイルからキーをインポート - ルームキーをインポート + ローカルファイルから鍵をインポート + ルームの暗号鍵をインポート ルームのエンドツーエンド暗号鍵をインポート パスフレーズを確認 パスフレーズを入力 エクスポート - 暗号鍵をローカルファイルにエクスポート + 鍵をローカルファイルにエクスポート ルームの暗号鍵をエクスポート 検証 通話 @@ -615,9 +615,9 @@ アルゴリズム セッションID 復号エラー - 発信者装置の情報 + 発信者のセッションの情報 公開端末名 - 端末キー + セッションキー Ed25519 フィンガープリント 未認証 ブラックリスト @@ -626,14 +626,14 @@ 認証を取り消す ブラックリスト ブラックリストから除外 - この端末が信頼できることを確認するために、その所有者に何らかの他の方法(直接会って、または、電話で)連絡し、以下のキーが、その端末の「設定」で確認できるキーと一致するかお尋ねください: + 他のセッションのユーザー設定で、以下を比較して確認してください: ルームのディレクトリを選択 公開のルームを表示するホームサーバーを入力してください サーバー名 %sサーバー上の全てのルーム 全てのローカルの%sルーム メッセージが未送信です。今%1$sまたは%2$sしますか? - 不明な端末が存在しているため、メッセージを送ることができませんでした。今%1$sまたは%2$sしますか? + 不明なセッションが存在しているため、メッセージを送ることができませんでした。今%1$sまたは%2$sしますか? 要求されたフィンガープリントキー Ed25519 jitsiを用いて会議通話を始める 端末のカメラを使用 @@ -671,8 +671,8 @@ ルームのエンドツーエンド暗号鍵は \'%s\' に保存されました。 \n \n警告: このファイルは、アプリケーションをアンインストールすると削除されることがあります。 - 暗号鍵を要求している新しい端末 \'%s\' を追加しました。 - 未認証の端末 \'%s\' が暗号鍵を要求しています。 + 暗号鍵を要求している新しいセッション \'%s\' を追加しました。 + 未認証のセッション \'%s\' が暗号鍵を要求しています。 作成 コミュニティーを作成 コミュニティーの名前 @@ -739,10 +739,10 @@ \n追加しますか? 続行する… 申し訳ありません、この操作を完了するための外部アプリが見つかりません。 - 他の端末から 暗号鍵を再度要求 します。 + 他のセッションから暗号鍵を再度要求します。 鍵のリクエストが送信されました。 リクエスト送信済 - 鍵をこの端末に送信できるように、メッセージを復号化できる他の端末で${app_name}を起動してください。 + 鍵をこのセッションに送信できるように、メッセージを復号化できる他の端末で${app_name}を起動してください。 %d秒 @@ -852,7 +852,7 @@ ルームのメンバーの簡易読み込み 申し訳ありません、エラーが発生しました バージョン %s - エクスポートされた鍵を暗号化するパスフレーズを作成してください。 キーをインポートするには、同じパスフレーズを入力する必要があります。 + エクスポートされた鍵を暗号化するパスフレーズを作成してください。 鍵をインポートするには、同じパスフレーズを入力する必要があります。 パスフレーズの作成 パスフレーズは一致する必要があります 情報領域を表示 @@ -877,7 +877,7 @@ サービスを初期化 鍵のバックアップ 鍵のバックアップを使用 - 端末を認証 + セッションを認証 鍵のバックアップが終了していません。しばらくお待ちください… 会議通話中。 \n%1$sまたは%2$sとして参加 @@ -896,7 +896,7 @@ 開封確認メッセージを表示 開封確認メッセージをクリックすると詳細なリストを確認できます。 エンター入力でメッセージを送信 - ソフトウェアキーボードのEnterボタンを押した際に改行せずにメッセージを送信します + ソフトウェアキーボードのEnterボタンを押した際、改行せずメッセージを送信 パスワード パスワードを更新 パスワードが無効です @@ -911,7 +911,7 @@ パスワード 今ここでサインアウトすると、あなたの暗号化されたメッセージは失われてしまいます 鍵のバックアップは現在処理中です。処理中にサインアウトすると暗号化されたメッセージにアクセスできなくなります。 - 暗号化されたメッセージにアクセスできなくなることを防ぐため、鍵の安全なバックアップはあなたの端末全てで有効化してください。 + 暗号化されたメッセージにアクセスできなくなることを防ぐため、鍵の安全なバックアップはあなたのセッション全てで有効化してください。 暗号化されたメッセージは不要です 鍵をバックアップしています… 鍵のバックアップを使用 @@ -1087,7 +1087,7 @@ このセッションで通知が無効化されています。 \n${app_name} の設定をご確認ください。 このセッションで通知は有効化されています。 - セッション設定 + セッションの設定。 有効化 あなたのアカウントで通知が無効化されています。 \nアカウント設定をご確認ください。 @@ -1454,7 +1454,7 @@ ディスカバリー(発見) これにより、現在のキーまたはフレーズが置き換えられます。 新しいセキュリティーキーを生成するか、既存のバックアップに新しいセキュリティーフレーズを設定します。 - サーバー上の暗号化キーをバックアップすることにより、暗号化されたメッセージとデータへのアクセスが失われるのを防ぎます。 + サーバー上の暗号鍵をバックアップすることにより、暗号化されたメッセージとデータへのアクセスが失われるのを防ぎます。 メッセージ作成画面に絵文字キーボードを開くボタンを追加 絵文字キーボードを表示 アバターと表示名の変更が含まれます。 @@ -1566,8 +1566,8 @@ キー%1$dと%2$dのインポートに成功。 - キーバックアップを管理 - キーのエクスポートに成功しました + 鍵のバックアップを管理 + 鍵のエクスポートに成功しました 選択 選択 詳細情報:%s @@ -1602,16 +1602,16 @@ バックアップの状態を確認中 バックアップの削除に失敗しました(%s) バックアップを削除しています… - このセッションで暗号鍵のバックアップを使用するには、パスフレーズまたはリカバリーキーでバックアップを復元してください。 - バックアップは%sという未検証セッションによる不正なしょめいがあります - バックアップは%sという検証されたセッションによる不正な署名があります - バックアップは%sという未検証セッションによる有効な署名があります - バックアップは%sという検証されたセッションによる署名があります。 + このセッションで鍵のバックアップを使用するには、パスフレーズまたはリカバリーキーでバックアップを復元してください。 + バックアップには未検証のセッション %s による不正な署名があります + バックアップには検証されたセッション %s による不正な署名があります + バックアップには未検証のセッション %s による有効な署名があります + バックアップには認証済のセッション %s による署名があります。 バックアップはこのセッションによる有効な署名があります。 - バックアップは%sというIDの不明のセッションによる署名があります。 - このセッションでは暗号鍵がバックアップされていません。 - このセッションでは暗号鍵のバックアップが無効になっています。 - このセッションでは暗号鍵のバックアップが正しく設定されています。 + バックアップには%sというIDの不明のセッションによる署名があります。 + このセッションでは鍵がバックアップされていません。 + このセッションでは鍵のバックアップが無効になっています。 + このセッションでは鍵のバックアップが正しく設定されています。 最新の復号キーのバージョンを取得するのに失敗しました(%s)。 %d個の新しい鍵がこのセッションに追加されました。 @@ -1648,7 +1648,7 @@ コピーをしてください 中止 上書き - 違うセッションにより設定されたキーのバックアップが存在してます。上書きしますか? + 別のセッションで鍵のバックアップを既に設定しているようです。上書きしますか? ホームサーバーにバックアップが存在しています リカバリーキーが保存されました。 リカバリーキーが%sに保存されました。 @@ -1681,7 +1681,7 @@ \nセッション名:%1$s \n最後のオンライン時刻:%2$s \n新たにログインして新しいセッションを開始しなかった場合、この要求を無視してください。 - 未検証のセッションが暗号鍵を要請しています。 + 未認証のセッションが暗号鍵を要請しています。 \nセッション名:%1$s \n最後のオンライン時刻:%2$s \n新たにログインして新しいセッションを開始しなかった場合、この要求を無視してください。 @@ -1844,7 +1844,7 @@ あなたは既にこのルームを見ています! その他のサードパーティーの使用に関する掲示 Matrix SDK バージョン - ファイル\"%1$s\"からe2eキーをインポートします。 + ファイル\"%1$s\"からエンドツーエンド暗号鍵をインポートします。 キーのバックアップデータの取得中にエラーが発生しました 信頼情報の取得中にエラーが発生しました ルームが作成されましたが、一部の招待が送信されていません。理由: @@ -1878,7 +1878,7 @@ ホームへようこそ! 未読メッセージはありません 未読はありません! - %sがセッションを検証を要求しています + %sがセッションの検証を要求しています インタラクティブセッション検証 ルームに参加してアプリの使用を開始します。 リトライ @@ -1912,7 +1912,7 @@ 相手が確認するのを待っています… リクエストを見る 検証リクエストを受信しました。 - 相手の画面に次の番号が表示されていることを確認して、このセッションを確認します + 相手の画面に次の番号が表示されていることを確認して、このセッションを検証 相手の画面に次の絵文字が表示されることを確認して、このセッションを確認します このセッションを検証すると、信頼済としてマークされ、自分も相手に信頼済としてマークされます。 このセッションを検証して、信頼済としてマークします。相手のセッションを信頼すると、さらに安心してエンドツーエンド暗号化を使用することができます。 @@ -1969,7 +1969,7 @@ %d 通話できません デフォルトで使いもう尋ねない - キー共有リクエストの履歴を送信 + 鍵の共有リクエストの履歴を送信 結果がありません 自分で電話をかけることはできません。メンバーが招待を受け入れるのを待ちます ミーティングはJitsiのセキュリティーとパーミッションポリシーを使用します。会議中は、現在ルームにいる全ての人に招待状が表示されます。 @@ -2490,7 +2490,7 @@ %1$sは、このルームを招待者のみ参加可能に設定しました。 %1$sが部屋をリンクを持っているユーザーにアクセスできるように設定しました。 選択したメッセージをネタバレとして送信 - ${app_name} がE2E暗号鍵をディスクに保存する許可を要求しています。 + ${app_name} がエンドツーエンド暗号鍵をディスクに保存する許可を要求しています。 \n \n暗号鍵を手動でエクスポートできるように、次のポップアップでアクセスを許可してください。 %1$sはリンクを知っている人がアクセスできるようにこのルームを設定しました。 @@ -2565,7 +2565,7 @@ デバッグ用の情報を画面に表示 初期同期中… 説明文が短すぎます - サインインして暗号鍵を取り戻さななければ、暗号化されたメッセージがアクセスできなくなります。 + サインインして暗号鍵を取り戻さなければ、暗号化されたメッセージにアクセスできなくなります。 再サインイン 有効なホームサーバーを発見できません。識別子を確認してください どこかのホームサーバーで既にアカウントを登録している場合、以下でMatrix ID(例:@user:domain.com)とパスワードを使用してください。 @@ -2715,13 +2715,13 @@ \n%sで利用規約を閲覧できます。 最初の検索結果のみ表示中、文字をもっと入力してください… matrix.toリンクのフォーマットが正しくありませんでした - 注意!この端末には未だ暗号鍵を含む個人情報が保存されています。 + 注意!この端末には暗号鍵を含む個人情報が保存されています。 \n \nこの端末での使用を終了したり、他のアカウントにサインインしたい場合、このデータをクリアしてください。 この端末に現在保存されているすべてのデータをクリアしますか? \nアカウントデータとメッセージにアクセスするにはもう一度サインインしてください。 - 現在のセッションはユーザー%1$sのものなのに、あなたが提供している資格情報はユーザー%2$sのものです。この操作は${app_name}にサポートされていません。 -\nまずはデータをクリアしてから別のアカウントにサインインしてください。 + 現在のセッションはユーザー %1$s のものですが、あなたが提供している資格情報はユーザー %2$s のものです。この操作は${app_name}ではサポートされていません。 +\nまずデータをクリアし、その後、別のアカウントにサインインしてください。 暗号化されたメッセージが読めるように、サインインしてこの端末にのみ保存されている暗号鍵を取り戻してください。 あなたのホームサーバー(%1$s)の管理者があなたを%2$sのアカウントからサインアウトしています。(%3$s) いくつかの原因が考えられます: @@ -2746,4 +2746,18 @@ \n登録を中止しますか? %1$sにアカウント登録 あなたはすべてのセッションからログアウトしており、これ以上プッシュ通知を受け取れません。通知をもう一度有効にするには、各端末でサインインしてください。 + セキュリティーフレーズを設定 + セキュリティーフレーズを使用 + セキュリティーキーは、パスワードマネージャーもしくは金庫のような安全な場所で保管してください。 + セキュリティーキーは、パスワードマネージャーもしくは金庫のような安全な場所で保管してください。 + セキュリティーキーを生成し、パスワードマネージャーもしくは金庫のような安全な場所で保管してください。 + セキュアバックアップ + セキュアバックアップを設定 + 会話を開く + このIDサーバーは最新のバージョンではありません。${app_name}はAPIのバージョン2のみをサポートしています。 + ユーザーを招待できませんでした。招待したいユーザーを確認して、もう一度試してください。 + %sの利用規約を開く + ユーザーによる同意は与えられていません。 + 代わりに、他のIDサーバーのURLを入力できます + サーバー上の暗号化キーをバックアップすることにより、暗号化されたメッセージとデータへのアクセスが失われるのを防ぎます。 \ No newline at end of file From 6326c4180559b1de4133d9565756b43c5264159b Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sun, 20 Feb 2022 12:58:10 +0000 Subject: [PATCH 225/302] Translated using Weblate (Japanese) Currently translated at 89.4% (2490 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 4a10ef383d..0974616532 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -798,7 +798,7 @@ 必要な変数が見つかりません。 変数が無効です。 - メッセージを送信するには、キーボードのエンターキーを使用してください + メッセージを送信するには、キーボードのエンターキーを押してください ボイスメッセージを送信 動作を表示 指定したIDのユーザーをブロック @@ -1017,7 +1017,7 @@ セッションの管理 このセッションからログアウト - %d 件の有効なセッション + %d件のアクティブなセッション このログインを検証 QRコード @@ -1670,7 +1670,7 @@ \n \n暗号鍵を失わないように保護されたバックアップをしてください。 (高度) - 暗号されたメッセージを絶対に失わないために + 暗号化されたメッセージを決して失わないために 利用可能なMatrixセッションがありません ${app_name}によるリカバリーキーの生成を望む場合、パスフレーズを削除してください。 マークダウンが無効です。 @@ -1685,7 +1685,7 @@ \nセッション名:%1$s \n最後のオンライン時刻:%2$s \n新たにログインして新しいセッションを開始しなかった場合、この要求を無視してください。 - 暗号鍵共有要請 + 鍵の共有リクエスト カスタムカメラ画面の代わりにシステムカメラを使用します。 使用中のウィジェットがありません インテグレーションを管理 From c179885d8b9fc1193ec9053745b46e880c3d0769 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sun, 20 Feb 2022 12:57:43 +0000 Subject: [PATCH 226/302] Translated using Weblate (Japanese) Currently translated at 89.4% (2490 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 0974616532..5a2286b8fa 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1927,9 +1927,9 @@ サーバーオプションをおまかせする 無効なホームサーバーディスカバリーレスポンス 新しいメッセージの暗号キー - 暗号化されたメッセージを失うことはありません + 暗号鍵を絶対に喪失しないために セキュアバックアップ - 暗号化されたメッセージを失いません + 暗号鍵を決して喪失しないために バックアップ (%s) のtrust infoの取得に失敗しました。 セッションの暗号化が有効になっていません これを使用するとデータを%sと共有します。 From 33a2cfacd3c11983703d36124dddf3ff4031d312 Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Sun, 20 Feb 2022 13:35:23 +0000 Subject: [PATCH 227/302] Translated using Weblate (Japanese) Currently translated at 89.8% (2502 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 5a2286b8fa..a87c6e46d1 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2760,4 +2760,7 @@ ユーザーによる同意は与えられていません。 代わりに、他のIDサーバーのURLを入力できます サーバー上の暗号化キーをバックアップすることにより、暗号化されたメッセージとデータへのアクセスが失われるのを防ぎます。 + 今キャンセルしてログインにアクセスできなくなると、暗号化されたメッセージとデータが失われる可能性があります。 +\n +\nまた、設定からバックアップの設定や鍵の管理ができます。 \ No newline at end of file From 5d578f69667fc2257521eb60b0cebee3244e24c7 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sun, 20 Feb 2022 13:33:54 +0000 Subject: [PATCH 228/302] Translated using Weblate (Japanese) Currently translated at 89.8% (2502 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 90 +++++++++++++---------- 1 file changed, 51 insertions(+), 39 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index a87c6e46d1..2f0816f1eb 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -922,10 +922,10 @@ 検証 バックアップから復元 バックアップを削除 - 鍵をバックアップしています… + 鍵をバックアップしています。これには数分かかる可能性があります… 全ての鍵をバックアップしました - %d 件の鍵をバックアップしています… + %d個の鍵をバックアップしています… バージョン アルゴリズム @@ -1538,8 +1538,8 @@ 成功! バックアップを作成しています パスフレーズを設定 - 手動でキーをエクスポート - キーバックアップを使って開始 + 手動で鍵をエクスポート + 鍵のバックアップを使用開始 パスフレーズが弱すぎます パスフレーズを入力してください Google PlayサービスのAPKが見つかりませんでした。通知がうまく機能しない場合があります。 @@ -1588,31 +1588,31 @@ このルームでグループ通話をする権利がありません オーディオミーティングを開始 安全バックアップを設定 - 暗号鍵バックアップで管理 - 暗号鍵バックアップを使用 + 鍵のバックアップで管理 + 鍵のバックアップを使用 暗号化されたメッセージ及びデータへのアクセスを喪失しないための安全措置 - 暗号鍵のバックアップを開始 + 鍵のバックアップを使用開始 自分でした - 新しい暗号化されたメッセージの暗号鍵バックアップが検出されました。 + メッセージの鍵の新しい安全なバックアップが検出されました。 \n -\n新しい復元方法を設定しなかった場合、攻撃者がアカウントへアクセスしようとしている可能性があります。アカウントを守るために、設定ですぐにアカウントのパスワードを変更し新しい復元方法を設定してください。 - 新しい暗号鍵バックアップ - バックアップされた暗号鍵をサーバーから削除しますか? 現在のリカバリーキーを使って、暗号化されたメッセージの履歴を読むことができなくなります。 +\n新しい復元方法を設定しなかった場合、攻撃者がアカウントへアクセスしようとしている可能性があります。アカウントを守るために、設定ですぐにアカウントのパスワードを変更し、新しい復元方法を設定してください。 + 鍵の新しいバックアップ + バックアップされた暗号鍵をサーバーから削除しますか?今後、現在のリカバリーキーを使って、暗号化されたメッセージの履歴を読むことができなくなります。 バックアップを削除 - バックアップの状態を確認中 + バックアップの状態を確認しています バックアップの削除に失敗しました(%s) バックアップを削除しています… このセッションで鍵のバックアップを使用するには、パスフレーズまたはリカバリーキーでバックアップを復元してください。 - バックアップには未検証のセッション %s による不正な署名があります - バックアップには検証されたセッション %s による不正な署名があります - バックアップには未検証のセッション %s による有効な署名があります + バックアップには未認証のセッション %s による不正な署名があります + バックアップには認証済のセッション %s による不正な署名があります + バックアップには未認証のセッション %s による有効な署名があります バックアップには認証済のセッション %s による署名があります。 バックアップはこのセッションによる有効な署名があります。 バックアップには%sというIDの不明のセッションによる署名があります。 このセッションでは鍵がバックアップされていません。 このセッションでは鍵のバックアップが無効になっています。 このセッションでは鍵のバックアップが正しく設定されています。 - 最新の復号キーのバージョンを取得するのに失敗しました(%s)。 + 最新の復号化キーのバージョンを取得するのに失敗しました(%s)。 %d個の新しい鍵がこのセッションに追加されました。 @@ -1622,25 +1622,25 @@ バックアップが復元されました %s! このリカバリーキーではバックアップを復号化できませんでした。正しいリカバリーキーを入力したことを確認してください。 リカバリーキーを入力してください - 履歴をアンロック + 履歴のロックを解除 鍵をインポートしています… 鍵をダウンロードしています… リカバリーキーを計算しています… - バックアップを復元: + バックアップを復元しています: ネットワークエラー: 接続を確認して再試行してください。 - このパスフレーズではバックアップを復号できませんでした。正しい復元パスフレーズを入力したことを確認してください。 + このパスフレーズではバックアップを復号化できませんでした。正しいリカバリーパスフレーズを入力したことを確認してください。 リカバリーキーを喪失しましたか? 設定で新しいリカバリーキーを設定できます。 - メッセージの復元 + メッセージの復旧 バックアップのバージョンを取得しています… 暗号化されたメッセージ履歴のロックを解除するには、復旧用のパスフレーズを使用してください 復旧用のパスフレーズが分からなければ、%sできます。 - リカバリーキーを使用して暗号化されたメッセージ履歴をアンロックする + リカバリーキーを使用して、暗号化されたメッセージの履歴のロックを解除 リカバリーキーを入力 リカバリーキーを使用 - ログアウトしたりこの端末を失くしたりすればメッセージへのアクセスを失う可能性があります。 + ログアウトしたりこの端末を失くしたりすると、メッセージにアクセスできなくなる可能性があります。 続行しますか? - 暗号鍵が現在バックグラウンドでホームサーバーへバックアップされています。初期バックアップは数分かかることがあります。 - バックアップが開始されました + 暗号鍵を現在バックグラウンドでホームサーバーにバックアップしています。最初のバックアップには数分かかることがあります。 + バックアップが開始しました 予期しないエラー リカバリーキー パスフレーズを使用してリカバリーキーを生成中です。数秒かかることがあります。 @@ -1659,16 +1659,16 @@ リカバリーキーはパスワードマネージャー(もしくは金庫)のような、非常に安全な場所で保管してください リカバリーキーはセーフティーネットとなります。パスフレーズを忘れた場合でも、リカバリーキーを使えば、暗号化されたメッセージにアクセスすることができます。 \nリカバリーキーは、パスワードマネージャー(もしくは金庫)のような、非常に安全な場所で保管してください。 - 暗号鍵をバックアップしています。 + 鍵をバックアップしています。 (高度)リカバリーキーを使用して設定 または、リカバリーキーでバックアップを保護し、安全な場所に保存してください。 - 暗号鍵のコピーを暗号化してホームサーバーに保存します。バックアップを保護するためにパスフレーズを設定してください。 + 鍵のコピーを暗号化してホームサーバーに保存します。バックアップを保護するためにパスフレーズを設定してください。 \n -\n最高度のセキュリティーのために、アカウントのパスワードと異なることが大切です。 +\n最高度のセキュリティーのために、アカウントのパスワードと異なるものに設定することが大切です。 パスフレーズを使用してバックアップを保護します。 - 暗号化が有効なルームで送信されたメッセージはエンドツーエンド暗号化によって保護されます。メッセージを読むための暗号鍵を持っているのは送受信者のみです。 + 暗号化が有効なルームで送信されたメッセージは、エンドツーエンド暗号化によって保護されます。メッセージを読むための鍵を持っているのは送受信者のみです。 \n -\n暗号鍵を失わないように保護されたバックアップをしてください。 +\n鍵を失わないために、鍵を安全にバックアップしてください。 (高度) 暗号化されたメッセージを決して失わないために 利用可能なMatrixセッションがありません @@ -1845,7 +1845,7 @@ その他のサードパーティーの使用に関する掲示 Matrix SDK バージョン ファイル\"%1$s\"からエンドツーエンド暗号鍵をインポートします。 - キーのバックアップデータの取得中にエラーが発生しました + 鍵のバックアップデータの取得中にエラーが発生しました 信頼情報の取得中にエラーが発生しました ルームが作成されましたが、一部の招待が送信されていません。理由: \n @@ -1887,12 +1887,12 @@ IDサーバーを使用していません 不明なエラー ユーザーの不一致 - キーの不一致 + 鍵の不一致 無効なメッセージを受信しました セッションに予期しないメッセージが表示されました SASが一致しませんでした ハッシュコミットメントが一致しませんでした - セッションは、キー共有、ハッシュ、MAC、SASメソッドについて合意できません + セッションは、鍵の共有、ハッシュ、MAC、SASメソッドについて合意できません セッションはそのトランザクションについて知りません 検証プロセスがタイムアウトしました ユーザーが検証をキャンセルしました @@ -1903,7 +1903,7 @@ 相手が検証をキャンセルしました。 \n%s リクエストはキャンセルされました - キーの検証 + 鍵の検証 レガシー検証を使います。 何も表示されませんか?全てのクライアントがインタラクティブ検証をまだサポートしているわけではありません。その場合はレガシー検証を使用してください。 了解 @@ -1926,10 +1926,10 @@ \n%2$s サーバーオプションをおまかせする 無効なホームサーバーディスカバリーレスポンス - 新しいメッセージの暗号キー - 暗号鍵を絶対に喪失しないために + メッセージの新しい鍵 + 暗号化されたメッセージを決して失わないために セキュアバックアップ - 暗号鍵を決して喪失しないために + 暗号化されたメッセージを決して失わないために バックアップ (%s) のtrust infoの取得に失敗しました。 セッションの暗号化が有効になっていません これを使用するとデータを%sと共有します。 @@ -2214,7 +2214,7 @@ "トピック: " トラブルシューティング 添付ファイルの取得中にエラーが発生しました。 - キーバックアップのバナーを閉じる + 鍵のバックアップのバナーを閉じる キーワードに「%s」を含めることはできません %s へのメール通知を有効にする ヒント:メッセージを長押しして「%s」を選択。 @@ -2492,7 +2492,7 @@ 選択したメッセージをネタバレとして送信 ${app_name} がエンドツーエンド暗号鍵をディスクに保存する許可を要求しています。 \n -\n暗号鍵を手動でエクスポートできるように、次のポップアップでアクセスを許可してください。 +\n鍵を手動でエクスポートできるように、次のポップアップでアクセスを許可してください。 %1$sはリンクを知っている人がアクセスできるようにこのルームを設定しました。 まず、設定画面でIDサーバーの利用規約に同意してください。 初めにIDサーバーを設定してください。 @@ -2629,7 +2629,7 @@ 国際電話番号は「+」から始まる必要があります コードを%1$sに送信しました。以下に入力して認証してください。 このメールアドレスはどのアカウントにも属していません - パスワードを変更すると、すべてのセッションでのエンドツーエンド暗号鍵がリセットされ、暗号化されたメッセージ履歴が読めなくなります。パスワードを再設定する前に、暗号鍵のバックアップを設定するか、他のセッションからエクスポートしておいてください。 + パスワードを変更すると、すべてのセッションでのエンドツーエンド暗号鍵がリセットされ、暗号化されたメッセージ履歴が読めなくなります。パスワードを再設定する前に、鍵のバックアップを設定するか、他のセッションから鍵をエクスポートしておいてください。 パスワードの再設定を確認するために認証メールを送信しました。 このメールアドレスはどのアカウントにも属していません。 このアプリではこのホームサーバーにアカウントを作成できません。 @@ -2763,4 +2763,16 @@ 今キャンセルしてログインにアクセスできなくなると、暗号化されたメッセージとデータが失われる可能性があります。 \n \nまた、設定からバックアップの設定や鍵の管理ができます。 + USBメモリーもしくはバックアップドライブに保存 + 鍵のバックアップの設定 + 自己署名キーを同期しています + ユーザーキーを同期しています + マスターキーを同期しています + SSSS デフォルトキーを規定しています + 安全な鍵をパスフレーズから生成しています + メッセージキーを生成 + 暗号化されたメッセージのロックを解除 + 鍵の要求 + 鍵は既に最新です! + 鍵をリセット \ No newline at end of file From 52020aacdb98f971372360d285833d8aa77dee84 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sun, 20 Feb 2022 17:49:17 +0000 Subject: [PATCH 229/302] Translated using Weblate (Japanese) Currently translated at 90.4% (2518 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 110 +++++++++++++--------- 1 file changed, 65 insertions(+), 45 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 2f0816f1eb..39b2d1df77 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -8,15 +8,15 @@ %1$sがあなたを招待しました %1$sが参加しました %1$sが退出しました - %1$sが招待を断りました + %1$sが招待を拒否しました %1$sが%2$sを追放しました - %1$sが%2$sをブロック解除しました + %1$sが%2$sのブロックを解除しました %1$sが%2$sをブロックしました - %1$sが%2$sの招待を撤回しました + %1$sが%2$sの招待を取り下げました %1$sがアバターを変更しました %1$sが表示名を%2$sに設定しました %1$sが表示名を%2$sから%3$sに変更しました - %1$sが表示名 (%2$s) を削除しました + %1$sが表示名(%2$s)を削除しました %1$sがテーマを%2$sに変更しました %1$sがルーム名を%2$sに変更しました %sがビデオ通話を開始しました。 @@ -38,13 +38,13 @@ 不明 (%s)。 %1$sがエンドツーエンド暗号化を有効にしました (%2$s) %1$sがVoIP会議をリクエストしました - VoIP会議が開始されました + VoIP会議が開始しました VoIP会議が終了しました (アバターも変更されました) %1$sがルーム名を削除しました - %1$sがルームトピックを削除しました - %1$sがプロフィール %2$sを更新しました - %1$sは%2$sにルームに参加するよう招待状を送りました + %1$sがルームのトピックを削除しました + %1$sがプロフィール %2$s を更新しました + %1$sは%2$sにルームへの招待を送りました %1$sは%2$sの招待を受け入れました ** 解読できません:%s ** 送信者の端末からこのメッセージの鍵が送信されていません。 @@ -59,14 +59,14 @@ ルームのアバターを変更しました %1$sがルームのアバターを変更しました トピックを%1$sに変更しました - 表示名を削除しました(%1$sでした) + 表示名を削除しました(%1$sでした) 表示名を%1$sから%2$sに変更しました 表示名を%1$sに設定しました アバターを変更しました %1$sの招待を取り下げました - %1$sをBANしました - %1$sのBANを解除しました - %1$sを退出させました + %1$sをブロックしました + %1$sのブロックを解除しました + %1$sを追放しました 招待を拒否しました ルームから退出しました %1$sがルームから退出しました @@ -739,9 +739,9 @@ \n追加しますか? 続行する… 申し訳ありません、この操作を完了するための外部アプリが見つかりません。 - 他のセッションから暗号鍵を再度要求します。 + あなたの他のセッションに暗号鍵を再要求する。 鍵のリクエストが送信されました。 - リクエスト送信済 + 要求が送信されました 鍵をこのセッションに送信できるように、メッセージを復号化できる他の端末で${app_name}を起動してください。 %d秒 @@ -923,7 +923,7 @@ バックアップから復元 バックアップを削除 鍵をバックアップしています。これには数分かかる可能性があります… - 全ての鍵をバックアップしました + 全ての鍵がバックアップされています %d個の鍵をバックアップしています… @@ -1119,7 +1119,7 @@ 相手のコードをスキャン スキャンできません 断る - 検証リクエスト + 認証の要求 通話の開始前に確認 意図しない通話を防止 お使いの端末は脆弱性のある古いTLSセキュリティープロトコルを使用しています、このセキュリティーでは接続できません @@ -1281,11 +1281,11 @@ 会話を始める %1$sがエンドツーエンド暗号化をオンにしました。 エンドツーエンド暗号化をオンにしました。 - ゲストがルームに入るのを拒否しています。 - %1$sはゲストがルームに参加するのを拒否しています。 - ゲストがルームに入るのを拒否しています。 + ゲストがルームに参加するのを拒否しました。 + %1$sはゲストがルームに参加するのを拒否しました。 + ゲストがルームに参加するのを拒否しました。 %1$sはゲストがルームに参加するのを拒否しました。 - ここへのゲストの入室を許可しました。 + ここにゲストが参加することを許可しました。 %1$sはここにゲストが参加することを許可しました。 ゲストにルームへの参加を許可しました。 %1$sがゲストにルームへの参加を許可しました。 @@ -1308,14 +1308,14 @@ %1$sの招待を受諾しました%2$。理由:%2$s %1$sのルームへの招待を取り消しました。理由:%2$s %1$sにルームへの招待状を送りました。理由:%2$s - VoIPカンファレンスをリクエストしました + VoIP会議を要求しました このルームのサーバーのアクセス制御リストを変更しました。 このルームのサーバーアクセス制御リストを設定しました。 ここをアップグレードしました。 - あなたはこのルームをアップグレードしました。 + このルームをアップグレードしました。 通話を終了しました。 - 通話に応答しました。 - 通話を設定するためのデータを送信しました。 + 電話に出ました。 + 通話を設定するためにデータを送信しました。 このルームのアドレスを変更しました。 %1$sはこのルームのメインおよび代替アドレスを変更しました。 %1$sがこのルームのアドレスを変更しました。 @@ -1342,7 +1342,7 @@ %1$sはこのルームのアドレスとして%2$sを追加しました。 - あなたのプロフィールが更新されました %1$s + プロフィール %1$s を更新しました %sがこのルームのサーバーのアクセス制御リストを変更しました。 IPリテラルに一致するサーバーは禁止されています。 ・IPリテラルに一致するサーバーを許可します。 @@ -1352,10 +1352,10 @@ %sがここをアップグレードしました。 %sがこのルームをアップグレードしました。 エンドツーエンド暗号化をオンにしました (%1$s) - あなたは今後のメッセージを%1$sに見えるように設定しました + あなたは、今後のメッセージを%1$sに見えるように設定しました 今後のルーム履歴を%1$sに見えるように設定しました - %1$sは今後のメッセージを%2$sに見えるように設定しました - %sが通話を設定するためのデータを送信しました。 + %1$sは、今後のメッセージを%2$sに見えるように設定しました + %sが通話を設定するためにデータを送信しました。 通話をしました。 ビデオ通話をしました。 あなたが%1$sをブロックしました。理由:%2$s @@ -1417,7 +1417,7 @@ デフォルト モデレーター 管理者 - あなたががビデオ会議を変更しました + ビデオ会議を変更しました %1$sがビデオ会議を変更しました ビデオ会議を開始しました ビデオ会議を終了しました @@ -1438,10 +1438,10 @@ %1$sが%2$sのルームへの招待を取り消しました %1$sが%2$sを招待しました あなたは%1$sにルームへの招待を送りました - メッセージが%1$sによって削除されました[理由:%2$s] + メッセージが%1$sにより削除されました[理由:%2$s] メッセージが削除されました[理由:%1$s] - %1$sがメッセージを削除しました - メッセージを削除 + メッセージが%1$sにより削除されました + メッセージが削除されました ルームのアバターを削除しました %1$sがルームのアバターを削除しました ルームのトピックを削除しました @@ -1487,14 +1487,14 @@ \n%1$s ${app_name}のバックグラウンド制限は無効になっています。 このテストは、モバイル(WIFIでない)を使用して実行する必要があります。 \n%1$s - 端末を再起動してもサービスは開始されません。${app_name}が一度開かれるまで通知は届きません。 + 端末を再起動してもサービスは開始しません。${app_name}を一度開くまで通知は届きません。 %1$s \nこのエラーは${app_name}の管理外です。 これはいくつかの理由で発生する可能性があります。 後で再試行すればうまくいくかもしれません。システム設定でGoogle Play Serviceのデータ使用量が制限されていないか、端末の時刻が正しいかどうか、もしくはカスタムROMで起こることがあります。 ${app_name}モバイルからこれを行うことはできません ${app_name}はバッテリー最適化の影響を受けません。 制限を無効にする 起動時の開始を有効にする - 端末を再起動するとサービスが開始されます。 + 端末を再起動するとサービスが開始します。 サービスの再起動に失敗しました サービスが強制終了され、自動的に再起動されました。 通知サービスの自動再起動 @@ -1666,9 +1666,9 @@ \n \n最高度のセキュリティーのために、アカウントのパスワードと異なるものに設定することが大切です。 パスフレーズを使用してバックアップを保護します。 - 暗号化が有効なルームで送信されたメッセージは、エンドツーエンド暗号化によって保護されます。メッセージを読むための鍵を持っているのは送受信者のみです。 + 暗号化されたメッセージは、エンドツーエンドの暗号化によって保護されています。これらの暗号化されたメッセージを読むための鍵を持っているのは、あなたと受信者だけです。 \n -\n鍵を失わないために、鍵を安全にバックアップしてください。 +\n鍵を失くさないよう、鍵を安全にバックアップしてください。 (高度) 暗号化されたメッセージを決して失わないために 利用可能なMatrixセッションがありません @@ -2147,7 +2147,7 @@ 地図 投票を終了 投票を終了 - 選択肢 %1$d + 選択肢%1$d 選択肢を作成 ロケーション ロケーションを共有 @@ -2225,9 +2225,9 @@ スレッドでディスカッションを整理して管理 %sを待機しています… この端末でスキャン - 検証を送信済 - 手動で検証 - このセッションを検証 + 認証を送信済 + 手動で認証 + このセッションを認証 音声 ルームのアドレスを入力してください このアドレスは既に使用されています @@ -2415,7 +2415,7 @@ 現在IDサーバー %1$s でメールアドレスや電話番号を共有しています。共有を停止するには %2$s に再接続する必要があります。 ルームを作成し設定しました。 QRコードを読み取り、新しいダイレクトメッセージを作成 - キーのインポートに失敗しました + 鍵のインポートに失敗しました Matrix IDで新しいダイレクトメッセージを作成 新しいダイレクトメッセージを作成 ルーム作成メニューを閉じる… @@ -2620,7 +2620,7 @@ クロス署名を開始 信頼されていません セキュリティーを確認 - 検証リクエスト + 認証の要求 %sがキャンセルしました 既読 検証 @@ -2722,7 +2722,7 @@ \nアカウントデータとメッセージにアクセスするにはもう一度サインインしてください。 現在のセッションはユーザー %1$s のものですが、あなたが提供している資格情報はユーザー %2$s のものです。この操作は${app_name}ではサポートされていません。 \nまずデータをクリアし、その後、別のアカウントにサインインしてください。 - 暗号化されたメッセージが読めるように、サインインしてこの端末にのみ保存されている暗号鍵を取り戻してください。 + 暗号化されたメッセージがどの端末でも読めるように、サインインしてこの端末にのみ保存されている暗号鍵を取り戻してください。 あなたのホームサーバー(%1$s)の管理者があなたを%2$sのアカウントからサインアウトしています。(%3$s) いくつかの原因が考えられます: \n @@ -2760,9 +2760,9 @@ ユーザーによる同意は与えられていません。 代わりに、他のIDサーバーのURLを入力できます サーバー上の暗号化キーをバックアップすることにより、暗号化されたメッセージとデータへのアクセスが失われるのを防ぎます。 - 今キャンセルしてログインにアクセスできなくなると、暗号化されたメッセージとデータが失われる可能性があります。 + いまキャンセルすると、ログインできなくなった際に、暗号化されたメッセージとデータを失ってしまう可能性があります。 \n -\nまた、設定からバックアップの設定や鍵の管理ができます。 +\nまた、設定から、安全なバックアップの設定や鍵の管理を行うことができます。 USBメモリーもしくはバックアップドライブに保存 鍵のバックアップの設定 自己署名キーを同期しています @@ -2775,4 +2775,24 @@ 鍵の要求 鍵は既に最新です! 鍵をリセット + 質問は空にできません + ここで送受信されるメッセージはエンドツーエンド暗号化されています。 +\n +\nメッセージは安全に保護されており、メッセージのロックを解除するための固有の鍵は、あなたと受信者だけが持っています。 + このルームのメッセージはエンドツーエンド暗号化されています。 +\n +\nメッセージは安全に保護されており、メッセージのロックを解除するための固有の鍵は、あなたと受信者だけが持っています。 + ステートキー + リカバリーキーを以下に保存 + 送信者が意図的に鍵を送信しなかったため、このメッセージにアクセスすることができません + 暗号鍵が適切に送信されませんでした。エンドツーエンド暗号化の性質上、相手のメッセージが届くまで待機する必要があるかもしれません。 + 鍵のバックアップのリカバリーキー + 鍵のバックアップのパスフレーズが分からなければ、%sできます。 + 鍵のバックアップのリカバリーキーを使用 + 続行するには鍵のバックアップのパスフレーズを入力してください。 + SSSS鍵をパスフレーズから生成しています(%s) + SSSS鍵をパスフレーズから生成しています + Curveキーを取得しています + バックアップキーを確認しています(%s) + バックアップキーを確認しています \ No newline at end of file From 5e573da5346bdd0100dd482bc4c202f1df06cb7d Mon Sep 17 00:00:00 2001 From: Rintan Date: Sun, 20 Feb 2022 18:24:19 +0000 Subject: [PATCH 230/302] Translated using Weblate (Japanese) Currently translated at 91.0% (2535 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 39b2d1df77..1ef2b2fa3e 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1971,7 +1971,7 @@ デフォルトで使いもう尋ねない 鍵の共有リクエストの履歴を送信 結果がありません - 自分で電話をかけることはできません。メンバーが招待を受け入れるのを待ちます + 自分との通話は開始できません、他の参加者が招待を受けるまでお待ちください ミーティングはJitsiのセキュリティーとパーミッションポリシーを使用します。会議中は、現在ルームにいる全ての人に招待状が表示されます。 権限がありません 音声メッセージを送信するには、マイクの権限を許可してください。 From 119d9547ffc3190e2e9cd4c7d368d8f3ff1d792c Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sun, 20 Feb 2022 18:23:46 +0000 Subject: [PATCH 231/302] Translated using Weblate (Japanese) Currently translated at 91.0% (2535 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 77 ++++++++++++----------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 1ef2b2fa3e..0f8e5e9327 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -30,13 +30,13 @@ %1$sと他%2$d名 - %1$sは、今後のルーム履歴を%2$sに見えるように設定しました - ルームのメンバー全員、招待された時点から。 - ルームのメンバー全員、参加した時点から。 - ルームのメンバー全員。 - 誰でも。 - 不明 (%s)。 - %1$sがエンドツーエンド暗号化を有効にしました (%2$s) + %1$sは、今後のルーム履歴を%2$sに見えるように設定しました。 + ルームのメンバー全員(招待された時点から) + ルームのメンバー全員(参加した時点から) + ルームのメンバー全員 + 全員 + 不明(%s) + %1$sがエンドツーエンド暗号化を有効にしました(%2$s) %1$sがVoIP会議をリクエストしました VoIP会議が開始しました VoIP会議が終了しました @@ -205,7 +205,7 @@ このユーザー名は既に使用されています 削除 参加 - あなたは%sさんに、このルームへ招待されています + %sさんがこのルームに招待しています 新しい会話 メンバーを追加 1名 @@ -219,7 +219,7 @@ 未送信のメッセージを再送信 未送信のメッセージを削除 ファイルが見つかりません - あなたはこのルームで発言する権限がありません。 + このルームで発言する権限がありません。 ルームの詳細 参加者 ファイル @@ -486,8 +486,8 @@ ルームのエンドツーエンド暗号鍵をエクスポート 認証 履歴を検索 - あなたはこのルームに参加していません。 - あなたはこのルームで権限がありません。 + このルームに参加していません。 + このルームで権限がありません。 ルーム %s は、見ることができません。 ユーザー名 ホームサーバーのURL @@ -562,7 +562,7 @@ ダウンロードファイルに保存しますか? この招待はこのアカウントに関連付けられていない%sに送信されました。 \n別のアカウントでログインするか、このメールを自分のアカウントに追加してください。 - あなたは%sにアクセスしようとしています。ディスカッションに参加しますか? + %sにアクセスしようとしています。ディスカッションに参加しますか? ルーム これはルームのプレビューです。ルームでのやり取りは無効化されています。 このユーザーにあなたと同じ権限を与えますが、この変更は取り消せません。 @@ -689,8 +689,8 @@ グループのメンバーをフィルタリング グループのルームを絞り込み 管理者はこのコミュニティーの詳細を規定していません。 - あなたは%2$sによって%1$sから除外されました - あなたは%2$sによって%1$sへの参加を禁止されました + %2$sによって%1$sから除外されました + %2$sによって%1$sへの参加を禁止されました 理由:%1$s 再参加 端末を振って不具合を報告 @@ -1305,10 +1305,10 @@ このルームのアドレスの%1$sを削除しました。 %1$sの招待を取り消しました。理由:%2$s - %1$sの招待を受諾しました%2$。理由:%2$s + %1$sの招待を受け入れました。理由:%2$s %1$sのルームへの招待を取り消しました。理由:%2$s %1$sにルームへの招待状を送りました。理由:%2$s - VoIP会議を要求しました + VoIP会議をリクエストしました このルームのサーバーのアクセス制御リストを変更しました。 このルームのサーバーアクセス制御リストを設定しました。 ここをアップグレードしました。 @@ -1337,7 +1337,7 @@ %1$sが%2$sにルームへの招待を送りました。理由:%3$s %1$sが%2$sのルームへの招待を取り消しました。理由:%3$s - %1$sが %2$sの招待を承諾しました。理由:%3$s + %1$sが %2$sの招待を受け入れました。理由:%3$s %1$sは%2$sの招待を取り下げました。理由:%3$s %1$sはこのルームのアドレスとして%2$sを追加しました。 @@ -1351,20 +1351,20 @@ %sがこのルームのサーバーアクセス制御リストを設定しました。 %sがここをアップグレードしました。 %sがこのルームをアップグレードしました。 - エンドツーエンド暗号化をオンにしました (%1$s) - あなたは、今後のメッセージを%1$sに見えるように設定しました - 今後のルーム履歴を%1$sに見えるように設定しました - %1$sは、今後のメッセージを%2$sに見えるように設定しました + エンドツーエンド暗号化を有効にしました(%1$s) + 今後のメッセージを%1$sに見えるように設定しました。 + 今後のルーム履歴を%1$sに見えるように設定しました。 + %1$sは、今後のメッセージを%2$sに見えるように設定しました。 %sが通話を設定するためにデータを送信しました。 - 通話をしました。 - ビデオ通話をしました。 + 通話を開始しました。 + ビデオ通話を開始しました。 あなたが%1$sをブロックしました。理由:%2$s %1$sが%2$sをブロックしました。理由:%3$s あなたが%1$sのブロックを解除しました。理由:%2$s %1$sが%2$sのブロックを解除しました。理由:%3$s - あなたは%1$sを除去しました。理由:%2$s + %1$sを除去しました。理由:%2$s %1$sが%2$sを除去しました。理由:%3$s - あなたは招待を拒否しました。理由:%1$s + 招待を拒否しました。理由:%1$s %1$sは招待を拒否しました。理由:%2$s 退出しました。理由:%1$s %1$sが退出しました。理由:%2$s @@ -1423,21 +1423,21 @@ ビデオ会議を終了しました %1$sがビデオ会議を開始しました %1$sがビデオ会議を開始しました - あなたは%1$sウィジェットを変更しました + %1$sウィジェットを変更しました %1$sは%2$sウィジェットを変更しました - あなたは%1$sウィジェットを削除しました + %1$sウィジェットを削除しました %1$sが%2$sウィジェットを削除しました - あなたは%1$sウィジェットを追加しました - あなたは%1$sの招待を受けました + %1$sウィジェットを追加しました + %1$sの招待を受け入れました %1$sが%2$sウィジェットを追加しました ルーム名を変更しました:%1$s - あなたは%1$sの招待を取り消しました + %1$sの招待を取り消しました %1$sが%2$sの招待を取り消しました - あなたは%1$sを招待しました - あなたは%1$sのルームへの招待を取り消しました + %1$sを招待しました + %1$sのルームへの招待を取り消しました %1$sが%2$sのルームへの招待を取り消しました %1$sが%2$sを招待しました - あなたは%1$sにルームへの招待を送りました + %1$sにルームへの招待を送りました メッセージが%1$sにより削除されました[理由:%2$s] メッセージが削除されました[理由:%1$s] メッセージが%1$sにより削除されました @@ -2585,7 +2585,7 @@ 通話は終了しました 自分自身にダイレクトメッセージを送信することはできません! %1$sは通話を開始しました - あなたは通話を開始しました + 通話を開始しました 電話番号(任意) 電話番号を確認 電話番号を設定 @@ -2713,7 +2713,7 @@ Elementの改善と課題抽出のために、匿名の使用分析データを収集させてくださいませんか?複数の端末での使用を解析するために、あなたの全端末共通のランダムな識別子を生成します。 \n \n%sで利用規約を閲覧できます。 - 最初の検索結果のみ表示中、文字をもっと入力してください… + 最初の検索結果のみ表示中。文字をもっと入力してください… matrix.toリンクのフォーマットが正しくありませんでした 注意!この端末には暗号鍵を含む個人情報が保存されています。 \n @@ -2731,12 +2731,12 @@ \n• 他のセッションでこのセッションを削除している。 \n \n• サーバーの管理者がセキュリティ上の理由であなたのアクセスを取り消している。 - 代理手段として、既にアカウントをお持ちでMatrix IDとパスワードをご存知なら、この方法が使用できます。 + 代わりに、既にアカウントをお持ちでMatrix IDとパスワードをご存知なら、この方法が使用できます。 リクエストが多すぎます。%1$d秒後に再試行できます… - このホームサーバーが古いバージョンで運営しています。管理者にアップグレードを要請してください。続行できますが、いくつかの機能が正しく作動しない可能性があります。 - このホームサーバーが古すぎるバージョンで運営しており、接続できません。管理者にアップグレードを要請してください。 + このホームサーバーは古いバージョンです。管理者にアップグレードを要請してください。続行できますが、いくつかの機能が正しく作動しない可能性があります。 + このホームサーバーのバージョンは古すぎるため、接続できません。管理者にアップグレードを要請してください。 ホームサーバーのバージョンが古すぎます ただいま%1$sにメールを送信しました。 \nアカウント登録を続けるにはメールに含まれたリンクをクリックしてください。 @@ -2795,4 +2795,5 @@ Curveキーを取得しています バックアップキーを確認しています(%s) バックアップキーを確認しています + ナビゲーションのメニューを開く \ No newline at end of file From ccd71d6072a4417b3971edcec7cd4619fe7ef2db Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sun, 20 Feb 2022 18:31:25 +0000 Subject: [PATCH 232/302] Translated using Weblate (Japanese) Currently translated at 91.0% (2536 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 0f8e5e9327..94c5f01468 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -578,7 +578,7 @@ リモートサーバーのIDを確認できませんでした。 誰かが不当にあなたの通信を傍受しているか、リモートサーバーの証明書をあなたの電話が信用していない可能性があります。 サーバーの管理者が、これは想定されていることであると言っているのであれば、以下のフィンガープリントが管理者によるフィンガープリントと一致していることを確認してください。 - 証明書はあなたの電話に信頼されていたものから変更されています。これはきわめて異常な事態です。この新しい証明書は承認しないことを強く推奨します。 + 証明書はあなたの電話に信頼されていたものから変更されています。これはきわめて異常な事態です。この新しい証明書を承認しないことを強く推奨します。 証明書は以前信頼されていたものから信頼されていないものへと変更されています。サーバーがその証明書を更新した可能性があります。予測されるフィンガープリントを取得するために、サーバーの管理者に連絡してください。 サーバーの管理者が上のフィンガープリントと一致するものを発行した場合に限り、証明書を承認してください。 不正な形式のIDです。メールアドレスまたは\'@localpart:domain\'という形式のMatrix IDを入力してください @@ -866,8 +866,8 @@ 畳む メッセージとエラーの場合 とにかく通話 - 了承 - このホームサーバーの方針を閲覧し承認してください: + 承諾 + このホームサーバーの方針を確認し承諾してください: 通話設定画面 着信に${app_name}の既定の着信音を使用 着信音 @@ -1448,7 +1448,7 @@ ルーム名を削除しました 許可を与える ${app_name}は、信頼できる通知を受け取るために、影響の少ないバックグラウンド接続を維持する必要があります。 -\n次の画面で、${app_name}を常にバックグラウンドで実行することを許可するように求められます。同意してください。 +\n次の画面で、${app_name}を常にバックグラウンドで実行することを許可するように求められます。承認してください。 バックグラウンド接続 ディスカバリー設定を管理します。 ディスカバリー(発見) @@ -1546,7 +1546,7 @@ ユーザー名を入力してください。 無視 共有 - 続けるには利用規約に同意する必要があります。 + 続けるには利用規約を承認する必要があります。 全てブロック 許可 ルームID @@ -1734,7 +1734,7 @@ 招待された人だけが発見し参加できます 非公開 不明のアクセス設定(%s) - 誰でもノックができ、メンバーがその参加を承認または拒否できます + 誰でもルームにノックができ、メンバーがその参加を承認または拒否できます 現在のルームディレクトリの見え方を取得できません(%1$s)。 このルームを%1$sのルームディレクトリに公開しますか? アドレスを非公開にする @@ -1779,8 +1779,8 @@ メールアドレスを設定 メールアドレスを確認しました 検出可能なメールアドレス - 続行するには条件に同意してください - ホームサーバーの利用規約に同意したら、再試行してください。 + 続行するには利用規約を承認してください + ホームサーバーの利用規約を承認したら、再試行してください。 次に 次に 次に @@ -1971,7 +1971,7 @@ デフォルトで使いもう尋ねない 鍵の共有リクエストの履歴を送信 結果がありません - 自分との通話は開始できません、他の参加者が招待を受けるまでお待ちください + 自分に電話をかけることはできません。参加者が招待を受け入れるまでお待ちください ミーティングはJitsiのセキュリティーとパーミッションポリシーを使用します。会議中は、現在ルームにいる全ての人に招待状が表示されます。 権限がありません 音声メッセージを送信するには、マイクの権限を許可してください。 @@ -1979,7 +1979,7 @@ このアクションを実行するには、いくつかの権限が不足しています。システム設定から権限を付与してください。 IDサーバーに接続できませんでした IDサーバーのURLを入力 - 連絡先を発見するために、あなたの連絡先のデータ(電話番号や電子メール)を、設定されたIDサーバー(%1$s)に送信することに同意しますか? + 連絡先を発見するために、あなたの連絡先のデータ(電話番号や電子メール)を、設定されたIDサーバー(%1$s)に送信することを承認しますか? \n \nプライバシーの保護のため、データは送信前にハッシュ化されます。 メールと電話番号を送信 @@ -2635,7 +2635,7 @@ このアプリではこのホームサーバーにアカウントを作成できません。 \n \nウェブクライエントを使用してアカウント登録しますか? - 申し訳ありません。このサーバーはアカウントの新規登録を認めていません。 + 申し訳ありませんが、このサーバーはアカウントの新規登録を受け入れていません。 このアプリではこのホームサーバーにサインインできません。このホームサーバーは次のサインイン方法に対応しています: %1$s \n \nウェブクライエントを使用してサインインしますか? From 613c17bca1b37b29355763e917367799259d4bdd Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sun, 20 Feb 2022 18:27:01 +0000 Subject: [PATCH 233/302] Translated using Weblate (Japanese) Currently translated at 91.0% (2536 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 94c5f01468..5cc693da7d 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2796,4 +2796,6 @@ バックアップキーを確認しています(%s) バックアップキーを確認しています ナビゲーションのメニューを開く + あなたが承諾しました + %sが承諾しました \ No newline at end of file From fff3a5eefa3ce16a1bbbe35a5b414c0cbad2bf87 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Sun, 20 Feb 2022 18:38:35 +0000 Subject: [PATCH 234/302] Translated using Weblate (Japanese) Currently translated at 91.1% (2539 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 5cc693da7d..0211a3f6af 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2798,4 +2798,9 @@ ナビゲーションのメニューを開く あなたが承諾しました %sが承諾しました + %sが検証済み + %sを検証する + 絵文字を比較して検証する + 絵文字を比較して検証する + 対面じゃなければ、代わりに絵文字を比較してください \ No newline at end of file From d22ac7464617990f8907b09daa498991de69c725 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sun, 20 Feb 2022 18:37:11 +0000 Subject: [PATCH 235/302] Translated using Weblate (Japanese) Currently translated at 91.1% (2539 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 0211a3f6af..4da3ae2078 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2494,7 +2494,7 @@ \n \n鍵を手動でエクスポートできるように、次のポップアップでアクセスを許可してください。 %1$sはリンクを知っている人がアクセスできるようにこのルームを設定しました。 - まず、設定画面でIDサーバーの利用規約に同意してください。 + 初めに設定画面でIDサーバーの利用規約を承認してください。 初めにIDサーバーを設定してください。 %1$d個の投票があります。結果を見るには投票してください @@ -2796,11 +2796,12 @@ バックアップキーを確認しています(%s) バックアップキーを確認しています ナビゲーションのメニューを開く - あなたが承諾しました + 承諾しました %sが承諾しました %sが検証済み %sを検証する 絵文字を比較して検証する 絵文字を比較して検証する 対面じゃなければ、代わりに絵文字を比較してください + あなたのホームサーバーは、最大%sのサイズの添付ファイルを受け付けています。 \ No newline at end of file From 865e0fa084617b9325b86155411e3e80b5635320 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sun, 20 Feb 2022 18:56:12 +0000 Subject: [PATCH 236/302] Translated using Weblate (Japanese) Currently translated at 91.1% (2539 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 42 +++++++++++------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 4da3ae2078..ad2b71b11d 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -28,7 +28,7 @@ %1$sと%2$s 空のルーム - %1$sと他%2$d名 + %1$sと他%2$d人 %1$sは、今後のルーム履歴を%2$sに見えるように設定しました。 ルームのメンバー全員(招待された時点から) @@ -1333,7 +1333,7 @@ %1$sはこのルームのアドレスの%2$sを削除しました。 - このルームのアドレスとして%1$sが追加されました。 + このルームのアドレスとして%1$sを追加しました。 %1$sが%2$sにルームへの招待を送りました。理由:%3$s %1$sが%2$sのルームへの招待を取り消しました。理由:%3$s @@ -1358,50 +1358,50 @@ %sが通話を設定するためにデータを送信しました。 通話を開始しました。 ビデオ通話を開始しました。 - あなたが%1$sをブロックしました。理由:%2$s + %1$sをブロックしました。理由:%2$s %1$sが%2$sをブロックしました。理由:%3$s - あなたが%1$sのブロックを解除しました。理由:%2$s + %1$sのブロックを解除しました。理由:%2$s %1$sが%2$sのブロックを解除しました。理由:%3$s - %1$sを除去しました。理由:%2$s - %1$sが%2$sを除去しました。理由:%3$s + %1$sを追放しました。理由:%2$s + %1$sが%2$sを追放しました。理由:%3$s 招待を拒否しました。理由:%1$s %1$sは招待を拒否しました。理由:%2$s 退出しました。理由:%1$s %1$sが退出しました。理由:%2$s - あなたがこのルームを退出しました。理由:%1$s + このルームを退出しました。理由:%1$s 初期同期: \n退出したルームをインポートしています 初期同期: \n招待されたルームをインポートしています - 初期同期: + 初期同期: \n会話を読み込んでいます \n多くのルームに参加している場合、読み込みに時間がかかるかもしれません %1$sがこのルームを退出しました。理由:%2$s - あなたがこのルームに参加しました。理由:%1$s + このルームに参加しました。理由:%1$s %1$sがこのルームに参加しました。理由:%2$s - あなたがこのルームに参加しました。理由:%1$s + このルームに参加しました。理由:%1$s %1$sがこのルームに参加しました。理由:%2$s %1$sがあなたを招待しました。 理由:%2$s - あなたが%1$sを招待しました。 理由:%2$s + %1$sを招待しました。 理由:%2$s %1$sが%2$sを招待しました。 理由:%3$s あなたの招待です。理由:%1$s %1$sの招待です。理由:%2$s 送信キューのクリア メッセージを送っています… メッセージを送りました - 初期同期: + 初期同期: \nアカウントデータをインポートしています - 初期同期: + 初期同期: \nコミュニティーをインポートしています - 初期同期: + 初期同期: \nルームをインポートしています - 初期同期: + 初期同期: \n暗号をインポートしています - 初期同期: + 初期同期: \nアカウントをインポートしています… - 初期同期: + 初期同期: \nデータをダウンロードしています… - 初期同期: + 初期同期: \nサーバーからの応答を待っています… 空のルーム(%sでした) @@ -2800,8 +2800,8 @@ %sが承諾しました %sが検証済み %sを検証する - 絵文字を比較して検証する - 絵文字を比較して検証する - 対面じゃなければ、代わりに絵文字を比較してください + 絵文字を比較して検証 + 絵文字を比較して検証 + 対面でない場合は、代わりに絵文字を比較してください あなたのホームサーバーは、最大%sのサイズの添付ファイルを受け付けています。 \ No newline at end of file From aa753cc4cfbfae3341e179d505c396d502efe6e2 Mon Sep 17 00:00:00 2001 From: Rintan Date: Sun, 20 Feb 2022 19:34:12 +0000 Subject: [PATCH 237/302] Translated using Weblate (Japanese) Currently translated at 91.3% (2543 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index ad2b71b11d..0a5f8a4926 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1585,7 +1585,7 @@ とにかく参加 ルームを追加 %sはあなたを招待しています - このルームでグループ通話をする権利がありません + このルームでグループ通話を開始する権限がありません オーディオミーティングを開始 安全バックアップを設定 鍵のバックアップで管理 From 756e975c34a7033506f75655da36bb78c3f12b75 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sun, 20 Feb 2022 19:33:39 +0000 Subject: [PATCH 238/302] Translated using Weblate (Japanese) Currently translated at 91.3% (2543 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 76 +++++++++++------------ 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 0a5f8a4926..cb5207b4bb 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -30,7 +30,7 @@ %1$sと他%2$d人 - %1$sは、今後のルーム履歴を%2$sに見えるように設定しました。 + %1$sが今後のルーム履歴を%2$sに見えるように設定しました。 ルームのメンバー全員(招待された時点から) ルームのメンバー全員(参加した時点から) ルームのメンバー全員 @@ -44,9 +44,9 @@ %1$sがルーム名を削除しました %1$sがルームのトピックを削除しました %1$sがプロフィール %2$s を更新しました - %1$sは%2$sにルームへの招待を送りました - %1$sは%2$sの招待を受け入れました - ** 解読できません:%s ** + %1$sが%2$sにルームへの招待を送りました + %1$sが%2$sの招待を受け入れました + ** 復号化できません:%s ** 送信者の端末からこのメッセージの鍵が送信されていません。 修正できませんでした メッセージを送信できません @@ -192,7 +192,7 @@ 黒いテーマ 同期しています… メッセージ - メンバー詳細 + メンバーの詳細 引用 後で 転送 @@ -344,8 +344,8 @@ より大きい とても大きい 巨大 - 発言更新を確認 - 暗号解除されたソースコードを表示 + 発言更新を確認しています + 復号化されたソースコードを表示 名前変更 オフライン 会話を開始 @@ -354,7 +354,7 @@ 写真または動画を撮影 初期化メール送信 写真撮影やビデオ通話には, ${app_name}アプリに端末のカメラの使用を許可する必要があります. - 通話を開始できませんでした。後ほどお試しください + 通話を開始できませんでした。後ほど試してください 権限が無いため、一部の機能を利用できない可能性があります… このルームで会議を開始するためには招待の権限が必要です とにかく送る @@ -874,7 +874,7 @@ 着信音を選んでください: 追い出す 理由 - サービスを初期化 + サービスを初期化しています 鍵のバックアップ 鍵のバックアップを使用 セッションを認証 @@ -910,7 +910,7 @@ パスワード パスワード 今ここでサインアウトすると、あなたの暗号化されたメッセージは失われてしまいます - 鍵のバックアップは現在処理中です。処理中にサインアウトすると暗号化されたメッセージにアクセスできなくなります。 + 鍵のバックアップは現在処理中です。処理中にサインアウトすると、暗号化されたメッセージにアクセスできなくなります。 暗号化されたメッセージにアクセスできなくなることを防ぐため、鍵の安全なバックアップはあなたのセッション全てで有効化してください。 暗号化されたメッセージは不要です 鍵をバックアップしています… @@ -1276,7 +1276,7 @@ 非公開 切り替える 加える - %1$sはエンドツーエンド暗号化(認識されていないアルゴリズム %2$s)をオンにしました。 + %1$sがエンドツーエンド暗号化(認識されていないアルゴリズム %2$s)をオンにしました。 エンドツーエンド暗号化(認識されていないアルゴリズム %1$s)をオンにしました。 会話を始める %1$sがエンドツーエンド暗号化をオンにしました。 @@ -1287,24 +1287,24 @@ %1$sはゲストがルームに参加するのを拒否しました。 ここにゲストが参加することを許可しました。 %1$sはここにゲストが参加することを許可しました。 - ゲストにルームへの参加を許可しました。 - %1$sがゲストにルームへの参加を許可しました。 + ゲストがルームに参加するのを許可しました。 + %1$sはゲストがルームに参加するのを許可しました。 システムデフォルト このルームのメインおよび代替のアドレスを変更しました。 このルームの代替アドレスを変更しました。 - このルームの代替アドレス%1$sを削除しました。 + このルームの代替アドレス %1$s を削除しました。 - このルームの代替アドレス%1$sを追加しました。 + このルームの代替アドレス %1$s を追加しました。 このルームのメインアドレスを削除しました。 このルームのメインアドレスを%1$sに設定しました。 - このルームのアドレスとして、%1$sを追加し%2$sを削除しました。 + このルームのアドレスに%1$sを追加し%2$sを削除しました。 このルームのアドレスの%1$sを削除しました。 - %1$sの招待を取り消しました。理由:%2$s + %1$sの招待を取り下げました。理由:%2$s %1$sの招待を受け入れました。理由:%2$s %1$sのルームへの招待を取り消しました。理由:%2$s %1$sにルームへの招待状を送りました。理由:%2$s @@ -1317,30 +1317,30 @@ 電話に出ました。 通話を設定するためにデータを送信しました。 このルームのアドレスを変更しました。 - %1$sはこのルームのメインおよび代替アドレスを変更しました。 + %1$sがこのルームのメインおよび代替アドレスを変更しました。 %1$sがこのルームのアドレスを変更しました。 - %1$sはこのルームの代替アドレスを変更しました。 + %1$sがこのルームの代替アドレスを変更しました。 - %1$sがこのルームの代替アドレス%2$sを削除しました。 + %1$sがこのルームの代替アドレス %2$s を削除しました。 - %1$sはこのルームの代替アドレス%2$sを追加しました。 + %1$sがこのルームの代替アドレス %2$s を追加しました。 %1$sがこのルームのメインアドレスを削除しました。 %1$sがこのルームのメインアドレスを%2$sに設定しました。 - %1$sはこのルームのアドレスとして%2$sを追加し%3$sを削除しました。 + %1$sがこのルームのアドレスに%2$sを追加し%3$sを削除しました。 - %1$sはこのルームのアドレスの%2$sを削除しました。 + %1$sがこのルームのアドレスの%2$sを削除しました。 - このルームのアドレスとして%1$sを追加しました。 + このルームのアドレスに%1$sを追加しました。 %1$sが%2$sにルームへの招待を送りました。理由:%3$s %1$sが%2$sのルームへの招待を取り消しました。理由:%3$s %1$sが %2$sの招待を受け入れました。理由:%3$s - %1$sは%2$sの招待を取り下げました。理由:%3$s + %1$sが%2$sの招待を取り下げました。理由:%3$s - %1$sはこのルームのアドレスとして%2$sを追加しました。 + %1$sがこのルームのアドレスに%2$sを追加しました。 プロフィール %1$s を更新しました %sがこのルームのサーバーのアクセス制御リストを変更しました。 @@ -1354,7 +1354,7 @@ エンドツーエンド暗号化を有効にしました(%1$s) 今後のメッセージを%1$sに見えるように設定しました。 今後のルーム履歴を%1$sに見えるように設定しました。 - %1$sは、今後のメッセージを%2$sに見えるように設定しました。 + %1$sが今後のメッセージを%2$sに見えるように設定しました。 %sが通話を設定するためにデータを送信しました。 通話を開始しました。 ビデオ通話を開始しました。 @@ -1365,11 +1365,11 @@ %1$sを追放しました。理由:%2$s %1$sが%2$sを追放しました。理由:%3$s 招待を拒否しました。理由:%1$s - %1$sは招待を拒否しました。理由:%2$s + %1$sが招待を拒否しました。理由:%2$s 退出しました。理由:%1$s %1$sが退出しました。理由:%2$s このルームを退出しました。理由:%1$s - 初期同期: + 初期同期: \n退出したルームをインポートしています 初期同期: \n招待されたルームをインポートしています @@ -1405,10 +1405,10 @@ \nサーバーからの応答を待っています… 空のルーム(%sでした) - %1$sと%2$sと%3$sと%4$dなど + %1$s、%2$s、%3$sと他%4$d人 - %1$sと%2$sと%3$sと%4$s - %1$sと%2$sと%3$s + %1$s、%2$s、%3$sと%4$s + %1$s、%2$sと%3$s %1$sの権限レベルを%2$sから%3$sへ変更しました。 %1$sが あなたは @@ -1424,7 +1424,7 @@ %1$sがビデオ会議を開始しました %1$sがビデオ会議を開始しました %1$sウィジェットを変更しました - %1$sは%2$sウィジェットを変更しました + %1$sが%2$sウィジェットを変更しました %1$sウィジェットを削除しました %1$sが%2$sウィジェットを削除しました %1$sウィジェットを追加しました @@ -2487,7 +2487,7 @@ 制限は不明です。 サーバーのファイルアップロードの制限 自分の会話は、自分のものに。 - %1$sは、このルームを招待者のみ参加可能に設定しました。 + %1$sが、このルームを、招待者のみ参加可能に設定しました。 %1$sが部屋をリンクを持っているユーザーにアクセスできるように設定しました。 選択したメッセージをネタバレとして送信 ${app_name} がエンドツーエンド暗号鍵をディスクに保存する許可を要求しています。 @@ -2552,8 +2552,8 @@ 最近のルーム 新しいセッションが認証されました。セッションは暗号化されたメッセージにアクセスでき、他のユーザーには信頼済として表示されます。 いったん有効にすると、暗号化を無効にすることはできません。 - この部屋を同じホームサーバー上で組織内のチームとのコラボレーションにのみ使用するなら、このオプションを有効にするといいかもしれません。これは後から変更できません。 - %sに属していないユーザーによるこの部屋への参加を今後永久的に拒否する + このルームを同じホームサーバー上で組織内のチームとのコラボレーションにのみ使用するなら、このオプションを有効にするといいかもしれません。これは後から変更できません。 + %sに属していないユーザーによるこのルームへの参加を、今後永久的に拒否 プレーンテキストメッセージの前に ( ͡° ͜ʖ ͡°) を付ける このメールアドレスのドメインの登録は許可されていません スペースを作成しています… @@ -2578,13 +2578,13 @@ 既存のサーバーに参加しますか? この質問をスキップ 友達と家族 - %1$sは、これを招待者のみ参加可能に設定しました。 + %1$sがこれを招待者のみ参加可能に設定しました。 メッセージを送信できませんでした ウィジェットを開く %1$sに転送 通話は終了しました 自分自身にダイレクトメッセージを送信することはできません! - %1$sは通話を開始しました + %1$sが通話を開始しました 通話を開始しました 電話番号(任意) 電話番号を確認 From 04225de7ef9fc5094d744b0d7a69d79dec3575f8 Mon Sep 17 00:00:00 2001 From: oksya8and8 Date: Sun, 20 Feb 2022 19:44:22 +0000 Subject: [PATCH 239/302] Translated using Weblate (Japanese) Currently translated at 91.3% (2543 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index cb5207b4bb..e4bdb3c692 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -734,9 +734,9 @@ 可能であれば、英語で説明文を記述してください。 音声を送信 スタンプを送信 - 使用可能なスタンプパックがありません。 + 現在、有効なスタンプパックがありません。 \n -\n追加しますか? +\nいくつか追加しますか? 続行する… 申し訳ありません、この操作を完了するための外部アプリが見つかりません。 あなたの他のセッションに暗号鍵を再要求する。 From aed16d0d9ee0316f120c8edb03ff2752c3db6726 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Sun, 20 Feb 2022 19:43:18 +0000 Subject: [PATCH 240/302] Translated using Weblate (Japanese) Currently translated at 91.3% (2543 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index e4bdb3c692..ebb15f50ee 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -116,7 +116,7 @@ 会話 公開されたルームがありません - %d名 + %d名のユーザー 不具合を報告 不具合の内容と状況の説明をお願いします。何をしましたか?何が起こるべきでしたか?実際に起こった事象は何でしょうか? @@ -126,7 +126,7 @@ ログを送信 開発者が問題を診断するために、このクライアントのログがバグレポートと一緒に送信されます。バグレポートは、ログとスクリーンショットを含めて、公開されることはありません。上記の説明文だけを送信したい場合は、以下のチェックを解除してください。 あなたは不満で端末を振っているようです。バグレポートの画面を開きますか? - 前回アプリケーションは正常に停止しませんでした。クラッシュ報告の画面を開きますか? + 前回、アプリケーションは正常に停止しませんでした。クラッシュ報告の画面を開きますか? 不具合を報告しました 不具合の報告の送信に失敗しました (%s) ルームに参加 @@ -358,7 +358,7 @@ 権限が無いため、一部の機能を利用できない可能性があります… このルームで会議を開始するためには招待の権限が必要です とにかく送る - ログアウト + サインアウト ホーム 会話なし 端末の電話帳を${app_name}アプリが読み取ることは許可されていません @@ -1034,7 +1034,7 @@ 暗号化が有効になっていません 通知設定 切断 - ログアウトしますか? + サインアウトしてよろしいですか? 既読にする コピー 成功 @@ -1072,7 +1072,7 @@ 元の大きさのまま画像を送信 - 自分自身には通話できません + 自分に電話をかけることはできません マークダウン書式 メッセージ送信前にマークダウン書式を適用します。これにより、アスタリスクを使用して斜体のテキストを表示するなどの高度な書式設定が利用できます。 音声とビデオ @@ -1118,7 +1118,7 @@ 相手ユーザーの端末のコードをスキャンし、相互に安全性を検証 相手のコードをスキャン スキャンできません - 断る + 拒否 認証の要求 通話の開始前に確認 意図しない通話を防止 @@ -1140,7 +1140,7 @@ ヘッドセット スピーカー 電話 - サウンド端末を選択 + サウンドデバイスを選択 リアルタイム接続を確立できませんでした。 \nホームサーバーの管理者に、通話が正常に動作するためにTURNを設定するようご連絡ください。 再び表示しない @@ -1265,7 +1265,7 @@ フォールバックコールアシストサーバーを許可 有効な認証情報がないため、権限がありません ${app_name} 呼び出し失敗 - 通話が確実に機能させるためには、ホームサーバー(%1$s)の管理者にTURNサーバーの設定を依頼してください。 + 確実に通話できるようにするためには、ホームサーバー(%1$s)の管理者にTURNサーバーの設定を依頼してください。 \n \n代わりに、%2$sのパブリックサーバーを使用することもできますが、信頼性は低く、あなたのIPアドレスがそのサーバーと共有されてしまいます。これは設定から管理することができます。 ルームディレクトリの全てのルームを表示(露骨なコンテンツのあるルームを含む)する。 @@ -1275,7 +1275,7 @@ 戻る 非公開 切り替える - 加える + 追加 %1$sがエンドツーエンド暗号化(認識されていないアルゴリズム %2$s)をオンにしました。 エンドツーエンド暗号化(認識されていないアルゴリズム %1$s)をオンにしました。 会話を始める From ebcb9faf53e759796d249d3305f39c4920050983 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Mon, 21 Feb 2022 10:53:18 +0000 Subject: [PATCH 241/302] Translated using Weblate (Japanese) Currently translated at 91.4% (2546 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index ebb15f50ee..dee4549787 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2804,4 +2804,5 @@ 絵文字を比較して検証 対面でない場合は、代わりに絵文字を比較してください あなたのホームサーバーは、最大%sのサイズの添付ファイルを受け付けています。 + 新しいパスワードを確認するには下記のリンクを開いてください。リンク先のリンクにアクセスしてから、この下をクリックしてください。 \ No newline at end of file From 9ff6e9e1b76ad425577af1e34032c7351815c847 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Mon, 21 Feb 2022 10:49:59 +0000 Subject: [PATCH 242/302] Translated using Weblate (Japanese) Currently translated at 91.4% (2546 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 331 +++++++++++----------- 1 file changed, 168 insertions(+), 163 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index dee4549787..c43dfd3d10 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -140,20 +140,20 @@ ファイルを送信 ログイン画面へ戻る 電話番号 - 電話番号 (任意で) + 電話番号(任意) ユーザー名かパスワードが正しくありません ユーザー名は半角英数字、ドット、ハイフン、アンダースコアのみで記して下さい - パスワードが短すぎます(最小6文字) + パスワードが短すぎます(最小6文字) 正しくないメールアドレスのようです 正しくない電話番号のようです - 既に登録されている電子メールアドレスです。 + 既に登録されているメールアドレスです。 パスワードが一致しません パスワードを忘れましたか? - 登録を続行するには電子メールを確認して下さい - URLはhttp://か、https://で始めて下さい - ログインできません:通信エラー + 登録を続行するにはメールボックスを確認して下さい + URLはhttp://かhttps://で始めて下さい + ログインできません:通信エラー ログインできません - 登録できません:通信エラー + 登録できません:通信エラー 登録できません 正しいURLを入力して下さい ユーザー名かパスワードが正しくありません @@ -161,8 +161,8 @@ 大き目 中程度 小さ目 - ダウンロードを停止しますか? - アップロードを停止しますか? + ダウンロードをキャンセルしますか? + アップロードをキャンセルしますか? %d秒 %1$d分%2$d秒 昨日 @@ -172,7 +172,7 @@ 呼び出し中です… はい いいえ - 続ける + 続行 最新の未読へ移動 ルームを退出 このルームを退出してよろしいですか? @@ -186,7 +186,7 @@ %sさんが文字を入力しています… %1$sさんと%2$sさんが文字を入力しています… %1$sさん、%2$sさん他が文字を入力しています… - 暗号文を送信… + 暗号化されたメッセージを送信… 明るいテーマ 暗いテーマ 黒いテーマ @@ -210,10 +210,10 @@ メンバーを追加 1名 セッション - 権限を一般メンバーへ変更 - 権限を司会者へ変更 + 権限を一般ユーザーへ戻す + 権限をモデレーターへ変更 権限を管理者へ変更 - ここに送信文を入力 (暗号なし)… + メッセージを送信(暗号化されていません)… サーバーとの接続が失われました。 全て再送信 未送信のメッセージを再送信 @@ -227,11 +227,11 @@ お気に入り 低優先度 対話 - 忘れる + 履歴を消去 自分のアイコン画像 表示名 - 電子メール - 電子メールアドレスを追加 + メールアドレス + メールアドレスを追加 電話番号 電話番号を追加 通知音 @@ -241,21 +241,21 @@ グループチャットでのメッセージ ルームへ招待されたとき 通話の呼び出しがあったとき - 自動発言プログラム(Bot)が発言した時 + 自動発言プログラム(Bot)が発言した時 端末起動時に開始 アプリを閉じているときの動作 - アプリを閉じても新着を確認 - 新着確認を失敗とするまでの時間 - リクエストの間隔 + バックグラウンド同期を有効にする + 同期のリクエストを失敗とするまでの時間 + 同期の間隔 一時保存を消去 - 画像等の一時保存を消去 - 画像等を一時保存する期間 - 利用者設定 + メディアの一時保存を消去 + メディアファイルを保存 + ユーザー設定 通知 無視しているユーザー その他 拡張設定 - 暗号化 + 暗号 通知対象 端末の電話帳 端末の電話帳の使用を許可 @@ -279,7 +279,7 @@ 端末操作表示 認証を確認中 電子メールを確認して、本文中のURLをクリックしてください。 完了したら「続ける」をクリックしてください。 - この電子メールアドレスは既に使われています。 + このメールアドレスは既に使われています。 あなたのパスワードは更新されました 国を選択 @@ -287,7 +287,7 @@ 電話番号 選択した国では、この電話番号は正しくありません 電話認証 - SMSで認証番号を送りました. 以下にその番号を入力してください. + SMSで認証番号を送りました。以下にその番号を入力してください。 認証番号を入力 3日 1週間 @@ -352,12 +352,12 @@ 音声通話を開始 ビデオ通話を開始 写真または動画を撮影 - 初期化メール送信 - 写真撮影やビデオ通話には, ${app_name}アプリに端末のカメラの使用を許可する必要があります. + 再設定用のメールを送信 + 写真撮影やビデオ通話には、${app_name}端末のカメラの使用を許可する必要があります。 通話を開始できませんでした。後ほど試してください 権限が無いため、一部の機能を利用できない可能性があります… このルームで会議を開始するためには招待の権限が必要です - とにかく送る + 無視して送る サインアウト ホーム 会話なし @@ -373,41 +373,41 @@ アカウントを作成 送信 飛ばす - ユーザー名または電子メール + ユーザー名またはメールアドレス パスワード 新しいパスワード ユーザー名 - 電子メールアドレス - 電子メールアドレス (任意で) + メールアドレス + メールアドレス(任意) パスワード再確認 新しいパスワードを再確認 パスワードが入力されていません メールアドレスが入力されていません 電話番号が入力されていません - 電子メールアドレスまたは電話番号が入力されていません + メールアドレスまたは電話番号が入力されていません 接続先サーバーを指定(高度) 不正なトークン メールと電話番号の同時登録はまだシステムが対応できませんが、電話番号だけの登録は可能です。 \n \n設定からプロフィールにメールアドレスを追加できます。 - このホームサーバーはあなたがロボットではない認証を求めます + このホームサーバーは、あなたがロボットではないことの確認を求めています ユーザー名は既に使用されています ホームサーバー: - IDサーバー: + IDサーバー: メールアドレスを認証しました - パスワードを初期化するには, アカウントに登録されている電子メールアドレスを入力してください: - あなたのアカウントに登録されたメールアドレスの入力が必要です。 + パスワードを再設定するには、アカウントに登録されているメールアドレスを入力してください: + アカウントに登録されたメールアドレスの入力が必要です。 新しいパスワードの入力が必要です。 - %sへ電子メールが送信されました. リンクをたどったら以下をクリックしてください. - 電子メールアドレスの確認に失敗しました: 電子メールのリンクをクリックしたことを確認してください + %sへ電子メールが送信されました。リンクをたどったら以下をクリックしてください。 + メールアドレスの確認に失敗しました:電子メールのリンクをクリックしたことを確認してください パスワードがリセットされました。 \n -\n全てのセッションからログアウトしたため、プッシュ通知を受け取れなくなりました。通知を再び有効にするには、各端末で再ログインをお願いします。 +\n全てのセッションがログアウトしたため、プッシュ通知を受け取れなくなりました。通知を再び有効にするには、各端末で再度ログインしてください。 登録できません:メールアドレスの所有権が確認できません 指定されたアクセストークンが認識されませんでした 不正な形式のJSON 有効なJSONを含んでいませんでした - ログイン要求が多すぎてサーバーが対応できません + ログイン要求が多すぎます まだクリックされていない電子メールのリンク 以下の容量で画像を送信 ルームの説明 @@ -422,35 +422,35 @@ 他の端末で通話に応答しました 写真または動画の撮影 動画を記録できません - 保存 + 保存済 プレビュー 拒否 管理者権限操作 通話 ダイレクトメッセージ - 再入室禁止 - 再入室禁止解除 - このメンバーの発言を全て非表示 + ブロック + ブロックを解除 + この参加者の発言を全て非表示 このメンバーの発言を全て表示 - 指名して呼掛け - ユーザーID, 表示名, 電子メールアドレス + メンション + ユーザーID、名前、メールアドレス セッション一覧を表示 %sさんをこのルームに招待してよろしいですか? ユーザーIDで招待 - メールアドレスまたはMatrix ID - 全て中止 + メールアドレスかMatrix ID + 全てキャンセル ログアウト 無視 招待中 参加者 - メンバーを検索 - 結果なし + ルームのメンバーを絞り込む + 結果がありません 参加者 ファイル ルーム ディレクトリを見る 会話から退出 - 会話 + メッセージ 設定 バージョン 利用規約 @@ -472,7 +472,7 @@ パスワードの更新に失敗しました %sの全てのメッセージを表示しますか? \n -\nこの操作はアプリを再起動するため時間がかかる場合があります。 +\nこの操作はアプリを再起動するため、時間がかかる場合があります。 電話番号の認証時にエラーが発生しました このルームへのリンクを作成するには、アドレスが必要です。 このルームは暗号化されています。 @@ -499,19 +499,19 @@ Matrixの連絡先のみ 通信先が通話の受取に失敗しました。 情報 - ${app_name}は添付ファイルを送信および保存するために写真とビデオライブラリにアクセスするための許可が必要です。 + ${app_name}は、添付ファイルを送信および保存するために、写真とビデオライブラリにアクセスするための許可を必要としています。 \n -\nあなたの端末からファイルを送信できるようにするには、次のポップアップでアクセスを許可してください。 +\n端末からファイルを送信できるようにするには、次のポップアップでアクセスを許可してください。 " \n -\n通話をするには、次のポップアップでアクセスできるように設定してください。" - ${app_name}アプリは、音声通話を実行するためにマイクへアクセスするための許可が必要です。 +\n通話をするためには、次のポップアップでアクセスを許可してください。" + ${app_name}は、音声通話を実行するためにマイクへアクセスするための許可を必要としています。 " \n \n通話をするためには、次のポップアップでアクセスを許可してください。" ${app_name}はビデオ通話を行うためにカメラとマイクにアクセスする許可を必要としています。 \n -\n次のポップアップでアクセスを許可して通話ができるようにしてください。 +\n通話をするためには、次のポップアップでアクセスを許可してください。 ${app_name}では、あなたの端末の電話帳のメールアドレスや電話番号をもとに、他のユーザーを検索することができます。${app_name}による電話帳の検索を許可する場合は、次のポップアップでアクセスを許可してください。 ${app_name}はあなたの電話帳のメールアドレスや電話番号をもとに他のユーザーを見つけることができます。 \n @@ -559,13 +559,13 @@ 通知あり(サイレント) 不具合の報告 開封確認メッセージのリスト - ダウンロードファイルに保存しますか? - この招待はこのアカウントに関連付けられていない%sに送信されました。 + ダウンロードフォルダーに保存しますか? + この招待は、このアカウントに関連付けられていない%sに送信されました。 \n別のアカウントでログインするか、このメールを自分のアカウントに追加してください。 %sにアクセスしようとしています。ディスカッションに参加しますか? ルーム これはルームのプレビューです。ルームでのやり取りは無効化されています。 - このユーザーにあなたと同じ権限を与えますが、この変更は取り消せません。 + このユーザーにあなたと同じ権限を与えます。この変更は取り消せません。 \nよろしいですか? 端末の連絡先 (%d) ユーザーディレクトリ (%s) @@ -574,25 +574,25 @@ メールアドレスかMatrix IDを入力してください 信用する 信用しない - フィンガープリント (%s): + フィンガープリント(%s): リモートサーバーのIDを確認できませんでした。 - 誰かが不当にあなたの通信を傍受しているか、リモートサーバーの証明書をあなたの電話が信用していない可能性があります。 - サーバーの管理者が、これは想定されていることであると言っているのであれば、以下のフィンガープリントが管理者によるフィンガープリントと一致していることを確認してください。 - 証明書はあなたの電話に信頼されていたものから変更されています。これはきわめて異常な事態です。この新しい証明書を承認しないことを強く推奨します。 - 証明書は以前信頼されていたものから信頼されていないものへと変更されています。サーバーがその証明書を更新した可能性があります。予測されるフィンガープリントを取得するために、サーバーの管理者に連絡してください。 + 誰かが不当にあなたの通信を傍受しているか、あなたの電話がリモートサーバーの証明書を信用していない可能性があります。 + サーバーの管理者が、これは想定されていることであると言っているのであれば、以下のフィンガープリントが、管理者によるフィンガープリントと一致していることを確認してください。 + 証明書はあなたの電話により信頼されていたものから変更されています。これはきわめて異常な事態です。この新しい証明書を承認しないことを強く推奨します。 + 証明書は以前信頼されていたものから信頼されていないものへと変更されています。サーバーがその証明書を更新した可能性があります。サーバーの管理者に連絡して、適切なフィンガープリントを確認してください。 サーバーの管理者が上のフィンガープリントと一致するものを発行した場合に限り、証明書を承認してください。 不正な形式のIDです。メールアドレスまたは\'@localpart:domain\'という形式のMatrix IDを入力してください このコンテンツを報告する理由 このユーザーによる全てのメッセージを非表示にしますか? \n -\nこの操作はアプリを再起動するため時間がかかる場合があります。 +\nこの操作はアプリを再起動するため、時間がかかる場合があります。 アップロードをキャンセル ダウンロードをキャンセル 検索 メッセージ ディレクトリを検索しています… サードパーティーの使用に関する掲示 - このアプリの情報をシステム設定で表示する。 + このアプリの情報をシステム設定で表示。 アプリの情報 自分の表示名を含むメッセージ 自分のユーザー名を含むメッセージ @@ -600,8 +600,8 @@ olmのバージョン サードパーティーの使用に関する掲示 ホーム画面 - 逃した通知があるルームをピン止め - 未読のあるルームをピン止め + 逃した通知があるルームを固定 + 未読のあるルームを固定 分析 データ節約モード メールアドレスを認証できません。メールを確認して、そこに記載してあるリンクをクリックしてください。その後、「続ける」をクリックしてください。 @@ -656,8 +656,8 @@ 音声通話を開始してよろしいですか? ビデオ通話を開始してよろしいですか? グループリスト - ユーザーをブロックすると、ユーザーはこのルームから削除され、二度と参加できなくなります。 - 全てのメッセージ (音量大) + ユーザーをブロックすると、ユーザーはこのルームから追放され、二度と参加できなくなります。 + 全てのメッセージ(音量大) 全てのメッセージ ミュート ホーム画面にショートカットを作成 @@ -695,27 +695,27 @@ 再参加 端末を振って不具合を報告 - %dメンバーシップの変更 + %d個のメンバーシップの変更 メンバーを表示 見出しを開く 同期しています… - %d名のメンバー + %d名のアクティブなメンバー - %d名 + %d名のメンバー %d件の新しいメッセージ - %dルーム + %d個のルーム - %2$sに%1$sルーム見つかりました + %2$sに%1$s個のルームが見つかりました - ルームの履歴を消す + ルームの履歴を消去 アバター メンションのみ 通知のプライバシー @@ -734,7 +734,7 @@ 可能であれば、英語で説明文を記述してください。 音声を送信 スタンプを送信 - 現在、有効なスタンプパックがありません。 + 現在、有効なステッカーパックがありません。 \n \nいくつか追加しますか? 続行する… @@ -760,16 +760,16 @@ "%1$s、 " %1$sと%2$s %1$s %2$s - 暗号化された返信を送信… - 返信を送る(未暗号化)… + 暗号化された返信を送る… + 返信を送る(暗号化されていません)… %d個選択済 低プライバシー - • 通知中のメッセージの内容は Matrixのホームサーバーから直接安全に入手しています - ・通知は メタデータとメッセージのデータ を含みます - • 通知は メッセージの内容を表示しません - ユーザーの名前をあげるときバイブレーションで通知 + • 通知中のメッセージの内容はMatrixのホームサーバーから直接安全に入手しています + ・通知はメタデータとメッセージのデータを含みます + • 通知はメッセージの内容を表示しません + ユーザーをメンションするとき、バイブレーションで通知 送信の前にメディアをプレビュー アカウントを停止 自分のアカウントを停止 @@ -798,7 +798,7 @@ 必要な変数が見つかりません。 変数が無効です。 - メッセージを送信するには、キーボードのエンターキーを押してください + メッセージを送信するには、キーボードのEnterキーを押してください ボイスメッセージを送信 動作を表示 指定したIDのユーザーをブロック @@ -827,10 +827,10 @@ アカウントを停止 この操作により、あなたのアカウントは永久に使えなくなります。あなたはログインできなくなり、誰も同じユーザーIDを再登録できなくなります。アカウントが参加している全てのルームを退出し、IDサーバーからアカウントの詳細は削除されます。 この操作は取り消せません。 \n -\nアカウントを停止しても、 デフォルトではあなたが送信したメッセージは忘却されません。メッセージの忘却を望む場合は、以下のボックスにチェックを入れてください。 +\nアカウントを停止しても、 デフォルトではあなたが送信したメッセージの履歴は消去されません。メッセージの履歴の消去を望む場合は、以下のボックスにチェックを入れてください。 \n -\nMatrixのメッセージの可視性は、電子メールと同様のものです。メッセージを忘却すると、あなたが送信したメッセージは、新規または未登録のユーザーには共有されることはありませんが、既にメッセージを取得している登録ユーザーは、今後もそのコピーにアクセスできます。 - アカウントを停止したとき自分の送信した全てのメッセージを削除(警告: この操作により、今後のユーザーは会話を不完全な形で見ることになります) +\nMatrixのメッセージの見え方は、電子メールと同様のものです。メッセージの履歴を消去すると、あなたが送信したメッセージは、新規または未登録のユーザーには共有されることはありませんが、既にメッセージを取得している登録ユーザーは、今後もそのコピーにアクセスできます。 + アカウントを停止したときに、自分の送信した全てのメッセージの履歴を消去してください(警告: この操作により、今後のユーザーは会話を不完全な形で見ることになります) 続けるには、パスワードを入力してください: アカウントを停止 パスワードを入力してください。 @@ -865,14 +865,14 @@ 展開 畳む メッセージとエラーの場合 - とにかく通話 + 無視して通話 承諾 このホームサーバーの方針を確認し承諾してください: 通話設定画面 着信に${app_name}の既定の着信音を使用 着信音 着信音を選んでください: - 追い出す + 会話から追放 理由 サービスを初期化しています 鍵のバックアップ @@ -890,13 +890,13 @@ バックグラウンド同期を行わない 優先同期間隔 %s -\n同期は、端末のリソース (バッテリ残量) または状態 (スリープ) に応じて延期される場合があります。 +\n同期は、端末のリソース (バッテリーの残量)または状態(スリープ)に応じて延期される場合があります。 入力中通知を送信 文字入力中であることを他のメンバーに伝えます。 開封確認メッセージを表示 - 開封確認メッセージをクリックすると詳細なリストを確認できます。 - エンター入力でメッセージを送信 - ソフトウェアキーボードのEnterボタンを押した際、改行せずメッセージを送信 + 開封確認メッセージをクリックすると、詳細な一覧を確認できます。 + Enterキーでメッセージを送信 + ソフトウェアキーボードのEnterボタンを押すと、改行の代わりにメッセージを送信 パスワード パスワードを更新 パスワードが無効です @@ -934,7 +934,7 @@ システム設定。 アカウント設定。 カスタム設定。 - 起動時の実行 + 起動時に実行 バックグラウンド制限の確認 とどまる 編集 @@ -1098,7 +1098,7 @@ システム設定で通知は有効化されています。 バッテリー最適化 - %d 秒 + %d秒 拡張設定 現在の言語 @@ -1106,7 +1106,7 @@ メッセージエディタ 環境設定 この端末で設定 - セキュアバックアップをリセット + セキュアバックアップを再設定 セキュアバックアップを設定 管理 セキュアバックアップ @@ -1122,9 +1122,9 @@ 認証の要求 通話の開始前に確認 意図しない通話を防止 - お使いの端末は脆弱性のある古いTLSセキュリティープロトコルを使用しています、このセキュリティーでは接続できません + お使いの端末は、脆弱性のある古いTLSセキュリティープロトコルを使用しています。セキュリティーの観点から、接続することはできません SSLエラー。 - SSLエラー:相手のアイデンティティが認証されていません。 + SSLエラー:相手のIDが認証されていません。 このURLからホームサーバーに接続できませんでした、ご確認ください 有効なMatrixサーバーのアドレスではありません このURLは検索結果に表示できません、ご確認ください @@ -1187,8 +1187,8 @@ \n%1$s Firebaseトークン Playサービスを修正 - GooglePlayサービスAPKは利用可能で最新の状態になっています。 - Playサービスチェック + Google PlayサービスのAPKは利用可能で最新の状態になっています。 + Playサービスのチェック 設定を確認 カスタムルールの読み込みに失敗しました。再試行してください。 一部の通知はカスタム設定で無効になっています。 @@ -1204,7 +1204,7 @@ %sを削除しますか? 認証が必要です パスワードを確認 - 暗号化されたルームでの検索はまだサポートされていません。 + 暗号化されたルームでの検索は、まだサポートされていません。 ブロックされたユーザーを絞り込む トピックを変更 ルームをアップグレード @@ -1219,48 +1219,48 @@ 全員への通知 他の人から送信されたメッセージの削除 ユーザーのブロック - ユーザーの除去 + ユーザーの追放 設定の変更 ユーザーの招待 メッセージの送信 - デフォルトルール + 既定の役割 ルームに関する変更を行うために必要な役割を更新する権限がありません ルームに関する変更を行うために必要な役割を選択 ルームの権限 権限 ルームに関する変更を行うために必要な役割を表示し更新します。 - ブロックを解除すると、ユーザーは再びルームに参加できるようになります。 - 禁止されたユーザー - 禁止の理由 + ブロックを解除すると、ユーザーはルームに再び参加できるようになります。 + ユーザーをブロック + ブロックする理由 ユーザーのブロックを解除 - このユーザーはルームから除去されます。 + このユーザーはルームから追放されます。 \n -\n再参加を防ぐためには、除去する代わりにブロックする必要があります。 - 除去の理由 - ユーザーを除去 +\n再参加を防ぐためには、追放する代わりにブロックする必要があります。 + 追放する理由 + ユーザーを追放 このユーザーの招待をキャンセルしてよろしいですか? 招待をキャンセル このユーザーを解除すると、そのユーザーからの全てのメッセージが再び表示されます。 ユーザーを無視しない このユーザーを無視すると、あなたが共有しているルームからそのユーザーのメッセージが削除されます。 \n -\nこの動作は、設定からいつでも元に戻すことができます。 +\nこの操作は、設定からいつでも元に戻すことができます。 ユーザーを無視 降格 - あなたは自分自身を降格させようとしているため、今後、この変更を元に戻すことはできなくなります。あなたがルームの中で最後の特権ユーザーである場合、特権を再取得することはできません。 + あなたは自分自身を降格させようとしています。この変更は取り消せません。あなたがルームの中で最後の特権ユーザーである場合、特権を再取得することはできません。 降格しますか? 招待をキャンセル このルームは公開されていません。 招待がなければ再び参加することはできません。 - このアクションを実行するには、設定にIDサーバーを追加してください。 + この操作を実行するには、設定にIDサーバーを追加してください。 連絡先へのアクセスを許可します。 QRコードをスキャンするには、カメラへのアクセスを許可する必要があります。 通話をかけました %sが通話をかけました - かける - コールし直す + 保留 + 通話に戻る 通話をやり直す アクティブな通話(%s) - あなたのホームサーバーがアシスト機能を提供しない場合、代わりに%sを使用します(IPアドレスは通話中に共有されます) + あなたのホームサーバーがアシスト機能を提供しない場合、代わりに%sを使用します(IPアドレスが通話中に共有されます) ビデオ通話が行われています… フォールバックコールアシストサーバーを許可 有効な認証情報がないため、権限がありません @@ -1457,23 +1457,23 @@ サーバー上の暗号鍵をバックアップすることにより、暗号化されたメッセージとデータへのアクセスが失われるのを防ぎます。 メッセージ作成画面に絵文字キーボードを開くボタンを追加 絵文字キーボードを表示 - アバターと表示名の変更が含まれます。 - アカウントイベントを表示 + アバターと表示名の変更を含む。 + アカウントのイベントを表示 招待、削除、ブロックは影響を受けません。 - 招待/参加/退出/削除/禁止イベントや、アバター/表示名の変更などを含む。 + 招待/参加/退出/追放/ブロックに関するイベントや、アバター/表示名の変更などを含む。 参加・退出イベントを表示 /confettiコマンドを使用するか、❄️または🎉を含むメッセージを送信 チャットでエフェクトを表示 ルームのメンバーのイベントを表示 ホームサーバーがこの機能をサポートしている場合は、チャット内のリンクをプレビューします。 ボット、ブリッジ、ウィジェット、ステッカーパックの管理をします。 -\nユーザーに代わり、構成データを受信しウィジェットを変更、ルーム招待の送信、権限の設定などができます。 +\nインテグレーションマネージャーは、構成データを受信し、ユーザーに代わってウィジェットの変更、ルーム招待の送信、権限の設定などを行うことができます。 設定の更新に失敗しました。 インテグレーション(統合) アプリがバックグラウンドにある場合、着信メッセージは通知されません。 ${app_name}は正確な時間に定期的にバックグラウンドで同期します(構成可能)。 -\nこれはラジオとバッテリーの使用量に影響し$ {app_name}がイベントをリッスンしていることを示す永続的な通知が表示されます。 - ${app_name}は、端末の限られたリソース(バッテリー)を維持する方法でバックグラウンド同期をします。 +\nこれは無線とバッテリーの使用量に影響し、$ {app_name}がイベントを待機していることを示す永続的な通知が表示されます。 + ${app_name}は、端末の限られたリソース(バッテリーの残量)を維持する方法でバックグラウンド同期をします。 \n端末の状態によっては、OSによって同期が延期される場合があります。 LEDの色、振動、音を選択してください… 通知(サイレント)を設定 @@ -1482,14 +1482,14 @@ アプリはバックグラウンドでホームサーバーに接続する必要がないためバッテリー使用量を減らすことができます 最適化を無視 画面をオフにした状態で端末のプラグを抜いて一定時間静止したままにすると、端末は機内モードになります。 これにより、アプリがネットワークにアクセスできなくなり、ジョブ、同期、および標準のアラームが防止されます。 - ${app_name}に対してバックグラウンド制限が有効になっています。 -\nアプリがバックグラウンドで実行しようとすると積極的に制限され、通知に影響を与える可能性があります。 + ${app_name}のバックグラウンド制限が有効になっています。 +\nアプリがバックグラウンドで実行しようとする作業が積極的に制限されるため、通知に影響を与える可能性があります。 \n%1$s - ${app_name}のバックグラウンド制限は無効になっています。 このテストは、モバイル(WIFIでない)を使用して実行する必要があります。 + ${app_name}のバックグラウンド制限が無効になっています。 このテストは、モバイル(WIFIでない)を使用して実行する必要があります。 \n%1$s 端末を再起動してもサービスは開始しません。${app_name}を一度開くまで通知は届きません。 - %1$s -\nこのエラーは${app_name}の管理外です。 これはいくつかの理由で発生する可能性があります。 後で再試行すればうまくいくかもしれません。システム設定でGoogle Play Serviceのデータ使用量が制限されていないか、端末の時刻が正しいかどうか、もしくはカスタムROMで起こることがあります。 + [%1$s] +\nこのエラーは${app_name}の管理外です。 これはいくつかの理由で発生する可能性があります。 後で再試行すればうまくいくかもしれません。システム設定でGoogle Playサービスのデータ使用量が制限されていないか、端末の時刻が正しいかどうかを確認してください。カスタムROMで生じることもあります。 ${app_name}モバイルからこれを行うことはできません ${app_name}はバッテリー最適化の影響を受けません。 制限を無効にする @@ -1502,19 +1502,19 @@ 通知をクリックしてください。 通知が表示されない場合は、システム設定を確認してください。 通知を表示 通知を表示しています。 クリックしてください! - プッシュの受信に失敗しました。 解決策は、アプリケーションを再インストールすることです。 - アプリケーションはプッシュを受信しています - アプリケーションはプッシュを待っています - テストプッシュ - FCMトークンのホームサーバーへの登録に失敗しました。: + プッシュ通知の受信に失敗しました。 アプリケーションを再インストールすれば解決するかもしれません。 + アプリケーションはプッシュ通知を受信しています + アプリケーションはプッシュ通知を待っています + プッシュ通知のテスト + FCMトークンのホームサーバーへの登録に失敗しました: \n%1$s FCMトークンのホームサーバーへの登録が成功しました。 トークンの登録 アカウントを追加 [%1$s] -\nこのエラーは、${app_name}の管理外です。このスマートフォンにはGoogleアカウントが登録されていません。アカウントマネージャーを開いて、Googleアカウントを追加してください。 - %1$s -\nこのエラーは${app_name}の管理外であり、Googleによると、このエラーは、端末にFCMに登録されているアプリが多すぎることを示しています。 このエラーは、アプリの数が極端に多い場合にのみ発生するため、平均的なユーザーには影響しません。 +\nこのエラーは${app_name}の管理外です。このスマートフォンにはGoogleアカウントが登録されていません。アカウントマネージャーを開いて、Googleアカウントを追加してください。 + [%1$s] +\nこのエラーは${app_name}の管理外です。Googleによると、このエラーは、FCMに登録されている端末上のアプリの数が多すぎることを示唆しています。 このエラーは、アプリの数が極端に多い場合にのみ発生するため、平均的なユーザーには影響しません。 ${app_name}はGoogle Playサービスを使用してプッシュメッセージを配信していますが、正しく設定されていないようです: \n%1$s FCMトークンの取得に失敗しました: @@ -1582,7 +1582,7 @@ Eメールで招待 詳細 連絡先を招待 - とにかく参加 + 無視して参加 ルームを追加 %sはあなたを招待しています このルームでグループ通話を開始する権限がありません @@ -1718,7 +1718,7 @@ 既に一覧に載っているサーバーです サーバーまたはそのルーム一覧が見つかりません - 検索される新しいサーバーの名前を入力します。 + 検索したい新しいサーバーの名前を入力してください。 新しいサーバーを追加 あなたのサーバー 暗号化されたメッセージの復元 @@ -1788,7 +1788,7 @@ 次に ユーザー名で招待 ユーザー名を選択してください。 - ユーザー名やパスワードが正しくありません。 入力したパスワードは、スペースで開始または終了しますので、ご確認ください。 + ユーザー名やパスワードが正しくありません。 入力したパスワードは、スペースで開始または終了していますので、ご確認ください。 そのユーザー名は既に使用されています ユーザー名 ユーザー名または電子メール @@ -1883,7 +1883,7 @@ ルームに参加してアプリの使用を開始します。 リトライ 他のホームサーバーに接続しようとしているようですね。サインアウトしますか? - IDサーバーが設定されていない場合は、パスワードの再設定が必要となります。 + IDサーバーが設定されていない場合は、パスワードを再設定する必要があります。 IDサーバーを使用していません 不明なエラー ユーザーの不一致 @@ -1920,7 +1920,7 @@ 検証を開始します 最大限のセキュリティーを確保するために、これを行うか、別の信頼できる通信手段を用いることをお勧めします。 短い文字列を比較して検証します。 - 認証が無効または期限切れのため、ログアウトされました。 + 認証情報が不正または期限切れのため、ログアウトされました。 構成を使用 ${app_name}がuserIdドメイン\"%1$s\"のカスタムサーバー構成を検出しました。 \n%2$s @@ -1947,7 +1947,7 @@ デフォルトの圧縮 ルームのアップグレード ボットによるメッセージ - ルーム招待 + ルームへの招待 \@roomを含むメッセージ ルームがアップグレードされたとき 暗号化されたグループメッセージ @@ -1963,10 +1963,10 @@ メンションとキーワード 通知のデフォルト - %d ビデオ通話できません + %d個の不在着信(ビデオ) - %d 通話できません + %d個の不在着信(音声) デフォルトで使いもう尋ねない 鍵の共有リクエストの履歴を送信 @@ -1975,8 +1975,8 @@ ミーティングはJitsiのセキュリティーとパーミッションポリシーを使用します。会議中は、現在ルームにいる全ての人に招待状が表示されます。 権限がありません 音声メッセージを送信するには、マイクの権限を許可してください。 - この動作を行うには、システム設定からカメラの権限を許可してください。 - このアクションを実行するには、いくつかの権限が不足しています。システム設定から権限を付与してください。 + この操作を実行するには、システム設定からカメラの権限を許可してください。 + この操作を実行するための権限が不足しています。システム設定から権限を付与してください。 IDサーバーに接続できませんでした IDサーバーのURLを入力 連絡先を発見するために、あなたの連絡先のデータ(電話番号や電子メール)を、設定されたIDサーバー(%1$s)に送信することを承認しますか? @@ -2037,9 +2037,9 @@ アドレス 継続 ファイル - このユーザーはスペースから除去されます。 + このユーザーはスペースから追放されます。 \n -\n再参加を防ぐためには、除去する代わりにブロックする必要があります。 +\n再参加を防ぐためには、追放する代わりにブロックする必要があります。 通話を終了しています… 通知を待機しています \@room @@ -2056,13 +2056,13 @@ %sとのビデオ通話 呼び出しています… ホームサーバーを選択 - %sのURLにあるホームサーバーに接続できません。リンクをチェックするか、手動でホームサーバーを選択してください。 + %sのURLにあるホームサーバーに接続できません。リンクを確認するか、手動でホームサーバーを選択してください。 後で スペース スレッドから 参加している全スレッドを表示 現在のルームのスレッドを全て表示 - ユーザーをブロックすると、ユーザーはこのスペースから削除され、二度と参加できなくなります。 + ユーザーをブロックすると、ユーザーはこのスペースから追放され、二度と参加できなくなります。 PINコードを有効にする これを招待者のみ参加可能に設定しました。 ルームの設定 @@ -2076,7 +2076,7 @@ 全てのスレッド ユーザーを自動的に招待 ユーザー - このユーザーのブロックを解除すると、そのユーザーはスペースに再び参加できるようになります。 + ブロックを解除すると、ユーザーはスペースに再び参加できるようになります。 このルームを招待者のみ参加可能に設定しました。 低優先度から削除 低優先度に追加 @@ -2202,8 +2202,8 @@ スペースのアバターの変更 投票を作成 投票を作成 - 暗号化が正しく設定されていないためメッセージを送ることができません。クリックして設定を開いてください。 - 暗号化が正しく設定されていないためメッセージを送ることができません。管理者に連絡して、暗号化を正しい状態に復元してください。 + 暗号化が正しく設定されていないため、メッセージを送ることができません。クリックして設定を開いてください。 + 暗号化が正しく設定されていないため、メッセージを送ることができません。管理者に連絡して、暗号化を正しい状態に復元してください。 %2$dの%1$d あなたは既にこのスレッドを見ています! ルームに表示 @@ -2303,9 +2303,9 @@ PINコードを変更 PINコードと生体認証でアクセスを保護できます。 アクセスを保護 - PINコードをリセットするには、再ログインして新しいコードを作成してください。 + PINコードを再設定するには、再ログインして新しいコードを作成してください。 新しいPINコード - PINコードをリセット + PINコードを再設定 PINコードを忘れましたか? PINコードを入力 PINコードを確認 @@ -2515,7 +2515,7 @@ Elementの使用に関するヘルプ 詳細なログは、イライラシェイクでログを送信する際に、より多くのログを提供することで、開発者にとっての助けになります。有効にした場合でも、メッセージの内容やその他のプライベートな情報は記録されません。 ルームのアップグレードは高度な作業であり、不具合や欠けている機能、セキュリティー上の脆弱性がある場合に推奨されます。 -\nアップグレードは普通、ルームがサーバー上で処理される仕方にだけ影響します。 +\nアップグレードは通常、ルームがサーバー上で処理される仕方にだけ影響します。 一度有効にしたルームの暗号化は無効にすることはできません。暗号化されたルームで送信されたメッセージは、サーバーからは見ることができず、そのルームのメンバーだけが見ることができます。暗号化を有効にすると、多くのボットやブリッジが正常に動作しなくなる場合があります。 %sして、このルームを皆に紹介しましょう。 このコードを皆と共有し、スキャンして追加してもらい、会話を始めましょう。 @@ -2571,7 +2571,7 @@ どこかのホームサーバーで既にアカウントを登録している場合、以下でMatrix ID(例:@user:domain.com)とパスワードを使用してください。 入力したコードが正しくありません。確認してください。 これは正しいユーザー識別子ではありません。正しいフォーマットは「@user:homeserver.org」です。 - パスワードをお忘れの場合、戻ってパスワードをリセットしてください。 + パスワードをお忘れの場合、戻ってパスワードを再設定してください。 メールボックスを確認してください カスタムサーバーに接続 既にアカウントを持っています @@ -2589,8 +2589,8 @@ 電話番号(任意) 電話番号を確認 電話番号を設定 - パスワードをリセットしました。 - %1$sでパスワードをリセット + パスワードを再設定しました。 + %1$sでパスワードを再設定 Element Matrix Servicesのアドレス %1$sにサインイン 誰と最もよく会話しますか? @@ -2720,7 +2720,7 @@ \nこの端末での使用を終了したり、他のアカウントにサインインしたい場合、このデータをクリアしてください。 この端末に現在保存されているすべてのデータをクリアしますか? \nアカウントデータとメッセージにアクセスするにはもう一度サインインしてください。 - 現在のセッションはユーザー %1$s のものですが、あなたが提供している資格情報はユーザー %2$s のものです。この操作は${app_name}ではサポートされていません。 + 現在のセッションはユーザー %1$s のものですが、あなたが提供している認証情報はユーザー %2$s のものです。この操作は${app_name}ではサポートされていません。 \nまずデータをクリアし、その後、別のアカウントにサインインしてください。 暗号化されたメッセージがどの端末でも読めるように、サインインしてこの端末にのみ保存されている暗号鍵を取り戻してください。 あなたのホームサーバー(%1$s)の管理者があなたを%2$sのアカウントからサインアウトしています。(%3$s) @@ -2745,7 +2745,7 @@ \n \n登録を中止しますか? %1$sにアカウント登録 - あなたはすべてのセッションからログアウトしており、これ以上プッシュ通知を受け取れません。通知をもう一度有効にするには、各端末でサインインしてください。 + あなたはすべてのセッションからログアウトしており、これ以上プッシュ通知を受け取れません。通知を再び有効にするには、各端末でサインインしてください。 セキュリティーフレーズを設定 セキュリティーフレーズを使用 セキュリティーキーは、パスワードマネージャーもしくは金庫のような安全な場所で保管してください。 @@ -2805,4 +2805,9 @@ 対面でない場合は、代わりに絵文字を比較してください あなたのホームサーバーは、最大%sのサイズの添付ファイルを受け付けています。 新しいパスワードを確認するには下記のリンクを開いてください。リンク先のリンクにアクセスしてから、この下をクリックしてください。 + PINコードを再設定するには「PINコードを忘れた」をタップしてログアウトし、その後再設定してください。 + + いま検証できる%d個の端末を表示 + + この操作を実行するには ${app_name}に認証情報を入力する必要があります。 \ No newline at end of file From 2f7856e521ad50d5cc6440160854cc26bcfb2ea6 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Mon, 21 Feb 2022 11:18:11 +0000 Subject: [PATCH 243/302] Translated using Weblate (Japanese) Currently translated at 91.4% (2546 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index c43dfd3d10..44368675b9 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1944,7 +1944,7 @@ スペース %s のメンバーが検索、プレビュー、参加できます。 非公開(招待のみ) デフォルトのメディアソース - デフォルトの圧縮 + 規定圧縮率 ルームのアップグレード ボットによるメッセージ ルームへの招待 From f9be66d017581527a682b7557f9fce12e88dc163 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Mon, 21 Feb 2022 11:17:15 +0000 Subject: [PATCH 244/302] Translated using Weblate (Japanese) Currently translated at 91.4% (2546 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 42 +++++++++++------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 44368675b9..226b1e421e 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -276,7 +276,7 @@ ログイン中のアカウント 言語を選択 言語 - 端末操作表示 + インターフェース 認証を確認中 電子メールを確認して、本文中のURLをクリックしてください。 完了したら「続ける」をクリックしてください。 このメールアドレスは既に使われています。 @@ -398,7 +398,7 @@ パスワードを再設定するには、アカウントに登録されているメールアドレスを入力してください: アカウントに登録されたメールアドレスの入力が必要です。 新しいパスワードの入力が必要です。 - %sへ電子メールが送信されました。リンクをたどったら以下をクリックしてください。 + %sへ電子メールが送信されました。リンクにアクセスしてから、以下をクリックしてください。 メールアドレスの確認に失敗しました:電子メールのリンクをクリックしたことを確認してください パスワードがリセットされました。 \n @@ -560,7 +560,7 @@ 不具合の報告 開封確認メッセージのリスト ダウンロードフォルダーに保存しますか? - この招待は、このアカウントに関連付けられていない%sに送信されました。 + この招待は、このアカウントに登録されていない%sに送信されました。 \n別のアカウントでログインするか、このメールを自分のアカウントに追加してください。 %sにアクセスしようとしています。ディスカッションに参加しますか? ルーム @@ -604,7 +604,7 @@ 未読のあるルームを固定 分析 データ節約モード - メールアドレスを認証できません。メールを確認して、そこに記載してあるリンクをクリックしてください。その後、「続ける」をクリックしてください。 + メールアドレスを認証できません。メールを確認して、記載されているリンクをクリックしてください。その後、「続ける」をクリックしてください。 この通知の対象を削除してよろしいですか? %1$s %2$sを削除してよろしいですか? コード @@ -774,12 +774,12 @@ アカウントを停止 自分のアカウントを停止 通知のプライバシー - ${app_name}は通知を安全で内密に扱うため、バックグラウンドで動作できます。これによりバッテリー使用に影響が出ることがあります。 + ${app_name}はバックグラウンドで動作し、通知を安全で内密に扱います。これによりバッテリー使用に影響が出ることがあります。 許可を与える 他のオプションを選択 - 解析データを送信 - ${app_name}はアプリを改善するため、匿名の解析データを収集します。 - ${app_name}を改善するのを助けるため、解析を許可してください。 + 分析データを送信 + ${app_name}はアプリを改善するため、匿名の分析データを収集します。 + 分析を有効にして、${app_name}の改善を手伝ってくれませんか? はい、手伝いたいです! あなたは現在どのコミュニティーのメンバーでもありません。 ここに入力… @@ -1081,7 +1081,7 @@ あなたのアカウントに追加されたメールアドレスはありません あなたのアカウントに追加された電話番号はありません 電話番号 - あなたの Matrix アカウントに関連付けられたメールアドレスと電話番号を管理 + あなたのMatrixアカウントに登録されたメールアドレスと電話番号を管理 メールアドレスと電話番号 有効化 このセッションで通知が無効化されています。 @@ -1178,10 +1178,10 @@ 無効なQRコード(無効なURI)! パスワードが一致しません メールアドレスの確認中にエラーが発生しました。 - これを行うには設定からインテグレーションを許可を有効にしてください。 + これを行うには設定から「インテグレーションを許可」を有効にしてください。 インテグレーションが無効になっています インテグレーションマネージャー - インテグレーションを許可 + インテグレーション(統合)を許可 データ節約モードでは、特定のフィルターを適用することで、プレゼンスの更新やタイピングの通知がフィルタリングされます。 FCMトークンが正常に取得されました: \n%1$s @@ -1448,14 +1448,14 @@ ルーム名を削除しました 許可を与える ${app_name}は、信頼できる通知を受け取るために、影響の少ないバックグラウンド接続を維持する必要があります。 -\n次の画面で、${app_name}を常にバックグラウンドで実行することを許可するように求められます。承認してください。 +\n次の画面で、${app_name}を常にバックグラウンドで実行することを許可するように求められますので、承認してください。 バックグラウンド接続 ディスカバリー設定を管理します。 ディスカバリー(発見) これにより、現在のキーまたはフレーズが置き換えられます。 新しいセキュリティーキーを生成するか、既存のバックアップに新しいセキュリティーフレーズを設定します。 - サーバー上の暗号鍵をバックアップすることにより、暗号化されたメッセージとデータへのアクセスが失われるのを防ぎます。 - メッセージ作成画面に絵文字キーボードを開くボタンを追加 + サーバー上の暗号鍵をバックアップすることにより、暗号化されたメッセージとデータへのアクセスが失われるのを予防します。 + メッセージ作成画面に絵文字キーボードを開くためのボタンを追加 絵文字キーボードを表示 アバターと表示名の変更を含む。 アカウントのイベントを表示 @@ -2312,9 +2312,9 @@ ユーザーのロケーションをタイムラインに表示 一度有効にすると、ロケーションはどのルームにも送れるようになります サードパーティー製ライブラリー - いつでも設定から無効にできます - 私たちは情報を第三者と共有することはありません - 私たちはアカウントのデータを記録したり分析したりすることはありません + これはいつでも設定から無効にできます + 私たちは、情報を第三者と共有することはありません + 私たちは、アカウントのデータを記録したり分析したりすることはありません Elementの改善を手伝う リンクを知っている人がアクセスできるようにこのルームを設定しました。 どのユーザーも無視していません @@ -2628,7 +2628,7 @@ 国際電話番号の形式を使用してください。 国際電話番号は「+」から始まる必要があります コードを%1$sに送信しました。以下に入力して認証してください。 - このメールアドレスはどのアカウントにも属していません + このメールアドレスはどのアカウントにも登録されていません パスワードを変更すると、すべてのセッションでのエンドツーエンド暗号鍵がリセットされ、暗号化されたメッセージ履歴が読めなくなります。パスワードを再設定する前に、鍵のバックアップを設定するか、他のセッションから鍵をエクスポートしておいてください。 パスワードの再設定を確認するために認証メールを送信しました。 このメールアドレスはどのアカウントにも属していません。 @@ -2696,7 +2696,7 @@ セキュリティーキーを保存 リカバリーキー 位置を共有しました - %sとリアクションしました + %sでリアクションしました 検証終了 次のいずれかのセキュリティが破られている可能性があります。 \n @@ -2710,7 +2710,7 @@ 次の絵文字が相手の画面にも同じ順番で現れるのを確認し、このユーザーを検証してください。 信頼できないサインイン 使用できない文字が含まれています - Elementの改善と課題抽出のために、匿名の使用分析データを収集させてくださいませんか?複数の端末での使用を解析するために、あなたの全端末共通のランダムな識別子を生成します。 + Elementの改善と課題抽出のために、匿名の使用分析データを収集させてくださいませんか?複数の端末での使用を分析するために、あなたの全端末共通のランダムな識別子を生成します。 \n \n%sで利用規約を閲覧できます。 最初の検索結果のみ表示中。文字をもっと入力してください… @@ -2804,7 +2804,7 @@ 絵文字を比較して検証 対面でない場合は、代わりに絵文字を比較してください あなたのホームサーバーは、最大%sのサイズの添付ファイルを受け付けています。 - 新しいパスワードを確認するには下記のリンクを開いてください。リンク先のリンクにアクセスしてから、この下をクリックしてください。 + 新しいパスワードを確認するには下記のリンクを開いてください。リンクにアクセスしてから、以下をクリックしてください。 PINコードを再設定するには「PINコードを忘れた」をタップしてログアウトし、その後再設定してください。 いま検証できる%d個の端末を表示 From 0dd9809166bc4aea4f8f0118f43e5c22eaf9d671 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Mon, 21 Feb 2022 11:18:34 +0000 Subject: [PATCH 245/302] Translated using Weblate (Japanese) Currently translated at 91.4% (2546 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 226b1e421e..d48027a6f9 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1943,7 +1943,7 @@ スペースのメンバーに発見とアクセスを許可します。 スペース %s のメンバーが検索、プレビュー、参加できます。 非公開(招待のみ) - デフォルトのメディアソース + 規定メディアソース 規定圧縮率 ルームのアップグレード ボットによるメッセージ From f3734bbb5340584155d799c3a8839f5e32fd26c2 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Mon, 21 Feb 2022 11:18:21 +0000 Subject: [PATCH 246/302] Translated using Weblate (Japanese) Currently translated at 91.4% (2546 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index d48027a6f9..2a57b5752f 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1944,7 +1944,7 @@ スペース %s のメンバーが検索、プレビュー、参加できます。 非公開(招待のみ) 規定メディアソース - 規定圧縮率 + 既定の圧縮率 ルームのアップグレード ボットによるメッセージ ルームへの招待 From 65239e403489f2439c67ff4759877c93390079ce Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 21 Feb 2022 12:04:02 +0000 Subject: [PATCH 247/302] relying on the glide caches (persisted and in memory) instead of our own - this effectively halves the amount of image memory used by notifications --- .../vector/app/features/notifications/BitmapLoader.kt | 10 +--------- .../im/vector/app/features/notifications/IconLoader.kt | 9 +-------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/BitmapLoader.kt b/vector/src/main/java/im/vector/app/features/notifications/BitmapLoader.kt index d1c4624cdc..da0f071841 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/BitmapLoader.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/BitmapLoader.kt @@ -28,11 +28,6 @@ import javax.inject.Singleton @Singleton class BitmapLoader @Inject constructor(private val context: Context) { - /** - * Avatar Url -> Bitmap - */ - private val cache = HashMap() - /** * Get icon of a room. * If already in cache, use it, else load it and call BitmapLoaderListener.onBitmapsLoaded() when ready @@ -42,10 +37,7 @@ class BitmapLoader @Inject constructor(private val context: Context) { if (path == null) { return null } - - return cache.getOrPut(path) { - loadRoomBitmap(path) - } + return loadRoomBitmap(path) } @WorkerThread diff --git a/vector/src/main/java/im/vector/app/features/notifications/IconLoader.kt b/vector/src/main/java/im/vector/app/features/notifications/IconLoader.kt index 3e68744c88..ec53e89d57 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/IconLoader.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/IconLoader.kt @@ -30,11 +30,6 @@ import javax.inject.Singleton @Singleton class IconLoader @Inject constructor(private val context: Context) { - /** - * Avatar Url -> IconCompat - */ - private val cache = HashMap() - /** * Get icon of a user. * If already in cache, use it, else load it and call IconLoaderListener.onIconsLoaded() when ready @@ -46,9 +41,7 @@ class IconLoader @Inject constructor(private val context: Context) { return null } - return cache.getOrPut(path) { - loadUserIcon(path) - } + return loadUserIcon(path) } @WorkerThread From af39632d3ec976d4c6123f880ed4d3745dc7b6a9 Mon Sep 17 00:00:00 2001 From: Linerly Date: Mon, 21 Feb 2022 07:59:03 +0000 Subject: [PATCH 248/302] Translated using Weblate (Indonesian) Currently translated at 100.0% (2785 of 2785 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 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index 5677c283a4..78c5b2708c 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -382,7 +382,7 @@ Ijinkan akses lewat halaman selanjutnya untuk menemukan pengguna ${app_name} yan Keluar Abaikan Sidik jari (%s): - Tidak dapat memastikan identitas remote server. + Tidak dapat memastikan identitas server jarak jauh. Ini dapat terjadi ketika seseorang sedang mensabotase arus data Anda, atau perangkat Anda tidak percaya terhadap sertifikat remote server. Apabila administrator server telah menyatakan ini memang akan terjadi, pastikan sidik jari berikut cocok dengan sidik jari yang mereka sediakan. Sertifikat ini tidak lagi sesuai dengan yang dipercayai oleh perangkat Anda sebelumnya. Ini SANGAT JANGGAL. Kami rekomendasikan Anda untuk TIDAK MENERIMA sertifikat baru ini. @@ -634,7 +634,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Ini adalah fitur uji coba dan mungkin rusak tanpa terduga. Hati-hati menggunakannya. Enkripsi Ujung-ke-Ujung Enkripsi Ujung-ke-Ujung aktif - Anda perlu keluar dulu untuk mengaktifkan enkripsi. + Anda perlu keluar terlebih dahulu untuk mengaktifkan enkripsi. Enkripsi ke perangkat terverifikasi saja Jangan mengirim pesan terenkripsi ke perangkat yang belum diverifikasi di ruangan ini dengan perangkat ini. Ruangan ini tidak punya alamat lokal @@ -1462,7 +1462,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Perubahan siapa yang dapat membaca riwayat hanya akan berlaku untuk pesan berikutnya di ruangan ini. Visibilitas riwayat yang ada tidak akan berubah. Pengaturan akun Anda dapat mengelola notifikasi di %1$s. - Harap dicatat bahwa sebutan & pemberitahuan keyword tidak tersedia di ruangan terenkripsi di ponsel. + Harap dicatat bahwa pemberitahuan sebutan & kata kunci tidak tersedia di ruangan terenkripsi di ponsel. Beritahu saya untuk Putar suara rana Pilih @@ -1825,7 +1825,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. \n%s Permintaan Dibatalkan Kunci Verifikasi - Gunakan verifikasi legacy. + Gunakan verifikasi lama. 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 dapat dibaca oleh pihak ketiga. @@ -2324,7 +2324,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Panggilan grup dimulai Maaf, sebuah kesalahan terjadi saat bergabung: %s Tingkatkan ke versi ruangan yang disarankan - Kamar ini menjalankan versi %s, yang ditandai oleh homeserver ini sebagai tidak stabil. + Ruangan ini menjalankan versi %s, yang ditandai oleh homeserver ini sebagai tidak stabil. Izinkan siapa saja di %s untuk mencari dan mengakses. Anda dapat memilih space yang lain juga. Anda membutuhkan izin untuk meningkatkan sebuah ruangan Otomatis memperbarui induk space @@ -2375,7 +2375,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Tinggalkan semua ruangan dan space Anda adalah admin satu-satunya di space ini. Meninggalkannya berarti siapa saja tidak akan mempunyai kontrol atas space-nya. Anda tidak akan dapat bergabung lagi kecuali jika Anda diundang lagi. - Anda hanya salah satu orang di sini. Jika Anda tinggalkan, siapa saja tidak dapat bergabung di masa depan, termasuk Anda. + Anda orang satu-satunya di sini. Jika Anda tinggalkan, siapa saja tidak dapat bergabung di masa depan, termasuk Anda. Apakah Anda yakin untuk meninggalkan %s\? Tinggalkan Space Tambahkan ruangan @@ -2693,9 +2693,9 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Gunakan File Masukkan %s Anda untuk melanjutkan Verifikasi diri Anda dan lainnya untuk tetap membuat pesan Anda aman - Aktifkan Tanda Tangan Silang + Aktifkan Penandatanganan Silang Peningkatan enkripsi tersedia - Pesan… + Kirim pesan… Akun ini telah dinonaktifkan. Nama pengguna dan/atau kata sandi salah. Kata sandi dimulai atau berakhir dengan spasi, mohon dicek. Mengirim pesan sebagai teks biasa, tanpa mengimpretasikannya sebagai markdown From cbad7de1c86ab59a92a52db75bc402c27cba8c3e Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Mon, 21 Feb 2022 12:09:09 +0000 Subject: [PATCH 249/302] Translated using Weblate (Japanese) Currently translated at 91.3% (2545 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 112 +++++++++++----------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 2a57b5752f..350ccedc38 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -254,7 +254,7 @@ 通知 無視しているユーザー その他 - 拡張設定 + 高度な設定 暗号 通知対象 端末の電話帳 @@ -267,7 +267,7 @@ ID(端末固有番号) 公開端末名 公開端末名の更新 - 最終接続日 + 最後のオンライン日時 %1$s @ %2$s 認証 この操作には追加の認証が必要です。 @@ -301,7 +301,7 @@ お気に入り 低優先度 なし - 参加と可視範囲 + アクセスと可視範囲 ルームディレクトリへ公開 ルームへのアクセス ルームの履歴の可視範囲 @@ -315,24 +315,24 @@ ルームのリンクを知っている人なら誰でも(ゲストユーザーを除く) ルームのリンクを知っている人なら誰でも(ゲストユーザーを含む) ブロックされたユーザー - 拡張設定 + 高度な設定 このルームのサーバー内識別ID ラボ - これらは予期せぬ不具合が生じるかもしれない実験的機能です。慎重に使用してください。 + これらは予期しない不具合が生じるかもしれない実験的機能です。慎重に使用してください。 エンドツーエンド暗号化 エンドツーエンド暗号化を使用中 - 暗号を有効にするためにはログアウトする必要があります. + 暗号化を有効にするためにはログアウトする必要があります. 認証済のセッションに対してのみ暗号化 - このセッションでは、このルームの未検証のセッションに対して暗号化されたメッセージを送信しない。 + このセッションから、このルームの未認証のセッションに対して、暗号化されたメッセージを送信しない。 新しいアドレス (記入例 #foo:matrix.org) このルームにはローカルアドレスがありません - 住所表記 + アドレス エイリアスのフォーマットが正しくありません \'%s\'はエイリアスの正しいフォーマットではありません このルームのメインアドレスが設定されていません。 メインアドレスの警告 メインアドレスとして設定 - メインアドレスとして設定を解除 + メインアドレスとしての設定を解除 ルーム固有IDをコピー ルームのアドレスをコピー セッションID @@ -484,11 +484,11 @@ エンドツーエンド暗号化についての情報 公開端末名 ルームのエンドツーエンド暗号鍵をエクスポート - 認証 + 認証済 履歴を検索 このルームに参加していません。 このルームで権限がありません。 - ルーム %s は、見ることができません。 + ルーム %s は閲覧できません。 ユーザー名 ホームサーバーのURL IDサーバーのURL @@ -524,20 +524,20 @@ 要求を無視 検証せずに共有 検証を開始 - リクエストに user_id がありません。 - リクエストに room_id がありません。 + リクエストにuser_idがありません。 + リクエストにroom_idがありません。 リクエストの送信に失敗しました。 ウィジェットを作成できません。 このルームのウィジェットを管理する権限が必要です ウィジェットの作成に失敗しました ウィジェットをこのルームから削除してもよろしいですか? サーバーが利用できないか、オーバーロードしている可能性があります - このルームは検証されていない不明なセッションが含まれています。 -\nこれは、そのセッションが主張するユーザーのものであるという保証がないことを意味します。 -\n続行する前に、各セッションの検証プロセスを進めることをおすすめしますが、検証せずにメッセージを再送信することもできます。 + このルームに、検証されていない不明なセッションがあります。 +\nそのセッションが、主張するユーザーのものであるという保証はありません。 +\n続行する前に、各セッションの検証プロセスを進めることを推奨しますが、検証せずにメッセージを再送信することもできます。 \n \n不明なセッション: - ルームに不明なセッションが含まれています + ルームに不明なセッションがあります 鍵が一致していることを確認 一致していない場合は、あなたのコミュニケーションの安全性が損なわれている可能性があります。 セッションを認証 @@ -608,7 +608,7 @@ この通知の対象を削除してよろしいですか? %1$s %2$sを削除してよろしいですか? コード - %sはこのルームのタイムラインのある箇所を読み込もうとしましたが、見つかりませんでした。 + %sはこのルームのタイムライン上の特定の箇所を読み込もうとしましたが、見つかりませんでした。 イベント情報 ユーザーID Curve25519 固有鍵 @@ -624,7 +624,7 @@ なし 認証する 認証を取り消す - ブラックリスト + ブラックリストに追加 ブラックリストから除外 他のセッションのユーザー設定で、以下を比較して確認してください: ルームのディレクトリを選択 @@ -635,10 +635,10 @@ メッセージが未送信です。今%1$sまたは%2$sしますか? 不明なセッションが存在しているため、メッセージを送ることができませんでした。今%1$sまたは%2$sしますか? 要求されたフィンガープリントキー Ed25519 - jitsiを用いて会議通話を始める + Jitsiを用いて会議通話を始める 端末のカメラを使用 警告! - ビデオ会議は開発中であり、確実でない可能性があります。 + ビデオ会議は開発中であり、安定して動作しない可能性があります。 コマンドエラー 認識されないコマンド:%s @@ -663,9 +663,9 @@ ホーム画面にショートカットを作成 インラインURLプレビュー 通知 - このルームはコミュニティーの特色を表示していません - 所属するコミュニティー - 新しいコミュニティーID (記入例 +foo:matrix.org) + このルームはコミュニティーのアバターを表示していません + コミュニティーのアバター + 新しいコミュニティーID(記入例 +foo:matrix.org) 無効なコミュニティーID \'%s\' は有効なコミュニティーIDではありません ルームのエンドツーエンド暗号鍵は \'%s\' に保存されました。 @@ -790,7 +790,7 @@ %d件の通知された未読メッセージ - %dルーム + %d個のルーム %2$s件中%1$s件 @@ -799,7 +799,7 @@ 必要な変数が見つかりません。 変数が無効です。 メッセージを送信するには、キーボードのEnterキーを押してください - ボイスメッセージを送信 + 音声メッセージを送信 動作を表示 指定したIDのユーザーをブロック 指定したIDのユーザーのブロックを解除 @@ -843,8 +843,8 @@ あなたのサービス管理者に連絡 このホームサーバーはリソース制限の1つを超過しているため、 ユーザーがログインできなくなることがあります このホームサーバーはリソース制限の1つを超過しています。 - このホームサーバーは月間アクティブユーザー上限に達しているため、 ユーザーがログインできなくなることがあります - このホームサーバーは月間アクティブユーザー上限に達しています。 + このホームサーバーは月間アクティブユーザーの上限に達しているため、 ユーザーがログインできなくなることがあります + このホームサーバーは月間アクティブユーザーの上限に達しています。 この上限を上げるには%sしてください。 このサービスを使い続けるには%sしてください。 最初にルームのメンバーのみを読み込むことでパフォーマンスを向上。 @@ -852,7 +852,7 @@ ルームのメンバーの簡易読み込み 申し訳ありません、エラーが発生しました バージョン %s - エクスポートされた鍵を暗号化するパスフレーズを作成してください。 鍵をインポートするには、同じパスフレーズを入力する必要があります。 + エクスポートされた鍵を暗号化するパスフレーズを作成してください。 鍵をインポートするには、同一のパスフレーズを入力する必要があります。 パスフレーズの作成 パスフレーズは一致する必要があります 情報領域を表示 @@ -1447,7 +1447,7 @@ ルームのトピックを削除しました ルーム名を削除しました 許可を与える - ${app_name}は、信頼できる通知を受け取るために、影響の少ないバックグラウンド接続を維持する必要があります。 + ${app_name}は、確実に通知を受け取るために、影響の少ないバックグラウンド接続を維持する必要があります。 \n次の画面で、${app_name}を常にバックグラウンドで実行することを許可するように求められますので、承認してください。 バックグラウンド接続 ディスカバリー設定を管理します。 @@ -1553,18 +1553,18 @@ ウィジェットID あなたのテーマ あなたのユーザーID - あなたのアバターURL + あなたのアバターのURL ブラウザーで開く - ウィジェットをロード + ウィジェットを読み込む ウィジェット - アクティブなウィジェット + 使用中のウィジェット 自分 新しいメッセージ ルーム 新しいイベント 不明なIP - キー%1$dと%2$dのインポートに成功。 + %2$d個の鍵のうち%1$d個のインポートに成功。 鍵のバックアップを管理 鍵のエクスポートに成功しました @@ -1573,7 +1573,7 @@ 詳細情報:%s ローカルアドレスを追加 このルームにはローカルアドレスがありません - アドレス \"%1$s\" を削除しますか? + アドレス\"%1$s\"を削除しますか? メインアドレス これがメインアドレスです 電話番号の認証中にエラーが発生しました。 @@ -1679,29 +1679,29 @@ この機能はメッセージを録音するために第三者のアプリを必要とします。 新しいセッションが暗号鍵を要請しています。 \nセッション名:%1$s -\n最後のオンライン時刻:%2$s +\n最後のオンライン日時:%2$s \n新たにログインして新しいセッションを開始しなかった場合、この要求を無視してください。 未認証のセッションが暗号鍵を要請しています。 \nセッション名:%1$s -\n最後のオンライン時刻:%2$s +\n最後のオンライン日時:%2$s \n新たにログインして新しいセッションを開始しなかった場合、この要求を無視してください。 鍵の共有リクエスト カスタムカメラ画面の代わりにシステムカメラを使用します。 使用中のウィジェットがありません インテグレーションを管理 - インテグレーション管理者が設定されていません。 - DRM保護されているメディアの読込 + インテグレーションマネージャーが設定されていません。 + DRM保護されているメディアを読み込む マイクの使用 カメラの使用 このウィジェットは次のリソースの使用を要求します: - 現在の会議から退出しもう一つの会議に参加しますか? + 現在の会議から退出し、もう一つの会議に参加しますか? 申し訳ありませんが、ビデオ会議に参加する途中で問題が発生しました - 申し訳ありませんが、古い端末(Android OS 6.0以前)はJitsiを使用したビデオ会議がサポートされていません + 申し訳ありませんが、古い端末(Android OS 6.0以前)はJitsiを使用したビデオ会議をサポートしていません あなたの表示名 - ウィジェットの読込に失敗しました。 + ウィジェットの読み込みに失敗しました。 \n%s - ウィジェットを再読込 - クッキーを設定し%sとデータを交換する可能性があります: + ウィジェットを再読み込み + これを使用すると、クッキーが設定され、データが%sと共有される可能性があります: ウィジェットの追加者: **送信に失敗 - ルームを開いてください 新しい招待 @@ -1727,7 +1727,7 @@ ブロックされたユーザー%d人 - このルームのあるスペースのメンバーは誰でも発見し参加できます。ルームをスペースに追加できるのは、ルームの管理者だけです。 + このルームのあるスペースのメンバーは、誰でもこのルームを発見し参加できます。ルームをスペースに追加できるのは、ルームの管理者だけです。 スペースのメンバーのみ 誰でもルームを発見し参加できます 公開 @@ -1737,8 +1737,8 @@ 誰でもルームにノックができ、メンバーがその参加を承認または拒否できます 現在のルームディレクトリの見え方を取得できません(%1$s)。 このルームを%1$sのルームディレクトリに公開しますか? - アドレスを非公開にする - アドレスを公開 + このアドレスを非公開にする + このアドレスを公開 アドレスを設定すれば、他のユーザーがあなたのホームサーバー (%1$s) を通じてこのルームを見つけられるようになります。 ローカルアドレス 新しい公開アドレス(例: #alias:server) @@ -1749,16 +1749,16 @@ 公開 手動で新しいアドレスを公開 他の公開アドレス: - 公開されたアドレスを通して、どのサーバーのどのユーザーでもこのルームに参加できます。アドレスを公開するには、まずローカルアドレスとして設定する必要があります。 + 公開アドレスを通して、どのサーバーのどのユーザーでも、このルームに参加できます。アドレスを公開するには、まずローカルアドレスとして設定する必要があります。 公開アドレス ルームのアドレス - ルームのアドレス及びルームディレクトリにおける可視性を管理できます。 + このルームのアドレスと、ルームディレクトリにおける見え方を管理できます。 スペースのアドレスを管理できます。 スペースのアドレス ルームのアドレス ゲストの参加を許可 ルームへのアクセス - 発信履歴閲覧権限の変更は今後送信されるメッセージにのみ適用されます。既存履歴の表示は影響されません。 + 履歴の閲覧権限に関する変更は、今後、このルームで表示されるメッセージにのみ適用されます。既存の履歴の見え方には影響しません。 無視して続行 毎回確認 招待 @@ -1897,7 +1897,7 @@ 検証プロセスがタイムアウトしました ユーザーが検証をキャンセルしました このルームを含む参加済のスペース - このルームにアクセスできるスペースを決定します。スペースが選択されるとそのメンバーはルーム名を見つけて参加できます。 + このルームにアクセスできるスペースを決定します。スペースが選択されると、そのメンバーはルーム名を見つけて参加できます。 検証がキャンセルされました。 \n理由:%s 相手が検証をキャンセルしました。 @@ -1918,7 +1918,7 @@ このセッションを検証して、信頼済としてマークします。相手のセッションを信頼すると、さらに安心してエンドツーエンド暗号化を使用することができます。 入力された検証要求 検証を開始します - 最大限のセキュリティーを確保するために、これを行うか、別の信頼できる通信手段を用いることをお勧めします。 + 最大限のセキュリティーを確保するために、これを対面で行うか、別の信頼済の通信手段を用いることを推奨します。 短い文字列を比較して検証します。 認証情報が不正または期限切れのため、ログアウトされました。 構成を使用 @@ -1932,7 +1932,7 @@ 暗号化されたメッセージを決して失わないために バックアップ (%s) のtrust infoの取得に失敗しました。 セッションの暗号化が有効になっていません - これを使用するとデータを%sと共有します。 + これを使用するとデータが%sと共有される可能性があります: %1$s:%2$s %3$s %1$s:%2$s あなたが知らないかもしれない他のスペースやルーム @@ -1943,7 +1943,7 @@ スペースのメンバーに発見とアクセスを許可します。 スペース %s のメンバーが検索、プレビュー、参加できます。 非公開(招待のみ) - 規定メディアソース + 既定のメディアソース 既定の圧縮率 ルームのアップグレード ボットによるメッセージ @@ -2363,12 +2363,12 @@ 暗号化されたルームでのメンションとキーワードによる通知は、携帯端末では利用できません。 ユーザーを無視し、そのメッセージを非表示にします %sとのコマンドは認識されていますが、スレッドではサポートされていません。 - 誰でもこのスペースを発見し参加できます + 誰でもスペースを発見し参加できます 法的情報 ユーザーに関する情報を表示します このルームにおいてのみアバターを変更します このルームにおいてのみ表示名を変更します - ユーザーの無視を解除し、これからのメッセージを表示します + ユーザーの無視を解除し、以後のメッセージを表示します 続行するには%sを入力してください 復旧用のパスフレーズ 有効なリカバリーキーではありません From 1b52124bb8ba56fd520ce3517d8628fd0e05539a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?= Date: Sat, 19 Feb 2022 23:55:16 +0000 Subject: [PATCH 250/302] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2785 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/ --- vector/src/main/res/values-pt-rBR/strings.xml | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index 9eabb09e69..cda7517f6b 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -405,7 +405,7 @@ Servidorcasa: Servidor de identidade: Eu tenho verificado meu endereço de email - Para resettar sua senha, entre o endereço de email linkado a sua conta: + Para resetar sua senha, digite o endereço de email vinculado a sua conta: O endereço de email linkado a sua conta deve ser entrado. Uma nova senha deve ser entrada. Um email tem sido enviado para %s. Uma vez que tenha seguido o link que ele contém, clique abaixo. @@ -508,7 +508,7 @@ Sair desta sala Banir Desbanir - Resettar a usuária(o) normal + Resetar a usuária(o) normal Fazer moderador(a) Fazer admin Ignorar @@ -678,7 +678,7 @@ Acesso e visibilidade Listar esta sala em diretório de salas Acesso a Sala - Legibilidade de Histórico de Sala + Legibilidade do Histórico da Sala Quem pode ler o histórico\? Quem pode acessar esta sala? Qualquer pessoa @@ -828,7 +828,7 @@ Som de notificação Mnsgns contendo meu nome de exibição Mnsgns contendo meu nome de usuária(o) - Previsualização de URL emlinha + Pré-visualização de URL em linha Mostrar timestamps em formato de 12 horas Vibrar ao mencionar um/uma usuário(a) Analítica @@ -1294,7 +1294,7 @@ Backup Seguro Gerenciar Configurar Backup Seguro - Resettar Backup Seguro + Resetar Backup Seguro Configurar neste dispositivo Salvaguardar-se contra perda de acesso a mensagens & dados encriptados ao fazer backup de chaves de encriptação em seu servidor. Gere uma nova Chave de Segurança ou defina uma nova Frase de Segurança para seu backup existente. @@ -1540,7 +1540,7 @@ Correspondência errada de usuária(o) Erro Desconhecido Você não está usando nenhum servidor de identidade - Nenhum servidor de identidade está configurado, ele é requerido para resettar sua senha. + Nenhum servidor de identidade está configurado, ele é requerido para resetar sua senha. Parece que você está tentando se conectar a um outro servidorcasa. Você quer fazer signout\? Editar Responder @@ -1783,13 +1783,13 @@ \n \nVocê quer fazer signup usando um cliente web\? Este email não está associado com nenhuma conta. - Resettar senha em %1$s + Resetar senha em %1$s Um email de verificação vai ser enviado para sua inbox para confirmar definição de sua nova senha. Próximo Email Nova senha Aviso! - Mudar sua senha vai resettar quaisquer chaves de encriptação ponta-a-ponta em todas as suas sessões, fazendo histórico de chat encriptado ilegível. Configure Backup de Chave ou exporte suas chaves de sala de uma outra sessão antes de resettar sua senha. + Mudar sua senha vai resetar quaisquer chaves de encriptação ponta-a-ponta em todas as suas sessões, tornando histórico de chat encriptado ilegível. Configure Backup de Chave ou exporte suas chaves de sala de uma outra sessão antes de resetar sua senha. Continuar Este email não está linkado a nenhuma conta Cheque sua inbox @@ -2032,7 +2032,7 @@ %1$s (%2$s) fez signin usando uma nova sessão: Até que esta(e) usuária(o) confie nesta sessão, mensagens enviadas para e desde ela são etiquetadas com avisos. Alternativamente, você pode verificá-la manualmente. Inicializar AssinaturaCruzada - Resettar Chaves + Resetar Chaves QR code Quase lá! %s está mostrando um tick (✓)\? Sim @@ -2287,11 +2287,11 @@ Falha para validar PIN, por favor toque um novo. Entre seu PIN Esqueceu PIN\? - Resettar PIN + Resetar PIN Novo PIN - Para resettar seu PIN, você vai precisar refazer login e criar um novo. + Para resetar seu PIN, você vai precisar refazer login e criar um novo. Habilitar PIN - Se você quer resettar seu PIN, toque em Esqueceu PIN para fazer logout e resettá-lo. + Se você quer resetar seu PIN, toque em Esqueceu PIN para fazer logout e resetá-lo. Confirmar PIN para desabilitar PIN Prevenir chamada acidental Pedir por confirmação antes de começar uma chamada @@ -2368,9 +2368,9 @@ Mostrar %d dispositivos com os quais você pode verificar agora Você vai recomeçar com nada de histórico, mensagens, dispositivos confiados ou usuárias(os) confiadas(os) - Se você resettar tudo + Se você resetar tudo Somente faça isto se você não tem nenhum outro dispositivo com o qual você pode verificar este dispositivo. - Resettar tudo + Resetar tudo Esqueceu ou perdeu todas as opções de recuperação\? Resette tudo Você juntou-se. Mensagens nesta sala são encriptadas ponta-a-ponta. @@ -2394,7 +2394,7 @@ Pesquisar em salas encriptadas não é suportado ainda. Você não tem permissão para começar uma chamada Você não tem permissão para começar uma chamada de conferência - Resettar + Resetar %1$s fez isto somente convite. Você fez isto somente convite. %s juntou-se. @@ -3050,7 +3050,7 @@ Recomece o aplicativo para a mudançar tomar efeito. Habilitar matemática LaTeX Você não é permitida(o) a juntar-se a esta sala - Criar sondagem + Criar enquete Abrir contatos Enviar sticker Fazer upload de arquivo From 89daabb24fc6db5706b2ac70f6d865969cbb1812 Mon Sep 17 00:00:00 2001 From: yaronsb Date: Mon, 21 Feb 2022 10:50:38 +0000 Subject: [PATCH 251/302] Translated using Weblate (Hebrew) Currently translated at 78.0% (2173 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/he/ --- vector/src/main/res/values-iw/strings.xml | 146 ++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/vector/src/main/res/values-iw/strings.xml b/vector/src/main/res/values-iw/strings.xml index a245b14b9d..48bc5a675d 100644 --- a/vector/src/main/res/values-iw/strings.xml +++ b/vector/src/main/res/values-iw/strings.xml @@ -2411,4 +2411,150 @@ כל חברי החדר, מהנקודה בה הם הוזמנו. את/ה הפכת הודעות עתידיות לגלויות בפני %1$s %1$s הפך הודעות עתידיות לגלויות בפני %2$s + חסמת את %1$s. סיבה: %2$s + %1$s חסם את %2$s. סיבה: %3$s + ביטלת את החסימה של %1$s. סיבה: %2$s + %1$s ביטל החסימה של %2$s. סיבה: %3$s + הסרת את %1$s. סיבה: %2$s + %1$s הסיר את %2$s. סיבה: %3$s + דחית את ההזמנה. סיבה: %1$s + %1$s דחה את ההזמנה. סיבה: %2$s + עזבת. סיבה: %1$s + %1$s עזב. סיבה: %2$s + יצאת מהחדר. סיבה: %1$s + %1$s עזבו את החדר. סיבה: %2$s + הצטרפת. סיבה: %1$s + %1$s הצטרף. סיבה: %2$s + הצטרפת לחדר. סיבה: %1$s + %1$s הצטרף לחדר. סיבה: %2$s + %1$s הזמין אותך. סיבה: %2$s + הזמנת את %1$s. סיבה: %2$s + %1$s הפעילה הצפנה מקצה לקצה (אלגוריתם לא מזוהה %2$s). + הפעלת הצפנה מקצה לקצה (אלגוריתם לא מזוהה %1$s). + %1$s הזמין את %2$s. סיבה: %3$s + ההזמנה שלך. סיבה: %1$s + ההזמנה של %1$s. סיבה: %2$s + נקה את תור השליחה + הודעה נשלחת… + הודעה נשלחה + סנכרון ראשוני: +\nייבוא נתוני חשבון + סנכרון ראשוני: +\nייבוא קהילות + סנכרון ראשוני: +\nייבוא חדרים עזובים + סנכרון ראשוני: +\nייבוא חדרים מוזמנים + סנכרון ראשוני: +\nטוען את השיחות שלך +\nאם הצטרפת להרבה חדרים, זה עשוי לקחת זמן מה + סנכרון ראשוני: +\nייבוא חדרים + סנכרון ראשוני: +\nייבוא קריפטו + סנכרון ראשוני: +\nמייבא חשבון… + סנכרון ראשוני: +\nמוריד נתונים… + סנכרון ראשוני: +\nממתין לתגובת השרת… + חדר ריק (היה %s) + חדר ריק + + %1$s ועוד אחד + %1$s ו-%2$d אחרים + %1$s ו-%2$d אחרים + %1$s ו-%2$d אחר + + + %1$s, %2$s, %3$s ו-%4$d אחר + %1$s, %2$s, %3$s ו-%4$d אחרים + %1$s, %2$s, %3$s ו-%4$d אחרים + %1$s, %2$s, %3$s ו-%4$d אחר + + %3$s, %2$s, %1$s ו-%4$s + %2$s, %1$s ו-%3$s + %1$s ו-%2$s + הזמנה לחדר + הזמן מ-%s + מספר טלפון + כתובת דוא\"ל + אינך רשאי להצטרף לחדר זה + כרגע לא ניתן להצטרף מחדש לחדר ריק. + שגיאת מטריקס + שגיאת רשת + העלאת התמונה נכשלה + לא ניתן לשלוח הודעה + לא ניתן היה לתקן + מכשיר השולח לא שלח לנו את המפתחות להודעה זו. + ** לא ניתן לפענח: %s ** + %1$s מ-%2$s עד %3$s + %1$s שינה את רמת העוצמה של %2$s. + שינית את רמת העוצמה של %1$s. + מותאם אישית + מותאם אישית (%1$d) + ברירת מחדל + מַנחֶה + מנהל מערכת + שינית ועידת וידאו + ועידת וידאו השתנתה ע\"י %1$s + סיימת ועידת וידאו + ועידת וידאו הסתיימה ע\"י %1$s + התחלת ועידת וידאו + ועידת וידאו התחילה על ידי %1$s + שינית את הווידג\'ט %1$s + %1$s שינה את %2$s ווידג\'ט + הסרת את ווידג\'ט %1$s + %1$s הסיר את %2$s ווידג\'ט + הוספת ווידג\'ט %1$s + %1$s הוסיף %2$s ווידג\'ט + קיבלת את ההזמנה עבור %1$s + %1$s קיבל את ההזמנה עבור %2$s + ביטלת את ההזמנה עבור %1$s + %1$s ביטל/ה את ההזמנה עבור %2$s + ביטלת את ההזמנה של %1$s להצטרף לחדר + %1$s ביטל/ה את ההזמנה של %2$s להצטרף לחדר + הזמנת את %1$s + %1$s הזמין את %2$s + שלחת הזמנה אל %1$s להצטרף לחדר + %1$s שלח הזמנה אל %2$s להצטרף לחדר + עדכנת את הפרופיל שלך %1$s + %1$s עדכן את הפרופיל שלו %2$s + הודעה הוסרה על ידי %1$s [סיבה: %2$s] + ההודעה הוסרה [סיבה: %1$s] + ההודעה הוסרה על ידי %1$s + ההודעה הוסרה + הסרת את דמות החדר + %1$s הסיר את דמות החדר + הסרת את נושא החדר + %1$s הסיר את נושא החדר + הסרת את שם החדר + %1$s הסיר את שם החדר + (גם האווטאר השתנה) + ועידת VoIP הסתיימה + ועידת VoIP החלה + ביקשת ועידת VoIP + %1$s ביקש ועידת VoIP + 🎉 כל השרתים אסורים להשתתף! לא ניתן עוד להשתמש בחדר זה. + ללא שינוי. + • שרתים התואמים ל-%s מורשים כעת. + • שרתים התואמים ל-%s הוסרו מרשימת המורשים. + • שרתים התואמים ל-%s הוסרו מרשימת החסומים. + • שרתים התואמים ל-%s נאסרו כעת. + שינית את רשימות ה-ACL של השרת עבור החדר הזה. + %s שינה את רשימות ה-ACL של השרת עבור החדר הזה. + • מותרים שרתים התואמים ל-%s. + • שרתים התואמים %s אסורים. + אתה מגדיר את רשימות ה-ACL של השרת עבור החדר הזה. + %s הגדר את רשימות ה-ACL של השרת עבור החדר הזה. + שדרגת כאן. + %s שודרג כאן. + שדרגת את החדר הזה. + %s שדרג את החדר הזה. + הפעלת הצפנה מקצה לקצה (%1$s) + %1$s הפעילה הצפנה מקצה לקצה (%2$s) + לא ידוע (%s). + כל אחד. + כל חברי החדר. + כל חברי החדר, מהנקודה בה הצטרפו. \ No newline at end of file From d51e1a4dfbcdcd6d61af9dc5b18cf25d145a6fe1 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Mon, 21 Feb 2022 12:19:05 +0000 Subject: [PATCH 252/302] Translated using Weblate (Japanese) Currently translated at 91.3% (2545 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 350ccedc38..b91820ca9b 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -42,7 +42,7 @@ VoIP会議が終了しました (アバターも変更されました) %1$sがルーム名を削除しました - %1$sがルームのトピックを削除しました + %1$sがルームの説明を削除しました %1$sがプロフィール %2$s を更新しました %1$sが%2$sにルームへの招待を送りました %1$sが%2$sの招待を受け入れました @@ -808,8 +808,8 @@ 指定したユーザーを現在のルームに招待 指定されたアドレスのルームに参加 ルームを退室 - ルームのテーマを設定 - 指定したIDのユーザーとの接続を切断 + ルームの説明を設定 + 指定したIDのユーザーをこのルームから追放 表示するニックネームを変更 Markdown書式の入/切 Matrixアプリの管理を修正するには @@ -1028,7 +1028,7 @@ アカウントデータ 削除… 削除の確認 - このイベントを削除してよろしいですか?ルーム名やトピックの変更を削除すると、変更が元に戻る点にご注意ください。 + このイベントを削除してよろしいですか?ルーム名や説明の変更を削除すると、変更が取り消されますのでご注意ください。 暗号化は有効です このルーム内でのメッセージはエンドツーエンド暗号化されます。詳細の確認や検証はユーザーのプロフィールをご確認ください。 暗号化が有効になっていません @@ -1444,7 +1444,7 @@ メッセージが削除されました ルームのアバターを削除しました %1$sがルームのアバターを削除しました - ルームのトピックを削除しました + ルームの説明を削除しました ルーム名を削除しました 許可を与える ${app_name}は、確実に通知を受け取るために、影響の少ないバックグラウンド接続を維持する必要があります。 @@ -1852,7 +1852,7 @@ \n%s ルームの設定 トピック - ルームトピック(オプション) + ルームの説明(任意) ルーム名 このルームはプレビューできません。参加しますか? 現在、このルームにはアクセスできません。 @@ -2365,9 +2365,9 @@ %sとのコマンドは認識されていますが、スレッドではサポートされていません。 誰でもスペースを発見し参加できます 法的情報 - ユーザーに関する情報を表示します - このルームにおいてのみアバターを変更します - このルームにおいてのみ表示名を変更します + ユーザーに関する情報を表示 + このルームにおいてのみアバターを変更 + このルームにおいてのみ表示名を変更 ユーザーの無視を解除し、以後のメッセージを表示します 続行するには%sを入力してください 復旧用のパスフレーズ From eeb9785651d844ba2675c0c684f210638ebb1762 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 21 Feb 2022 13:03:31 +0000 Subject: [PATCH 253/302] limiting the room bitmap loader image size, the notification icon size is relatively small and there's no cap on the image size --- .../im/vector/app/features/notifications/BitmapLoader.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/BitmapLoader.kt b/vector/src/main/java/im/vector/app/features/notifications/BitmapLoader.kt index da0f071841..9190141dfb 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/BitmapLoader.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/BitmapLoader.kt @@ -21,6 +21,7 @@ import android.graphics.Bitmap import androidx.annotation.WorkerThread import com.bumptech.glide.Glide import com.bumptech.glide.load.DecodeFormat +import com.bumptech.glide.signature.ObjectKey import timber.log.Timber import javax.inject.Inject import javax.inject.Singleton @@ -28,6 +29,9 @@ import javax.inject.Singleton @Singleton class BitmapLoader @Inject constructor(private val context: Context) { + private val iconWidth = context.resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_width) + private val iconHeight = context.resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_height) + /** * Get icon of a room. * If already in cache, use it, else load it and call BitmapLoaderListener.onBitmapsLoaded() when ready @@ -47,8 +51,10 @@ class BitmapLoader @Inject constructor(private val context: Context) { Glide.with(context) .asBitmap() .load(path) + .fitCenter() .format(DecodeFormat.PREFER_ARGB_8888) - .submit() + .signature(ObjectKey("room-icon-notification")) + .submit(iconWidth, iconHeight) .get() } catch (e: Exception) { Timber.e(e, "decodeFile failed") From f050fc1e4ae757d4b947b2257d905cc0bba6d8fd Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Mon, 21 Feb 2022 14:55:08 +0100 Subject: [PATCH 254/302] Returning empty viewState instead of null to avoid crash --- .../app/features/signout/soft/SoftLogoutViewModel.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt index 84b443a60f..00422d8872 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt @@ -56,7 +56,7 @@ class SoftLogoutViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { - override fun initialState(viewModelContext: ViewModelContext): SoftLogoutViewState? { + override fun initialState(viewModelContext: ViewModelContext): SoftLogoutViewState { val sessionHolder = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java) .activeSessionHolder() @@ -72,7 +72,13 @@ class SoftLogoutViewModel @AssistedInject constructor( hasUnsavedKeys = session.hasUnsavedKeys() ) } else { - null + SoftLogoutViewState( + homeServerUrl = "", + userId = "", + deviceId = "", + userDisplayName = "", + hasUnsavedKeys = false + ) } } } From 95c00a1cce66946ce1c62d6f143891db575d0287 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 21 Feb 2022 17:52:26 +0100 Subject: [PATCH 255/302] Udpate comment --- .../internal/crypto/store/db/migration/MigrateCryptoTo015.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt index 7bfea7d72f..465c18555a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -// Version 14L Update the way we remember key sharing +// Version 15L adds wasEncryptedOnce field to CryptoRoomEntity class MigrateCryptoTo015(realm: DynamicRealm) : RealmMigrator(realm, 15) { override fun doMigrate(realm: DynamicRealm) { From 9f44975b4a23ec6bf3398e8dc24862ac49acbe3a Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 21 Feb 2022 16:54:51 +0000 Subject: [PATCH 256/302] tranforming images for adaptive shortcuts within glides transformations - avoid creating new bitmaps each time the room list changes --- .../home/AdaptiveIconTransformation.kt | 54 +++++++++++++++++++ .../app/features/home/AvatarRenderer.kt | 45 +++++++++++----- .../app/features/home/ShortcutCreator.kt | 14 ++--- 3 files changed, 92 insertions(+), 21 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/home/AdaptiveIconTransformation.kt diff --git a/vector/src/main/java/im/vector/app/features/home/AdaptiveIconTransformation.kt b/vector/src/main/java/im/vector/app/features/home/AdaptiveIconTransformation.kt new file mode 100644 index 0000000000..9efd842e58 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/AdaptiveIconTransformation.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 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.home + +import android.graphics.Bitmap +import android.graphics.Canvas +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool +import com.bumptech.glide.load.resource.bitmap.BitmapTransformation +import com.bumptech.glide.util.Util +import java.nio.ByteBuffer +import java.security.MessageDigest + +private const val ADAPTIVE_TRANSFORMATION_ID = "adaptive-icon-transform" +private val ID_BYTES = ADAPTIVE_TRANSFORMATION_ID.toByteArray() + +class AdaptiveIconTransformation(private val adaptiveIconSize: Int, private val adaptiveIconOuterSides: Float) : BitmapTransformation() { + + override fun updateDiskCacheKey(messageDigest: MessageDigest) { + messageDigest.update(ID_BYTES) + messageDigest.update(ByteBuffer.allocate(4).putInt(adaptiveIconSize).putFloat(adaptiveIconOuterSides).array()) + } + + override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap { + val insetBmp = Bitmap.createBitmap(adaptiveIconSize, adaptiveIconSize, Bitmap.Config.ARGB_8888) + val canvas = Canvas(insetBmp) + canvas.drawBitmap(toTransform, adaptiveIconOuterSides, adaptiveIconOuterSides, null) + canvas.setBitmap(null) + return insetBmp + } + + override fun equals(other: Any?): Boolean { + return if (other is AdaptiveIconTransformation) { + other.adaptiveIconSize == adaptiveIconSize && other.adaptiveIconOuterSides == adaptiveIconOuterSides + } else { + false + } + } + + override fun hashCode() = Util.hashCode(ADAPTIVE_TRANSFORMATION_ID.hashCode(), Util.hashCode(adaptiveIconSize, Util.hashCode(adaptiveIconOuterSides))) +} diff --git a/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt b/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt index 2ee3233637..d8a8409f5a 100644 --- a/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt @@ -26,6 +26,7 @@ import androidx.core.graphics.drawable.toBitmap import com.amulyakhare.textdrawable.TextDrawable import com.bumptech.glide.load.MultiTransformation import com.bumptech.glide.load.Transformation +import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.resource.bitmap.CenterCrop import com.bumptech.glide.load.resource.bitmap.CircleCrop import com.bumptech.glide.load.resource.bitmap.RoundedCorners @@ -157,25 +158,41 @@ class AvatarRenderer @Inject constructor(private val activeSessionHolder: Active fun shortcutDrawable(glideRequests: GlideRequests, matrixItem: MatrixItem, iconSize: Int): Bitmap { return glideRequests .asBitmap() - .let { - val resolvedUrl = resolvedUrl(matrixItem.avatarUrl) - if (resolvedUrl != null) { - it.load(resolvedUrl) - } else { - val avatarColor = matrixItemColorProvider.getColor(matrixItem) - it.load(TextDrawable.builder() - .beginConfig() - .bold() - .endConfig() - .buildRect(matrixItem.firstLetterOfDisplayName(), avatarColor) - .toBitmap(width = iconSize, height = iconSize)) - } - } + .avatarOrText(matrixItem, iconSize) .apply(RequestOptions.centerCropTransform()) .submit(iconSize, iconSize) .get() } + @AnyThread + @Throws + fun adaptiveShortcutDrawable(glideRequests: GlideRequests, matrixItem: MatrixItem, iconSize: Int, adaptiveIconSize: Int, adaptiveIconOuterSides: Float): Bitmap { + return glideRequests + .asBitmap() + .avatarOrText(matrixItem, iconSize) + .transform(CenterCrop(), AdaptiveIconTransformation(adaptiveIconSize, adaptiveIconOuterSides)) + .diskCacheStrategy(DiskCacheStrategy.RESOURCE) + .submit(adaptiveIconSize, adaptiveIconSize) + .get() + } + + private fun GlideRequest.avatarOrText(matrixItem: MatrixItem, iconSize: Int): GlideRequest { + return this.let { + val resolvedUrl = resolvedUrl(matrixItem.avatarUrl) + if (resolvedUrl != null) { + it.load(resolvedUrl) + } else { + val avatarColor = matrixItemColorProvider.getColor(matrixItem) + it.load(TextDrawable.builder() + .beginConfig() + .bold() + .endConfig() + .buildRect(matrixItem.firstLetterOfDisplayName(), avatarColor) + .toBitmap(width = iconSize, height = iconSize)) + } + } + } + @UiThread fun renderBlur(matrixItem: MatrixItem, imageView: ImageView, diff --git a/vector/src/main/java/im/vector/app/features/home/ShortcutCreator.kt b/vector/src/main/java/im/vector/app/features/home/ShortcutCreator.kt index ee7edc021d..082d318cc7 100644 --- a/vector/src/main/java/im/vector/app/features/home/ShortcutCreator.kt +++ b/vector/src/main/java/im/vector/app/features/home/ShortcutCreator.kt @@ -19,7 +19,6 @@ package im.vector.app.features.home import android.content.Context import android.content.pm.ShortcutInfo import android.graphics.Bitmap -import android.graphics.Canvas import android.os.Build import androidx.annotation.WorkerThread import androidx.core.content.pm.ShortcutInfoCompat @@ -61,7 +60,12 @@ class ShortcutCreator @Inject constructor( fun create(roomSummary: RoomSummary, rank: Int = 1): ShortcutInfoCompat { val intent = RoomDetailActivity.shortcutIntent(context, roomSummary.roomId) val bitmap = try { - avatarRenderer.shortcutDrawable(GlideApp.with(context), roomSummary.toMatrixItem(), iconSize) + val glideRequests = GlideApp.with(context) + val matrixItem = roomSummary.toMatrixItem() + when (useAdaptiveIcon) { + true -> avatarRenderer.adaptiveShortcutDrawable(glideRequests, matrixItem, iconSize, adaptiveIconSize, adaptiveIconOuterSides.toFloat()) + false -> avatarRenderer.shortcutDrawable(glideRequests, matrixItem, iconSize) + } } catch (failure: Throwable) { null } @@ -83,11 +87,7 @@ class ShortcutCreator @Inject constructor( private fun Bitmap.toProfileImageIcon(): IconCompat { return if (useAdaptiveIcon) { - val insetBmp = Bitmap.createBitmap(adaptiveIconSize, adaptiveIconSize, Bitmap.Config.ARGB_8888) - val canvas = Canvas(insetBmp) - canvas.drawBitmap(this, adaptiveIconOuterSides.toFloat(), adaptiveIconOuterSides.toFloat(), null) - - IconCompat.createWithAdaptiveBitmap(insetBmp) + IconCompat.createWithAdaptiveBitmap(this) } else { IconCompat.createWithBitmap(this) } From 33c30e27faa68a64b07a04dbd9e13a48f96f1ad2 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 21 Feb 2022 17:14:36 +0000 Subject: [PATCH 257/302] flattening the room and user icon loading into the same file --- .../features/notifications/BitmapLoader.kt | 65 ------------- .../app/features/notifications/IconLoader.kt | 66 ------------- .../notifications/NotificationBitmapLoader.kt | 92 +++++++++++++++++++ .../notifications/RoomGroupMessageCreator.kt | 11 +-- 4 files changed, 96 insertions(+), 138 deletions(-) delete mode 100644 vector/src/main/java/im/vector/app/features/notifications/BitmapLoader.kt delete mode 100644 vector/src/main/java/im/vector/app/features/notifications/IconLoader.kt create mode 100644 vector/src/main/java/im/vector/app/features/notifications/NotificationBitmapLoader.kt diff --git a/vector/src/main/java/im/vector/app/features/notifications/BitmapLoader.kt b/vector/src/main/java/im/vector/app/features/notifications/BitmapLoader.kt deleted file mode 100644 index 9190141dfb..0000000000 --- a/vector/src/main/java/im/vector/app/features/notifications/BitmapLoader.kt +++ /dev/null @@ -1,65 +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.notifications - -import android.content.Context -import android.graphics.Bitmap -import androidx.annotation.WorkerThread -import com.bumptech.glide.Glide -import com.bumptech.glide.load.DecodeFormat -import com.bumptech.glide.signature.ObjectKey -import timber.log.Timber -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class BitmapLoader @Inject constructor(private val context: Context) { - - private val iconWidth = context.resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_width) - private val iconHeight = context.resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_height) - - /** - * Get icon of a room. - * If already in cache, use it, else load it and call BitmapLoaderListener.onBitmapsLoaded() when ready - */ - @WorkerThread - fun getRoomBitmap(path: String?): Bitmap? { - if (path == null) { - return null - } - return loadRoomBitmap(path) - } - - @WorkerThread - private fun loadRoomBitmap(path: String): Bitmap? { - return path.let { - try { - Glide.with(context) - .asBitmap() - .load(path) - .fitCenter() - .format(DecodeFormat.PREFER_ARGB_8888) - .signature(ObjectKey("room-icon-notification")) - .submit(iconWidth, iconHeight) - .get() - } catch (e: Exception) { - Timber.e(e, "decodeFile failed") - null - } - } - } -} diff --git a/vector/src/main/java/im/vector/app/features/notifications/IconLoader.kt b/vector/src/main/java/im/vector/app/features/notifications/IconLoader.kt deleted file mode 100644 index ec53e89d57..0000000000 --- a/vector/src/main/java/im/vector/app/features/notifications/IconLoader.kt +++ /dev/null @@ -1,66 +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.notifications - -import android.content.Context -import android.os.Build -import androidx.annotation.WorkerThread -import androidx.core.graphics.drawable.IconCompat -import com.bumptech.glide.Glide -import com.bumptech.glide.load.DecodeFormat -import com.bumptech.glide.request.RequestOptions -import timber.log.Timber -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class IconLoader @Inject constructor(private val context: Context) { - - /** - * Get icon of a user. - * If already in cache, use it, else load it and call IconLoaderListener.onIconsLoaded() when ready - * Before Android P, this does nothing because the icon won't be used - */ - @WorkerThread - fun getUserIcon(path: String?): IconCompat? { - if (path == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { - return null - } - - return loadUserIcon(path) - } - - @WorkerThread - private fun loadUserIcon(path: String): IconCompat? { - return path.let { - try { - Glide.with(context) - .asBitmap() - .load(path) - .apply(RequestOptions.circleCropTransform() - .format(DecodeFormat.PREFER_ARGB_8888)) - .submit() - .get() - } catch (e: Exception) { - Timber.e(e, "decodeFile failed") - null - }?.let { bitmap -> - IconCompat.createWithBitmap(bitmap) - } - } - } -} diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationBitmapLoader.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationBitmapLoader.kt new file mode 100644 index 0000000000..518b011ffd --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationBitmapLoader.kt @@ -0,0 +1,92 @@ +/* + * 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.notifications + +import android.content.Context +import android.graphics.Bitmap +import android.os.Build +import androidx.annotation.WorkerThread +import androidx.core.graphics.drawable.IconCompat +import com.bumptech.glide.Glide +import com.bumptech.glide.load.DecodeFormat +import com.bumptech.glide.load.resource.bitmap.CircleCrop +import com.bumptech.glide.signature.ObjectKey +import timber.log.Timber +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class NotificationBitmapLoader @Inject constructor(private val context: Context) { + + /** + * Get icon of a room + */ + @WorkerThread + fun getRoomBitmap(path: String?): Bitmap? { + if (path == null) { + return null + } + return loadRoomBitmap(path) + } + + @WorkerThread + private fun loadRoomBitmap(path: String): Bitmap? { + return try { + Glide.with(context) + .asBitmap() + .load(path) + .format(DecodeFormat.PREFER_ARGB_8888) + .signature(ObjectKey("room-icon-notification")) + .submit() + .get() + } catch (e: Exception) { + Timber.e(e, "decodeFile failed") + null + } + } + + /** + * Get icon of a user. + * Before Android P, this does nothing because the icon won't be used + */ + @WorkerThread + fun getUserIcon(path: String?): IconCompat? { + if (path == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { + return null + } + + return loadUserIcon(path) + } + + @WorkerThread + private fun loadUserIcon(path: String): IconCompat? { + return try { + val bitmap = Glide.with(context) + .asBitmap() + .load(path) + .transform(CircleCrop()) + .format(DecodeFormat.PREFER_ARGB_8888) + .signature(ObjectKey("user-icon-notification")) + .submit() + .get() + IconCompat.createWithBitmap(bitmap) + } catch (e: Exception) { + Timber.e(e, "decodeFile failed") + null + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt index b57c81f686..8310c15daa 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt @@ -16,7 +16,6 @@ package im.vector.app.features.notifications -import android.content.Context import android.graphics.Bitmap import androidx.core.app.NotificationCompat import androidx.core.app.Person @@ -28,11 +27,9 @@ import timber.log.Timber import javax.inject.Inject class RoomGroupMessageCreator @Inject constructor( - private val iconLoader: IconLoader, - private val bitmapLoader: BitmapLoader, + private val bitmapLoader: NotificationBitmapLoader, private val stringProvider: StringProvider, - private val notificationUtils: NotificationUtils, - private val appContext: Context + private val notificationUtils: NotificationUtils ) { fun createRoomMessage(events: List, roomId: String, userDisplayName: String, userAvatarUrl: String?): RoomNotification.Message { @@ -41,7 +38,7 @@ class RoomGroupMessageCreator @Inject constructor( val roomIsGroup = !firstKnownRoomEvent.roomIsDirect val style = NotificationCompat.MessagingStyle(Person.Builder() .setName(userDisplayName) - .setIcon(iconLoader.getUserIcon(userAvatarUrl)) + .setIcon(bitmapLoader.getUserIcon(userAvatarUrl)) .setKey(firstKnownRoomEvent.matrixID) .build() ).also { @@ -92,7 +89,7 @@ class RoomGroupMessageCreator @Inject constructor( } else { Person.Builder() .setName(event.senderName) - .setIcon(iconLoader.getUserIcon(event.senderAvatarPath)) + .setIcon(bitmapLoader.getUserIcon(event.senderAvatarPath)) .setKey(event.senderId) .build() } From 5bbb3f28b14186e750385cfa3bb6cb308e453ccf Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 21 Feb 2022 17:30:45 +0000 Subject: [PATCH 258/302] adding changelog entry --- changelog.d/5276.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5276.misc diff --git a/changelog.d/5276.misc b/changelog.d/5276.misc new file mode 100644 index 0000000000..437bd28eb6 --- /dev/null +++ b/changelog.d/5276.misc @@ -0,0 +1 @@ +Improves bitmap memory usage by caching the shortcut images \ No newline at end of file From 506690a8979a58203f0a1cf9dc31acde0cabf050 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 21 Feb 2022 17:54:05 +0000 Subject: [PATCH 259/302] fixing wrong shortcut icon size and ensuring the transformed files are stored with unique keys --- .../im/vector/app/features/home/AdaptiveIconTransformation.kt | 2 +- .../main/java/im/vector/app/features/home/AvatarRenderer.kt | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/AdaptiveIconTransformation.kt b/vector/src/main/java/im/vector/app/features/home/AdaptiveIconTransformation.kt index 9efd842e58..6eb41a1d85 100644 --- a/vector/src/main/java/im/vector/app/features/home/AdaptiveIconTransformation.kt +++ b/vector/src/main/java/im/vector/app/features/home/AdaptiveIconTransformation.kt @@ -31,7 +31,7 @@ class AdaptiveIconTransformation(private val adaptiveIconSize: Int, private val override fun updateDiskCacheKey(messageDigest: MessageDigest) { messageDigest.update(ID_BYTES) - messageDigest.update(ByteBuffer.allocate(4).putInt(adaptiveIconSize).putFloat(adaptiveIconOuterSides).array()) + messageDigest.update(ByteBuffer.allocate(8).putInt(adaptiveIconSize).putFloat(adaptiveIconOuterSides).array()) } override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap { diff --git a/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt b/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt index d8a8409f5a..5b96caa3f1 100644 --- a/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt @@ -33,6 +33,7 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.target.DrawableImageViewTarget import com.bumptech.glide.request.target.Target +import com.bumptech.glide.signature.ObjectKey import im.vector.app.core.contacts.MappedContact import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.glide.AvatarPlaceholder @@ -171,8 +172,9 @@ class AvatarRenderer @Inject constructor(private val activeSessionHolder: Active .asBitmap() .avatarOrText(matrixItem, iconSize) .transform(CenterCrop(), AdaptiveIconTransformation(adaptiveIconSize, adaptiveIconOuterSides)) + .signature(ObjectKey("adaptive-icon")) .diskCacheStrategy(DiskCacheStrategy.RESOURCE) - .submit(adaptiveIconSize, adaptiveIconSize) + .submit(iconSize, iconSize) .get() } From 6ded62a9fa30d2e8676ae33d3f4923818bb87f72 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Mon, 21 Feb 2022 23:49:44 +0000 Subject: [PATCH 260/302] Translated using Weblate (Japanese) Currently translated at 91.6% (2552 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 272 +++++++++++----------- 1 file changed, 140 insertions(+), 132 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index b91820ca9b..b604f11442 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -144,9 +144,9 @@ ユーザー名かパスワードが正しくありません ユーザー名は半角英数字、ドット、ハイフン、アンダースコアのみで記して下さい パスワードが短すぎます(最小6文字) - 正しくないメールアドレスのようです - 正しくない電話番号のようです - 既に登録されているメールアドレスです。 + メールアドレスの形式が正しくありません + 電話番号の形式が正しくありません + このメールアドレスは既に登録されています。 パスワードが一致しません パスワードを忘れましたか? 登録を続行するにはメールボックスを確認して下さい @@ -172,7 +172,7 @@ 呼び出し中です… はい いいえ - 続行 + 続行する 最新の未読へ移動 ルームを退出 このルームを退出してよろしいですか? @@ -278,7 +278,7 @@ 言語 インターフェース 認証を確認中 - 電子メールを確認して、本文中のURLをクリックしてください。 完了したら「続ける」をクリックしてください。 + 電子メールを確認して、本文中のURLをクリックしてください。 完了したら「続行する」をクリックしてください。 このメールアドレスは既に使われています。 あなたのパスワードは更新されました 国を選択 @@ -348,14 +348,14 @@ 復号化されたソースコードを表示 名前変更 オフライン - 会話を開始 + チャットを開始 音声通話を開始 ビデオ通話を開始 写真または動画を撮影 再設定用のメールを送信 写真撮影やビデオ通話には、${app_name}端末のカメラの使用を許可する必要があります。 通話を開始できませんでした。後ほど試してください - 権限が無いため、一部の機能を利用できない可能性があります… + 権限がないため、一部の機能を利用できない可能性があります… このルームで会議を開始するためには招待の権限が必要です 無視して送る サインアウト @@ -398,7 +398,7 @@ パスワードを再設定するには、アカウントに登録されているメールアドレスを入力してください: アカウントに登録されたメールアドレスの入力が必要です。 新しいパスワードの入力が必要です。 - %sへ電子メールが送信されました。リンクにアクセスしてから、以下をクリックしてください。 + %sへ電子メールが送信されました。メール内のリンクにアクセスしてから、以下をクリックしてください。 メールアドレスの確認に失敗しました:電子メールのリンクをクリックしたことを確認してください パスワードがリセットされました。 \n @@ -604,7 +604,7 @@ 未読のあるルームを固定 分析 データ節約モード - メールアドレスを認証できません。メールを確認して、記載されているリンクをクリックしてください。その後、「続ける」をクリックしてください。 + メールアドレスを認証できません。メールを確認して、記載されているリンクをクリックしてください。その後、「続行する」をクリックしてください。 この通知の対象を削除してよろしいですか? %1$s %2$sを削除してよろしいですか? コード @@ -686,11 +686,11 @@ ルーム 参加済 招待済 - グループのメンバーをフィルタリング - グループのルームを絞り込み + グループのメンバーを絞り込む + グループのルームを絞り込む 管理者はこのコミュニティーの詳細を規定していません。 - %2$sによって%1$sから除外されました - %2$sによって%1$sへの参加を禁止されました + %2$sによって%1$sから追放されました + %2$sによって%1$sからブロックされました 理由:%1$s 再参加 端末を振って不具合を報告 @@ -817,44 +817,44 @@ %d名のメンバー - %dルーム + %d個のルーム - アバターを読み込み - %1$のホームサーバーを使用し続けるには、利用規約を読み、同意する必要があります。 + 開封確認用のアバター + %1$sのホームサーバーの使用を継続するには、利用規約を確認し、同意する必要があります。 エラー - アバターに通知を表示 - 今すぐ見る + 通知用のアバター + 今すぐ確認 アカウントを停止 この操作により、あなたのアカウントは永久に使えなくなります。あなたはログインできなくなり、誰も同じユーザーIDを再登録できなくなります。アカウントが参加している全てのルームを退出し、IDサーバーからアカウントの詳細は削除されます。 この操作は取り消せません。 \n \nアカウントを停止しても、 デフォルトではあなたが送信したメッセージの履歴は消去されません。メッセージの履歴の消去を望む場合は、以下のボックスにチェックを入れてください。 \n -\nMatrixのメッセージの見え方は、電子メールと同様のものです。メッセージの履歴を消去すると、あなたが送信したメッセージは、新規または未登録のユーザーには共有されることはありませんが、既にメッセージを取得している登録ユーザーは、今後もそのコピーにアクセスできます。 - アカウントを停止したときに、自分の送信した全てのメッセージの履歴を消去してください(警告: この操作により、今後のユーザーは会話を不完全な形で見ることになります) - 続けるには、パスワードを入力してください: +\nMatrixのメッセージの見え方は、電子メールと同様のものです。メッセージの履歴を消去すると、あなたが送信したメッセージは、新規または未登録のユーザーに共有されることはありませんが、既にメッセージを取得している登録ユーザーは、今後もそのコピーにアクセスできます。 + アカウントを停止するときに、自分の送信した全てのメッセージの履歴を消去してください(警告: この操作により、今後のユーザーは会話を不完全な形で見ることになります) + 続行するには、パスワードを入力してください: アカウントを停止 パスワードを入力してください。 - このルームは置き換えられており、アクティブではありません。 - ここで会話が続いています + このルームは交換されており、使用されていません。 + こちらから継続中の会話を確認 このルームは別の会話の続きです - より古いメッセージを見るには、ここをクリックしてください - リソース制限の超過 + 以前のメッセージを見るには、ここをクリックしてください + リソース制限を超えました 管理者に連絡 - あなたのサービス管理者に連絡 + サービス管理者に連絡してください このホームサーバーはリソース制限の1つを超過しているため、 ユーザーがログインできなくなることがあります このホームサーバーはリソース制限の1つを超過しています。 このホームサーバーは月間アクティブユーザーの上限に達しているため、 ユーザーがログインできなくなることがあります このホームサーバーは月間アクティブユーザーの上限に達しています。 - この上限を上げるには%sしてください。 - このサービスを使い続けるには%sしてください。 - 最初にルームのメンバーのみを読み込むことでパフォーマンスを向上。 - あなたのホームサーバーはルームのメンバーの簡易読み込みをサポートしていません。後で試してください。 - ルームのメンバーの簡易読み込み + この制限を上げるには、%sしてください。 + このサービスを使い続けるには、%sしてください。 + 最初に表示されるルームのメンバーのみを読み込むことでパフォーマンスを向上。 + あなたのホームサーバーは、ルームのメンバーの遅延読み込みをサポートしていません。後で試してください。 + ルームのメンバーの遅延読み込み 申し訳ありません、エラーが発生しました バージョン %s エクスポートされた鍵を暗号化するパスフレーズを作成してください。 鍵をインポートするには、同一のパスフレーズを入力する必要があります。 パスフレーズの作成 - パスフレーズは一致する必要があります + パスフレーズが一致していません 情報領域を表示 常に エラーの場合のみ @@ -941,7 +941,7 @@ 返信 メッセージが削除されました 削除済のメッセージを表示 - 削除されたメッセージの代わりに削除されたという通知を表示します。 + 削除されたメッセージに関する通知を表示 ユーザーによって削除されたイベント 新しいルームを作成 変更 @@ -962,8 +962,8 @@ ダイレクトメッセージ (編集済) 会話を検索… - Matrix ID から追加 - ユーザー名または ID で検索… + Matrix IDから追加 + ユーザー名またはIDで検索… 全てのメッセージ (音量大) 全てのメッセージ メンションのみ @@ -980,7 +980,7 @@ 暗号化を有効にする いったん有効にすると、暗号化を無効にすることはできません。 セキュリティー - 詳細 + 詳しく知る その他の設定 管理者としての操作 ルームの設定 @@ -1043,17 +1043,17 @@ 破棄 再生 一時停止 - 消去 + 閉じる スキップ 完了 無視 レビュー 待機しています… サムネイルを暗号化しています… - サムネイルを送信しています (%1$s/%2$s) + サムネイルを送信しています(%2$s個のうち%1$s個) ファイルを暗号化しています… - ファイルを送信しています (%1$s/%2$s) - ファイル %1$sをダウンロードしています… + ファイルを送信しています(%2$s個のうち%1$s個) + ファイル %1$s をダウンロードしています… ファイル 連絡先 カメラ @@ -1128,7 +1128,7 @@ このURLからホームサーバーに接続できませんでした、ご確認ください 有効なMatrixサーバーのアドレスではありません このURLは検索結果に表示できません、ご確認ください - この電話番号は既に使用されています。 + この電話番号は既に登録されています。 アカウント復旧用のメールアドレスを設定します。後からオプションでメールアドレスや電話番号を使用して知人に見つけてもらえるようにできます。 シングルサインオンを使用してサインイン HDを使用する @@ -1169,8 +1169,8 @@ タイムラインで非表示のイベントを表示 QRコードをスキャン QRコード画像 - QR コード - QR コードによる追加 + QRコード + QRコードによる追加 コードを共有 ${app_name} で会話しましょう:%s 友達を招待 @@ -1454,7 +1454,7 @@ ディスカバリー(発見) これにより、現在のキーまたはフレーズが置き換えられます。 新しいセキュリティーキーを生成するか、既存のバックアップに新しいセキュリティーフレーズを設定します。 - サーバー上の暗号鍵をバックアップすることにより、暗号化されたメッセージとデータへのアクセスが失われるのを予防します。 + サーバー上の暗号鍵をバックアップして、暗号化されたメッセージとデータへのアクセスが失われるのを防ぎましょう。 メッセージ作成画面に絵文字キーボードを開くためのボタンを追加 絵文字キーボードを表示 アバターと表示名の変更を含む。 @@ -1542,11 +1542,11 @@ 鍵のバックアップを使用開始 パスフレーズが弱すぎます パスフレーズを入力してください - Google PlayサービスのAPKが見つかりませんでした。通知がうまく機能しない場合があります。 + Google PlayサービスのAPKが見つかりませんでした。通知が適切に機能しない場合があります。 ユーザー名を入力してください。 無視 共有 - 続けるには利用規約を承認する必要があります。 + 続行するには利用規約を承認する必要があります。 全てブロック 許可 ルームID @@ -1590,7 +1590,7 @@ 安全バックアップを設定 鍵のバックアップで管理 鍵のバックアップを使用 - 暗号化されたメッセージ及びデータへのアクセスを喪失しないための安全措置 + 暗号化されたメッセージとデータへのアクセスが失われるのを防ぎましょう 鍵のバックアップを使用開始 自分でした メッセージの鍵の新しい安全なバックアップが検出されました。 @@ -1627,7 +1627,7 @@ 鍵をダウンロードしています… リカバリーキーを計算しています… バックアップを復元しています: - ネットワークエラー: 接続を確認して再試行してください。 + ネットワークエラー:接続を確認して再試行してください。 このパスフレーズではバックアップを復号化できませんでした。正しいリカバリーパスフレーズを入力したことを確認してください。 リカバリーキーを喪失しましたか? 設定で新しいリカバリーキーを設定できます。 メッセージの復旧 @@ -1664,7 +1664,7 @@ または、リカバリーキーでバックアップを保護し、安全な場所に保存してください。 鍵のコピーを暗号化してホームサーバーに保存します。バックアップを保護するためにパスフレーズを設定してください。 \n -\n最高度のセキュリティーのために、アカウントのパスワードと異なるものに設定することが大切です。 +\n最大限のセキュリティーを確保するために、アカウントのパスワードと異なるものに設定することが大切です。 パスフレーズを使用してバックアップを保護します。 暗号化されたメッセージは、エンドツーエンドの暗号化によって保護されています。これらの暗号化されたメッセージを読むための鍵を持っているのは、あなたと受信者だけです。 \n @@ -1718,7 +1718,7 @@ 既に一覧に載っているサーバーです サーバーまたはそのルーム一覧が見つかりません - 検索したい新しいサーバーの名前を入力してください。 + 探索したい新しいサーバーの名前を入力してください。 新しいサーバーを追加 あなたのサーバー 暗号化されたメッセージの復元 @@ -1759,7 +1759,7 @@ ゲストの参加を許可 ルームへのアクセス 履歴の閲覧権限に関する変更は、今後、このルームで表示されるメッセージにのみ適用されます。既存の履歴の見え方には影響しません。 - 無視して続行 + 無視して続行する 毎回確認 招待 おすすめのルーム @@ -1778,7 +1778,7 @@ アカウント復旧用のメールアドレスを設定します。後からオプションで知人に見つけてもらえるようにできます。 メールアドレスを設定 メールアドレスを確認しました - 検出可能なメールアドレス + 発見可能なメールアドレス 続行するには利用規約を承認してください ホームサーバーの利用規約を承認したら、再試行してください。 次に @@ -1791,18 +1791,18 @@ ユーザー名やパスワードが正しくありません。 入力したパスワードは、スペースで開始または終了していますので、ご確認ください。 そのユーザー名は既に使用されています ユーザー名 - ユーザー名または電子メール + ユーザー名またはメールアドレス %sでサインイン %sでサインアップ - %sで続ける + %sで続行 または - SSOを続行します + シングルサインオンで続行 サインイン サインアップ Element Matrix Servicesに接続 Matrix IDでサインイン Matrix IDでサインイン - もっと詳しく知る + 詳しく知る その他 カスタムと高度な設定 組織向けのプレミアムホスティング @@ -1814,16 +1814,16 @@ エクスペリエンスを拡張およびカスタマイズ 暗号化して会話をプライベートに保つ 直接またはグループで連絡先とチャット - あなたの会話。 それを所有する。 + 自分の会話は、自分のものに。 アカウント復旧用のメールアドレスを設定します。後からオプションで知人に見つけてもらえるようにできます。 ここが%sとのダイレクトメッセージのスタート地点です。 変更履歴はありません メッセージの変更履歴 - ファイル %1$sをダウンロードしました! - ビデオの圧縮%d%% + ファイル %1$s をダウンロードしました! + ビデオを%d%%圧縮しています 画像を圧縮しています… 暗号化されたルームで完全な履歴を表示 - フィードバックを与える + フィードバックを送信 フィードバックを送信できませんでした (%s) ありがとうございます、あなたのフィードバックは正常に送信されました 追加で確認が必要な事項がある場合は、連絡可 @@ -1837,13 +1837,13 @@ app_id: push_key: 登録されたプッシュゲートウェイはありません - プッシュルールが定義されていません + プッシュ通知に関するルールが定義されていません プッシュ通知に関するルール エキスパート クイックリアクション - あなたは既にこのルームを見ています! + あなたは既にこのルームを見ています! その他のサードパーティーの使用に関する掲示 - Matrix SDK バージョン + Matrix SDKバージョン ファイル\"%1$s\"からエンドツーエンド暗号鍵をインポートします。 鍵のバックアップデータの取得中にエラーが発生しました 信頼情報の取得中にエラーが発生しました @@ -1888,7 +1888,7 @@ 不明なエラー ユーザーの不一致 鍵の不一致 - 無効なメッセージを受信しました + 不正なメッセージを受信しました セッションに予期しないメッセージが表示されました SASが一致しませんでした ハッシュコミットメントが一致しませんでした @@ -1904,23 +1904,23 @@ \n%s リクエストはキャンセルされました 鍵の検証 - レガシー検証を使います。 - 何も表示されませんか?全てのクライアントがインタラクティブ検証をまだサポートしているわけではありません。その場合はレガシー検証を使用してください。 + レガシー検証を使用する。 + 何も表示されませんか?インタラクティブな検証をサポートしてないクライアントを使っているかもしれません。その場合は、レガシー検証を使用してください。 了解 - このユーザーとのメッセージはエンドツーエンドで暗号化され第三者が読むことはできません。 + このユーザーとのメッセージはエンドツーエンドで暗号化され、第三者が読むことはできません。 完了しました! 相手が確認するのを待っています… リクエストを見る 検証リクエストを受信しました。 相手の画面に次の番号が表示されていることを確認して、このセッションを検証 - 相手の画面に次の絵文字が表示されることを確認して、このセッションを確認します + 相手の画面に次の絵文字が表示されることを確認して、このセッションを検証 このセッションを検証すると、信頼済としてマークされ、自分も相手に信頼済としてマークされます。 - このセッションを検証して、信頼済としてマークします。相手のセッションを信頼すると、さらに安心してエンドツーエンド暗号化を使用することができます。 - 入力された検証要求 - 検証を開始します - 最大限のセキュリティーを確保するために、これを対面で行うか、別の信頼済の通信手段を用いることを推奨します。 + このセッションを検証して、信頼済としてマークします。相手のセッションを信頼すると、より一層安心してエンドツーエンド暗号化を使用することができます。 + 検証リクエストがあります + 検証を開始 + セキュリティを最大限に高めるために、これを対面で行うか、他の信頼できる通信手段を使用することを推奨します。 短い文字列を比較して検証します。 - 認証情報が不正または期限切れのため、ログアウトされました。 + 認証情報が不正または期限切れのため、ログアウトしました。 構成を使用 ${app_name}がuserIdドメイン\"%1$s\"のカスタムサーバー構成を検出しました。 \n%2$s @@ -1976,26 +1976,26 @@ 権限がありません 音声メッセージを送信するには、マイクの権限を許可してください。 この操作を実行するには、システム設定からカメラの権限を許可してください。 - この操作を実行するための権限が不足しています。システム設定から権限を付与してください。 + この操作を実行するための権限がありません。システム設定から権限を付与してください。 IDサーバーに接続できませんでした IDサーバーのURLを入力 - 連絡先を発見するために、あなたの連絡先のデータ(電話番号や電子メール)を、設定されたIDサーバー(%1$s)に送信することを承認しますか? + 連絡先を発見するために、あなたの連絡先のデータ(電話番号やメールアドレス)を、設定されたIDサーバー(%1$s)に送信することを承認しますか? \n \nプライバシーの保護のため、データは送信前にハッシュ化されます。 - メールと電話番号を送信 + メールアドレスと電話番号を送信 同意する 同意を撤回 - あなたの連絡先から他のユーザーを発見するために、電子メールや電話番号をこのIDサーバーに送信することに同意していません。 - あなたの連絡先から他のユーザーを発見するために、このIDサーバーにメールや電話番号を送信することに同意しています。 + あなたの連絡先から他のユーザーを発見するために、メールアドレスや電話番号をこのIDサーバーに送信することに同意していません。 + あなたの連絡先から他のユーザーを発見するために、メールアドレスや電話番号をこのIDサーバーに送信することに同意しています。 メールと電話番号を送信 未確認 %sに確認メールを送りました。まず、メールを確認してリンクをクリックしてください %sに確認のためのメールを送りました。メールにて確認リンクをクリックしてください - 検出可能な電話番号 + 発見可能な電話番号 IDサーバーとの接続を解除すると、他のユーザーによって発見されなくなり、また、メールアドレスや電話で他のユーザーを招待することができなくなります。 電話番号を追加すると、発見可能に設定する電話番号を選択できるようになります。 メールアドレスを追加すると、発見可能に設定するメールアドレスを選択できるようになります。 - 現在、IDサーバーを使用していません。あなたの知っている連絡先を発見したり、その連絡先から発見されるようにするには、以下を設定してください。 + 現在、IDサーバーを使用していません。あなたの知っている連絡先を発見したり、その連絡先から発見されるようにするには、以下でIDサーバーを設定してください。 あなたは現在%1$sを使って連絡先を見つけたり、連絡先から見つけられるようにしています。 IDサーバーを変更 IDサーバーの設定 @@ -2011,7 +2011,7 @@ 連絡先 最近の 入力すると検索結果が表示されます - 結果が見つかりません、matrix IDを使ってサーバー上で検索してください。 + 結果が見つかりません。Matrix IDを使ってサーバー上で検索してください。 クリップボードにコピーされたリンク メイン画面に未読通知専用のタブを追加する。 ルーム名を検索 @@ -2033,9 +2033,9 @@ \n- あなたの端末が使用しているインターネット接続 \n \n設定画面からパスワードとリカバリーキーを早急に変更することを推奨します。 - Eメール + 電子メール アドレス - 継続 + 続行する ファイル このユーザーはスペースから追放されます。 \n @@ -2064,7 +2064,7 @@ 現在のルームのスレッドを全て表示 ユーザーをブロックすると、ユーザーはこのスペースから追放され、二度と参加できなくなります。 PINコードを有効にする - これを招待者のみ参加可能に設定しました。 + これを「招待者のみ参加可能」に設定しました。 ルームの設定 コンテンツが報告されました ヘルプとサポート @@ -2077,13 +2077,13 @@ ユーザーを自動的に招待 ユーザー ブロックを解除すると、ユーザーはスペースに再び参加できるようになります。 - このルームを招待者のみ参加可能に設定しました。 + このルームを「招待者のみ参加可能」に設定しました。 低優先度から削除 低優先度に追加 スパムとして報告済 このルームにファイルはありません このルームにメディアはありません - 公開ルームをアップグレード + 公開されたルームをアップグレード 非公開スペース 公開スペース 送信済 @@ -2119,9 +2119,9 @@ 警告 警告 成功しました! - 続ける + 続行する 警告! - ロケーション + 位置情報 メディア 投票終了 投票を終了しますか? @@ -2138,7 +2138,7 @@ ルームのアップグレードには権限が必要です アップグレード アップグレードが必要です - 非公開ルームをアップグレード + 非公開のルームをアップグレード 音声メッセージを一時停止 音声メッセージを有効にする このメールアドレスをアカウントにリンク @@ -2149,20 +2149,20 @@ 投票を終了 選択肢%1$d 選択肢を作成 - ロケーション - ロケーションを共有 - ロケーションの共有を有効にする + 位置情報 + 位置情報を共有 + 位置情報の共有を有効にする 地図を読み込めませんでした スレッドで返信 - ロケーションを共有 - ロケーションを共有 + 位置情報を共有 + 位置情報を共有 カメラを開く 画像と動画を送信 ファイルをアップロード 連絡先を開く ステッカーを送信 投票を作成 - ロケーションを共有 + 位置情報を共有 スペースに関する変更を行うために必要な役割を更新する権限がありません スペースに関する変更を行うために必要な役割を選択 スペースに関する変更を行うために必要な役割を表示し更新します。 @@ -2176,7 +2176,7 @@ 応答がありません スレッドへのリンクをコピー 有効にする - もっと知る + 詳しく知る あなたのIDサーバーのポリシー 新しいルームを作成 認証コードが正しくありません。 @@ -2205,7 +2205,7 @@ 暗号化が正しく設定されていないため、メッセージを送ることができません。クリックして設定を開いてください。 暗号化が正しく設定されていないため、メッセージを送ることができません。管理者に連絡して、暗号化を正しい状態に復元してください。 %2$dの%1$d - あなたは既にこのスレッドを見ています! + あなたは既にこのスレッドを見ています! ルームに表示 ルームに表示 スレッドを表示 @@ -2261,8 +2261,8 @@ 添付ファイルを送信 詳細なログを有効にする。 メールアドレスか電話番号でアカウントを見つけてもらえるようにするには、IDサーバー(%s)の利用規約への同意が必要です。 - ${app_name}はロケーションにアクセスできませんでした - ${app_name}はロケーションにアクセスできませんでした。後でもう一度やり直してください。 + ${app_name}は位置情報にアクセスできませんでした + ${app_name}は位置情報にアクセスできませんでした。後でもう一度やり直してください。 音声メッセージ(%1$s) 推奨のルームバージョンへとアップグレード 音声メッセージを録音 @@ -2292,7 +2292,7 @@ イベントを送信しました! 送信に失敗した全てのメッセージを削除 失敗しました - 公開スペース + 公開されたスペース 公開されたルーム アバターを削除 アバターを変更 @@ -2309,14 +2309,14 @@ PINコードを忘れましたか? PINコードを入力 PINコードを確認 - ユーザーのロケーションをタイムラインに表示 - 一度有効にすると、ロケーションはどのルームにも送れるようになります + ユーザーの位置情報をタイムラインに表示 + 一度有効にすると、位置情報はどのルームにも送れるようになります サードパーティー製ライブラリー これはいつでも設定から無効にできます 私たちは、情報を第三者と共有することはありません 私たちは、アカウントのデータを記録したり分析したりすることはありません Elementの改善を手伝う - リンクを知っている人がアクセスできるようにこのルームを設定しました。 + このルームを「リンクを知っている人が参加可能」に設定しました。 どのユーザーも無視していません キーワードを入力するとリアクションを検索できます。 変更を加えませんでした @@ -2349,7 +2349,7 @@ シェイクを検出しました! 電話を振って、しきい値を試してください 検出のしきい値 - 予期しないエラーが生じた際に、${app_name}はより頻繁にクラッシュするかもしれません + 予期しないエラーが生じた際に、${app_name}はより頻繁にクラッシュする可能性があります 素早くクラッシュ 開発者モードは隠された機能を有効にするため、アプリケーションが不安定になる恐れがあります。開発者向けです! 復号エラーが生じた際に、自動的にログを送信 @@ -2361,14 +2361,14 @@ 誰がアクセスできますか? 通知は%1$sで管理できます。 暗号化されたルームでのメンションとキーワードによる通知は、携帯端末では利用できません。 - ユーザーを無視し、そのメッセージを非表示にします + ユーザーを無視し、そのメッセージを非表示に設定 %sとのコマンドは認識されていますが、スレッドではサポートされていません。 誰でもスペースを発見し参加できます 法的情報 ユーザーに関する情報を表示 このルームにおいてのみアバターを変更 このルームにおいてのみ表示名を変更 - ユーザーの無視を解除し、以後のメッセージを表示します + ユーザーの無視を解除し、以後のメッセージを表示 続行するには%sを入力してください 復旧用のパスフレーズ 有効なリカバリーキーではありません @@ -2399,8 +2399,8 @@ 招待者のみ参加可能。個人やチームに最適 スペースを作成 連絡先をスペースに招待 - IDサーバーは利用規約がありません - あなたの連絡先はプライベートです。端末の連絡先からユーザーを発見できるように、連絡先の情報をIDサーバーへ送信する許可が必要です。 + IDサーバーには利用規約がありません + あなたの連絡先は非公開です。端末の連絡先からユーザーを発見するためには、連絡先の情報をIDサーバーに送信する許可が必要です。 ディスカバリー設定を開く 既読時間 クロス証明を有効にする @@ -2410,9 +2410,9 @@ %sが参加しました。 このルームで使用されている暗号化はサポートされていません 暗号化が正しく設定されていません - %sにテキストメッセージを送信しました。メッセージにある確認コードを入力してください。 + %sにテキストメッセージを送信しました。メッセージ内の確認コードを入力してください。 選択したIDサーバーには利用規約がありません。サービス提供者を信頼している場合にのみ続行してください - 現在IDサーバー %1$s でメールアドレスや電話番号を共有しています。共有を停止するには %2$s に再接続する必要があります。 + 現在IDサーバー %1$s でメールアドレスや電話番号を共有しています。共有を停止するには%2$sに再接続する必要があります。 ルームを作成し設定しました。 QRコードを読み取り、新しいダイレクトメッセージを作成 鍵のインポートに失敗しました @@ -2429,7 +2429,7 @@ この投票を削除してよろしいですか?一度削除すると復元することはできません。 共有データの取り扱いに失敗しました 回転とクロップ - ルームを探す + ルームを探索 既存のルームとスペースを追加 スレッドのメッセージを有効にする おすすめに追加 @@ -2479,21 +2479,21 @@ 検証済 未送信のメッセージを削除 カスタムイベントを送信 - ルームの状態を調べる + ルームの状態を探索 開封確認メッセージを表示 通知しない ファイルから鍵をインポート 未確認 制限は不明です。 サーバーのファイルアップロードの制限 - 自分の会話は、自分のものに。 - %1$sが、このルームを、招待者のみ参加可能に設定しました。 + 自分の会話は、自分のもの。 + %1$sがこのルームを「招待者のみ参加可能」に設定しました。 %1$sが部屋をリンクを持っているユーザーにアクセスできるように設定しました。 選択したメッセージをネタバレとして送信 ${app_name} がエンドツーエンド暗号鍵をディスクに保存する許可を要求しています。 \n \n鍵を手動でエクスポートできるように、次のポップアップでアクセスを許可してください。 - %1$sはリンクを知っている人がアクセスできるようにこのルームを設定しました。 + %1$sはこのルームを「リンクを知っている人が参加可能」に設定しました。 初めに設定画面でIDサーバーの利用規約を承認してください。 初めにIDサーバーを設定してください。 @@ -2507,7 +2507,7 @@ 降雪❄️を送る あなたのチームのメッセージングに。 エンドツーエンドで暗号化され、電話番号不要。広告やデータマイニング無し。 - 会話の保存先を自分で決められ、自分で管理できる独立したコミュニケーション。Matrixを基に。 + 会話の保存先を自分で決められ、自分で管理できる独立したコミュニケーション。Matrixをもとに。 お宅での対面会話と同じぐらいのプライバシーを提供する、セキュアで独立したコミュニケーション。 チームワークを効率よくしましょう。 セキュアメッセージング @@ -2553,7 +2553,7 @@ 新しいセッションが認証されました。セッションは暗号化されたメッセージにアクセスでき、他のユーザーには信頼済として表示されます。 いったん有効にすると、暗号化を無効にすることはできません。 このルームを同じホームサーバー上で組織内のチームとのコラボレーションにのみ使用するなら、このオプションを有効にするといいかもしれません。これは後から変更できません。 - %sに属していないユーザーによるこのルームへの参加を、今後永久的に拒否 + %sに属していないユーザーによるこのルームへの参加を、今後永久に拒否 プレーンテキストメッセージの前に ( ͡° ͜ʖ ͡°) を付ける このメールアドレスのドメインの登録は許可されていません スペースを作成しています… @@ -2578,7 +2578,7 @@ 既存のサーバーに参加しますか? この質問をスキップ 友達と家族 - %1$sがこれを招待者のみ参加可能に設定しました。 + %1$sがこれを「招待者のみ参加可能」に設定しました。 メッセージを送信できませんでした ウィジェットを開く %1$sに転送 @@ -2630,13 +2630,13 @@ コードを%1$sに送信しました。以下に入力して認証してください。 このメールアドレスはどのアカウントにも登録されていません パスワードを変更すると、すべてのセッションでのエンドツーエンド暗号鍵がリセットされ、暗号化されたメッセージ履歴が読めなくなります。パスワードを再設定する前に、鍵のバックアップを設定するか、他のセッションから鍵をエクスポートしておいてください。 - パスワードの再設定を確認するために認証メールを送信しました。 + パスワードの再設定を確認するために認証メールを送信します。 このメールアドレスはどのアカウントにも属していません。 このアプリではこのホームサーバーにアカウントを作成できません。 \n \nウェブクライエントを使用してアカウント登録しますか? 申し訳ありませんが、このサーバーはアカウントの新規登録を受け入れていません。 - このアプリではこのホームサーバーにサインインできません。このホームサーバーは次のサインイン方法に対応しています: %1$s + このアプリではこのホームサーバーにサインインできません。このホームサーバーは次のサインインの方法に対応しています:%1$s \n \nウェブクライエントを使用してサインインしますか? %1$sを読み込み中にエラーが発生しました(%2$d) @@ -2695,7 +2695,7 @@ カメラを停止 セキュリティーキーを保存 リカバリーキー - 位置を共有しました + 位置情報を共有しました %sでリアクションしました 検証終了 次のいずれかのセキュリティが破られている可能性があります。 @@ -2705,25 +2705,25 @@ \n - あなたか相手のインターネット接続 \n - あなたか相手の端末 セキュアではない - この緑の盾のシンボルが信頼できるユーザーの印です。部屋のセキュリティを確認するには、全ての参加者に信頼できることを確認してください。 - セキュリティを最大限に高めるには、対面で行うか他の信頼できる通信媒体を利用してください。 + 信頼済のユーザーには、この緑の盾のシンボルが表示されます。全てのユーザーについて信頼の設定作業を行うと、ルームの安全性を確保することができます。 + セキュリティを最大限に高めるには、対面で行うか、他の信頼できる通信手段を使用してください。 次の絵文字が相手の画面にも同じ順番で現れるのを確認し、このユーザーを検証してください。 信頼できないサインイン 使用できない文字が含まれています - Elementの改善と課題抽出のために、匿名の使用分析データを収集させてくださいませんか?複数の端末での使用を分析するために、あなたの全端末共通のランダムな識別子を生成します。 + Elementの改善と課題抽出のために、匿名の使用状況データの送信をお願いします。複数の端末での使用を分析するために、あなたの全端末共通のランダムな識別子を生成します。 \n \n%sで利用規約を閲覧できます。 - 最初の検索結果のみ表示中。文字をもっと入力してください… + 最初の検索結果のみ表示しています。文字をもっと入力してください… matrix.toリンクのフォーマットが正しくありませんでした 注意!この端末には暗号鍵を含む個人情報が保存されています。 \n -\nこの端末での使用を終了したり、他のアカウントにサインインしたい場合、このデータをクリアしてください。 - この端末に現在保存されているすべてのデータをクリアしますか? +\nこの端末での使用を終了、または他のアカウントにサインインしたい場合、このデータをクリアしてください。 + この端末に現在保存されている全てのデータをクリアしますか? \nアカウントデータとメッセージにアクセスするにはもう一度サインインしてください。 現在のセッションはユーザー %1$s のものですが、あなたが提供している認証情報はユーザー %2$s のものです。この操作は${app_name}ではサポートされていません。 \nまずデータをクリアし、その後、別のアカウントにサインインしてください。 暗号化されたメッセージがどの端末でも読めるように、サインインしてこの端末にのみ保存されている暗号鍵を取り戻してください。 - あなたのホームサーバー(%1$s)の管理者があなたを%2$sのアカウントからサインアウトしています。(%3$s) + あなたのホームサーバー(%1$s)の管理者があなたを%2$sのアカウントからサインアウトしました(%3$s)。 いくつかの原因が考えられます: \n \n• 他のセッションでパスワードを変更している。 @@ -2739,7 +2739,7 @@ このホームサーバーのバージョンは古すぎるため、接続できません。管理者にアップグレードを要請してください。 ホームサーバーのバージョンが古すぎます ただいま%1$sにメールを送信しました。 -\nアカウント登録を続けるにはメールに含まれたリンクをクリックしてください。 +\nアカウント登録を続行するにはメール内のリンクをクリックしてください。 CAPTCHA認証を行ってください アカウントがまだ登録されていません。 \n @@ -2750,7 +2750,7 @@ セキュリティーフレーズを使用 セキュリティーキーは、パスワードマネージャーもしくは金庫のような安全な場所で保管してください。 セキュリティーキーは、パスワードマネージャーもしくは金庫のような安全な場所で保管してください。 - セキュリティーキーを生成し、パスワードマネージャーもしくは金庫のような安全な場所で保管してください。 + セキュリティーキーを生成します。パスワードマネージャーもしくは金庫のような安全な場所で保管してください。 セキュアバックアップ セキュアバックアップを設定 会話を開く @@ -2759,7 +2759,7 @@ %sの利用規約を開く ユーザーによる同意は与えられていません。 代わりに、他のIDサーバーのURLを入力できます - サーバー上の暗号化キーをバックアップすることにより、暗号化されたメッセージとデータへのアクセスが失われるのを防ぎます。 + サーバー上の暗号鍵をバックアップして、暗号化されたメッセージとデータへのアクセスが失われるのを防ぎましょう。 いまキャンセルすると、ログインできなくなった際に、暗号化されたメッセージとデータを失ってしまう可能性があります。 \n \nまた、設定から、安全なバックアップの設定や鍵の管理を行うことができます。 @@ -2768,7 +2768,7 @@ 自己署名キーを同期しています ユーザーキーを同期しています マスターキーを同期しています - SSSS デフォルトキーを規定しています + SSSSデフォルトキーを規定しています 安全な鍵をパスフレーズから生成しています メッセージキーを生成 暗号化されたメッセージのロックを解除 @@ -2810,4 +2810,12 @@ いま検証できる%d個の端末を表示 この操作を実行するには ${app_name}に認証情報を入力する必要があります。 + あなただけが知っている秘密のパスワードを入力してください。バックアップ用にセキュリティーキーを生成します。 + 暗号化されたメッセージにアクセスするには、ログインを検証し、本人確認を行う必要があります。 + 暗号化されたメッセージにアクセスするには、あなたの他のセッションからログインを検証し、本人確認を行う必要があります。 + 詳しく知る + セキュリティーを確保するために、使い捨てコードをチェックして、%sを検証してください。 + よりセキュリティーを確保するために、両方の端末で使い捨てコードをチェックして、%sを検証してください。 +\n +\n最大限のセキュリティーを確保するために、ご自身の目で直接確かめて行ってください。 \ No newline at end of file From 50685448246dac5a867334e779e2cd80dae82d35 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Tue, 22 Feb 2022 01:01:12 +0000 Subject: [PATCH 261/302] Translated using Weblate (Japanese) Currently translated at 91.6% (2552 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index b604f11442..b170753754 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1579,7 +1579,7 @@ 電話番号の認証中にエラーが発生しました。 リンクを共有 %sに招待 - Eメールで招待 + 電子メールで招待 詳細 連絡先を招待 無視して参加 From 8bfcb1d9d8992059bfd0e1ed64a81aa2e83a3303 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Tue, 22 Feb 2022 12:05:45 +0300 Subject: [PATCH 262/302] Allow creating disclosed polls. --- .../im/vector/app/features/poll/create/CreatePollController.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/poll/create/CreatePollController.kt b/vector/src/main/java/im/vector/app/features/poll/create/CreatePollController.kt index 6ccf7fc6aa..b4f61dbc1f 100644 --- a/vector/src/main/java/im/vector/app/features/poll/create/CreatePollController.kt +++ b/vector/src/main/java/im/vector/app/features/poll/create/CreatePollController.kt @@ -54,7 +54,6 @@ class CreatePollController @Inject constructor( title(host.stringProvider.getString(R.string.poll_type_title).toEpoxyCharSequence()) } - /* pollTypeSelectionItem { id("poll_type_selection") pollType(currentState.pollType) @@ -68,7 +67,6 @@ class CreatePollController @Inject constructor( ) } } - */ genericItem { id("question_title") From a858e89ca1d0ea12858bd5841ce2e30959e976ce Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Tue, 22 Feb 2022 12:15:37 +0300 Subject: [PATCH 263/302] Changelog added. --- changelog.d/5290.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5290.feature diff --git a/changelog.d/5290.feature b/changelog.d/5290.feature new file mode 100644 index 0000000000..6f7e9aea7f --- /dev/null +++ b/changelog.d/5290.feature @@ -0,0 +1 @@ +Support creating disclosed polls \ No newline at end of file From 89e97748bc617a8cae0e9e48fa987b4393397112 Mon Sep 17 00:00:00 2001 From: NIkita Fedrunov Date: Tue, 22 Feb 2022 10:24:27 +0100 Subject: [PATCH 264/302] ScreenEvent removed --- .../app/core/platform/VectorBaseActivity.kt | 3 +- .../VectorBaseBottomSheetDialogFragment.kt | 3 +- .../app/core/platform/VectorBaseFragment.kt | 3 +- .../features/analytics/screen/ScreenEvent.kt | 46 ------------------- .../features/call/dialpad/DialPadFragment.kt | 4 +- .../vector/app/features/home/HomeActivity.kt | 3 +- .../home/room/detail/RoomDetailActivity.kt | 3 +- .../settings/VectorSettingsBaseFragment.kt | 3 +- 8 files changed, 7 insertions(+), 61 deletions(-) delete mode 100644 vector/src/main/java/im/vector/app/features/analytics/screen/ScreenEvent.kt diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index 6c49a1ff01..2c161feb37 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -68,7 +68,6 @@ import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.plan.MobileScreen -import im.vector.app.features.analytics.screen.ScreenEvent import im.vector.app.features.configuration.VectorConfiguration import im.vector.app.features.consent.ConsentNotGivenHelper import im.vector.app.features.navigation.Navigator @@ -337,7 +336,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver super.onResume() Timber.i("onResume Activity ${javaClass.simpleName}") analyticsScreenName?.let { - ScreenEvent(it).send(analyticsTracker) + analyticsTracker.screen(MobileScreen(screenName = it)) } configurationViewModel.onActivityResumed() diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt index 11bfcdd9ef..ddc281fdd1 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -39,7 +39,6 @@ import im.vector.app.core.extensions.toMvRxBundle import im.vector.app.core.utils.DimensionConverter import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.plan.MobileScreen -import im.vector.app.features.analytics.screen.ScreenEvent import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import reactivecircus.flowbinding.android.view.clicks @@ -139,7 +138,7 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomShe super.onResume() Timber.i("onResume BottomSheet ${javaClass.simpleName}") analyticsScreenName?.let { - ScreenEvent(it).send(analyticsTracker) + analyticsTracker.screen(MobileScreen(screenName = it)) } } diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index 7b8eda76ff..70b265ff9f 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -45,7 +45,6 @@ import im.vector.app.core.extensions.toMvRxBundle import im.vector.app.core.utils.ToolbarConfig import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.plan.MobileScreen -import im.vector.app.features.analytics.screen.ScreenEvent import im.vector.app.features.navigation.Navigator import im.vector.lib.ui.styles.dialogs.MaterialProgressDialog import kotlinx.coroutines.flow.launchIn @@ -145,7 +144,7 @@ abstract class VectorBaseFragment : Fragment(), MavericksView super.onResume() Timber.i("onResume Fragment ${javaClass.simpleName}") analyticsScreenName?.let { - ScreenEvent(it).send(analyticsTracker) + analyticsTracker.screen(MobileScreen(screenName = it)) } } diff --git a/vector/src/main/java/im/vector/app/features/analytics/screen/ScreenEvent.kt b/vector/src/main/java/im/vector/app/features/analytics/screen/ScreenEvent.kt deleted file mode 100644 index 400bede415..0000000000 --- a/vector/src/main/java/im/vector/app/features/analytics/screen/ScreenEvent.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021 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.analytics.screen - -import im.vector.app.features.analytics.AnalyticsTracker -import im.vector.app.features.analytics.plan.MobileScreen -import timber.log.Timber - -/** - * Track a screen display. Unique usage. - */ -class ScreenEvent(val screenName: MobileScreen.ScreenName) { - // Protection to avoid multiple sending - private var isSent = false - - /** - * @param screenNameOverride can be used to override the screen name passed in constructor parameter - */ - fun send(analyticsTracker: AnalyticsTracker, - screenNameOverride: MobileScreen.ScreenName? = null) { - if (isSent) { - Timber.w("Event $screenName Already sent!") - return - } - isSent = true - analyticsTracker.screen( - MobileScreen( - screenName = screenNameOverride ?: screenName - ) - ) - } -} diff --git a/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt b/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt index 9d77680ff5..606ba1d1e9 100644 --- a/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt +++ b/vector/src/main/java/im/vector/app/features/call/dialpad/DialPadFragment.kt @@ -41,7 +41,6 @@ import im.vector.app.R import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.plan.MobileScreen -import im.vector.app.features.analytics.screen.ScreenEvent import im.vector.app.features.themes.ThemeUtils class DialPadFragment : Fragment(), TextWatcher { @@ -66,10 +65,9 @@ class DialPadFragment : Fragment(), TextWatcher { analyticsTracker = singletonEntryPoint.analyticsTracker() } - private var screenEvent: ScreenEvent? = null override fun onResume() { super.onResume() - ScreenEvent(MobileScreen.ScreenName.Dialpad).send(analyticsTracker) + analyticsTracker.screen(MobileScreen(screenName = MobileScreen.ScreenName.Dialpad)) } override fun onCreateView( 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 b7bfdef21c..47f1a9208b 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 @@ -49,7 +49,6 @@ import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs import im.vector.app.features.analytics.accountdata.AnalyticsAccountDataViewModel import im.vector.app.features.analytics.plan.MobileScreen -import im.vector.app.features.analytics.screen.ScreenEvent import im.vector.app.features.disclaimer.showDisclaimerDialog import im.vector.app.features.matrixto.MatrixToBottomSheet import im.vector.app.features.navigation.Navigator @@ -164,7 +163,7 @@ class HomeActivity : private val drawerListener = object : DrawerLayout.SimpleDrawerListener() { override fun onDrawerOpened(drawerView: View) { - ScreenEvent(MobileScreen.ScreenName.Sidebar).send(analyticsTracker) + analyticsTracker.screen(MobileScreen(screenName = MobileScreen.ScreenName.Sidebar)) } override fun onDrawerStateChanged(newState: Int) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index f40bee44db..aa4ee825dc 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -36,7 +36,6 @@ import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityRoomDetailBinding import im.vector.app.features.analytics.plan.MobileScreen -import im.vector.app.features.analytics.screen.ScreenEvent import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsFragment import im.vector.app.features.home.room.detail.arguments.TimelineArgs import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlaybackTracker @@ -159,7 +158,7 @@ class RoomDetailActivity : private val drawerListener = object : DrawerLayout.SimpleDrawerListener() { override fun onDrawerOpened(drawerView: View) { - ScreenEvent(MobileScreen.ScreenName.Breadcrumbs).send(analyticsTracker) + analyticsTracker.screen(MobileScreen(screenName = MobileScreen.ScreenName.Breadcrumbs)) } override fun onDrawerStateChanged(newState: Int) { diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt index c907168954..dae234eecc 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt @@ -31,7 +31,6 @@ import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.toast import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.plan.MobileScreen -import im.vector.app.features.analytics.screen.ScreenEvent import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.session.Session @@ -91,7 +90,7 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), Maverick super.onResume() Timber.i("onResume Fragment ${javaClass.simpleName}") analyticsScreenName?.let { - ScreenEvent(it).send(analyticsTracker) + analyticsTracker.screen(MobileScreen(screenName = it)) } vectorActivity.supportActionBar?.setTitle(titleRes) // find the view from parent activity From bad45799b97d7b832a7398bc9af54930c16ea321 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 22 Feb 2022 09:45:20 +0000 Subject: [PATCH 265/302] reducing line length (using existing formatting style) --- .../main/java/im/vector/app/features/home/AvatarRenderer.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt b/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt index 5b96caa3f1..3678808b2d 100644 --- a/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/home/AvatarRenderer.kt @@ -167,7 +167,10 @@ class AvatarRenderer @Inject constructor(private val activeSessionHolder: Active @AnyThread @Throws - fun adaptiveShortcutDrawable(glideRequests: GlideRequests, matrixItem: MatrixItem, iconSize: Int, adaptiveIconSize: Int, adaptiveIconOuterSides: Float): Bitmap { + fun adaptiveShortcutDrawable(glideRequests: GlideRequests, + matrixItem: MatrixItem, iconSize: Int, + adaptiveIconSize: Int, + adaptiveIconOuterSides: Float): Bitmap { return glideRequests .asBitmap() .avatarOrText(matrixItem, iconSize) From 9726c8ae07d9d23af2bb8fd2448bdef3c08fd053 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Tue, 22 Feb 2022 09:54:25 +0000 Subject: [PATCH 266/302] Translated using Weblate (Japanese) Currently translated at 91.6% (2553 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index b170753754..c920754ca4 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2779,9 +2779,9 @@ ここで送受信されるメッセージはエンドツーエンド暗号化されています。 \n \nメッセージは安全に保護されており、メッセージのロックを解除するための固有の鍵は、あなたと受信者だけが持っています。 - このルームのメッセージはエンドツーエンド暗号化されています。 + この部屋のメッセージはエンドツーエンド暗号化されています。 \n -\nメッセージは安全に保護されており、メッセージのロックを解除するための固有の鍵は、あなたと受信者だけが持っています。 +\nメッセージは安全に保護されており、メッセージのロックを解除するための固有の鍵を持っているのはあなたと受信者だけです。 ステートキー リカバリーキーを以下に保存 送信者が意図的に鍵を送信しなかったため、このメッセージにアクセスすることができません @@ -2815,7 +2815,7 @@ 暗号化されたメッセージにアクセスするには、あなたの他のセッションからログインを検証し、本人確認を行う必要があります。 詳しく知る セキュリティーを確保するために、使い捨てコードをチェックして、%sを検証してください。 - よりセキュリティーを確保するために、両方の端末で使い捨てコードをチェックして、%sを検証してください。 + セキュリティーを高めるために、自分と相手の端末でコードが一致していることを確認して、%sを検証しましょう。 \n -\n最大限のセキュリティーを確保するために、ご自身の目で直接確かめて行ってください。 +\n対面で行うのが最もセキュアです。 \ No newline at end of file From a9493db5841bc7f8dbdebf82be799a74957c3489 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Tue, 22 Feb 2022 09:18:20 +0000 Subject: [PATCH 267/302] Translated using Weblate (Japanese) Currently translated at 91.6% (2553 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index c920754ca4..ac43dd3e8b 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1459,7 +1459,7 @@ 絵文字キーボードを表示 アバターと表示名の変更を含む。 アカウントのイベントを表示 - 招待、削除、ブロックは影響を受けません。 + 招待、追放、ブロックは影響を受けません。 招待/参加/退出/追放/ブロックに関するイベントや、アバター/表示名の変更などを含む。 参加・退出イベントを表示 /confettiコマンドを使用するか、❄️または🎉を含むメッセージを送信 @@ -1759,7 +1759,7 @@ ゲストの参加を許可 ルームへのアクセス 履歴の閲覧権限に関する変更は、今後、このルームで表示されるメッセージにのみ適用されます。既存の履歴の見え方には影響しません。 - 無視して続行する + 無視して続行 毎回確認 招待 おすすめのルーム @@ -2818,4 +2818,5 @@ セキュリティーを高めるために、自分と相手の端末でコードが一致していることを確認して、%sを検証しましょう。 \n \n対面で行うのが最もセキュアです。 + 暗号化が正しく設定されていません。 \ No newline at end of file From b699701b5c86e58ee127ccc52128a83120ed10ec Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Tue, 22 Feb 2022 09:58:17 +0000 Subject: [PATCH 268/302] Translated using Weblate (Japanese) Currently translated at 91.7% (2555 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index ac43dd3e8b..489b1da915 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2778,10 +2778,10 @@ 質問は空にできません ここで送受信されるメッセージはエンドツーエンド暗号化されています。 \n -\nメッセージは安全に保護されており、メッセージのロックを解除するための固有の鍵は、あなたと受信者だけが持っています。 +\nメッセージは安全に保護されており、メッセージのロックを解除できる固有の鍵を持っているのはあなたと受信者だけです。 この部屋のメッセージはエンドツーエンド暗号化されています。 \n -\nメッセージは安全に保護されており、メッセージのロックを解除するための固有の鍵を持っているのはあなたと受信者だけです。 +\nメッセージは安全に保護されており、メッセージのロックを解除できる固有の鍵を持っているのはあなたと受信者だけです。 ステートキー リカバリーキーを以下に保存 送信者が意図的に鍵を送信しなかったため、このメッセージにアクセスすることができません @@ -2818,5 +2818,7 @@ セキュリティーを高めるために、自分と相手の端末でコードが一致していることを確認して、%sを検証しましょう。 \n \n対面で行うのが最もセキュアです。 - 暗号化が正しく設定されていません。 + 暗号化の設定が正しくありません。 + 暗号化を復元する + 暗号化を有効な状態に取り戻すために、管理者に連絡してください。 \ No newline at end of file From f187bffc11104c6f8326d8d5c4ee3e147abb2786 Mon Sep 17 00:00:00 2001 From: Sonia Date: Tue, 22 Feb 2022 11:11:31 +0100 Subject: [PATCH 269/302] changes roomUnreadIndicator colour in item_room.xml --- vector/src/main/res/layout/item_room.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/layout/item_room.xml b/vector/src/main/res/layout/item_room.xml index 68e3a85008..7dc7984b4a 100644 --- a/vector/src/main/res/layout/item_room.xml +++ b/vector/src/main/res/layout/item_room.xml @@ -15,7 +15,7 @@ android:id="@+id/roomUnreadIndicator" android:layout_width="4dp" android:layout_height="0dp" - android:background="?colorSecondary" + android:background="?vctr_content_secondary" android:visibility="gone" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" From 344bc0e3fe2eb99435c32a3f1d71eb253274b9b7 Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Tue, 22 Feb 2022 10:20:38 +0000 Subject: [PATCH 270/302] Translated using Weblate (Japanese) Currently translated at 92.0% (2564 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 489b1da915..4bc5ff4a29 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -278,7 +278,7 @@ 言語 インターフェース 認証を確認中 - 電子メールを確認して、本文中のURLをクリックしてください。 完了したら「続行する」をクリックしてください。 + 電子メールを確認して、本文中のURLをクリックしてください。完了したら「続行する」をクリックしてください。 このメールアドレスは既に使われています。 あなたのパスワードは更新されました 国を選択 @@ -1875,7 +1875,7 @@ ルーム 会話 ここで未読メッセージに追いつく - ホームへようこそ! + ホームにようこそ! 未読メッセージはありません 未読はありません! %sがセッションの検証を要求しています @@ -2819,6 +2819,6 @@ \n \n対面で行うのが最もセキュアです。 暗号化の設定が正しくありません。 - 暗号化を復元する + 暗号化を復元 暗号化を有効な状態に取り戻すために、管理者に連絡してください。 \ No newline at end of file From bc8a88c351ea8bfbb1d2ba72e7bdd0561250ec70 Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Tue, 22 Feb 2022 10:09:36 +0000 Subject: [PATCH 271/302] Translated using Weblate (Japanese) Currently translated at 92.0% (2564 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 4bc5ff4a29..e7a5d53d4a 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2814,11 +2814,21 @@ 暗号化されたメッセージにアクセスするには、ログインを検証し、本人確認を行う必要があります。 暗号化されたメッセージにアクセスするには、あなたの他のセッションからログインを検証し、本人確認を行う必要があります。 詳しく知る - セキュリティーを確保するために、使い捨てコードをチェックして、%sを検証してください。 + セキュリティー高めるために、使い捨てコードが一致しているのを確認して、%sを検証しましょう。 セキュリティーを高めるために、自分と相手の端末でコードが一致していることを確認して、%sを検証しましょう。 \n \n対面で行うのが最もセキュアです。 暗号化の設定が正しくありません。 暗号化を復元 暗号化を有効な状態に取り戻すために、管理者に連絡してください。 + このユーザーとのメッセージがエンドツーエンド暗号化されており、第三者には読めません。 + このコードを相手の画面に現れているコードと比較してください。 + 絵文字を比較して、同じ順番に現れているのを確認してください。 + 対面で行うか、他の信頼できる通信媒体を利用するのが最もセキュアです。 + 選択されたエモートを虹色にして送信します + 選択されたテキストを虹色にして送信します + ${app_name}がID%1$sのイベントを処理中にエラーが発生しました + ${app_name}は%1$sという種類のメッセージに対応していません + ${app_name}は%1$sという種類のイベントに対応していません + 既読通知へ移動 \ No newline at end of file From ff0b0f293b62e1020265002cdea254d8a58835dc Mon Sep 17 00:00:00 2001 From: Sonia0912 <41631672+Sonia0912@users.noreply.github.com> Date: Tue, 22 Feb 2022 11:45:51 +0100 Subject: [PATCH 272/302] adds changelog file --- changelog.d/5294.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5294.misc diff --git a/changelog.d/5294.misc b/changelog.d/5294.misc new file mode 100644 index 0000000000..857110efab --- /dev/null +++ b/changelog.d/5294.misc @@ -0,0 +1 @@ +Changes unread marker in room list from green to grey \ No newline at end of file From fcca75ee235edfa442bfb0c3b4298a42b2827311 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 22 Feb 2022 12:45:10 +0100 Subject: [PATCH 273/302] Realm: remove usage of freeze as it was not necessary (unique thread) --- .../session/room/timeline/TimelineChunk.kt | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt index 8507b63d1f..25957de1b5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt @@ -90,8 +90,7 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity, private val timelineEventsChangeListener = OrderedRealmCollectionChangeListener { results: RealmResults, changeSet: OrderedCollectionChangeSet -> Timber.v("on timeline events chunk update") - val frozenResults = results.freeze() - handleDatabaseChangeSet(frozenResults, changeSet) + handleDatabaseChangeSet(results, changeSet) } private var timelineEventEntities: RealmResults = chunkEntity.sortedTimelineEvents(timelineSettings.rootThreadEventId) @@ -287,7 +286,7 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity, * @return the number of events loaded. If we are in a thread timeline it also returns * whether or not we reached the end/root message */ - private suspend fun loadFromStorage(count: Int, direction: Timeline.Direction): LoadedFromStorage { + private fun loadFromStorage(count: Int, direction: Timeline.Direction): LoadedFromStorage { val displayIndex = getNextDisplayIndex(direction) ?: return LoadedFromStorage() val baseQuery = timelineEventEntities.where() @@ -428,10 +427,10 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity, * This method is responsible for managing insertions and updates of events on this chunk. * */ - private fun handleDatabaseChangeSet(frozenResults: RealmResults, changeSet: OrderedCollectionChangeSet) { + private fun handleDatabaseChangeSet(results: RealmResults, changeSet: OrderedCollectionChangeSet) { val insertions = changeSet.insertionRanges for (range in insertions) { - val newItems = frozenResults + val newItems = results .subList(range.startIndex, range.startIndex + range.length) .map { it.buildAndDecryptIfNeeded() } builtEventsIndexes.entries.filter { it.value >= range.startIndex }.forEach { it.setValue(it.value + range.length) } @@ -447,7 +446,7 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity, val modifications = changeSet.changeRanges for (range in modifications) { for (modificationIndex in (range.startIndex until range.startIndex + range.length)) { - val updatedEntity = frozenResults[modificationIndex] ?: continue + val updatedEntity = results[modificationIndex] ?: continue try { builtEvents[modificationIndex] = updatedEntity.buildAndDecryptIfNeeded() } catch (failure: Throwable) { @@ -458,20 +457,20 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity, if (insertions.isNotEmpty() || modifications.isNotEmpty()) { onBuiltEvents(true) } + } private fun getNextDisplayIndex(direction: Timeline.Direction): Int? { - val frozenTimelineEvents = timelineEventEntities.freeze() - if (frozenTimelineEvents.isEmpty()) { + if (timelineEventEntities.isEmpty()) { return null } return if (builtEvents.isEmpty()) { if (initialEventId != null) { - frozenTimelineEvents.where().equalTo(TimelineEventEntityFields.EVENT_ID, initialEventId).findFirst()?.displayIndex + timelineEventEntities.where().equalTo(TimelineEventEntityFields.EVENT_ID, initialEventId).findFirst()?.displayIndex } else if (direction == Timeline.Direction.BACKWARDS) { - frozenTimelineEvents.first(null)?.displayIndex + timelineEventEntities.first(null)?.displayIndex } else { - frozenTimelineEvents.last(null)?.displayIndex + timelineEventEntities.last(null)?.displayIndex } } else if (direction == Timeline.Direction.FORWARDS) { builtEvents.first().displayIndex + 1 From d27acfa64f7b5d014eb54888b764f0d078dfb4f4 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 22 Feb 2022 12:45:54 +0100 Subject: [PATCH 274/302] Read receipts: use RoomMember instead of User and avoid creating realm instance each time --- .../sdk/api/session/room/model/ReadReceipt.kt | 4 +--- .../mapper/ReadReceiptsSummaryMapper.kt | 18 ++++++++---------- .../database/mapper/TimelineEventMapper.kt | 2 +- .../detail/timeline/TimelineEventController.kt | 2 +- .../factory/ReadReceiptsItemFactory.kt | 2 +- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/ReadReceipt.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/ReadReceipt.kt index 67cb9600c8..5639730219 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/ReadReceipt.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/ReadReceipt.kt @@ -16,9 +16,7 @@ package org.matrix.android.sdk.api.session.room.model -import org.matrix.android.sdk.api.session.user.model.User - data class ReadReceipt( - val user: User, + val roomMember: RoomMemberSummary, val originServerTs: Long ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/ReadReceiptsSummaryMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/ReadReceiptsSummaryMapper.kt index 5413dd3d71..5aaa49b9e8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/ReadReceiptsSummaryMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/ReadReceiptsSummaryMapper.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.database.mapper import org.matrix.android.sdk.api.session.room.model.ReadReceipt import org.matrix.android.sdk.internal.database.RealmSessionProvider import org.matrix.android.sdk.internal.database.model.ReadReceiptsSummaryEntity -import org.matrix.android.sdk.internal.database.model.UserEntity +import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity import org.matrix.android.sdk.internal.database.query.where import javax.inject.Inject @@ -29,14 +29,12 @@ internal class ReadReceiptsSummaryMapper @Inject constructor(private val realmSe if (readReceiptsSummaryEntity == null) { return emptyList() } - return realmSessionProvider.withRealm { realm -> - val readReceipts = readReceiptsSummaryEntity.readReceipts - readReceipts - .mapNotNull { - val user = UserEntity.where(realm, it.userId).findFirst() - ?: return@mapNotNull null - ReadReceipt(user.asDomain(), it.originServerTs.toLong()) - } - } + val readReceipts = readReceiptsSummaryEntity.readReceipts + return readReceipts + .mapNotNull { + val roomMember = RoomMemberSummaryEntity.where(readReceiptsSummaryEntity.realm, roomId = it.roomId, userId = it.userId).findFirst() + ?: return@mapNotNull null + ReadReceipt(roomMember.asDomain(), it.originServerTs.toLong()) + } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/TimelineEventMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/TimelineEventMapper.kt index f3bea68c26..55c7f2a8ee 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/TimelineEventMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/TimelineEventMapper.kt @@ -48,7 +48,7 @@ internal class TimelineEventMapper @Inject constructor(private val readReceiptsS ), readReceipts = readReceipts ?.distinctBy { - it.user + it.roomMember }?.sortedByDescending { it.originServerTs }.orEmpty() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt index e3f162dfd4..43fa9e0c2e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt @@ -516,7 +516,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec val event = itr.previous() timelineEventsGroups.addOrIgnore(event) val currentReadReceipts = ArrayList(event.readReceipts).filter { - it.user.userId != session.myUserId + it.roomMember.userId != session.myUserId } if (timelineEventVisibilityHelper.shouldShowEvent( timelineEvent = event, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/ReadReceiptsItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/ReadReceiptsItemFactory.kt index d477a3d40e..e66dd4b043 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/ReadReceiptsItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/ReadReceiptsItemFactory.kt @@ -36,7 +36,7 @@ class ReadReceiptsItemFactory @Inject constructor(private val avatarRenderer: Av } val readReceiptsData = readReceipts .map { - ReadReceiptData(it.user.userId, it.user.avatarUrl, it.user.displayName, it.originServerTs) + ReadReceiptData(it.roomMember.userId, it.roomMember.avatarUrl, it.roomMember.displayName, it.originServerTs) } .toList() From 6998e846f9951a66cbe3d1bcdafdad56c52ae9c8 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 22 Feb 2022 11:41:47 +0000 Subject: [PATCH 275/302] adding missing instance of the qr scanner args being passed --- .../app/features/createdirect/CreateDirectRoomActivity.kt | 3 ++- .../im/vector/app/features/qrcode/QrCodeScannerFragment.kt | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt index a6b34eda25..9df4f52d0f 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt @@ -152,7 +152,8 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() { private val permissionCameraLauncher = registerForPermissionsResult { allGranted, deniedPermanently -> if (allGranted) { - addFragment(views.container, QrCodeScannerFragment::class.java) + val args = QrScannerArgs(showExtraButtons = false, R.string.add_by_qr_code) + addFragment(views.container, QrCodeScannerFragment::class.java, args) } else if (deniedPermanently) { onPermissionDeniedSnackbar(R.string.permissions_denied_qr_code) } diff --git a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt index c514a1c8aa..0f438a77cd 100644 --- a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt @@ -56,7 +56,7 @@ data class QrScannerArgs( open class QrCodeScannerFragment @Inject constructor() : VectorBaseFragment(), ZXingScannerView.ResultHandler { private val qrViewModel: QrCodeScannerViewModel by activityViewModel() - private val scannerArgs: QrScannerArgs? by args() + private val scannerArgs: QrScannerArgs by args() override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentQrCodeScannerBinding { return FragmentQrCodeScannerBinding.inflate(inflater, container, false) @@ -93,13 +93,13 @@ open class QrCodeScannerFragment @Inject constructor() : VectorBaseFragment + scannerArgs.showExtraButtons.let { showButtons -> views.userCodeMyCodeButton.isVisible = showButtons views.userCodeOpenGalleryButton.isVisible = showButtons From 909c3a667a7e649cafc9328473821d0f141deecb Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 22 Feb 2022 11:52:33 +0000 Subject: [PATCH 276/302] removing unneeded open scope --- .../java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt index 0f438a77cd..9dc7fa6548 100644 --- a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt @@ -53,7 +53,7 @@ data class QrScannerArgs( @StringRes val titleRes: Int ) : Parcelable -open class QrCodeScannerFragment @Inject constructor() : VectorBaseFragment(), ZXingScannerView.ResultHandler { +class QrCodeScannerFragment @Inject constructor() : VectorBaseFragment(), ZXingScannerView.ResultHandler { private val qrViewModel: QrCodeScannerViewModel by activityViewModel() private val scannerArgs: QrScannerArgs by args() From 16e372304328c149afc253619c790ccbd67208c2 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 22 Feb 2022 11:55:44 +0000 Subject: [PATCH 277/302] adding changelog entry --- changelog.d/5295.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5295.bugfix diff --git a/changelog.d/5295.bugfix b/changelog.d/5295.bugfix new file mode 100644 index 0000000000..c5e55cde5d --- /dev/null +++ b/changelog.d/5295.bugfix @@ -0,0 +1 @@ +Fixing crash when adding room by QR code after accepting the camera permission for the first time \ No newline at end of file From 80d19fa49780217e8d0b8c3cd8e496422742cd63 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 22 Feb 2022 13:00:22 +0100 Subject: [PATCH 278/302] Realm transactions: use Realm.WRITE_EXECUTOR (and use in Create/Join Room tasks) --- .../sdk/internal/database/AsyncTransaction.kt | 42 ++++++++----------- .../session/room/create/CreateRoomTask.kt | 3 +- .../room/membership/joining/JoinRoomTask.kt | 5 +-- 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/AsyncTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/AsyncTransaction.kt index d5a96f5ba1..ebc9bcce5a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/AsyncTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/AsyncTransaction.kt @@ -19,11 +19,9 @@ import com.zhuinden.monarchy.Monarchy import io.realm.Realm import io.realm.RealmConfiguration import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.isActive import kotlinx.coroutines.launch -import kotlinx.coroutines.sync.Semaphore -import kotlinx.coroutines.sync.withPermit import kotlinx.coroutines.withContext import timber.log.Timber @@ -37,30 +35,26 @@ internal fun CoroutineScope.asyncTransaction(realmConfiguration: RealmConfig } } -private val realmSemaphore = Semaphore(1) - suspend fun awaitTransaction(config: RealmConfiguration, transaction: suspend (realm: Realm) -> T): T { - return realmSemaphore.withPermit { - withContext(Dispatchers.IO) { - Realm.getInstance(config).use { bgRealm -> - bgRealm.beginTransaction() - val result: T - try { - val start = System.currentTimeMillis() - result = transaction(bgRealm) - if (isActive) { - bgRealm.commitTransaction() - val end = System.currentTimeMillis() - val time = end - start - Timber.v("Execute transaction in $time millis") - } - } finally { - if (bgRealm.isInTransaction) { - bgRealm.cancelTransaction() - } + return withContext(Realm.WRITE_EXECUTOR.asCoroutineDispatcher()) { + Realm.getInstance(config).use { bgRealm -> + bgRealm.beginTransaction() + val result: T + try { + val start = System.currentTimeMillis() + result = transaction(bgRealm) + if (isActive) { + bgRealm.commitTransaction() + val end = System.currentTimeMillis() + val time = end - start + Timber.v("Execute transaction in $time millis") + } + } finally { + if (bgRealm.isInTransaction) { + bgRealm.cancelTransaction() } - result } + result } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt index ac6e0562b0..4377bcbd55 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt @@ -28,6 +28,7 @@ import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.session.room.model.create.CreateRoomPreset import org.matrix.android.sdk.internal.database.awaitNotEmptyResult +import org.matrix.android.sdk.internal.database.awaitTransaction import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields import org.matrix.android.sdk.internal.database.query.where @@ -105,7 +106,7 @@ internal class DefaultCreateRoomTask @Inject constructor( throw CreateRoomFailure.CreatedWithTimeout(roomId) } - Realm.getInstance(realmConfiguration).executeTransactionAsync { + awaitTransaction(realmConfiguration){ RoomSummaryEntity.where(it, roomId).findFirst()?.lastActivityTime = System.currentTimeMillis() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt index 82fea237db..13fc6e3708 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt @@ -24,6 +24,7 @@ import org.matrix.android.sdk.api.session.room.failure.JoinRoomFailure import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.internal.database.awaitNotEmptyResult +import org.matrix.android.sdk.internal.database.awaitTransaction import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields import org.matrix.android.sdk.internal.database.query.where @@ -89,11 +90,9 @@ internal class DefaultJoinRoomTask @Inject constructor( } catch (exception: TimeoutCancellationException) { throw JoinRoomFailure.JoinedWithTimeout } - - Realm.getInstance(realmConfiguration).executeTransactionAsync { + awaitTransaction(realmConfiguration){ RoomSummaryEntity.where(it, roomId).findFirst()?.lastActivityTime = System.currentTimeMillis() } - setReadMarkers(roomId) } From 7ba86f032aa1a495dcbd1abe2676f1f02c5d6a37 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Mon, 21 Feb 2022 13:32:09 +0000 Subject: [PATCH 279/302] Translated using Weblate (Czech) Currently translated at 100.0% (2785 of 2785 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 6004d94ee7..fd6a180e48 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -3136,7 +3136,7 @@ Sdílet polohu Výsledky se zobrazí až po ukončení hlasování Uzavřené hlasování - Hlasující vidí výsledky ihned po hlasování + Hlasující uvidí výsledky ihned po hlasování Otevřené hlasování Typ hlasování UPRAVIT HLASOVÁNÍ From f5593860cfd50718d3bc15ac69971298b5442ade Mon Sep 17 00:00:00 2001 From: Joe Sagawa Date: Tue, 22 Feb 2022 12:36:33 +0000 Subject: [PATCH 280/302] Translated using Weblate (Japanese) Currently translated at 92.9% (2589 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 37 ++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index e7a5d53d4a..5fa9c84f41 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2803,7 +2803,7 @@ 絵文字を比較して検証 絵文字を比較して検証 対面でない場合は、代わりに絵文字を比較してください - あなたのホームサーバーは、最大%sのサイズの添付ファイルを受け付けています。 + あなたのホームサーバーで許容されている添付ファイルの最大サイズは%sです。 新しいパスワードを確認するには下記のリンクを開いてください。リンクにアクセスしてから、以下をクリックしてください。 PINコードを再設定するには「PINコードを忘れた」をタップしてログアウトし、その後再設定してください。 @@ -2831,4 +2831,39 @@ ${app_name}は%1$sという種類のメッセージに対応していません ${app_name}は%1$sという種類のイベントに対応していません 既読通知へ移動 + 大切に保護しましょう + 完了! + アカウントパスワードと違うものにしてください。 + 確認のため、%sをもう一度入力してください。 + 続行するには%sを入力してください。 + %sを確認 + %sを設定 + 検証を中止しました + 今中止すれば、%1$s(%2$s)の検証をしません。検証は相手のユーザープロフィールからもう一度開始できます。 + 中止すれば、新しい端末では暗号化されたメッセージが読めないし他のユーザーに信頼されません + 中止すれば、この端末では暗号化されたメッセージが読めないし他のユーザーに信頼されません + 自分ではない + 新しいセッションを検証して、暗号化されたメッセージにアクセスできるようにしましょう。 + タップして確認及び検証 + 新しいログイン。あなたですか? + ${app_name} Android + 部屋の管理者によって削除されています、理由:%1$s + ユーザーによって削除されています、理由: + 削除した理由 + この添付ファイルを%1$sに送信しますか? + 秘密ストレージは信頼されている端末でのみアクセスしましょう + 秘密ストレージのパスフレーズを入力してください + 既存のセッションにアクセスできない場合 + シンプルなアンケートを作ります + %1$sというタイプのアカウントデータを削除しますか? +\n +\n予期せぬトラブルを起こす可能性があるので注意してください。 + %1$s(%2$s)が新しいセッションでサインインしました: + このセッションは%1$s(%2$s)によって検証されているので、メッセージのセキュリティは信頼できます。 + 既存のセッションでこのセッションを検証して、暗号化されたメッセージへアクセスできるようにしましょう。 + 他のユーザーに信頼されない可能性があります + あなたはこのセッションを検証しているので、メッセージのセキュリティは信頼できます。 + 利用可能な暗号情報がありません + 既定のバージョン + 非公開部屋とダイレクトメッセージにおけるエンドツーエンド暗号化はあなたのサーバーの管理者によって既定として無効にされています。 \ No newline at end of file From 8628619578fd52eb974840468436cf6086aba1af Mon Sep 17 00:00:00 2001 From: Suguru Hirahara Date: Tue, 22 Feb 2022 10:38:44 +0000 Subject: [PATCH 281/302] Translated using Weblate (Japanese) Currently translated at 92.9% (2589 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/ --- vector/src/main/res/values-ja/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 5fa9c84f41..f1e8322730 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2814,17 +2814,17 @@ 暗号化されたメッセージにアクセスするには、ログインを検証し、本人確認を行う必要があります。 暗号化されたメッセージにアクセスするには、あなたの他のセッションからログインを検証し、本人確認を行う必要があります。 詳しく知る - セキュリティー高めるために、使い捨てコードが一致しているのを確認して、%sを検証しましょう。 + セキュリティーを高めるために、使い捨てコードが一致しているのを確認して、%sを検証しましょう。 セキュリティーを高めるために、自分と相手の端末でコードが一致していることを確認して、%sを検証しましょう。 \n \n対面で行うのが最もセキュアです。 暗号化の設定が正しくありません。 暗号化を復元 暗号化を有効な状態に取り戻すために、管理者に連絡してください。 - このユーザーとのメッセージがエンドツーエンド暗号化されており、第三者には読めません。 + このユーザーとのメッセージはエンドツーエンド暗号化されており、第三者には読めません。 このコードを相手の画面に現れているコードと比較してください。 絵文字を比較して、同じ順番に現れているのを確認してください。 - 対面で行うか、他の信頼できる通信媒体を利用するのが最もセキュアです。 + セキュリティーを高めるために、対面で行うか、他の信頼できる通信手段を利用しましょう。 選択されたエモートを虹色にして送信します 選択されたテキストを虹色にして送信します ${app_name}がID%1$sのイベントを処理中にエラーが発生しました From bfd8f6c3ff2f974fc4162db964bd87ec88b1fd44 Mon Sep 17 00:00:00 2001 From: Edward Gera Date: Mon, 21 Feb 2022 15:13:40 +0000 Subject: [PATCH 282/302] Translated using Weblate (Hebrew) Currently translated at 84.2% (2345 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/he/ --- vector/src/main/res/values-iw/strings.xml | 35 +++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-iw/strings.xml b/vector/src/main/res/values-iw/strings.xml index 48bc5a675d..7db0d5a0cb 100644 --- a/vector/src/main/res/values-iw/strings.xml +++ b/vector/src/main/res/values-iw/strings.xml @@ -2545,8 +2545,8 @@ %s שינה את רשימות ה-ACL של השרת עבור החדר הזה. • מותרים שרתים התואמים ל-%s. • שרתים התואמים %s אסורים. - אתה מגדיר את רשימות ה-ACL של השרת עבור החדר הזה. - %s הגדר את רשימות ה-ACL של השרת עבור החדר הזה. + אתה מגדיר את ה-ACL של השרת עבור החדר הזה. + %s הגדר את ה-ACL של השרת עבור החדר הזה. שדרגת כאן. %s שודרג כאן. שדרגת את החדר הזה. @@ -2557,4 +2557,35 @@ כל אחד. כל חברי החדר. כל חברי החדר, מהנקודה בה הצטרפו. + מפה + שתף מיקום + מיקום + שתף מיקום + התוצאות נחשפות רק לאחר מסיום הסקר + סקר סגור + מצביעים רואים את התוצאות לאחר ההצבעה + פתח סקר + סוג סקר + ערוך סקר + ערוך סקר + האם את/ה בטוח שברצונך להסיר את הסקר\? לא ניתן לשחזור לאחר הסרה. + הסר סקר + הסקר הסתיים + נא הצביעו + שתף מיקום + צור סקר + פתח אנשי קשר + שלח סטיקר + העלה קובץ + שלח תמונות וסרטונים + פתח מצלמה + הצג בועות הודעה + טעינת המפה נכשלה + מיפוי מיקומי משתמשים בציר הזמן + לאחר ההפעלה, תוכל לשלוח את המיקום שלך לכל חדר + אפשר שיתוף מיקום + לפתוח בעזרת + ${app_name} לא הצליח לגשת למיקום שלך. בבקשה נסה שוב מאוחר יותר. + ${app_name} לא הצליח לגשת למיקום שלך + שתף מיקום \ No newline at end of file From 79a53c68b08f0f48a7dcb0c65485cbc345c5c190 Mon Sep 17 00:00:00 2001 From: yaronsb Date: Mon, 21 Feb 2022 14:07:26 +0000 Subject: [PATCH 283/302] Translated using Weblate (Hebrew) Currently translated at 84.2% (2345 of 2785 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/he/ --- vector/src/main/res/values-iw/strings.xml | 229 +++++++++++++++++++--- 1 file changed, 203 insertions(+), 26 deletions(-) diff --git a/vector/src/main/res/values-iw/strings.xml b/vector/src/main/res/values-iw/strings.xml index 7db0d5a0cb..744e3d726b 100644 --- a/vector/src/main/res/values-iw/strings.xml +++ b/vector/src/main/res/values-iw/strings.xml @@ -126,8 +126,8 @@ משתמש %d %d משתמשים - מעט - אחר + %d משתמשים + %d משתמש אין חדרים ציבורים אין חדרים @@ -158,7 +158,7 @@ התחל שיחה קולית התחל צ\'אט חדש חיפוש - קישור לשרת הזיהוי + קישור שרת הזהות קישור לשרת הבית יציאה כניסה @@ -216,7 +216,7 @@ שרת זיהוי: שרת הבית: שם משתמש כבר נמצא בשימוש - שרת בית זה רוצה לוודא שאתה לא רובוט + שרת הבית רוצה לוודא שאתה לא רובוט הרשמה באמצעות דוא\"ל ומספר טלפון בבת אחת עדיין אינה נתמכת עד להתקנת ה- API. רק מספר הטלפון ייקח בחשבון. \n \nתוכל להוסיף את הדוא\"ל שלך לפרופיל שלך בהגדרות. @@ -293,7 +293,7 @@ הזמנה זו נשלחה אל%s, שאינה משויכת לחשבון זה. \nייתכן שתרצה להתחבר עם חשבון אחר, או להוסיף דוא\"ל זה לחשבונך. הוזמנת להצטרף לחדר זה על ידי%s - קפיצה להודעה הראשונה שלא נקראה. + עבור להודעה שלא נקראה מסנכרן… פתח כותרת חברי רשימה @@ -348,7 +348,7 @@ שִׂיחָה בחר רינגטון לשיחות: רינגטון שיחה נכנסת - ישתמש ב-%s כסיוע כאשר השרת הביתי שלך אינו מציע כזה (כתובת ה- IP שלך תשותף במהלך שיחה) + ישתמש ב-%s כסיוע כאשר השרת הבית שלך אינו מציע כזה (כתובת ה- IP שלך תשותף במהלך שיחה) אפשר שרת עזרה לשיחות השתמש ברינגטון ברירת המחדל של אלמנט לשיחות נכנסות בקש אישור לפני שמתחילים בשיחה @@ -368,10 +368,10 @@ מקור שלח כ - שינוי בפרט חברות - שינוי בפרטי חברות - שינוי בפרטי חברות - שינוי בפרטי חברות + %d שינוי בפרט חברות + %d שינוי בפרטי חברות + %d שינוי בפרטי חברות + %d שינוי בפרטי חברות רשימת קבוצות קרא את רשימת הקבלות @@ -510,6 +510,7 @@ בטל הורדה בטל העלאה האם ברצונך להסתיר את כל ההודעות ממשתמש זה\? +\n \nשים לב שפעולה זו תפעיל מחדש את האפליקציה והיא עשויה להימשך זמן מה. סיבה לדיווח על תוכן זה הצטרף @@ -537,12 +538,12 @@ אל תתן אמון אמון - הודעה חדשה - הודעות חדשות - הודעות חדשות - הודעות חדשות + %d הודעה חדשה + d% הודעות חדשות + %d הודעות חדשות + %d הודעות חדשות - אין לך הרשאה לפרסם בחדר זה + אין לך הרשאה לפרסם בחדר זה. הקובץ לא נמצא מחק הודעות שלא נשלחו שלח שוב הודעות שלא נשלחו @@ -565,7 +566,7 @@ האם אתה בטוח שברצונך להזמין את%s לצ\'אט זה\? סיבה הסרת נידוי ממשתמש יאפשר לו להצטרף שוב לחדר. - איסור על המשתמש יבעט בהם מחדר זה וימנע מהם להצטרף שוב. + חסימת משתמש תסיר אותם מהחדר הזה ותמנע ממנו להצטרף שוב. הסר נידוי ממשתמש סיבות לנידוי נדה משתמש @@ -710,16 +711,16 @@ חבר אחד - חבר - חברים - חברים - חברים + %d חבר + %d חברים + %d חברים + %d חברים - חבר פעיל - חברים פעילים - חברים פעילים - חברים פעילים + %d חבר פעיל + %d חברים פעילים + %d חברים פעילים + %d חברים פעילים הוסף חבר התחל אימות @@ -2429,7 +2430,7 @@ %1$s הצטרף לחדר. סיבה: %2$s %1$s הזמין אותך. סיבה: %2$s הזמנת את %1$s. סיבה: %2$s - %1$s הפעילה הצפנה מקצה לקצה (אלגוריתם לא מזוהה %2$s). + %1$s הפעיל הצפנה מקצה לקצה (אלגוריתם לא מזוהה %2$s). הפעלת הצפנה מקצה לקצה (אלגוריתם לא מזוהה %1$s). %1$s הזמין את %2$s. סיבה: %3$s ההזמנה שלך. סיבה: %1$s @@ -2507,7 +2508,7 @@ הסרת את ווידג\'ט %1$s %1$s הסיר את %2$s ווידג\'ט הוספת ווידג\'ט %1$s - %1$s הוסיף %2$s ווידג\'ט + %1$s הוסיף את%2$s ווידג\'ט קיבלת את ההזמנה עבור %1$s %1$s קיבל את ההזמנה עבור %2$s ביטלת את ההזמנה עבור %1$s @@ -2588,4 +2589,180 @@ ${app_name} לא הצליח לגשת למיקום שלך. בבקשה נסה שוב מאוחר יותר. ${app_name} לא הצליח לגשת למיקום שלך שתף מיקום + אפשר התראת דוא\"ל עבור %s + מילות מפתח לא יכולות להכיל \'%s\' + מילות מפתח אינן יכולות להתחיל ב-\'.\' + הוסף מילת מפתח חדשה + מילות המפתח שלך + הודע לי עבור + אחר + אזכורים ומילות מפתח + התראת ברירת מחדל + כדי לקבל אימייל עם התראה, אנא שיוך דוא\"ל לחשבון Matrix שלך + הודעה באימייל + הסשן יצא מהחשבון! + החדר הוצא! + אף אחד + אזכורים ומילות מפתח בלבד + מתוך שרשור + טיפ: הקש ארוכות על הודעה והשתמש ב-\"%s\". + שרשורים עוזרים לשמור על השיחות שלך בנושא וקל למעקב. + שמור על דיונים מאורגנים באמצעות שרשורים + מציג את כל השרשורים שבהם השתתפת + השרשורים שלי + הצג את כל השרשורים בחדר זה + כל השרשורים + מסנן + שרשורים + שרשורים + סנן שרשורים בחדר + שדרג המרחב + שנה את שם המרחב + אפשר הצפנת מרחב + שנה את הכתובת הראשית של המרחב + שנה את דמות המרחב + אין לך הרשאה לעדכן את התפקידים הנדרשים כדי לשנות חלקים שונים במרחב הזה + בחר את התפקידים הדרושים כדי לשנות חלקים שונים במרחב הזה + הרשאות אזור + הצג ועדכן את התפקידים הנדרשים לשינוי חלקים שונים של האזור. + ההצפנה הוגדרה בצורה שגויה כך שאינך יכול לשלוח הודעות. לחץ כדי לפתוח את ההגדרות. + ההצפנה הוגדרה בצורה שגויה כך שאינך יכול לשלוח הודעות. אנא צור קשר עם מנהל מערכת כדי לשחזר את ההצפנה למצב חוקי. + ביטול החסימה של המשתמש יאפשר לו להצטרף שוב למרחב. + חסימת משתמש תסיר אותם מהמרחב הזה ותמנע ממנו להצטרף שוב. + המשתמש יוסר מהמרחב הזה. +\n +\nכדי למנוע מהם להצטרף שוב, עליך לחסום אותם במקום זאת. + המשך בכל זאת + מסיים שיחה… + אין מענה + המשתמש אליו התקשרת עסוק. + מנוי תפוס + החזקת השיחה + %s החזיק את השיחה + להחזיק + לְהַמשִׁיך + שיחת שמע עם %s + שיחת וידאו עם %s + + שיחת וידאו שלא נענתה + %d שיחות וידאו שלא נענו + %d שיחות וידאו שלא נענו + שיחת וידאו שלא נענתה + + + שיחה שלא נענתה + "%d שיחות שלא נענו" + "%d שיחות שלא נענו" + שיחה שלא נענתה + + צלצול שיחה… + לא מורשה, חסרים אישורי אימות חוקיים + בחר שרת בית + לא ניתן להגיע לשרת ביתי בכתובת ה- %s. אנא בדוק את הקישור שלך או בחר שרת ביתי באופן ידני. + השתמש כברירת מחדל ואל תשאל שוב + תמיד תשאל + כתובת ה-API של שרת הבית + רווחים + מזמין + הצג את כל החדרים בספריית החדרים, כולל חדרים עם תוכן מפורש. + הצג חדרים עם תוכן מפורש + ספריית חדרים + חדרים מוצעים + ערך חדש + העתק קישור לשרשור + צפיה בחדר + לא כעת + אפשר + חזור + החלף + הצג שרשורים + חסרות הרשאות + כדי לשלוח הודעות קוליות, אנא הענק הרשאה למיקרופון. + כדי לבצע פעולה זו, אנא הענק למצלמה הרשאה מהגדרות המערכת. + חסרות חלק מההרשאות לביצוע פעולה זו, אנא הענק את ההרשאות מהגדרות המערכת. + רווחים + למד עוד + מאזין להתראות + • שרתים התואמים את כתובות ה-IP נאסרו כעת. + • כעת מותרים שרתים התואמים את כתובות ה-IP. + • שרתים התואמים את כתובות ה-IP אסורות. + • מותר להשתמש בשרתים התואמים את כתובות ה-IP. + הפעלת הצפנה מקצה לקצה. + %1$s הפעיל/ה הצפנה מקצה לקצה. + מנעת מאורחים להצטרף לחדר. + %1$s מנע מאורחים להצטרף לחדר. + מנעת מאורחים להצטרף לחדר. + %1$s מנע מאורחים להצטרף לחדר. + אפשרת לאורחים להצטרף לכאן. + %1$s איפשר לאורחים להצטרף לכאן. + אפשרת לאורחים להצטרף לחדר. + %1$s אפשר/ה לאורחים להצטרף לחדר. + שינית את הכתובות של החדר הזה. + %1$s שינה את הכתובות של החדר הזה. + שינית את הכתובת הראשית והחלופית לחדר הזה. + %1$s שינה את הכתובת הראשית והאלטרנטיבית של החדר הזה. + שינית את הכתובות החלופיות של החדר הזה. + %1$s שינה את הכתובות החלופיות עבור החדר הזה. + + הסרת את הכתובת החלופית %1$s עבור החדר הזה. + הסרת את הכתובות החלופיות %1$s עבור החדר הזה. + הסרת את הכתובות החלופיות %1$s עבור החדר הזה. + הסרת את הכתובת החלופית %1$s עבור החדר הזה. + + + %1$s הסיר את הכתובת החלופית %2$s עבור החדר הזה. + %1$s הסיר את הכתובות החלופיות %2$s עבור החדר הזה. + %1$s הסיר את הכתובות החלופיות %2$s עבור החדר הזה. + %1$s הסיר את הכתובת החלופית %2$s עבור החדר הזה. + + + הוספת את הכתובת החלופית %1$s לחדר הזה. + הוספת את הכתובות החלופיות %1$s לחדר הזה. + הוספת את הכתובות החלופיות %1$s לחדר הזה. + הוספת את הכתובת החלופית %1$s לחדר הזה. + + + %1$s הוסיף את הכתובת החלופית %2$s לחדר הזה. + %1$s הוסיף את הכתובות החלופיות %2$s לחדר הזה. + %1$s הוסיף את הכתובות החלופיות %2$s לחדר הזה. + %1$s הוסיף את הכתובת החלופית %2$s לחדר הזה. + + הסרת את הכתובת הראשית של החדר הזה. + %1$s הסיר את הכתובת הראשית של החדר הזה. + הגדרת הכתובת הראשית של חדר זה ל-%1$s. + %1$s הגדיר את הכתובת הראשית של החדר הזה ל-%2$s. + הוספת את %1$s והסרת את %2$s ככתובות לחדר הזה. + %1$s הוסיף את %2$s והסיר את %3$s ככתובות לחדר הזה. + + הסרת את %1$s ככתובת לחדר הזה. + הסרת את %1$s ככתובות לחדר הזה. + הסרת את %1$s ככתובות לחדר הזה. + הסרת את %1$s ככתובת לחדר הזה. + + + %1$s הסיר את %2$s ככתובת לחדר הזה. + %1$s הסיר את %2$s ככתובות עבור החדר הזה. + %1$s הסיר את %2$s ככתובות עבור החדר הזה. + %1$s הסיר את %2$s ככתובת עבור החדר הזה. + + + הוספת את %1$s ככתובת לחדר הזה. + הוספת את %1$s ככתובות לחדר הזה. + הוספת את %1$s ככתובות לחדר הזה. + הוספת את %1$s ככתובת לחדר הזה. + + + %1$s הוסיף את %2$s ככתובת לחדר הזה. + %1$s הוסיפו את %2$s ככתובות לחדר הזה. + %1$s הוסיפו את %2$s ככתובות לחדר הזה. + %1$s הוסיפו את %2$s ככתובות לחדר הזה. + + משכת את ההזמנה של %1$s. סיבה: %2$s + %1$s משך את ההזמנה של %2$s. סיבה: %3$s + קיבלת את ההזמנה עבור %1$s. סיבה: %2$s + %1$s קיבל את ההזמנה עבור %2$s. סיבה: %3$s + ביטלת את ההזמנה של %1$s להצטרף לחדר. סיבה: %2$s + %1$s ביטל את ההזמנה של %2$s להצטרף לחדר. סיבה: %3$s + שלחת הזמנה אל %1$s להצטרף לחדר. סיבה: %2$s + %1$s שלח הזמנה אל %2$s להצטרף לחדר. סיבה: %3$s \ No newline at end of file From 4cc80162cacf10a4b63b58ed30536de608436195 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 22 Feb 2022 14:23:45 +0100 Subject: [PATCH 284/302] Clean and add Changelog --- changelog.d/5297.misc | 1 + .../android/sdk/internal/session/room/create/CreateRoomTask.kt | 3 +-- .../internal/session/room/membership/joining/JoinRoomTask.kt | 3 +-- .../sdk/internal/session/room/timeline/TimelineChunk.kt | 1 - 4 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 changelog.d/5297.misc diff --git a/changelog.d/5297.misc b/changelog.d/5297.misc new file mode 100644 index 0000000000..f45490ce3d --- /dev/null +++ b/changelog.d/5297.misc @@ -0,0 +1 @@ +Improve some internal realm usages. \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt index 4377bcbd55..9bd15a0267 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomTask.kt @@ -17,7 +17,6 @@ package org.matrix.android.sdk.internal.session.room.create import com.zhuinden.monarchy.Monarchy -import io.realm.Realm import io.realm.RealmConfiguration import kotlinx.coroutines.TimeoutCancellationException import org.matrix.android.sdk.api.failure.Failure @@ -106,7 +105,7 @@ internal class DefaultCreateRoomTask @Inject constructor( throw CreateRoomFailure.CreatedWithTimeout(roomId) } - awaitTransaction(realmConfiguration){ + awaitTransaction(realmConfiguration) { RoomSummaryEntity.where(it, roomId).findFirst()?.lastActivityTime = System.currentTimeMillis() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt index 13fc6e3708..22a46b6cfc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt @@ -16,7 +16,6 @@ package org.matrix.android.sdk.internal.session.room.membership.joining -import io.realm.Realm import io.realm.RealmConfiguration import kotlinx.coroutines.TimeoutCancellationException import org.matrix.android.sdk.api.session.events.model.toContent @@ -90,7 +89,7 @@ internal class DefaultJoinRoomTask @Inject constructor( } catch (exception: TimeoutCancellationException) { throw JoinRoomFailure.JoinedWithTimeout } - awaitTransaction(realmConfiguration){ + awaitTransaction(realmConfiguration) { RoomSummaryEntity.where(it, roomId).findFirst()?.lastActivityTime = System.currentTimeMillis() } setReadMarkers(roomId) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt index 25957de1b5..c0dc31fcf8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt @@ -457,7 +457,6 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity, if (insertions.isNotEmpty() || modifications.isNotEmpty()) { onBuiltEvents(true) } - } private fun getNextDisplayIndex(direction: Timeline.Direction): Int? { From c4d9ba24d3f139f474b616d8e05186c5dd43800d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 15:27:44 +0100 Subject: [PATCH 285/302] Remove duplicated string - keep the latest version. --- vector/src/main/res/values-ja/strings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index f1e8322730..50ffa35f89 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2488,7 +2488,6 @@ サーバーのファイルアップロードの制限 自分の会話は、自分のもの。 %1$sがこのルームを「招待者のみ参加可能」に設定しました。 - %1$sが部屋をリンクを持っているユーザーにアクセスできるように設定しました。 選択したメッセージをネタバレとして送信 ${app_name} がエンドツーエンド暗号鍵をディスクに保存する許可を要求しています。 \n From ad2ee0e9bce6388f5d39a0e41a32c4b208e68d1e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 15:29:52 +0100 Subject: [PATCH 286/302] Remove unused string --- vector/src/main/res/values-cs/strings.xml | 1 - vector/src/main/res/values-de/strings.xml | 1 - vector/src/main/res/values-eo/strings.xml | 1 - vector/src/main/res/values-es/strings.xml | 1 - vector/src/main/res/values-et/strings.xml | 1 - vector/src/main/res/values-fa/strings.xml | 1 - vector/src/main/res/values-fi/strings.xml | 1 - vector/src/main/res/values-fr-rCA/strings.xml | 1 - vector/src/main/res/values-fr/strings.xml | 1 - vector/src/main/res/values-hu/strings.xml | 1 - vector/src/main/res/values-in/strings.xml | 1 - vector/src/main/res/values-it/strings.xml | 1 - vector/src/main/res/values-ja/strings.xml | 1 - vector/src/main/res/values-lv/strings.xml | 1 - vector/src/main/res/values-nl/strings.xml | 1 - vector/src/main/res/values-pl/strings.xml | 1 - vector/src/main/res/values-pt-rBR/strings.xml | 1 - vector/src/main/res/values-ru/strings.xml | 1 - vector/src/main/res/values-sk/strings.xml | 1 - vector/src/main/res/values-sq/strings.xml | 1 - vector/src/main/res/values-sv/strings.xml | 1 - vector/src/main/res/values-uk/strings.xml | 1 - vector/src/main/res/values-vi/strings.xml | 1 - vector/src/main/res/values-zh-rCN/strings.xml | 1 - vector/src/main/res/values-zh-rTW/strings.xml | 1 - vector/src/main/res/values/strings.xml | 2 -- 26 files changed, 27 deletions(-) diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index fd6a180e48..9070bbdb2e 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -2700,7 +2700,6 @@ Na jakých tématech pracujete\? Založíme pro ně místnosti. Můžete přidat další později. Doplňte nějaké podrobnosti, aby jej lidé mohli identifikovat. Můžete je kdykoli změnit. - Prostory jsou nový způsob organizace místností a lidí Prostory Jste zváni Vítejte v prostorech! diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 5852e2de31..54d69277e6 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2692,7 +2692,6 @@ Meine Teamkameraden und ich Ein privater Space um deine Räume zu organisieren Um einem bereits existierenden Space beizutreten, benötigst du eine Einladung. - Wir haben Spaces entwickelt, damit ihr eure Räume besser organisieren könnt Dein privater Space Dein öffentlicher Space Betrete einen Space mit der angegebenen ID diff --git a/vector/src/main/res/values-eo/strings.xml b/vector/src/main/res/values-eo/strings.xml index 4a55ada402..fd97994323 100644 --- a/vector/src/main/res/values-eo/strings.xml +++ b/vector/src/main/res/values-eo/strings.xml @@ -2695,7 +2695,6 @@ Por aliĝi al jam ekzistanta aro, vi bezonos inviton. Vi povos ŝanĝi ĉi tion poste Kian aron volas vi krei\? - Aroj estas nova maniero grupigi ĉambrojn kaj personojn Via privata aro Via publika aro Aldoni aron diff --git a/vector/src/main/res/values-es/strings.xml b/vector/src/main/res/values-es/strings.xml index 6392d243fe..071c7731e5 100644 --- a/vector/src/main/res/values-es/strings.xml +++ b/vector/src/main/res/values-es/strings.xml @@ -2499,7 +2499,6 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua Añade un Espacio Crea un Espacio Crear un espacio - Los Espacios son una nueva forma de agrupar salas y personas Sincronización inicial: \nEsperando respuesta del servidor… El mensaje no se pudo enviar por un error diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index 2da0cc9125..e74f7ce6f7 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -2700,7 +2700,6 @@ Olemasoleva kogukonnakeskusega liitumiseks vajad sa kutset. Sa võid seda hiljem muuta Missugust kogukonnakeskust sooviksid sa luua\? - Kogukonnakeskused on uus viis jututubade ja inimeste ühendamiseks Sinu privaatne kogukonnakeskus Sinu avalik kogukonnakeskus Lisa kogukonnakeskus diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index 1c912b9fd6..b8b7038d37 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -2704,7 +2704,6 @@ برای پیوستن به یک فضای موجود، نیاز به دعوت دارید. می‌توانید بعداً این را تغییر دهید می‌خواهید چه نوع فضایی ایجاد کنید؟ - فضاها راهی جدید برای گروه‌بندی اتاق‌ها و افراد است فضای خصوصیتان فضا عمومیتان افزودن فضا diff --git a/vector/src/main/res/values-fi/strings.xml b/vector/src/main/res/values-fi/strings.xml index 0712d15e4a..724fe7759f 100644 --- a/vector/src/main/res/values-fi/strings.xml +++ b/vector/src/main/res/values-fi/strings.xml @@ -2236,7 +2236,6 @@ Tarvitset kutsun liittyäksesi olemassa olevaan avaruuteen. Voit muuttaa tämän myöhemmin Minkä tyyppisen avaruuden haluat luoda\? - Avaruudet ovat uusi tapa ryhmitellä huoneita ja ihmisiä Yksityinen avaruutesi Julkinen avaruutesi Lisää avaruus diff --git a/vector/src/main/res/values-fr-rCA/strings.xml b/vector/src/main/res/values-fr-rCA/strings.xml index 0cf789c04f..4f57799d80 100644 --- a/vector/src/main/res/values-fr-rCA/strings.xml +++ b/vector/src/main/res/values-fr-rCA/strings.xml @@ -2661,7 +2661,6 @@ Pour rejoindre un espace existant, il vous faut une invitation. Vous pouvez changer ceci plus tard Quel type d’espace voulez-vous créer\? - Les espaces sont un nouveau moyen de regrouper les salons et les personnes Votre espace privé Votre espace public Ajouter un espace diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index 08dcb09190..12ca5e46bd 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -2648,7 +2648,6 @@ Message envoyé Vous pouvez changer ceci plus tard Quel type d’espace voulez-vous créer \? - Les espaces sont un nouveau moyen de regrouper les salons et les personnes Votre espace privé Votre espace public Ajouter un espace diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index b206744119..ac136bc0f0 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -2506,7 +2506,6 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Létező térbe való belépéshez meghívó szükséges. Ezt később meg lehet változtatni Milyen típusú teret szeretnél készíteni\? - A Terek használata egy új lehetőség a szobák és felhasználók csoportosítására Privát tér Nyilvános tér Tér hozzáadása diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index 78c5b2708c..5c8d06229f 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -2435,7 +2435,6 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Untuk bergabung ke space yang sudah ada, Anda membutuhkan undangan ke space itu. Anda dapat mengubahnya nanti Tipe space apa yang Anda ingin buat\? - Space adalah cara baru untuk mengelompokkan ruangan dan pengguna Space privat Anda Space publik Anda Tambahkan Space diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index 7e6433dca4..dfbf2d84f6 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -2690,7 +2690,6 @@ Per unirti ad uno Spazio già esistente, ti serve un invito. Puoi cambiarlo in seguito Che tipo di Spazio vuoi creare\? - Gli Spazi sono un nuovo modo di raggruppare stanze e contatti Il tuo Spazio privato Il tuo Spazio pubblico Aggiungi Spazio diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 50ffa35f89..eb1d1336d8 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2521,7 +2521,6 @@ 正当な参加者が%sにアクセスできることを確認してください。これは後から変更できます。 新規:スペースの参加者が非公開のルームを検索し、参加できるようになりました 参加者を追加 - スペースは、ルームや連絡先をグループ化する新しい方法です %d人の知り合いがすでに参加しています diff --git a/vector/src/main/res/values-lv/strings.xml b/vector/src/main/res/values-lv/strings.xml index 703ec4f229..e5c808e2e5 100644 --- a/vector/src/main/res/values-lv/strings.xml +++ b/vector/src/main/res/values-lv/strings.xml @@ -2358,7 +2358,6 @@ Nākotnē šī pārbaudes procedūra plānota sarežģītāka. Lai pievienotos esošai Telpai, ir nepieciešams ielūgums. To var mainīt vēlāk Kādu Telpu vēlaties izveidot\? - Telpas ir jauns veids, kā grupēt istabas un cilvēkus Jūsu privātā Telpa Jūsu publiskā Telpa Pievienot Telpu diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index 819958feb3..51c4d29688 100644 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -3045,7 +3045,6 @@ Met wie werkt u samen\? U kunt dit later wijzigen Wat voor soort space wilt u creëren\? - Spaces zijn een nieuwe manier om kamers en mensen te groeperen Uw privé space Uw openbare space Space toevoegen diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index f3b3888a20..a72331453f 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -2725,7 +2725,6 @@ Aby dołączyć do istniejącej przestrzeni, potrzebujesz zaproszenia. Możesz zmienić to później Jaki rodzaj przestrzeni chcesz stworzyć\? - Przestrzenie są nowym sposobem na organizację pokojów i osób Wiadomość wysłana Wstępna synchronizacja: \nPobieranie danych… diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index cda7517f6b..f18198bbf4 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -2755,7 +2755,6 @@ Para se juntar a um espaço existente, você precisa de um convite. Você pode mudar isto mais tarde Que tipo de espaço você quer criar\? - Espaços são uma nova forma de agrupar salas e pessoas Seu espaço privado Seu espaço público Adicionar Espaço diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index f164afc11b..67f4ebf0da 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -2822,7 +2822,6 @@ Чтобы присоединиться к существующему пространству, вам необходимо получить приглашение. Вы сможете изменить это позже Какой тип пространства вы хотите создать\? - Пространства - это новый способ группировки комнат и людей Ваше приватное пространство Ваше публичное пространство Добавить пространство diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml index dd410031a8..bd15a87f83 100644 --- a/vector/src/main/res/values-sk/strings.xml +++ b/vector/src/main/res/values-sk/strings.xml @@ -2586,7 +2586,6 @@ Ak sa chcete pripojiť k existujúcemu priestoru, potrebujete pozvánku. Neskôr to môžete zmeniť Aký typ priestoru chcete vytvoriť\? - Priestory sú novým spôsobom spájania miestností a ľudí Nesprávne používateľské meno a/alebo heslo. Zadané heslo začína alebo končí medzerami, skontrolujte ho. Používate beta verziu Priestorov. Vaša spätná väzba pomôže pri tvorbe ďalších verzií. Vaša platforma a používateľské meno budú zaznamenané, aby sme mohli čo najlepšie využiť vašu spätnú väzbu. Ďalšie priestory alebo miestnosti, o ktorých možno neviete diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index 1f49d5ba43..81e5187efa 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -2689,7 +2689,6 @@ Që të hyni në një hapësirë ekzistuese, ju duhet një ftesë. Këtë mund ta ndryshoni më vonë Ç’lloj hapësire doni të krijoni\? - Hapësirat janë një mënyrë e re për të grupuar dhoma dhe persona Hapësira juaj private Hapësira juaj publike Shtoni Hapësirë diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 45e3b55007..b1c3f0de55 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -2660,7 +2660,6 @@ För att gå med i ett existerande utrymme så behöver du en inbjudan. Detta kan ändras senare Vilket sorts utrymme vill du skapa\? - Utrymmen är ett nytt sätt att gruppera rum och personer Ditt privata utrymme Ditt offentliga utrymme Lägg till utrymme diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index 25703d19cb..e1678e64d0 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -2024,7 +2024,6 @@ Налаштувати безпечне резервне копіювання Безпечне резервне копіювання Простори — це новий спосіб згуртувати кімнати та людей. - Простори — це новий спосіб згуртувати кімнати та людей Надіслати відгук Можете зв’язатися зі мною, якщо у вас виникнуть додаткові запитання Лише запрошені, найкраще для себе та команд diff --git a/vector/src/main/res/values-vi/strings.xml b/vector/src/main/res/values-vi/strings.xml index c71e59d685..6673cb4e4d 100644 --- a/vector/src/main/res/values-vi/strings.xml +++ b/vector/src/main/res/values-vi/strings.xml @@ -1838,7 +1838,6 @@ Để tham gia một Space hiện có, bạn cần một lời mời. Bạn có thể thay đổi điều này sau Bạn muốn tạo ra loại Space nào\? - Space là một cách mới để nhóm phòng và con người Space riêng tư của bạn Space công cộng của bạn Thêm Space diff --git a/vector/src/main/res/values-zh-rCN/strings.xml b/vector/src/main/res/values-zh-rCN/strings.xml index 953ae5c91a..dfc24d9293 100644 --- a/vector/src/main/res/values-zh-rCN/strings.xml +++ b/vector/src/main/res/values-zh-rCN/strings.xml @@ -2556,7 +2556,6 @@ 正在寻找不在 %s 中的人? %s 邀请了你 你被邀请 - 空间是一种将聊天室和人们进行分组的新方式 空间是一种将聊天室和人们进行重新分组的新方式。 欢迎来到空间! 添加聊天室 diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index ec901985ea..b485f07c4c 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -2650,7 +2650,6 @@ 要加入既有的空間,您需要邀請。 您可以稍後再更改 您想要建立哪種類型的空間? - 空間是一種將聊天室與人們分組的新方式 您的私人空間 您的公開空間 新增空間 diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index edf9ef189b..43c8b9605a 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -3524,8 +3524,6 @@ Add Space Your public space Your private space - - Spaces are a new way to group rooms and people What type of space do you want to create? You can change this later To join an existing space, you need an invite. From 2f048d8f8885a4b6ff06e8060eb13ddcdc1aea74 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 15:32:39 +0100 Subject: [PATCH 287/302] Remove unused string --- vector/src/main/res/values-cs/strings.xml | 5 ----- vector/src/main/res/values-de/strings.xml | 5 ----- vector/src/main/res/values-es/strings.xml | 5 ----- vector/src/main/res/values-et/strings.xml | 5 ----- vector/src/main/res/values-fa/strings.xml | 5 ----- vector/src/main/res/values-fr/strings.xml | 5 ----- vector/src/main/res/values-hu/strings.xml | 5 ----- vector/src/main/res/values-in/strings.xml | 5 ----- vector/src/main/res/values-it/strings.xml | 5 ----- vector/src/main/res/values-ja/strings.xml | 2 -- vector/src/main/res/values-nl/strings.xml | 5 ----- vector/src/main/res/values-pt-rBR/strings.xml | 5 ----- vector/src/main/res/values-ru/strings.xml | 5 ----- vector/src/main/res/values-sk/strings.xml | 5 ----- vector/src/main/res/values-sq/strings.xml | 5 ----- vector/src/main/res/values-sv/strings.xml | 5 ----- vector/src/main/res/values-uk/strings.xml | 5 ----- vector/src/main/res/values-vi/strings.xml | 5 ----- vector/src/main/res/values-zh-rCN/strings.xml | 5 ----- vector/src/main/res/values-zh-rTW/strings.xml | 5 ----- vector/src/main/res/values/strings.xml | 11 ----------- 21 files changed, 108 deletions(-) diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index 9070bbdb2e..ae1e386818 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -2917,11 +2917,6 @@ Propojte tento e-mail se svým účtem Pozvánka do této místnosti byla odeslána na adresu %s, která není spojena s vaším účtem Pozvánka do tohoto prostoru byla odeslána na adresu %s, která není spojena s vaším účtem - Chcete-li členům prostoru pomoci najít soukromou místnost a připojit se k ní, přejděte do nastavení dané místnosti klepnutím na avatar. - Pomozte členům prostoru najít soukromé místnosti - Díky tomu mohou místnosti zůstat soukromé a zároveň je mohou lidé v prostoru najít a připojit se k nim. Všechny nové místnosti v prostoru budou mít tuto možnost k dispozici. - Pomozte lidem v prostorech, aby sami našli soukromé místnosti a připojili se k nim, není třeba všechny zvát ručně. - Novinka: Nechat lidi v prostorech vyhledat a připojit se k soukromým místnostem Skupinový hovor zahájen Všechny místnosti, ve kterých se nacházíte, se zobrazí v Úvodu. Zobrazit všechny místnosti v Úvodu diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 54d69277e6..d2523da011 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2895,7 +2895,6 @@ Deine Schlüsselwörter Verknüpfe diese E-Mail-Adresse mit deinem Konto Die Einladung zu diesem Raum wurde an %s gesendet, welche nicht mit deinem Konto verknüpft ist - Hilf Space-Mitgliedern private Räume zu finden Auf deinem Mobilgerät wirst du keine Benachrichtigungen für Erwähnungen und Schlüsselwörter in verschlüsselten Räumen erhalten. Existierende Spaces hinzufügen Existierende Räume hinzufügen @@ -3014,10 +3013,6 @@ LaTeX-Mathematik aktivieren %s in den Einstellungen, um Einladungen direkt in Element zu erhalten. Diese Einladung zu diesem Raum wurde an %s gesendet, der nicht mit deinem Konto verbunden ist - Um Spacemitgliedern zu helfen, einen privaten Raum zu finden und ihm beizutreten, gehe zu den Einstellungen des Raums, indem du auf den Avatar tippst. - Dies macht es für Räume einfach, privat in einem Space zu bleiben, während die Leute im Space diese finden und ihnen beitreten können. Alle neuen Räume in einem Raum haben diese Option zur Verfügung. - Hilf Personen in Spaces, private Räume selbst zu finden und ihnen beizutreten, damit du nicht alle einzeln einladen musst. - Neu: Personen in Spaces können private Räume finden und ihnen beitreten Das System sendet automatisch Protokolle, wenn ein Fehler bei der Entschlüsselung auftritt Entschlüsselungsfehler automatisch melden. Auffindbarkeit (%s) diff --git a/vector/src/main/res/values-es/strings.xml b/vector/src/main/res/values-es/strings.xml index 071c7731e5..3b4c761757 100644 --- a/vector/src/main/res/values-es/strings.xml +++ b/vector/src/main/res/values-es/strings.xml @@ -2938,11 +2938,6 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua Vincula este correo electrónico con tu cuenta Esta invitación a este espacio se envió a %s que no está asociado con su cuenta Esta invitación a esta sala se envió a %s que no está asociado con su cuenta - Para ayudar a los miembros del espacio a encontrar y unirse a una sala privada, vaya a la configuración de esa sala tocando el avatar. - Ayuda a los miembros del espacio a encontrar salas privadas - Esto facilita que las habitaciones se mantengan privadas de un espacio, al tiempo que permite que las personas en el espacio las encuentren y se unan. Todas las habitaciones nuevas de un espacio tendrán esta opción disponible. - Ayude a las personas en los espacios a encontrar y unirse a salas privadas por sí mismas, sin necesidad de invitar a todos manualmente. - Nuevo: Permita que las personas en los espacios encuentren y se unan a salas privadas Tenga en cuenta que la mejora creará una nueva versión de la habitación. Todos los mensajes actuales permanecerán en esta sala archivada. Cualquiera en un espacio para padres podrá encontrar y unirse a esta sala, sin necesidad de invitar a todos manualmente. Podrás cambiar esto en la configuración de la habitación en cualquier momento. Cualquiera en %s podrá encontrar y unirse a esta sala, sin necesidad de invitar a todos manualmente. Podrás cambiar esto en la configuración de la habitación en cualquier momento. diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index e74f7ce6f7..c17bc1844b 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -2865,11 +2865,6 @@ Seo see e-posti aadress oma kasutajakontoga See kutse siia kogukonnakeskusesse saadeti aadressile %s, mis ei ole seotud sinu kontoga See kutse siia jututuppa saadeti aadressile %s, mis ei ole seotud sinu kontoga - Selleks, et kogukonnakeskuse liikmed saaks privaatseid jututube leida ning nendega liituda ava tunnuspildile klõpsides jututoa seadistused. - Aita kogukonnakeskuse liitmetel leida privaatseid jututube - See muudab lihtsaks, et jututoad jääksid kogukonnakeskuse piires privaatseks, kuid lasevad kogukonnakeskuses viibivatel inimestel need üles leida ja nendega liituda. Kõik kogukonnakeskuse uued jututoad on selle võimalusega. - Aita kogukonnakeskuse liikmetel endil leida privaatseid jututube ning nendega liituda nii et sa ei pea kõigile eraldi kutset saatma. - Uus funktsionaalsus: Võimalda kogukonnakeskuse liikmetel leida privaatseid jututube ning nendega liituda Rühmakõne algas Kõik sinu jututoad on nähtavad avalehel. Näita kõiki jututubasid avalehel diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index b8b7038d37..f76bf594a1 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -2863,11 +2863,6 @@ این رایانامه را به حسابتان پیوند دهید این دعوت به این فضا به %s فرستاده شده که با حسابتان در ارتباط نیست این دعوت به این اتاق به %s فرستاده شده که با حسابتان در ارتباط نیست - برای کمک به اعضای فضا برای یافتن و پیوستن به یک اتاق خصوصی، با زدن روی چهرک، به تنظیمات اتاق بروید. - کمک به اعضای فضا برای یافتن اتاق‌های خصوصی - این کار، خصوصی ماندن اتاق‌ها در فضا را، در عین اجازه به افراد داخل فضا برای یافتن و پیوستن، آسان می‌کند. تمامی اتاق‌های جدید در یک فضا، این گزینه را موجود دارند. - به افراد کمک‌کنید خودشان اتاق‌های خصوصی را یافته و بپیوندند. نیازی به دعوت دستی همه نیست. - جدید: بکذارید افراد در فضا، اتاق‌های خصوصی را یافته و بپیوندند تماس گروهی آغاز شد این اتاق را از %1$s به %2$s ارتقا خواهید داد. تمام اتاق‌هایی که‌در آن‌هایید، در خانه نشان داده خواهند شد. diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index 12ca5e46bd..d92e498b9d 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -2865,11 +2865,6 @@ 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 diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index ac136bc0f0..078237ef3b 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -2860,12 +2860,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze %s a Beállításokba a közvetlen meghívások fogadásához az Elemenetben. Ehhez a térhez a meghívó ide lett elküldve: %s, ami nincs összefüggésben a fiókoddal Ehhez a szobához a meghívó ide lett elküldve: %s, ami nincs összefüggésben a fiókoddal - A Tér tagságnak privát szoba megtalálásában és belépésben való segítséghez menj a szoba beállításaiba a profilképre való koppintással. Ennek az e-mailnek a fiókhoz való kötése - Segíts a tér tagságának privát szobák megtalálásában - A szobák egyszerűbben maradhatnak privátok a téren kívül, amíg a tér tagsága megtalálhatja és beléphet oda. Minden új szoba a téren rendelkezik ezzel a beállítási lehetőséggel. - Segíts a téren az embereknek privát szobák megtalálásába és a belépésben, nem szükséges a személyes meghívó. - Új: Engedd az embereknek a privát szobák megtalálását és a belépést Csoportos hívás elkezdődött Minden szoba amibe beléptél megjelenik a Kezdő téren. Minden szoba megjelenítése a Kezdő téren diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index 5c8d06229f..bc533a12dd 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -2300,9 +2300,6 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Email Lanjut Email verifikasi akan dikirim ke kotak masuk Anda untuk mengkonfirmasi pengaturan kata sandi baru Anda. - Ini membuatnya mudah untuk ruangan tetap privat di ruangan, sambil membiarkan orang-orang di space dapat menemukan dan bergabung ke ruangannya. Semua ruangan baru di space akan memiliki opsi ini. - Bantu orang-orang di space untuk menemukan dan bergabung ruangan privat sendiri, tidak perlu mengundang semua secara manual. - Baru: Izinkan orang-orang di space untuk menemukan dan bergabung ruangan privat Dicatat bahwa meningkatkan akan membuat versi baru dari ruangannya. Semua pesan saat ini akan tetap di ruangan yang diarsip. Siapa saja di induk ruangan dapat menemukan dan bergabung ke ruangan ini — tidak perlu mengundang semua secara manual. Anda dapat mengubahnya di pengaturan ruangan kapan saja. Siapa saja di %s dapat menemukan dan bergabung ke ruangan ini — tidak perlu mengundang semua secara manual. Anda dapat mengubahnya di pengaturan ruangan kapan saja. @@ -2627,8 +2624,6 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Tautkan email ini ke akun Anda Undangan space ini telah dikirim ke %s yang tidak diasosiasikan dengan akun Anda Undangan ruangan ini telah dikirim ke %s yang tidak diasosiasikan dengan akun Anda - Untuk membantu anggota space menemukan dan bergabung ke ruangan privat, pergilah ke pengaturan ruangannya dengan mengetuk pada avatarnya. - Bantu anggota space untuk menemukan ruangan privat Periksa ulang tautan ini Mohon pilih sebuah kata sandi. Mohon pilih sebuah nama pengguna. diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index dfbf2d84f6..46bd61afdf 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -2854,11 +2854,6 @@ Collega questa email con il tuo account Questo invito per questo spazio è stato inviato a %s, la quale non è associata al tuo account Questo invito per questa stanza è stato inviato a %s, la quale non è associata al tuo account - Per aiutare i membri dello spazio a trovare ed entrare in una stanza privata, vai nelle impostazioni di quella stanza toccando il suo avatar. - Aiuta i membri dello spazio a trovare stanze private - Ciò rende facile mantenere private le stanze in uno spazio, mentre le persone potranno trovarle ed unirsi. Tutte le stanze nuove in uno spazio avranno questa opzione disponibile. - Aiuta le persone negli spazi a trovare ed entrare nelle stanze private da sole, non c\'è bisogno di invitarle a mano. - Novità: consenti alle persone negli spazi di trovare ed entrare nelle stanze private Chiamata di gruppo iniziata Tutte le stanze in cui sei appariranno nella pagina principale. Mostra tutte le stanze nella pagina principale diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index eb1d1336d8..6ea7b83aa2 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2453,7 +2453,6 @@ %1$sにより%2$sに 質問あるいはトピック 投票の質問あるいはトピック - スペースのメンバーが非公開のルームを発見できるよう手伝う 少々お待ちください。少し時間がかかるかもしれません。 ルームのバージョン 👓 不安定 @@ -2519,7 +2518,6 @@ %sして、このルームを皆に紹介しましょう。 このコードを皆と共有し、スキャンして追加してもらい、会話を始めましょう。 正当な参加者が%sにアクセスできることを確認してください。これは後から変更できます。 - 新規:スペースの参加者が非公開のルームを検索し、参加できるようになりました 参加者を追加 %d人の知り合いがすでに参加しています diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index 51c4d29688..2fbe83db1b 100644 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -2875,11 +2875,6 @@ Space aanmaken… Aanmaken een space Gebeurtenis inhoud - Om leden van een kamer te helpen een privékamer te vinden en eraan deel te nemen, gat u naar de instellingen van die kamer door op de avatar te tikken. - Help leden van een space privékamers te vinden - Dit maakt het gemakkelijk voor kamers om privé te blijven voor een ruimte, terwijl mensen in de kamer ze kunnen vinden en erbij kunnen voegen. Alle nieuwe kamers in een kamer hebben deze optie beschikbaar. - Help mensen in kamers om zelf privékamers te vinden en eraan deel te nemen, het is niet nodig om iedereen handmatig uit te nodigen. - Nieuw: laat mensen in kamers, privékamers zoeken en er lid van worden Houd er rekening mee dat bij het upgraden een nieuwe versie van de kamer wordt gemaakt. Alle huidige berichten blijven in deze gearchiveerde kamer. Iedereen in een ouderkamer kan deze kamer vinden en er lid van worden. Het is niet nodig om iedereen handmatig uit te nodigen. U kunt dit op elk moment wijzigen in de kamer instellingen. Sta iedereen in %s toe om te zoeken en toegang te krijgen. U kunt ook andere kamers selecteren. diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index f18198bbf4..092460a80d 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -2864,11 +2864,6 @@ Linkar este email com sua conta Este convite para este espaço foi enviado para %s que não está associado com sua conta Este convite para esta sala foi enviado para %s que não está associado com sua conta - Para ajudar membros de espaço encontrarem e se juntarem uma sala privada, vá para as configurações dessa sala ao tocar no avatar. - Ajude membros de espaço encontrarem salas privadas - Isto facilita salas ficarem privadas a um espaço, enquanto deixa pessoas no espaço encontrarem e se juntarem a elas. Todas as salas novas em um espaço vão ter esta opção disponível. - Ajude pessoas em espaços a elas mesmas encontrarem e se juntarem a salas privadas, sem necessidade de manualmente convidar todo mundo. - Novo: Deixe pessoas em espaços encontrarem e se juntarem a salas privadas Chamada de grupo começada Todas as salas em que você está vão ser mostradas em Home. Mostrar todas as salas em Home diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index 67f4ebf0da..5dbf5f42db 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -2950,11 +2950,6 @@ Свяжите этот адрес электронной почты с вашей учетной записью Приглашение в эту комнату было отправлено на %s, который не связан с вашей учетной записью Приглашение в это пространство было отправлено на %s, который не связан с вашей учетной записью - Чтобы помочь участникам пространства найти и присоединиться к частной комнате, перейдите в настройки этой комнаты, нажав на ее аватар. - Помогите участникам пространства в поиске частных комнат - Это позволяет комнатам оставаться приватными для пространства, в то же время позволяя людям в пространстве находить их и присоединяться к ним. Все новые комнаты в пространстве будут иметь эту возможность. - Помогите людям в пространствах самим находить и присоединяться к приватным комнатам, без необходимости вручную приглашать всех. - Новое: Позволяет людям в пространствах находить и присоединяться к приватным комнатам Начался групповой вызов Все комнаты, в которых вы находитесь, будут отображаться в Начале. Показать все комнаты в Начале diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml index bd15a87f83..e0d87f48e4 100644 --- a/vector/src/main/res/values-sk/strings.xml +++ b/vector/src/main/res/values-sk/strings.xml @@ -2405,8 +2405,6 @@ Vyberte role potrebné na zmenu rôznych častí miestnosti Žiadna odpoveď Podržali ste hovor - Vďaka tomu môžu miestnosti zostať súkromné a zároveň ich môžu ľudia v priestore nájsť a pripojiť sa k nim. Túto možnosť budú mať k dispozícii všetky nové miestnosti v priestore. - Nové: Umožnite ľuďom v priestoroch nájsť a pripojiť sa k súkromným miestnostiam Umožniť komukoľvek v %s nájsť a získať prístup. Môžete vybrať aj iné priestory. Automaticky aktualizovať nadradený priestor Momentálne sa ľudia nemusia môcť pripojiť k súkromným miestnostiam, ktoré ste vytvorili. @@ -2508,9 +2506,6 @@ Toto je začiatok histórie vašich priamych správ s %s. Toto je začiatok tejto konverzácie. Toto je začiatok miestnosti %s. - Ak chcete pomôcť členom priestoru nájsť súkromnú miestnosť a pripojiť sa k nej, prejdite do nastavení danej miestnosti ťuknutím na obrázok. - Pomôcť členom priestoru nájsť súkromné miestnosti - Pomôžte ľuďom v priestoroch, aby sami našli súkromné miestnosti a pripojili sa k nim, aby nebolo potrebné každého ručne pozývať. Nepoznáte svoju prístupovú frázu pre zálohovanie kľúčov, môžete %s. Overte tohto používateľa potvrdením, že sa na jeho obrazovke zobrazujú nasledujúce jedinečné emotikony v rovnakom poradí. Zobrazenie niektorých užitočných informácií na pomoc pri ladení aplikácie diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index 81e5187efa..4198be4113 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -2854,11 +2854,6 @@ Lidheni këtë email me llogarinë tuaj Kjo ftesë për te kjo hapësirë u dërgua te %s që s’është i përshoqëruar me llogarinë tuaj Kjo ftesë për te kjo dhomë qe dërguar për %s që s’është i përshoqëruar me llogarinë tuaj - Për t’i ndihmuar anëtarët të gjejnë dhe hyjnë në një dhomë private, kaloni te rregullimet e asaj dhome duke prekur mbi avatarin. - Ndihmoni anëtarë hapësirash të gjejnë dhoma private - Kjo e bën të lehtë mbajtjen private të dhomave në një hapësirë, ndërkohë që u lejon njerëzve në hapësirë të gjejnë dhe hyjnë në të tilla. Krejt dhomat e reja në një hapësirë do ta ofrojnë këtë mundësi. - Ndihmojini njerëzit në hapësira të gjejnë dhe hyjnë vetë në dhoma private, pa pasur nevojë për ftesë dorazi të gjithkujt. - E re: Lejoni persona në hapësira të gjejnë dhe hyjnë në dhoma private U fillua thirrje grupi Krejt dhomat ku gjendeni do të shfaqen te Home. Shfaq krejt dhomat te Home diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index b1c3f0de55..e0b41886b9 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -2864,11 +2864,6 @@ Länka den här e-postadressen med ditt konto Denna inbjudan till det här utrymmet skickades till %s, vilket inte är associerat med ditt konto Denna inbjudan till det här rummet skickades till %s, vilket inte är associerat med ditt konto - För att hjälpa utrymmesmedlemmar att hitta och gå med i ett privat rum, gå till rummets inställningar genom att trycka på avataren. - Hjälp utrymmesmedlemmar att hitta privata rum - Detta gör det enklare för rum att hållas privata till ett utrymme, medans personer i utrymmet kan hitta och gå med i dem. Alla nya rum i ett utrymme kommer ha det här alternativet tillgängligt. - Hjälp personer i utrymmen att hitta och gå med i privata rum själva, utan behov av att manuellt bjuda in alla. - Nytt: Låt personer i utrymmen hitta och gå med i privata rum Gruppsamtal påbörjat Visa alla rum i Hem Alla rum du är i kommer att visas i Hem. diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index e1678e64d0..d9215cc654 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -2163,7 +2163,6 @@ Відео має не надіслану чернетку Деякі повідомлення не було надіслано - Щоб допомогти учасникам простору знайти та приєднатися до приватної кімнати, перейдіть до її налаштувань, торкнувшись аватара. Видалити аватар Установити аватар Змінити аватар @@ -2982,8 +2981,6 @@ \n - Домашній сервер, до якого під\'єднаний користувач, якого ви перевірили \n - Ваше інтернет-з\'єднання або інтернет-з\'єднання вашого користувача \n - Ваш пристрій або пристрій іншого користувача - Допоможіть учасникам простору знаходити приватні кімнати - Нове: Дозволити людям у просторах знаходити та приєднуватися до приватних кімнат Лише в цю кімнату Вони зможуть переглядати %s Запрошення за іменем користувача або е-поштою @@ -3018,8 +3015,6 @@ \nСпробуйте згодом або запитайте адміністратора кімнати, чи є у вас доступ. Це запрошення до простору надіслане %s, не пов\'язаній із вашим обліковим записом Це запрошення до кімнати надіслане %s, не пов\'язаній із вашим обліковим записом - Кімнати можуть лишатися закритими для людей ззовні простору, водночас люди в просторі можуть знаходити їх і приєднуватися. Всі нові кімнати в просторі матимуть цю опцію. - Допомагає людям у просторах знаходити закриті кімнати й приєднуватися самостійно, без потреби вручну запрошувати всіх. Зауважте, що поліпшення створить нову версію кімнати. Всі наявні повідомлення залишаться в цій архівованій кімнаті. Будь-хто в батьківському просторі зможемо знайти кімнату й долучитись — нема потреба вручну запрошувати всіх. Можна змінити це в налаштуваннях кімнати будь-коли. Будь-хто в %s зможе знайти кімнату й долучитись — нема потреби вручну запрошувати всіх. Можна змінити це в налаштуваннях кімнати будь-коли. diff --git a/vector/src/main/res/values-vi/strings.xml b/vector/src/main/res/values-vi/strings.xml index 6673cb4e4d..ad7c87b64f 100644 --- a/vector/src/main/res/values-vi/strings.xml +++ b/vector/src/main/res/values-vi/strings.xml @@ -1709,11 +1709,6 @@ Liên kết email này với tài khoản của bạn Lời mời này đến Space này đã được gửi đến %s không được liên kết với tài khoản của bạn Lời mời này đến phòng này đã được gửi đến %s không được liên kết với tài khoản của bạn - Để giúp các thành viên Space tìm và tham gia một phòng riêng, hãy vào cài đặt của căn phòng đó bằng cách nhấn vào hình đại diện. - Giúp các thành viên Space tìm phòng riêng - Điều này giúp các phòng dễ dàng giữ riêng tư cho một Space, đồng thời cho phép mọi người trong Space tìm và tham gia cùng họ. Tất cả các phòng mới trong một Space sẽ có tùy chọn này có sẵn. - Giúp mọi người trong Space tự tìm và tham gia phòng riêng, không cần phải tự mời mọi người. - Mới: Cho phép mọi người trong Space tìm và tham gia phòng riêng Xin lưu ý nâng cấp sẽ tạo ra một phiên bản mới của căn phòng. Tất cả các tin nhắn hiện tại sẽ ở trong phòng lưu trữ này. Bất cứ ai trong Space cha mẹ sẽ có thể tìm và tham gia căn phòng này - không cần phải mời mọi người theo cách thủ công. Bạn sẽ có thể thay đổi điều này trong cài đặt phòng bất cứ lúc nào. Bất kỳ ai trong %s sẽ có thể tìm và tham gia phòng này - không cần phải mời mọi người theo cách thủ công. Bạn sẽ có thể thay đổi điều này trong cài đặt phòng bất cứ lúc nào. diff --git a/vector/src/main/res/values-zh-rCN/strings.xml b/vector/src/main/res/values-zh-rCN/strings.xml index dfc24d9293..9313282491 100644 --- a/vector/src/main/res/values-zh-rCN/strings.xml +++ b/vector/src/main/res/values-zh-rCN/strings.xml @@ -2813,11 +2813,6 @@ 将此邮箱与您的账户相链接 加入这个空间的邀请被发送至 %s,此邮箱未与您的账户相关联 加入这个聊天室的邀请被发送至 %s,此邮箱未与您的账户相关联 - 要帮助空间成员找到并加入一个私人聊天室,只需点击头像进入聊天室设置。 - 帮助空间成员找到私人聊天室 - 这使聊天室很容易在空间中保持私密性,同时让空间中的人们找到并加入它们。空间中的所有新聊天室都有这个选项。 - 帮助空间里的人们自己找到和加入私人房间,不需要手动邀请每个人。 - 新:让人们在空间中找到并加入私人聊天室 群通话已启动 你所在的全部聊天室将显示在主页上。 在主页上显示所有聊天室 diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index b485f07c4c..a5da6e876c 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -2811,11 +2811,6 @@ 將此電子郵件與您的帳號連結 此空間的邀請已傳送給與您的帳號無關的 %s 此聊天室的邀請已傳送給與您的帳號無關的 %s - 要協助空間成員尋找並加入私人聊天室,請點擊大頭照進入該聊天是的設定中。 - 協助空間成員尋找私人聊天室 - 這讓聊天室可以輕鬆地對空間維持隱密,同時讓空間中的夥伴找到並加入它們。空間中的所有新的聊天室都將提供此選項。 - 協助空間內的夥伴自己尋找私人聊天室,不需要手動邀請所有人。 - 新功能:讓空間中的人尋找並加入私人聊天室 群組通話開始 您所在的所有聊天室都會顯示在 Home 中。 顯示 Home 中的所有聊天室 diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 43c8b9605a..b8ebd90fc9 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -3687,17 +3687,6 @@ Please note upgrading will make a new version of the room. All current messages will stay in this archived room. - - New: Let people in spaces find and join private rooms - - Help people in spaces to find and join private rooms themselves, no need to manually invite everyone. - - This makes it easy for rooms to stay private to a space, while letting people in the space find and join them. All new rooms in a space will have this option available. - - Help space members find private rooms - - To help space members find and join a private room, go to that room’s settings by tapping on the avatar. - This invite to this room was sent to %s which is not associated with your account From 672e798e7c09c80d0395a5bb16cc6faa84841838 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 15:34:14 +0100 Subject: [PATCH 288/302] Remove unused string --- vector/src/main/res/values-bg/strings.xml | 1 - vector/src/main/res/values-ca/strings.xml | 1 - vector/src/main/res/values-cs/strings.xml | 2 -- vector/src/main/res/values-de/strings.xml | 2 -- vector/src/main/res/values-el/strings.xml | 1 - vector/src/main/res/values-eo/strings.xml | 1 - vector/src/main/res/values-es/strings.xml | 1 - vector/src/main/res/values-et/strings.xml | 2 -- vector/src/main/res/values-fa/strings.xml | 2 -- vector/src/main/res/values-fi/strings.xml | 1 - vector/src/main/res/values-fr-rCA/strings.xml | 1 - vector/src/main/res/values-fr/strings.xml | 2 -- vector/src/main/res/values-fy/strings.xml | 1 - vector/src/main/res/values-hu/strings.xml | 2 -- vector/src/main/res/values-in/strings.xml | 2 -- vector/src/main/res/values-it/strings.xml | 2 -- vector/src/main/res/values-iw/strings.xml | 1 - vector/src/main/res/values-ja/strings.xml | 2 -- vector/src/main/res/values-kab/strings.xml | 1 - vector/src/main/res/values-lv/strings.xml | 1 - vector/src/main/res/values-nb-rNO/strings.xml | 1 - vector/src/main/res/values-nl/strings.xml | 2 -- vector/src/main/res/values-pl/strings.xml | 1 - vector/src/main/res/values-pt-rBR/strings.xml | 2 -- vector/src/main/res/values-ru/strings.xml | 2 -- vector/src/main/res/values-sk/strings.xml | 1 - vector/src/main/res/values-sq/strings.xml | 1 - vector/src/main/res/values-sv/strings.xml | 1 - vector/src/main/res/values-th/strings.xml | 1 - vector/src/main/res/values-tr/strings.xml | 2 -- vector/src/main/res/values-uk/strings.xml | 2 -- vector/src/main/res/values-vi/strings.xml | 1 - vector/src/main/res/values-zh-rCN/strings.xml | 1 - vector/src/main/res/values-zh-rTW/strings.xml | 2 -- vector/src/main/res/values/strings.xml | 4 ---- 35 files changed, 53 deletions(-) diff --git a/vector/src/main/res/values-bg/strings.xml b/vector/src/main/res/values-bg/strings.xml index edab57ba1b..0e8b35a9b6 100644 --- a/vector/src/main/res/values-bg/strings.xml +++ b/vector/src/main/res/values-bg/strings.xml @@ -2010,7 +2010,6 @@ Не е добавен имейл адрес в профила ви Имейл адрес Не е добавен телефонен номер в профила ви - Търсенето в шифровани стаи все още не се поддържа. Филтрирай блокираните потребители Премахването на блокирането ще позволи на потребителя пак да влезе в стаята. Премахване на блокиране diff --git a/vector/src/main/res/values-ca/strings.xml b/vector/src/main/res/values-ca/strings.xml index 4a0e8c6a47..2ac886d3d1 100644 --- a/vector/src/main/res/values-ca/strings.xml +++ b/vector/src/main/res/values-ca/strings.xml @@ -1464,7 +1464,6 @@ \n \nVols iniciar sessió utilitzant un client web\? No pots fer això des d\'${app_name} per a mòbils - La cerca en sales xifrades encara no està disponible. La sala encara no s\'ha acabat de crear. Vols cancel·lar la seva creació\? No s\'ha trobat aquesta sala. Assegura\'t que existeixi. Mostra detalls com per exemple noms de sala i contingut dels missatges. diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index ae1e386818..c7ae3aa034 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -2456,7 +2456,6 @@ Aplikace přijímá PUSH Aplikace čeká na PUSH Testovat push - Prohledávání šifrovaných místností ještě není podporováno. Filtrovat vykázané uživatele Nemáte oprávnění k zahájení hovoru Nemáte oprávnění k zahájení konferenčního hovoru @@ -3113,7 +3112,6 @@ Automaticky nahlašovat chyby dešifrování. Přepsat barvu přezdívky Již mám účet - Zlepšete týmovou komunikaci. Bezpečené zasílání zpráv. Máte vše pod kontrolou. Vlastněte své konverzace. diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index d2523da011..e617540a95 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2351,7 +2351,6 @@ Die Applikation empfängt den PUSH Die Applikation wartet auf den PUSH Push testen - Die Suche in verschlüsselten Räumen wird noch nicht unterstützt. Gebannte Nutzer filtern Du bist nicht berechtigt einen Anruf zu starten Du hast keine Berechtigung ein Konferenzgespräch zu starten @@ -3051,7 +3050,6 @@ Endgültiges Ergebnis basiert auf %1$d Stimme Endgültiges Ergebnis basiert auf %1$d Stimmen - Element verbindet Datenschutz mit tollen Features. Verschlüsselung wiederherstellen Standort freigeben Standort freigeben diff --git a/vector/src/main/res/values-el/strings.xml b/vector/src/main/res/values-el/strings.xml index 48fca269d9..40eadb4bfe 100644 --- a/vector/src/main/res/values-el/strings.xml +++ b/vector/src/main/res/values-el/strings.xml @@ -593,7 +593,6 @@ Ρυθμίσεις Λεπτομέρειες Δωματίου ΚΑΛΕΣΜΕΝΟΣ/Η - Η αναζήτηση σε κρυπτογραφημένα δωμάτια δεν υποστηρίζεται ακόμα. ΑΡΧΕΙΑ ΜΗΝΥΜΑΤΑ ΔΩΜΑΤΙΑ diff --git a/vector/src/main/res/values-eo/strings.xml b/vector/src/main/res/values-eo/strings.xml index fd97994323..bdf8e88ed5 100644 --- a/vector/src/main/res/values-eo/strings.xml +++ b/vector/src/main/res/values-eo/strings.xml @@ -1862,7 +1862,6 @@ %1$s ĉambro trovita por %2$s %1$s ĉambroj trovitaj por %2$s - Serĉado en ĉifritaj ĉambroj ankoraŭ en estas subtenata. Filtri forbaritajn uzantojn Akceptu la atestilon nur se administranto de la servilo publikigis fingrospuron akordan kun tiu ĉi-supre. La atestilo ŝanĝiĝis de antaŭe fidata al alia, nefidata. Eble la servilo renovigis sian atestilon. Kontaktu la administranton de la servilo por ricevi la ĝustan fingrospuron. diff --git a/vector/src/main/res/values-es/strings.xml b/vector/src/main/res/values-es/strings.xml index 3b4c761757..5de1aa8bc3 100644 --- a/vector/src/main/res/values-es/strings.xml +++ b/vector/src/main/res/values-es/strings.xml @@ -2358,7 +2358,6 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua La aplicación está recibiendo PUSH La aplicación está esperando al PUSH Probar Push - Todavía no se puede hacer búsquedas en salas cifradas. Filtrar usuarios excluidos Enviar la historia de peticiones de claves compartidas No hay más resultados diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index c17bc1844b..75e9eaabd7 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -2399,7 +2399,6 @@ Rakendus võtab vastu tõuketeavitust Rakendus ootab tõuketeavitust Tõuketeavituse test - Otsing krüptitud jututubades ei ole veel toetatud. Otsi suhtluskeelu saanud kasutajaid Sul ei ole õigusi siin jututoas helistamiseks Sul ei ole piisavalt õigusi, et selles jututoas alustada konverentsikõnet @@ -3054,7 +3053,6 @@ Automaatselt teata dekrüptimise vigadest. Asenda hüüdnime värvid Mul on kasutajakonto juba olemas - Lase tiimidel vabalt tegutseda. Turvaline sõnumivahetus. Sul on kontroll oma andmete üle. Vestlused, mida sa tegelikult ka omad. diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index f76bf594a1..1d514025b0 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -1732,7 +1732,6 @@ هیچ رایانامه‌ای به حسابتان افزوده نشده نشانی‌های رایانامه هیچ شماره تلفنی به حسابتان افزوده نشده - قابلیت جستجو در اتاق‌های رمزشده هنوز پیاده‌سازی نشده است. نتیجه‌ای در پی نداشت فیلترکردن کاربران مسدود شده لغو دانلود @@ -3074,7 +3073,6 @@ ایجاد حساب پیام‌رسانی برای گروهتان. مکان - قطع اسلک از تیم‌ها. پرداخت مکان‌های کاربری در خط زمانی پس از به کار افتادن، قادر خواهید بد مکانتان را به هر اتاقی بفرستید ${app_name} نتوانست به مکانتان دست یابد. لطفاً بعداً دوباره تلاش کنید. diff --git a/vector/src/main/res/values-fi/strings.xml b/vector/src/main/res/values-fi/strings.xml index 724fe7759f..a4b217f504 100644 --- a/vector/src/main/res/values-fi/strings.xml +++ b/vector/src/main/res/values-fi/strings.xml @@ -2517,7 +2517,6 @@ Poistetaanko %s\? Ei mitään Vain maininnat ja avainsanat - Hakeminen salatuista huoneista ei ole vielä tuettu. Vaihda avaruuden nimeä Ota avaruuden salaus käyttöön Avaruuden käyttöoikeudet diff --git a/vector/src/main/res/values-fr-rCA/strings.xml b/vector/src/main/res/values-fr-rCA/strings.xml index 4f57799d80..58004d1932 100644 --- a/vector/src/main/res/values-fr-rCA/strings.xml +++ b/vector/src/main/res/values-fr-rCA/strings.xml @@ -1443,7 +1443,6 @@ Notification sonore pour chaque message Recherche dans le répertoire… Parcourir le répertoire - La recherche dans les salons chiffrés n\'est pas encore prise en charge. FICHIERS PARTICIPANTS MESSAGES diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index d92e498b9d..d51d644f0d 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -2339,7 +2339,6 @@ Aucune adresse e-mail n’a été ajoutée à votre compte Adresses e-mail Aucun numéro de téléphone n’a été ajouté à votre compte - La recherche dans les salons chiffrés n\'est pas encore prise en charge. Filtrer les utilisateurs exclus Ne plus ignorer cet utilisateur aura pour effet de ré-afficher ses messages. expulser un utilisateur le supprimera de ce salon. @@ -3054,7 +3053,6 @@ Signalement automatique des erreurs de déchiffrement. Outrepasser la couleur du pseudo J’ai déjà un compte - Être vicTeams, ce n’est pas Slack vous voulez. Messagerie sécurisée. Vous êtes aux commandes. Contrôlez vos conversations. diff --git a/vector/src/main/res/values-fy/strings.xml b/vector/src/main/res/values-fy/strings.xml index bf6c65c92e..c3fd5c36e5 100644 --- a/vector/src/main/res/values-fy/strings.xml +++ b/vector/src/main/res/values-fy/strings.xml @@ -1402,7 +1402,6 @@ %d keamers Katalogus trochblêdzje - Sykjen yn fersifere keamers wurdt op dit stuit net stipe. BESTANNEN PERSOANEN BERJOCHTEN diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index 078237ef3b..aad01c11f9 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -2381,7 +2381,6 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Push tesztelése Ellenőrizd, hogy rákattintottál arra a hivatkozásra amit e-mailben küldtünk neked. %s törlése\? - Titkosított szobákban való keresés egyelőre nem támogatott. Kitiltott felhasználók szűrése Téma megváltoztatása Szoba fejlesztése @@ -3052,7 +3051,6 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Kamera megnyitása Becenév színének megváltoztatása Már van fiókom - Rázd fel a csoportjaidat. Biztonságos üzenetküldés. Te irányítasz. Tartózkodási hely megosztása diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index bc533a12dd..5b86d5aa67 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -985,7 +985,6 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Anda tidak dapat melakukan ini dari ponsel ${app_name} Konfirmasi kata sandi Anda Tidak ada nomor telepon yang ditambahkan ke akun Anda - Pencarian di ruangan terenkripsi belum didukung. Saring pengguna yang dicekal Mengubah topik Meng-upgrade ruangan ini @@ -2999,7 +2998,6 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Laporkan Kesalahan Dekripsi Secara Otomatis. Ubah warna nama tampilan Saya sudah punya akun - Bebaskan. Perpesanan yang aman. Anda dalam kendali. Miliki percakapan Anda. diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index 46bd61afdf..a07a02a66a 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -2384,7 +2384,6 @@ Ricezione push fallita. La soluzione può essere di reinstallare l\'applicazione. L\'applicazione sta ricevendo il PUSH Prova push - La ricerca in stanze cifrate non è ancora supportata. Filtra utenti banditi Non hai il permesso di avviare una chiamata Non hai il permesso di avviare una chiamata di gruppo @@ -3044,7 +3043,6 @@ Auto-segnala errori di decifrazione. Sovrascrivi colore nick Ho già un account - Riduci il carico ai team. Messaggistica sicura. Tu hai il controllo. Prendi il controllo delle tue conversazioni. diff --git a/vector/src/main/res/values-iw/strings.xml b/vector/src/main/res/values-iw/strings.xml index 744e3d726b..b6f83d4822 100644 --- a/vector/src/main/res/values-iw/strings.xml +++ b/vector/src/main/res/values-iw/strings.xml @@ -679,7 +679,6 @@ %d חדרים חפש בתיקיות - עדיין אין תמיכה בחיפוש בחדרים מוצפנים. קבצים אנשים הודעות diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 6ea7b83aa2..9dbad1bc22 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1204,7 +1204,6 @@ %sを削除しますか? 認証が必要です パスワードを確認 - 暗号化されたルームでの検索は、まだサポートされていません。 ブロックされたユーザーを絞り込む トピックを変更 ルームをアップグレード @@ -2507,7 +2506,6 @@ エンドツーエンドで暗号化され、電話番号不要。広告やデータマイニング無し。 会話の保存先を自分で決められ、自分で管理できる独立したコミュニケーション。Matrixをもとに。 お宅での対面会話と同じぐらいのプライバシーを提供する、セキュアで独立したコミュニケーション。 - チームワークを効率よくしましょう。 セキュアメッセージング 管理権を握るのは、あなたです。 Elementの使用に関するヘルプ diff --git a/vector/src/main/res/values-kab/strings.xml b/vector/src/main/res/values-kab/strings.xml index 0f22997e23..08bf1f913f 100644 --- a/vector/src/main/res/values-kab/strings.xml +++ b/vector/src/main/res/values-kab/strings.xml @@ -2273,7 +2273,6 @@ Ur tesɛiḍ ara tasiregt ad tebduḍ asiwel deg texxamt-a Issedmer s: %s Sekyed Push - Anadi deg texxamin yettwawgelhen ur yettusefrak ara akka tura. Sizdeg iseqdacen yettwagedlen Mudd tisirag i unekcum ɣer yinermisen-inek;inem. I usmiḍen n tengalt QR, tesriḍ ad tsirgeḍ anekcum ɣer tkamiṛat. diff --git a/vector/src/main/res/values-lv/strings.xml b/vector/src/main/res/values-lv/strings.xml index e5c808e2e5..41fcd1e1fa 100644 --- a/vector/src/main/res/values-lv/strings.xml +++ b/vector/src/main/res/values-lv/strings.xml @@ -1144,7 +1144,6 @@ Nākotnē šī pārbaudes procedūra plānota sarežģītāka. Apstipriniet paroli Jūsu kontam nav pievienots neviens tālruņa numurs Versija %s - Meklēšana šifrētās istabās pagaidām netiek atbalstīta. Mainīt tematu Mainīt atļaujas Nomainīt istabas nosaukumu diff --git a/vector/src/main/res/values-nb-rNO/strings.xml b/vector/src/main/res/values-nb-rNO/strings.xml index fa564a83c7..fcfba6f93c 100644 --- a/vector/src/main/res/values-nb-rNO/strings.xml +++ b/vector/src/main/res/values-nb-rNO/strings.xml @@ -1018,7 +1018,6 @@ %1$s rom funnet for %2$s Bla gjennom katalogen - Søking i krypterte rom støttes ikke ennå. FOLK Årsak til å rapportere dette innholdet Misdannet ID. Bør være en e-postadresse eller en Matrix ID som \'@localpart: domain\' diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index 2fbe83db1b..84bd540e9b 100644 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -2286,7 +2286,6 @@ De sessie is afgemeld! De kamer is verlaten! Alleen vermeldingen en trefwoorden - Zoeken in versleutelde kamers wordt nog niet ondersteund. Filter verbannen gebruikers Verander onderwerp Space upgraden @@ -2869,7 +2868,6 @@ Je wachtwoord is gereset. Ik heb mijn e-mailadres geverifieerd Tik op de link om uw nieuwe wachtwoord te bevestigen. Klik hieronder als u de link hebt gevolgd die erin staat. - Geef je teams meer ruimte. Word eigenaar van uw gesprekken. Space aanmaken Space aanmaken… diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index a72331453f..fc852245eb 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -2187,7 +2187,6 @@ Żaden adres e-mail nie został dodany do Twojego konta Adres e-mail Nie dodano żadnego numeru telefonu do Twojego konta - Wyszukiwanie w pokojach stosujących szyfrowanie nie jest obecnie wspierane. Filtruj zbanowanych użytkowników Odbanowanie użytkownika pozwoli mu na ponowne dołączenie do pokoju. Zbanuj użytkownika diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index 092460a80d..cff40afaa8 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -2391,7 +2391,6 @@ Falha para receber push. Solução podia ser reinstalar o aplicativo. O aplicativo está recebendo PUSH O aplicativo está esperando pelo PUSH - Pesquisar em salas encriptadas não é suportado ainda. Você não tem permissão para começar uma chamada Você não tem permissão para começar uma chamada de conferência Resetar @@ -3054,7 +3053,6 @@ Auro Reportar Erros de Decriptação. Sobrepor cor de nick Eu já tenho uma conta - Dê liberdade a times. Mensageria segura. Você está em controle. Tenha posse de suas conversas. diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index 5dbf5f42db..d5e878f954 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -2457,7 +2457,6 @@ %d приглашений %d приглашений - Поиск в зашифрованных комнатах пока не поддерживается. Фильтр заблокированных пользователей У вас нет разрешения на запуск звонка У вас нет разрешения на запуск конференции @@ -3148,7 +3147,6 @@ Сквозное шифрование не требующее номера телефона. Нет рекламы или сбора данных. Выбор где хранятся ваши разговоры дает вам власть и независимость. Подключено с помощью Matrix. Безопасное и независимое общение, обеспечивающее вам такой же уровень конфиденциальности, как при личном общении в вашем собственном доме. - Удалите шлак из команд. Безопасный обмен сообщениями. Ваше управление. Ваши собственные разговоры. diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml index e0d87f48e4..817cbd3fb1 100644 --- a/vector/src/main/res/values-sk/strings.xml +++ b/vector/src/main/res/values-sk/strings.xml @@ -2397,7 +2397,6 @@ Uistite sa, že ste klikli na odkaz v e-maile, ktorý sme vám poslali. Do vášho účtu nebol pridaný žiadny e-mail Do vášho účtu nebolo pridané žiadne telefónne číslo - Vyhľadávanie v zašifrovaných miestnostiach zatiaľ nie je podporované. Poslať udalosti m.room.server_acl Zmeniť hlavnú adresu miestnosti Odstrániť správy odoslané inými osobami diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index 4198be4113..6200c8f900 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -2387,7 +2387,6 @@ S’u arrit të merrej push. Zgjidhje mund të jetë riinstalimi i aplikacionit. Aplikacioni po merr PUSH Aplikacioni po pret për PUSH-in - Kërkimi në dhoma të fshehtëzuara nuk mbulohet ende. Filtro përdorues të dëbuar S’keni leje të nisni një thirrje S’keni leje të nisni një thirrje konferencë diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index e0b41886b9..4aa1d41f05 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -2399,7 +2399,6 @@ Appen tar emot PUSH:en Appen väntar på PUSH:en Testa push - Sökning i krypterade rum stöds inte än. Filtrera bannade användare Du är inte behörig att starta ett samtal Du är inte behörig att starta ett gruppsamtal diff --git a/vector/src/main/res/values-th/strings.xml b/vector/src/main/res/values-th/strings.xml index c0a5da1604..0304a52a21 100644 --- a/vector/src/main/res/values-th/strings.xml +++ b/vector/src/main/res/values-th/strings.xml @@ -173,7 +173,6 @@ %d ห้อง - ยังไม่รองรับการค้นหาในห้องที่เข้ารหัส ไฟล์ ผู้คน ข้อความ diff --git a/vector/src/main/res/values-tr/strings.xml b/vector/src/main/res/values-tr/strings.xml index d42e2532a1..e75b3857b9 100644 --- a/vector/src/main/res/values-tr/strings.xml +++ b/vector/src/main/res/values-tr/strings.xml @@ -1325,7 +1325,6 @@ Hesabınıza e-posta adresi eklenmemiş E-posta hesapları Hesabınıza hiçbir telefon numarası eklenmedi - Şifreli odalarda arama yapmak henüz desteklenmiyor. Banlanan kullanıcıları filtrele Konuyu değiştir Odayı geliştir @@ -2223,7 +2222,6 @@ Uçtan uca şifrelenir ve telefon numarası gerekmez. Reklam veya veri madenciliği yok. Size kontrol ve bağımsızlık vererek konuşmalarınızın nerede tutulacağını seçin. Matrix ile bağlandı. Size kendi evinizde yüz yüze görüşmeyle aynı düzeyde mahremiyet sağlayan güvenli ve bağımsız iletişim. - Takımların gevşekliğini kesin. Güvenli mesajlaşma. Kontrol sende. Konuşmalarınıza sahip çıkın. diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index d9215cc654..1bbbb0bc73 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -1104,7 +1104,6 @@ Аудіо Створити нову кімнату Кімнати - Пошук у зашифрованих кімнатах не наразі не підтримується. Запитувати підтвердження перед початком виклику Запобігати випадковим викликам Мені не потрібні мої зашифровані повідомлення @@ -3156,7 +3155,6 @@ Автозвіт про помилки шифрування. Замінити колір псевдоніма Я вже маю обліковий запис - Удоскональте спілкування в команді. Захищене спілкування. Ви контролюєте все. Володійте своїми розмовами. diff --git a/vector/src/main/res/values-vi/strings.xml b/vector/src/main/res/values-vi/strings.xml index ad7c87b64f..6e632a87d8 100644 --- a/vector/src/main/res/values-vi/strings.xml +++ b/vector/src/main/res/values-vi/strings.xml @@ -1430,7 +1430,6 @@ %d phòng Duyệt danh mục phòng - Tìm kiếm trong phòng mã hóa chưa được hỗ trợ. FILES NGƯỜI TIN NHẮN diff --git a/vector/src/main/res/values-zh-rCN/strings.xml b/vector/src/main/res/values-zh-rCN/strings.xml index 9313282491..fa5e819ec1 100644 --- a/vector/src/main/res/values-zh-rCN/strings.xml +++ b/vector/src/main/res/values-zh-rCN/strings.xml @@ -2307,7 +2307,6 @@ 应用正在接受推送 应用正在等待推送 测试推送 - 尚不支持在加密聊天室中搜索。 过滤被封禁的用户 你没有权限发起通话 你没有权限发起会议通话 diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index a5da6e876c..b4a8808e49 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -2352,7 +2352,6 @@ 應用程式正在接收 PUSH 應用程式正在等待 PUSH 測試推播 - 目前尚不支援在已加密的聊天室中搜尋。 過濾被封鎖的使用者 您沒有開始通話的權限 您沒有開始會議通話的權限 @@ -2995,7 +2994,6 @@ 自動回報解密錯誤。 覆寫暱稱色彩 我已有一個帳號 - 減少團隊的懈怠。 安全傳送訊息。 您已掌控了您的資料。 擁有您的對話。 diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index b8ebd90fc9..2da817767e 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1068,8 +1068,6 @@ MESSAGES PEOPLE FILES - - Searching in encrypted rooms is not supported yet. Browse directory @@ -2548,8 +2546,6 @@ Own your conversations. You\'re in control. Secure messaging. - - Cut the slack from teams. Secure and independent communication that gives you the same level of privacy as a face-to-face conversation in your own home. From 98b9f1b1ca4c646da78b10ecd274cccd84ce0e6d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 15:38:43 +0100 Subject: [PATCH 289/302] Rename some string resources --- .../ftueauth/SplashCarouselStateFactory.kt | 16 ++++++++-------- vector/src/main/res/values-cs/strings.xml | 14 +++++++------- vector/src/main/res/values-de/strings.xml | 14 +++++++------- vector/src/main/res/values-et/strings.xml | 14 +++++++------- vector/src/main/res/values-fa/strings.xml | 14 +++++++------- vector/src/main/res/values-fr/strings.xml | 14 +++++++------- vector/src/main/res/values-hu/strings.xml | 14 +++++++------- vector/src/main/res/values-in/strings.xml | 14 +++++++------- vector/src/main/res/values-it/strings.xml | 14 +++++++------- vector/src/main/res/values-ja/strings.xml | 14 +++++++------- vector/src/main/res/values-nl/strings.xml | 14 +++++++------- vector/src/main/res/values-pl/strings.xml | 6 +++--- vector/src/main/res/values-pt-rBR/strings.xml | 14 +++++++------- vector/src/main/res/values-ru/strings.xml | 14 +++++++------- vector/src/main/res/values-sk/strings.xml | 14 +++++++------- vector/src/main/res/values-sq/strings.xml | 14 +++++++------- vector/src/main/res/values-sv/strings.xml | 14 +++++++------- vector/src/main/res/values-tr/strings.xml | 14 +++++++------- vector/src/main/res/values-uk/strings.xml | 14 +++++++------- vector/src/main/res/values-zh-rTW/strings.xml | 14 +++++++------- vector/src/main/res/values/strings.xml | 19 ++++++++----------- 21 files changed, 145 insertions(+), 148 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/SplashCarouselStateFactory.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/SplashCarouselStateFactory.kt index da5f8b6379..006492f6dc 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/SplashCarouselStateFactory.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/SplashCarouselStateFactory.kt @@ -43,26 +43,26 @@ class SplashCarouselStateFactory @Inject constructor( fun hero(@DrawableRes lightDrawable: Int, @DrawableRes darkDrawable: Int) = if (lightTheme) lightDrawable else darkDrawable return SplashCarouselState(listOf( SplashCarouselState.Item( - R.string.ftue_auth_carousel_1_title.colorTerminatingFullStop(R.attr.colorAccent), - R.string.ftue_auth_carousel_body_secure, + R.string.ftue_auth_carousel_secure_title.colorTerminatingFullStop(R.attr.colorAccent), + R.string.ftue_auth_carousel_secure_body, hero(R.drawable.ic_splash_conversations, R.drawable.ic_splash_conversations_dark), background(R.drawable.bg_carousel_page_1) ), SplashCarouselState.Item( - R.string.ftue_auth_carousel_2_title.colorTerminatingFullStop(R.attr.colorAccent), - R.string.ftue_auth_carousel_body_control, + R.string.ftue_auth_carousel_control_title.colorTerminatingFullStop(R.attr.colorAccent), + R.string.ftue_auth_carousel_control_body, hero(R.drawable.ic_splash_control, R.drawable.ic_splash_control_dark), background(R.drawable.bg_carousel_page_2) ), SplashCarouselState.Item( - R.string.ftue_auth_carousel_3_title.colorTerminatingFullStop(R.attr.colorAccent), - R.string.ftue_auth_carousel_body_encrypted, + R.string.ftue_auth_carousel_encrypted_title.colorTerminatingFullStop(R.attr.colorAccent), + R.string.ftue_auth_carousel_encrypted_body, hero(R.drawable.ic_splash_secure, R.drawable.ic_splash_secure_dark), background(R.drawable.bg_carousel_page_3) ), SplashCarouselState.Item( collaborationTitle().colorTerminatingFullStop(R.attr.colorAccent), - R.string.ftue_auth_carousel_body_workplace, + R.string.ftue_auth_carousel_workplace_body, hero(R.drawable.ic_splash_collaboration, R.drawable.ic_splash_collaboration_dark), background(R.drawable.bg_carousel_page_4) ) @@ -72,7 +72,7 @@ class SplashCarouselStateFactory @Inject constructor( private fun collaborationTitle(): Int { return when { localeProvider.isEnglishSpeaking() -> R.string.cut_the_slack_from_teams - else -> R.string.ftue_auth_carousel_title_messaging + else -> R.string.ftue_auth_carousel_workplace_title } } diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index c7ae3aa034..1808e05cca 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -3112,9 +3112,9 @@ Automaticky nahlašovat chyby dešifrování. Přepsat barvu přezdívky Již mám účet - Bezpečené zasílání zpráv. - Máte vše pod kontrolou. - Vlastněte své konverzace. + Bezpečené zasílání zpráv. + Máte vše pod kontrolou. + Vlastněte své konverzace. Sdílet polohu Zobrazit polohy uživatele na časové ose Po zapnutí budete moci odeslat svou polohu do libovolné místnosti @@ -3142,10 +3142,10 @@ Šifrování bylo špatně nakonfigurováno. Sdíleli svou polohu Vytvořit účet - Zasílání zpráv pro váš tým. - Koncové šifrování bez potřeby telefonního čísla. Žádné reklamy ani vytěžování dat. - Můžete si vybrat, kde budou vaše konverzace uloženy, a získat tak kontrolu a nezávislost. Připojeno přes Matrix. - Bezpečná a nezávislá komunikace, která vám poskytne stejnou úroveň soukromí jako osobní rozhovor u vás doma. + Zasílání zpráv pro váš tým. + Koncové šifrování bez potřeby telefonního čísla. Žádné reklamy ani vytěžování dat. + Můžete si vybrat, kde budou vaše konverzace uloženy, a získat tak kontrolu a nezávislost. Připojeno přes Matrix. + Bezpečná a nezávislá komunikace, která vám poskytne stejnou úroveň soukromí jako osobní rozhovor u vás doma. Poloha Šifrování bylo špatně nakonfigurováno, takže nelze odesílat zprávy. Kliknutím otevřete nastavení. Zobrazit bubliny zpráv diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index e617540a95..f9214383fb 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2994,7 +2994,7 @@ Hilf mit, Element zu verbessern Aktivieren Farbe des Nicknamens ändern - Du hast die volle Kontrolle. + Du hast die volle Kontrolle. Du hast nicht die Berechtigung um diesen Raum zu betreten Keine Stimme abgegeben @@ -3019,8 +3019,8 @@ Schließe die Konfiguration des Auffindbarkeitsdienstes ab. Du verwendest derzeit keinen Identitätsserver. Um Teammitglieder einzuladen und für sie auffindbar zu sein, müssen du einen solchen Server konfigurieren. Ich habe schon ein Konto - Sichere Nachrichtenübertragung. - Besitze deine Konversationen. + Sichere Nachrichtenübertragung. + Besitze deine Konversationen. Richtlinie Um bestehende Kontakte ermitteln zu können, müsst du Kontaktinformationen (E-Mails und Telefonnummern) an Ihren Identitätsserver senden. Wir verschlüsseln deine Daten vor dem Senden, um den Datenschutz zu gewährleisten. Um bestehende Kontakte zu ermitteln, müssen Sie Kontaktinformationen an deinen Identitätsserver senden. @@ -3069,10 +3069,10 @@ Umfrage bearbeiten Keine Stimmen abgegeben Konto erstellen - Nachrichtenaustausch für dein Team. - Ende-zu-Ende-verschlüsselt und ohne Telefonnummer nutzbar. Keine Werbung oder Datenerfassung. - Wähle wo deine Gespräche liegen, für Kontrolle und Unabhängigkeit. Verbunden mit Matrix. - Sichere und unabhängige Kommunikation, die für die gleiche Vertraulichkeit sorgt, wie ein Gespräch von Angesicht zu Angesicht in deinem eigenen Zuhause. + Nachrichtenaustausch für dein Team. + Ende-zu-Ende-verschlüsselt und ohne Telefonnummer nutzbar. Keine Werbung oder Datenerfassung. + Wähle wo deine Gespräche liegen, für Kontrolle und Unabhängigkeit. Verbunden mit Matrix. + Sichere und unabhängige Kommunikation, die für die gleiche Vertraulichkeit sorgt, wie ein Gespräch von Angesicht zu Angesicht in deinem eigenen Zuhause. Standort Fehlerhaft konfiguriertes Vertrauenslevel Die Verschlüsselung ist fehlerhaft konfiguriert diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index 75e9eaabd7..e6ad731065 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -3053,9 +3053,9 @@ Automaatselt teata dekrüptimise vigadest. Asenda hüüdnime värvid Mul on kasutajakonto juba olemas - Turvaline sõnumivahetus. - Sul on kontroll oma andmete üle. - Vestlused, mida sa tegelikult ka omad. + Turvaline sõnumivahetus. + Sul on kontroll oma andmete üle. + Vestlused, mida sa tegelikult ka omad. Jaga asukohta Kuva ajajoonel kasutaja asukohti Kui see seadistus on kasutusel, siis sa saad oma asukohta jagada igas jututoas @@ -3082,10 +3082,10 @@ Krüptimise seadistustes on viga. Jagas oma asukohta Loo kasutajakonto - Sõnumisuhtlus sinu tiimi või kogukonna jaoks. - Tagatud on andmete läbiv krüptimine ning oma telefoninumbrit ei pea sa jagama. Pole reklaame ega sinu andmete kogumist. - Sa ise valid serveri, kus sinu vestlusi hoitakse ning sellega tagadki kontrolli oma andmete üle. Lahendus põhineb Matrix\'i võrgul. - Turvaline ja sõltumatu suhtluslahendus, mis tagab sama privaatsuse, kui omavaheline vestlus sinu kodus. + Sõnumisuhtlus sinu tiimi või kogukonna jaoks. + Tagatud on andmete läbiv krüptimine ning oma telefoninumbrit ei pea sa jagama. Pole reklaame ega sinu andmete kogumist. + Sa ise valid serveri, kus sinu vestlusi hoitakse ning sellega tagadki kontrolli oma andmete üle. Lahendus põhineb Matrix\'i võrgul. + Turvaline ja sõltumatu suhtluslahendus, mis tagab sama privaatsuse, kui omavaheline vestlus sinu kodus. Asukoht Krüptimise seadistustes on viga ja sa ei saa sõnumeid saata. Seadistuste avamiseks klõpsi siin. Krüptimise seadistustes on viga ja sa ei saa sõnumeid saata. Kui soovid krüptimist töökorda saada, siis võta ühendust serveri haldajaga. diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index 1d514025b0..340a39e585 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -3052,9 +3052,9 @@ سامانه‌تان هنگام‌ مواجهه با خطای ناتوانی در رمزگشایی، گزارش‌ها را به صورت خودکار خواهد فرستاد گزارش خودکار خطاهای رمزگشایی. از پیش حساب دارم - پیام‌رسانی امن. - شما کنترل می‌کنید. - صاحب گفت‌وگوهایتان باشید. + پیام‌رسانی امن. + شما کنترل می‌کنید. + صاحب گفت‌وگوهایتان باشید. هم‌رسانی مکان به کار انداختن هم‌رسانی مکان گشودن با @@ -3071,7 +3071,7 @@ بازیابی رمزنگاری مکانش را هم‌رسانی کرد ایجاد حساب - پیام‌رسانی برای گروهتان. + پیام‌رسانی برای گروهتان. مکان پرداخت مکان‌های کاربری در خط زمانی پس از به کار افتادن، قادر خواهید بد مکانتان را به هر اتاقی بفرستید @@ -3084,9 +3084,9 @@ پایمالی رنگ نام مستعار لطفاً برای بازگردانی رمزنگاری به یه وضعیتی معتبر، با مدیری تماس بگیرید. رمزنگاری بد پیکربندی شده. - رمزنگاشتهٔ سرتاسری و بدون نیاز به شماره تلفن. بدون تبلیغات یا داده‌کاوی. - مکان نگه‌داری گفت‌وگوهایتان را برگزینید که به شما کنترل و استقلال می‌هد. وصل شده با ماتریکس. - ارتباطات امن و مستقل که به شما همان سطح محرمانگی گفت‌وگوی رودررو در خانهٔ خودتان را می‌دهد. + رمزنگاشتهٔ سرتاسری و بدون نیاز به شماره تلفن. بدون تبلیغات یا داده‌کاوی. + مکان نگه‌داری گفت‌وگوهایتان را برگزینید که به شما کنترل و استقلال می‌هد. وصل شده با ماتریکس. + ارتباطات امن و مستقل که به شما همان سطح محرمانگی گفت‌وگوی رودررو در خانهٔ خودتان را می‌دهد. از آن‌جا که رمزنگاری بد پیکربندی شده، نمی‌توانید پیام بفرستید. برای گشودن تنظیمات، بزنید. از آن‌جا که رمزنگاری بد پیکربندی شده، نمی‌توانید پیام بفرستید. لطفاً برای بازگردانی رمزنگاری به یه وضعیت معتبر، با مدیری تماس بگیرید. نمایش حباب‌های پیام diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index d51d644f0d..26f3c4f36b 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -3053,11 +3053,11 @@ Signalement automatique des erreurs de déchiffrement. Outrepasser la couleur du pseudo J’ai déjà un compte - Messagerie sécurisée. - Vous êtes aux commandes. - Contrôlez vos conversations. + Messagerie sécurisée. + Vous êtes aux commandes. + Contrôlez vos conversations. Vous n’êtes pas autorisé à rejoindre ce salon - Choisissez où vos conversations sont stockées, vous avez le contrôle et êtes indépendant. Connecté via Matrix. + Choisissez où vos conversations sont stockées, vous avez le contrôle et êtes indépendant. Connecté via Matrix. Le chiffrement a été mal configuré ce qui vous empêche d’envoyer des messages. Veuillez contacter un administrateur pour remettre le chiffrement en état de marche. Partager la localisation Afficher les localisations de l\'utilisateur dans le temps @@ -3085,9 +3085,9 @@ Le chiffrement a été mal configuré. On partagé leur localisation Créer un compte - Messagerie pour votre équipe. - Chiffré de bout en bout et aucun numéro de téléphone n\'est nécessaire. Pas de pubs ni de collecte de données. - Communication indépendante et sécurisée qui vous donne le même niveau d\'intimité qu\'une discussion face-à-face dans votre maison. + Messagerie pour votre équipe. + Chiffré de bout en bout et aucun numéro de téléphone n\'est nécessaire. Pas de pubs ni de collecte de données. + Communication indépendante et sécurisée qui vous donne le même niveau d\'intimité qu\'une discussion face-à-face dans votre maison. Localisation Le chiffrement a été mal configuré ce qui vous empêche d\'envoyer des messages. Cliquez pour ouvrir les paramètres. \ No newline at end of file diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index aad01c11f9..77e18e0567 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -3040,7 +3040,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze A változások életbelépéséhez indítsd újra az alkalmazást. LaTeX matematikai szintaxis engedélyezése Nem léphetsz be ebbe a szobába - Az ön beszélgetései csak az öné. + Az ön beszélgetései csak az öné. Titkosítás visszafejtési hiba esemény alkalmával a rendszer automatikusan elküldi a logokat Titkosítás visszafejtési hibák automatikus jelentése. Szavazás létrehozása @@ -3051,8 +3051,8 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Kamera megnyitása Becenév színének megváltoztatása Már van fiókom - Biztonságos üzenetküldés. - Te irányítasz. + Biztonságos üzenetküldés. + Te irányítasz. Tartózkodási hely megosztása A felhasználó földrajzi helyzetének megjelenítése az idővonalon A beállítás után bármelyik szobában megoszthatod a földrajzi helyzetedet @@ -3079,10 +3079,10 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze A titkosítás beállítása hibás. A földrajzi helyzetüket megosztották Fiók létrehozása - Üzenetküldés a csoportodnak. - Telefonszám nélkül végpontok között titkosított. Reklámok és adatbányászat nélkül. - Válaszd meg hol legyenek a beszélgetéseid tárolva, visszaadja az irányítást és függetlenné tesz. Csatlakozva a Matrixhoz. - Biztonságos és független kommunikáció ami olyan biztonságos mintha valakivel négyszemközt beszélgetnél a házadban. + Üzenetküldés a csoportodnak. + Telefonszám nélkül végpontok között titkosított. Reklámok és adatbányászat nélkül. + Válaszd meg hol legyenek a beszélgetéseid tárolva, visszaadja az irányítást és függetlenné tesz. Csatlakozva a Matrixhoz. + Biztonságos és független kommunikáció ami olyan biztonságos mintha valakivel négyszemközt beszélgetnél a házadban. Földrajzi helyzet A titkosítás beállítása hibás így nem lehet üzenetet küldeni. Kattints a beállításokért. A titkosítás beállítása hibás így nem lehet üzenetet küldeni. Kérjük vedd fel a kapcsolatot az adminisztrátorral a titkosítás helyreállításához. diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index 5b86d5aa67..21af56e580 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -2998,9 +2998,9 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Laporkan Kesalahan Dekripsi Secara Otomatis. Ubah warna nama tampilan Saya sudah punya akun - Perpesanan yang aman. - Anda dalam kendali. - Miliki percakapan Anda. + Perpesanan yang aman. + Anda dalam kendali. + Miliki percakapan Anda. Bagikan lokasi Tampilkan lokasi pengguna di linimasa Setelah diaktifkan Anda akan dapat mengirim lokasi Anda ke ruangan apa saja @@ -3027,10 +3027,10 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Enkripsi telah dikonfigurasi dengan salah. Membagikan lokasinya Buat akun - Perpesanan untuk tim Anda. - Terenkripsi secara ujung-ke-ujung dan tidak memerlukan nomor telepon. Tidak ada iklan atau penambangan data. - Anda pilih di mana percakapan Anda disimpan, memberikan Anda kendali dan kebebasan. Terhubung via Matrix. - Komunikasi aman dan independen yang memberikan tingkat privasi yang sama seperti percakapan wajah-ke-wajah di dalam rumah Anda sendiri. + Perpesanan untuk tim Anda. + Terenkripsi secara ujung-ke-ujung dan tidak memerlukan nomor telepon. Tidak ada iklan atau penambangan data. + Anda pilih di mana percakapan Anda disimpan, memberikan Anda kendali dan kebebasan. Terhubung via Matrix. + Komunikasi aman dan independen yang memberikan tingkat privasi yang sama seperti percakapan wajah-ke-wajah di dalam rumah Anda sendiri. Lokasi Enkripsi telah dikonfigurasi dengan salah sehingga Anda tidak dapat mengirim pesan. Klik untuk membuka pengaturan. Enkripsi telah dikonfigurasi dengan salah sehingga Anda tidak dapat mengirim pesan. Mohon hubungi sebuah admin untuk memulihkan enkripsi ke status yang valid. diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index a07a02a66a..2eff4ea6cf 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -3043,9 +3043,9 @@ Auto-segnala errori di decifrazione. Sovrascrivi colore nick Ho già un account - Messaggistica sicura. - Tu hai il controllo. - Prendi il controllo delle tue conversazioni. + Messaggistica sicura. + Tu hai il controllo. + Prendi il controllo delle tue conversazioni. Condividi posizione Mostra le posizioni dell\'utente nella linea temporale Una volta attivata, potrai inviare la tua posizione in qualsiasi stanza @@ -3072,10 +3072,10 @@ La crittografia è stata configurata male. Ha condiviso la sua posizione Crea account - Messaggistica per la tua squadra. - Crittografia end-to-end e nessun numero di telefono richiesto. Niente pubblicità o raccolta di dati. - Scegli dove vengono tenute le tue conversazioni, dandoti controllo e indipendenza. Connesso via Matrix. - Comunicazioni sicure e indipendenti che ti danno lo stesso livello di riservatezza di una conversazione faccia a faccia in casa tua. + Messaggistica per la tua squadra. + Crittografia end-to-end e nessun numero di telefono richiesto. Niente pubblicità o raccolta di dati. + Scegli dove vengono tenute le tue conversazioni, dandoti controllo e indipendenza. Connesso via Matrix. + Comunicazioni sicure e indipendenti che ti danno lo stesso livello di riservatezza di una conversazione faccia a faccia in casa tua. Posizione La crittografia è stata configurata male, perciò non puoi inviare messaggi. Clicca per aprire le impostazioni. La crittografia è stata configurata male, perciò non puoi inviare messaggi. Contatta l\'amministratore per reimpostare la crittografia ad uno stato valido. diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 9dbad1bc22..d530447478 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2484,7 +2484,7 @@ 未確認 制限は不明です。 サーバーのファイルアップロードの制限 - 自分の会話は、自分のもの。 + 自分の会話は、自分のもの。 %1$sがこのルームを「招待者のみ参加可能」に設定しました。 選択したメッセージをネタバレとして送信 ${app_name} がエンドツーエンド暗号鍵をディスクに保存する許可を要求しています。 @@ -2502,12 +2502,12 @@ メッセージを降雪と共に送る 紙吹雪🎉を送る 降雪❄️を送る - あなたのチームのメッセージングに。 - エンドツーエンドで暗号化され、電話番号不要。広告やデータマイニング無し。 - 会話の保存先を自分で決められ、自分で管理できる独立したコミュニケーション。Matrixをもとに。 - お宅での対面会話と同じぐらいのプライバシーを提供する、セキュアで独立したコミュニケーション。 - セキュアメッセージング - 管理権を握るのは、あなたです。 + あなたのチームのメッセージングに。 + エンドツーエンドで暗号化され、電話番号不要。広告やデータマイニング無し。 + 会話の保存先を自分で決められ、自分で管理できる独立したコミュニケーション。Matrixをもとに。 + お宅での対面会話と同じぐらいのプライバシーを提供する、セキュアで独立したコミュニケーション。 + セキュアメッセージング + 管理権を握るのは、あなたです。 Elementの使用に関するヘルプ 詳細なログは、イライラシェイクでログを送信する際に、より多くのログを提供することで、開発者にとっての助けになります。有効にした場合でも、メッセージの内容やその他のプライベートな情報は記録されません。 ルームのアップグレードは高度な作業であり、不具合や欠けている機能、セキュリティー上の脆弱性がある場合に推奨されます。 diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index 84bd540e9b..f013aa8a7e 100644 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -2868,7 +2868,7 @@ Je wachtwoord is gereset. Ik heb mijn e-mailadres geverifieerd Tik op de link om uw nieuwe wachtwoord te bevestigen. Klik hieronder als u de link hebt gevolgd die erin staat. - Word eigenaar van uw gesprekken. + Word eigenaar van uw gesprekken. Space aanmaken Space aanmaken… Aanmaken een space @@ -3054,8 +3054,8 @@ Maak een Space Bijnaam kleur overschrijven Ik heb al een account - Veilig berichtenverkeer. - U heeft de controle. + Veilig berichtenverkeer. + U heeft de controle. Deel locatie Gebruikerslocaties in de tijdlijn weergeven Eenmaal ingeschakeld, kun je je locatie naar elke kamer sturen @@ -3082,10 +3082,10 @@ Versleuteling is verkeerd geconfigureerd. Hun locatie gedeeld Account aanmaken - Berichten voor uw team. - End-to-end versleuteld en geen telefoonnummer vereist. Geen advertenties of dataverzameling. - Kies waar je gesprekken worden bewaard, zodat u controle en onafhankelijkheid heeft. Verbonden via Matrix. - Veilige en onafhankelijke communicatie die u dezelfde mate van privacy geeft als een persoonlijk gesprek in uw eigen huis. + Berichten voor uw team. + End-to-end versleuteld en geen telefoonnummer vereist. Geen advertenties of dataverzameling. + Kies waar je gesprekken worden bewaard, zodat u controle en onafhankelijkheid heeft. Verbonden via Matrix. + Veilige en onafhankelijke communicatie die u dezelfde mate van privacy geeft als een persoonlijk gesprek in uw eigen huis. Locatie De versleuteling is verkeerd geconfigureerd, zodat u geen berichten kunt verzenden. Klik om instellingen te openen. De versleuteling is verkeerd geconfigureerd, zodat u geen berichten kunt verzenden. Neem contact op met een beheerder om de versleuteling in een geldige staat te herstellen. diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index fc852245eb..c9478d0997 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -3057,9 +3057,9 @@ Nadpisz kolor nicku Posiadam już konto - Połącz się z każdym. - Ty jesteś w kontroli. - Przejmij swoje konwersacje. + Połącz się z każdym. + Ty jesteś w kontroli. + Przejmij swoje konwersacje. By odkryć istniejące kontakty, musisz najpierw przesłać swoje dane kontaktowe (adresy e-mail i numer telefonu) do serwera tożsamości. Przed wysłaniem Twoje dane zostaną zaszyfrowane w celu zachowania prywatności. Uzyskaj pomoc w korzystaniu z Element Nie masz uprawnień by dołączyć do tego pokoju diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index cff40afaa8..c6cda60972 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -3053,9 +3053,9 @@ Auro Reportar Erros de Decriptação. Sobrepor cor de nick Eu já tenho uma conta - Mensageria segura. - Você está em controle. - Tenha posse de suas conversas. + Mensageria segura. + Você está em controle. + Tenha posse de suas conversas. Compartilhar localização Render localizações de usuária(o) na timeline Uma vez habilitada você vai ser capaz de enviar sua localização a qualquer sala @@ -3083,10 +3083,10 @@ Localização Encriptação tem sido malconfigurada. Criar conta - Mensageria para seu time. - Encriptado ponta-a-ponta e nenhum número de telefone requerido. Sem publicidade ou datamining. - Escolha onde suas conversas são mantidas, dando-lhe controle e independência. Conectado via Matrix. - Comunicação segura e independente que lhe dá o mesmo nível de privacidade que conversa face-a-face em sua própria casa. + Mensageria para seu time. + Encriptado ponta-a-ponta e nenhum número de telefone requerido. Sem publicidade ou datamining. + Escolha onde suas conversas são mantidas, dando-lhe controle e independência. Conectado via Matrix. + Comunicação segura e independente que lhe dá o mesmo nível de privacidade que conversa face-a-face em sua própria casa. Encriptação tem sido malconfigurada então você não pode enviar mensagens. Clique para abrir configurações. Encriptação tem sido malconfigurada então você não pode enviar mensagens. Por favor contacte um(a) admin para restaurar encriptação a um estado válido. Mostrar Bolhas de mensagem diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index d5e878f954..9ecb710da4 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -3143,13 +3143,13 @@ Поделились своим местоположением У меня уже есть учетная запись Создать учетную запись - Обмен сообщениями для вашей команды. - Сквозное шифрование не требующее номера телефона. Нет рекламы или сбора данных. - Выбор где хранятся ваши разговоры дает вам власть и независимость. Подключено с помощью Matrix. - Безопасное и независимое общение, обеспечивающее вам такой же уровень конфиденциальности, как при личном общении в вашем собственном доме. - Безопасный обмен сообщениями. - Ваше управление. - Ваши собственные разговоры. + Обмен сообщениями для вашей команды. + Сквозное шифрование не требующее номера телефона. Нет рекламы или сбора данных. + Выбор где хранятся ваши разговоры дает вам власть и независимость. Подключено с помощью Matrix. + Безопасное и независимое общение, обеспечивающее вам такой же уровень конфиденциальности, как при личном общении в вашем собственном доме. + Безопасный обмен сообщениями. + Ваше управление. + Ваши собственные разговоры. Местоположение Вы согласны отправить эту информацию\? Чтобы обнаружить существующие контакты, необходимо отправить контактную информацию (электронную почту и номера телефонов) на сервер обнаружения. Мы хешируем ваши данные перед отправкой для обеспечения конфиденциальности. diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml index 817cbd3fb1..daed54c19d 100644 --- a/vector/src/main/res/values-sk/strings.xml +++ b/vector/src/main/res/values-sk/strings.xml @@ -2083,7 +2083,7 @@ Skontrolujte prosím svoj e-mail Anketa skončila Pozvať podľa používateľského mena - Vlastnite svoje konverzácie. + Vlastnite svoje konverzácie. Už mám účet Nahrať súbor Videohovor s %s @@ -2189,8 +2189,8 @@ Pozvať pomocou používateľského mena alebo e-mailu Povoliť matematiku LaTeX Reštartujte aplikáciu, aby sa zmena prejavila. - Vy máte všetko pod kontrolou. - Bezpečné zasielanie správ. + Vy máte všetko pod kontrolou. + Bezpečné zasielanie správ. Automatické hlásenie chýb dešifrovania. Váš systém bude automaticky odosielať záznamy, keď sa vyskytne chyba dešifrovania Otvoriť kameru @@ -2198,10 +2198,10 @@ Odoslať nálepku Otvoriť kontakty Vytvoriť anketu - Bezpečná a nezávislá komunikácia, ktorá vám poskytuje rovnakú úroveň súkromia ako rozhovor zoči-voči vo vašom vlastnom dome. - Vyberte si, kde budú vaše rozhovory uložené, a získajte tak kontrolu a nezávislosť. Pripojené cez Matrix. - End-to-end šifrovanie a bez potreby telefónneho čísla. Žiadne reklamy ani zneužívanie údajov. - Zasielanie správ pre váš tím. + Bezpečná a nezávislá komunikácia, ktorá vám poskytuje rovnakú úroveň súkromia ako rozhovor zoči-voči vo vašom vlastnom dome. + Vyberte si, kde budú vaše rozhovory uložené, a získajte tak kontrolu a nezávislosť. Pripojené cez Matrix. + End-to-end šifrovanie a bez potreby telefónneho čísla. Žiadne reklamy ani zneužívanie údajov. + Zasielanie správ pre váš tím. Vytvoriť účet Šifrovanie je nesprávne nastavené. Obráťte sa na správcu, aby obnovil platný stav šifrovania. diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index 6200c8f900..03d8a94cdd 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -3041,9 +3041,9 @@ Raporto Vetvetiu Gabime Shfshehtëzimi. Anashkalo ngjyrë nofke Kam tashmë një llogari - Shkëmbim i siguruar mesazhesh. - Kontrollin e keni ju. - Jini zot i bisedave tuaja. + Shkëmbim i siguruar mesazhesh. + Kontrollin e keni ju. + Jini zot i bisedave tuaja. Jepe vendndodhjen Aktivizoni dhënie vendndodhjeje Jepe vendndodhjen @@ -3056,10 +3056,10 @@ Anketim i hapur Lloj anketimi Krijoni llogari - Shkëmbim mesazhesh për ekipin tuaj. - I fshehtëzuar skaj më skaj dhe pa u dashur numër telefoni. Pa reklama, apo shfrytëzim të dhënash. - Zgjidhni ku mbahen bisedat tuaja, duke ju dhënë kontroll dhe pavarësi. Të lidhur përmes Matrix-i. - Komunikim i sigurt dhe i pavarur, që ju jep të njëjtën shkallë privatësie si biseda kokë më kokë, në shtëpinë tuaj. + Shkëmbim mesazhesh për ekipin tuaj. + I fshehtëzuar skaj më skaj dhe pa u dashur numër telefoni. Pa reklama, apo shfrytëzim të dhënash. + Zgjidhni ku mbahen bisedat tuaja, duke ju dhënë kontroll dhe pavarësi. Të lidhur përmes Matrix-i. + Komunikim i sigurt dhe i pavarur, që ju jep të njëjtën shkallë privatësie si biseda kokë më kokë, në shtëpinë tuaj. Trego vendndodhje përdoruesi në rrjedhën kohore Pasi të aktivizohet, do të jeni në gjendje të dërgoni vendndodhjen tuaj në çfarëdo dhome Hape me diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 4aa1d41f05..5d6e3572c8 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -3052,9 +3052,9 @@ Rapportera avkrypteringsfel automatiskt. Åsidosätt visningsnamnsfärg Jag har redan ett konto - Säkra meddelanden. - Du har kontroll. - Äg dina konversationer. + Säkra meddelanden. + Du har kontroll. + Äg dina konversationer. Du får inte gå med i det här rummet Dela plats Visa användarplatser i tidslinjen @@ -3082,10 +3082,10 @@ Kryptering har felkonfigurerats. Delade sin plats Skapa konto - Meddelanden för ditt team. - Totalsträckskrypterad och inget telefonnummer krävs. Ingen reklam eller datainsamling. - Välj var dina konversationer lagras, vilket ger dig kontroll och självständighet. Ansluts via Matrix. - Säker och oberoende kommunikation som ger dig samma sekretessnivå som en personlig konversation i ditt eget hem. + Meddelanden för ditt team. + Totalsträckskrypterad och inget telefonnummer krävs. Ingen reklam eller datainsamling. + Välj var dina konversationer lagras, vilket ger dig kontroll och självständighet. Ansluts via Matrix. + Säker och oberoende kommunikation som ger dig samma sekretessnivå som en personlig konversation i ditt eget hem. Plats Kryptering har felkonfigurerats så du kan inte skicka meddelanden. Klicka för att öppna inställningar. Kryptering har felkonfigurerats så du kan inte skicka meddelanden. Vänligen kontakta en admin för att återställa kryptering till ett giltigt tillstånd. diff --git a/vector/src/main/res/values-tr/strings.xml b/vector/src/main/res/values-tr/strings.xml index e75b3857b9..b2ca20d871 100644 --- a/vector/src/main/res/values-tr/strings.xml +++ b/vector/src/main/res/values-tr/strings.xml @@ -2218,13 +2218,13 @@ %s ile devam et zaten bir hesabım var Hesap oluştur - Ekibiniz için mesajlaşma. - Uçtan uca şifrelenir ve telefon numarası gerekmez. Reklam veya veri madenciliği yok. - Size kontrol ve bağımsızlık vererek konuşmalarınızın nerede tutulacağını seçin. Matrix ile bağlandı. - Size kendi evinizde yüz yüze görüşmeyle aynı düzeyde mahremiyet sağlayan güvenli ve bağımsız iletişim. - Güvenli mesajlaşma. - Kontrol sende. - Konuşmalarınıza sahip çıkın. + Ekibiniz için mesajlaşma. + Uçtan uca şifrelenir ve telefon numarası gerekmez. Reklam veya veri madenciliği yok. + Size kontrol ve bağımsızlık vererek konuşmalarınızın nerede tutulacağını seçin. Matrix ile bağlandı. + Size kendi evinizde yüz yüze görüşmeyle aynı düzeyde mahremiyet sağlayan güvenli ve bağımsız iletişim. + Güvenli mesajlaşma. + Kontrol sende. + Konuşmalarınıza sahip çıkın. Bu daveti yalnızca siz yaptınız. %1$s bu daveti yalnızca yaptı. %1$s odayı yalnızca davet etti. diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index 1bbbb0bc73..dd07ae649e 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -3155,9 +3155,9 @@ Автозвіт про помилки шифрування. Замінити колір псевдоніма Я вже маю обліковий запис - Захищене спілкування. - Ви контролюєте все. - Володійте своїми розмовами. + Захищене спілкування. + Ви контролюєте все. + Володійте своїми розмовами. Поділитися місцеперебуванням Зображувати місцеперебування користувача у стрічці Після увімкнення ви зможете надіслати своє місцеперебування до будь-якої кімнати @@ -3184,10 +3184,10 @@ Шифрування неправильно налаштовано. Поділилися своїм місцеперебуванням Створити обліковий запис - Спілкування вашої команди. - З наскрізним шифруванням і без вимоги номера телефону. Без реклами чи аналізу даних. - Оберіть де спілкуватись, що дасть вам контроль і незалежність. Під\'єднано через Matrix. - Захищене та незалежне спілкування, яке дає вам такий самий рівень приватності, як розмова віч-на-віч у вашому власному домі. + Спілкування вашої команди. + З наскрізним шифруванням і без вимоги номера телефону. Без реклами чи аналізу даних. + Оберіть де спілкуватись, що дасть вам контроль і незалежність. Під\'єднано через Matrix. + Захищене та незалежне спілкування, яке дає вам такий самий рівень приватності, як розмова віч-на-віч у вашому власному домі. Місцеперебування Шифрування було налаштовано неправильно, тому ви не можете надсилати повідомлення. Торкніться, щоб відкрити налаштування. Шифрування було налаштовано неправильно, тому ви не можете надсилати повідомлення. Зверніться до адміністратора, щоб відновити роботу шифрування. diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index b4a8808e49..6fe33a224d 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -2994,9 +2994,9 @@ 自動回報解密錯誤。 覆寫暱稱色彩 我已有一個帳號 - 安全傳送訊息。 - 您已掌控了您的資料。 - 擁有您的對話。 + 安全傳送訊息。 + 您已掌控了您的資料。 + 擁有您的對話。 分享位置 在時間軸中繪製使用者位置 啟用後,您就能將您的位置傳送至任何聊天室 @@ -3023,10 +3023,10 @@ 加密設定錯誤。 分享了他們的位置 建立帳號 - 為您的團隊傳送訊息。 - 端到端加密,不需要電話號碼。沒有廣告或資料挖礦。 - 選擇保留對話的位置,讓您擁有控制權與獨立性。透過 Matrix 連結。 - 安全且獨立的通訊,為您提供與在家中進行面對面對話相同的隱私等級。 + 為您的團隊傳送訊息。 + 端到端加密,不需要電話號碼。沒有廣告或資料挖礦。 + 選擇保留對話的位置,讓您擁有控制權與獨立性。透過 Matrix 連結。 + 安全且獨立的通訊,為您提供與在家中進行面對面對話相同的隱私等級。 位置 加密設定錯誤,因此您無法傳送訊息。點擊以開啟設定。 加密設定錯誤,因此您無法傳送訊息。請聯絡管理員將加密還原至有效的狀態。 diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 2da817767e..ed54500a9d 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2542,19 +2542,16 @@ Unread messages - - Own your conversations. - You\'re in control. - Secure messaging. + Own your conversations. + You\'re in control. + Secure messaging. + Messaging for your team. - - Secure and independent communication that gives you the same level of privacy as a face-to-face conversation in your own home. - Choose where your conversations are kept, giving you control and independence. Connected via Matrix. - End-to-end encrypted and no phone number required. No ads or datamining. - - Messaging for your team. + Secure and independent communication that gives you the same level of privacy as a face-to-face conversation in your own home. + Choose where your conversations are kept, giving you control and independence. Connected via Matrix. + End-to-end encrypted and no phone number required. No ads or datamining. - ${app_name} is also great for the workplace. It’s trusted by the world’s most secure organisations. + ${app_name} is also great for the workplace. It’s trusted by the world’s most secure organisations. Who will you chat to the most? We\'ll help you get connected. From 407394b7fac267df76297f22d23ee31569c03bba Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 15:42:29 +0100 Subject: [PATCH 290/302] Create template with the app name --- vector/src/main/res/values-cs/strings.xml | 2 +- vector/src/main/res/values-de/strings.xml | 2 +- vector/src/main/res/values-es/strings.xml | 2 +- vector/src/main/res/values-et/strings.xml | 2 +- vector/src/main/res/values-fa/strings.xml | 2 +- vector/src/main/res/values-fr/strings.xml | 2 +- vector/src/main/res/values-hu/strings.xml | 2 +- vector/src/main/res/values-in/strings.xml | 2 +- vector/src/main/res/values-it/strings.xml | 2 +- vector/src/main/res/values-nl/strings.xml | 2 +- vector/src/main/res/values-pl/strings.xml | 2 +- vector/src/main/res/values-pt-rBR/strings.xml | 2 +- vector/src/main/res/values-ru/strings.xml | 2 +- vector/src/main/res/values-sk/strings.xml | 2 +- vector/src/main/res/values-sq/strings.xml | 2 +- vector/src/main/res/values-sv/strings.xml | 2 +- vector/src/main/res/values-uk/strings.xml | 2 +- vector/src/main/res/values-vi/strings.xml | 2 +- vector/src/main/res/values-zh-rCN/strings.xml | 2 +- vector/src/main/res/values-zh-rTW/strings.xml | 2 +- vector/src/main/res/values/strings.xml | 3 +-- 21 files changed, 21 insertions(+), 22 deletions(-) diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index 1808e05cca..ddb342d60d 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -2912,7 +2912,7 @@ Další Zmínky a klíčová slova Výchozí oznámení - %s v Nastavení pro příjem pozvánek přímo v Elementu. + %s v Nastavení pro příjem pozvánek přímo v ${app_name}u. Propojte tento e-mail se svým účtem Pozvánka do této místnosti byla odeslána na adresu %s, která není spojena s vaším účtem Pozvánka do tohoto prostoru byla odeslána na adresu %s, která není spojena s vaším účtem diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index f9214383fb..493a58ca0e 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -3010,7 +3010,7 @@ Starte die Anwendung neu, damit die Änderung wirksam wird. LaTeX-Mathematik aktivieren - %s in den Einstellungen, um Einladungen direkt in Element zu erhalten. + %s in den Einstellungen, um Einladungen direkt in ${app_name} zu erhalten. Diese Einladung zu diesem Raum wurde an %s gesendet, der nicht mit deinem Konto verbunden ist Das System sendet automatisch Protokolle, wenn ein Fehler bei der Entschlüsselung auftritt Entschlüsselungsfehler automatisch melden. diff --git a/vector/src/main/res/values-es/strings.xml b/vector/src/main/res/values-es/strings.xml index 5de1aa8bc3..c0a5308ca7 100644 --- a/vector/src/main/res/values-es/strings.xml +++ b/vector/src/main/res/values-es/strings.xml @@ -2933,7 +2933,7 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua Llamada sonando… Espacios Aprende más - %s en Configuración para recibir invitaciones directamente en Element. + %s en Configuración para recibir invitaciones directamente en ${app_name}. Vincula este correo electrónico con tu cuenta Esta invitación a este espacio se envió a %s que no está asociado con su cuenta Esta invitación a esta sala se envió a %s que no está asociado con su cuenta diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index e6ad731065..f61afa6dce 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -2860,7 +2860,7 @@ Kõik hõlmava kogukonna liikmed saavad antud jututuba leida ja sellega liituda - sa ei pea kedagi ükshaaval kutsuma. Neid jututoa seadistusi saad igal hetkel muuta. Kõik %s jututoa liikmed saavad antud jututuba leida ja sellega liituda - sa ei pea kedagi ükshaaval kutsuma. Neid jututoa seadistusi saad igal hetkel muuta. %1$s - tagasipöördumiseks klõpsi - %s ja saa kutsed otse Element\'i. + %s ja saa kutsed otse ${app_name}\'i. Seo see e-posti aadress oma kasutajakontoga See kutse siia kogukonnakeskusesse saadeti aadressile %s, mis ei ole seotud sinu kontoga See kutse siia jututuppa saadeti aadressile %s, mis ei ole seotud sinu kontoga diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index 340a39e585..fb07fc7d81 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -2858,7 +2858,7 @@ دیگر اشاره‌ها و کلیدواژگان آگاهی‌های پیش‌گزیده - %s در تنظیمات برای دریافت مستقیم دعوت‌ها در المنت. + %s در تنظیمات برای دریافت مستقیم دعوت‌ها در المنت. این رایانامه را به حسابتان پیوند دهید این دعوت به این فضا به %s فرستاده شده که با حسابتان در ارتباط نیست این دعوت به این اتاق به %s فرستاده شده که با حسابتان در ارتباط نیست diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index 26f3c4f36b..d573dd3718 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -2860,7 +2860,7 @@ Autre Mentions et mots-clés Notifications par défaut - %s dans les paramètres pour recevoir les invitations directement dans Element. + %s dans les paramètres pour recevoir les invitations directement dans ${app_name}. 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 diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index 77e18e0567..51e9ac831e 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -2856,7 +2856,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Elhúzás a megszakításhoz Hang üzenet felvétele %s tér tagság megtalálhatja és hozzáférhet. Más tereket is beállíthatsz. - %s a Beállításokba a közvetlen meghívások fogadásához az Elemenetben. + %s a Beállításokba a közvetlen meghívások fogadásához az ${app_name}. Ehhez a térhez a meghívó ide lett elküldve: %s, ami nincs összefüggésben a fiókoddal Ehhez a szobához a meghívó ide lett elküldve: %s, ami nincs összefüggésben a fiókoddal Ennek az e-mailnek a fiókhoz való kötése diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index 21af56e580..98cd4d27bf 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -2619,7 +2619,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Tambahkan sebuah space ke space apa saja yang Anda dapat kelola. Beri nama untuk melanjutkan. Gagal untuk memvalidasi PIN, mohon ketuk yang baru. - %s di Pengaturan untuk menerima undangan secara langsung di Element. + %s di Pengaturan untuk menerima undangan secara langsung di ${app_name}. Tautkan email ini ke akun Anda Undangan space ini telah dikirim ke %s yang tidak diasosiasikan dengan akun Anda Undangan ruangan ini telah dikirim ke %s yang tidak diasosiasikan dengan akun Anda diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index 2eff4ea6cf..afd2dffd4e 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -2849,7 +2849,7 @@ Altro Menzioni e parole chiave Notifiche predefinite - %s nella impostazioni per ricevere inviti direttamente in Element. + %s nella impostazioni per ricevere inviti direttamente in ${app_name}. Collega questa email con il tuo account Questo invito per questo spazio è stato inviato a %s, la quale non è associata al tuo account Questo invito per questa stanza è stato inviato a %s, la quale non è associata al tuo account diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index f013aa8a7e..1c3e540cbd 100644 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -2934,7 +2934,7 @@ Poll maken Start de toepassing opnieuw om de wijziging door te voeren. LaTeX wiskunde inschakelen - %s in Instellingen om uitnodigingen rechtstreeks in Element te ontvangen. + %s in Instellingen om uitnodigingen rechtstreeks in ${app_name} te ontvangen. Koppel deze e-mail aan uw account Deze uitnodiging voor deze space is verzonden naar %s die niet is gekoppeld aan uw account Deze uitnodiging voor deze kamer is verzonden naar %s die niet is gekoppeld aan uw account diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index c9478d0997..04ef105f60 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -2477,7 +2477,7 @@ • Serwery pasujące do %s zostały usunięte z listy zablokowanych. • Serwery pasujące do %s są teraz zablokowane. %1$s, %2$s i %3$s - %s w Ustawieniach, aby otrzymywać zaproszenia bezpośrednio w Elememencie. + %s w Ustawieniach, aby otrzymywać zaproszenia bezpośrednio w ${app_name}. Zmiana tematu Aktualizacja Przestrzeni Aktualizacja pokoju diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index c6cda60972..4f529b08e7 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -2859,7 +2859,7 @@ Outras Menções e Palavrachaves Notificações Default - %s em Configurações para receber convites diretamente em Element. + %s em Configurações para receber convites diretamente em ${app_name}. Linkar este email com sua conta Este convite para este espaço foi enviado para %s que não está associado com sua conta Este convite para esta sala foi enviado para %s que não está associado com sua conta diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index 9ecb710da4..6a9498a564 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -2945,7 +2945,7 @@ Упоминания и ключевые слова Уведомления по умолчанию Чтобы отправлять голосовые сообщения, предоставьте разрешение на Микрофон. - %s в настройках, чтобы получать приглашения непосредственно в Element. + %s в настройках, чтобы получать приглашения непосредственно в ${app_name}. Свяжите этот адрес электронной почты с вашей учетной записью Приглашение в эту комнату было отправлено на %s, который не связан с вашей учетной записью Приглашение в это пространство было отправлено на %s, который не связан с вашей учетной записью diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml index daed54c19d..14ee5d9356 100644 --- a/vector/src/main/res/values-sk/strings.xml +++ b/vector/src/main/res/values-sk/strings.xml @@ -2463,7 +2463,7 @@ Obrázok QR kódu Vytvorte novú priamu konverzáciu naskenovaním QR kódu Pridať pomocou QR kódu - %s v Nastaveniach na prijímanie pozvánok priamo v Elemente. + %s v Nastaveniach na prijímanie pozvánok priamo v ${app_name}e. Táto pozvánka do tohto priestoru bola odoslaná na adresu %s, ktorá nie je spojená s vaším účtom Táto pozvánka do tejto miestnosti bola odoslaná na adresu %s, ktorá nie je spojená s vaším účtom Každý, kto sa nachádza v nadradenom priestore, bude môcť túto miestnosť nájsť a pripojiť sa k nej - nie je potrebné každého ručne pozývať. V nastaveniach miestnosti to budete môcť kedykoľvek zmeniť. diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index 03d8a94cdd..6dfa7b928b 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -2849,7 +2849,7 @@ Tjetër Përmendje dhe Fjalëkyçe Njoftime Parazgjedhje - %s te Rregullimet, që të merrni ftesa drejt e në Element. + %s te Rregullimet, që të merrni ftesa drejt e në ${app_name}. Lidheni këtë email me llogarinë tuaj Kjo ftesë për te kjo hapësirë u dërgua te %s që s’është i përshoqëruar me llogarinë tuaj Kjo ftesë për te kjo dhomë qe dërguar për %s që s’është i përshoqëruar me llogarinë tuaj diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 5d6e3572c8..5fc5ab9312 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -2859,7 +2859,7 @@ Hemserver-API-URL Saknar behörighet För att skicka röstmeddelanden, vänligen ge mikrofonåtkomst. - %s i inställningar för att ta emot inbjudningar direkt i Element. + %s i inställningar för att ta emot inbjudningar direkt i ${app_name}. Länka den här e-postadressen med ditt konto Denna inbjudan till det här utrymmet skickades till %s, vilket inte är associerat med ditt konto Denna inbjudan till det här rummet skickades till %s, vilket inte är associerat med ditt konto diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index dd07ae649e..56d95e711a 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -2062,7 +2062,7 @@ Створення кімнати… Створення кімнати… Адміністратор вашого сервера вимкнув автоматичне наскрізне шифрування для приватних кімнат та особистих повідомлень. - %s у налаштуваннях, щоб отримувати запрошення безпосередньо в Element. + %s у налаштуваннях, щоб отримувати запрошення безпосередньо в ${app_name}. Зашифровані особисті повідомлення Особисті повідомлення Введіть ключ відновлення diff --git a/vector/src/main/res/values-vi/strings.xml b/vector/src/main/res/values-vi/strings.xml index 6e632a87d8..94147d6e45 100644 --- a/vector/src/main/res/values-vi/strings.xml +++ b/vector/src/main/res/values-vi/strings.xml @@ -1704,7 +1704,7 @@ Câu hỏi hoặc chủ đề Câu hỏi hoặc chủ đề thăm dò ý kiến Tạo Cuộc thăm dò ý kiến - %s trong Cài đặt để nhận lời mời trực tiếp trong Element. + %s trong Cài đặt để nhận lời mời trực tiếp trong ${app_name}. Liên kết email này với tài khoản của bạn Lời mời này đến Space này đã được gửi đến %s không được liên kết với tài khoản của bạn Lời mời này đến phòng này đã được gửi đến %s không được liên kết với tài khoản của bạn diff --git a/vector/src/main/res/values-zh-rCN/strings.xml b/vector/src/main/res/values-zh-rCN/strings.xml index fa5e819ec1..afafabf60d 100644 --- a/vector/src/main/res/values-zh-rCN/strings.xml +++ b/vector/src/main/res/values-zh-rCN/strings.xml @@ -2808,7 +2808,7 @@ 默认通知 活跃视频通话 活跃语音通话 - 在 Element 中直接接收邀请的设置 %s。 + 在 ${app_name} 中直接接收邀请的设置 %s。 将此邮箱与您的账户相链接 加入这个空间的邀请被发送至 %s,此邮箱未与您的账户相关联 加入这个聊天室的邀请被发送至 %s,此邮箱未与您的账户相关联 diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index 6fe33a224d..79329d7534 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -2806,7 +2806,7 @@ 其他 提及與關鍵字 預設通知 - 設定中的 %s 可直接在 Element 中接收邀請。 + 設定中的 %s 可直接在 ${app_name} 中接收邀請。 將此電子郵件與您的帳號連結 此空間的邀請已傳送給與您的帳號無關的 %s 此聊天室的邀請已傳送給與您的帳號無關的 %s diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index ed54500a9d..a1152dbb8f 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -3686,9 +3686,8 @@ This invite to this space was sent to %s which is not associated with your account Link this email with your account - - %s in Settings to receive invites directly in Element. + %s in Settings to receive invites directly in ${app_name}. Enable LaTeX mathematics Restart the application for the change to take effect. From e35d6a676a6790654a5b20f2f314f2a63633b2da Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 15:44:14 +0100 Subject: [PATCH 291/302] Create template with the app name --- vector/src/main/res/values-cs/strings.xml | 2 +- vector/src/main/res/values-de/strings.xml | 2 +- vector/src/main/res/values-et/strings.xml | 2 +- vector/src/main/res/values-fa/strings.xml | 2 +- vector/src/main/res/values-fr/strings.xml | 2 +- vector/src/main/res/values-hu/strings.xml | 2 +- vector/src/main/res/values-in/strings.xml | 2 +- vector/src/main/res/values-it/strings.xml | 2 +- vector/src/main/res/values-ja/strings.xml | 2 +- vector/src/main/res/values-nl/strings.xml | 2 +- vector/src/main/res/values-pl/strings.xml | 2 +- vector/src/main/res/values-pt-rBR/strings.xml | 2 +- vector/src/main/res/values-ru/strings.xml | 2 +- vector/src/main/res/values-sk/strings.xml | 2 +- vector/src/main/res/values-sq/strings.xml | 2 +- vector/src/main/res/values-sv/strings.xml | 2 +- vector/src/main/res/values-tr/strings.xml | 2 +- vector/src/main/res/values-uk/strings.xml | 2 +- vector/src/main/res/values-vi/strings.xml | 2 +- vector/src/main/res/values-zh-rCN/strings.xml | 2 +- vector/src/main/res/values-zh-rTW/strings.xml | 2 +- vector/src/main/res/values/strings.xml | 3 +-- 22 files changed, 22 insertions(+), 23 deletions(-) diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index ddb342d60d..871b6df78b 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -3097,7 +3097,7 @@ Pomozte nám identifikovat problémy a vylepšit Element sdílením anonymních údajů o používání. Abychom pochopili, jak lidé používají více zařízení, vygenerujeme náhodný identifikátor sdílený vašimi zařízeními. \n \nMůžete si přečíst všechny naše podmínky %s. - Pomozte vylepšit Element + Pomozte vylepšit ${app_name} Povolit Restartujte aplikaci, aby se změna projevila. Povolit matematické výrazy LaTeXu diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 493a58ca0e..e9f621f2c6 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2991,7 +2991,7 @@ Rechtliches Entscheide, welche Spaces Zugriff auf den Raum haben sollen. Die Mitglieder der Spaces können diesen Räumen beitreten. hier - Hilf mit, Element zu verbessern + Hilf mit, ${app_name} zu verbessern Aktivieren Farbe des Nicknamens ändern Du hast die volle Kontrolle. diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index f61afa6dce..bf57e8e16b 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -3037,7 +3037,7 @@ Võimalike vigade leidmiseks ja Element\'i arendamiseks jaga meiega anonüümseid andmeid. Selleks, et mõistaksime, kuidas kasutajad erinevaid seadmeid pruugivad me loome sinu seadmetele ühise juhusliku tunnuse. \n \nMeie kasutustingimused leiad siit - %s. - Aita Element\'i arendamisel + Aita ${app_name}\'i arendamisel Võta kasutusele Muudatuste jõustamiseks käivita rakendus uuesti. Kasuta LaTeX-vorminduses matemaatika märgistust diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index fb07fc7d81..59440e3343 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -3038,7 +3038,7 @@ ما اطّلاعات را با سوم‌شخص‌ها هم‌رسانی نمی‌کنیم ما هیچ دادهٔ حسابی را ذخیره یا نمایه نمی‌کنیم این‌جا - کمک به بهبود المنت + کمک به بهبود المنت به کار انداختن برای اثربخشی تغییر، برنامه را دوباره اجرا کنید. به کار انداختن ریاضیات لاتک diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index d573dd3718..e664ff63d1 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -3039,7 +3039,7 @@ Aidez nous à identifier les problèmes et améliorer Element en envoyant des rapports d’usage anonymes. Pour comprendre de quelle manière les gens utilisent Element sur plusieurs appareils, nous créeront un identifiant aléatoire commun à tous vos appareils. \n \nVous pouvez lire toutes les conditions %s. - Aider à améliorer Element + Aider à améliorer ${app_name} Activer Créer un sondage Ouvrir les contacts diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index 51e9ac831e..6d85204172 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -3034,7 +3034,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Segíts észrevennünk a hibákat, és jobbá tenni az Element-et a névtelen használati adatok küldése által. Ahhoz, hogy megértsük, hogyan használnak a felhasználók egyszerre több eszközt, egy véletlenszerű azonosítót generálunk, ami az eszközeid között meg lesz osztva. \n \nElolvashatod a feltételeinket %s. - Segíts az Element-et jobbá tenni + Segíts az ${app_name}-et jobbá tenni nyerő válasz Jogi dolgok A változások életbelépéséhez indítsd újra az alkalmazást. diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index 98cd4d27bf..c45f2f54ae 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -2983,7 +2983,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Bantu kami mengidentifikasi masalah-masalah dan membuat Element lebih baik dengan membagikan data penggunaan anonim. Untuk memahami bagaimana orang-orang menggunakan beberapa perangkat-perangkat, kami akan membuat pengenal acak, yang dibagikan oleh perangkat Anda. \n \nAnda dapat membaca semua kebijakan kami %s. - Bantu buat Element lebih baik + Bantu buat ${app_name} lebih baik Aktifkan Mulai ulang aplikasi ini untuk menerapkan perubahan. Aktifkan matematika LaTeX diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index afd2dffd4e..d6768d2a04 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -3028,7 +3028,7 @@ Aiutaci a identificare problemi e a migliorare Element condividendo dati di utilizzo anonimi. Per capire come le persone usano diversi dispositivi, genereremo un identificativo casuale, condiviso dai tuoi dispositivi. \n \nPuoi leggere i nostri termini di servizio %s. - Aiuta a migliorare Element + Aiuta a migliorare ${app_name} Attiva Riavvia l\'applicazione per applicare le modifiche. Attiva la matematica LaTeX diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index d530447478..84b2c3263b 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2314,7 +2314,7 @@ これはいつでも設定から無効にできます 私たちは、情報を第三者と共有することはありません 私たちは、アカウントのデータを記録したり分析したりすることはありません - Elementの改善を手伝う + ${app_name}の改善を手伝う このルームを「リンクを知っている人が参加可能」に設定しました。 どのユーザーも無視していません キーワードを入力するとリアクションを検索できます。 diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index 1c3e540cbd..8a4c267011 100644 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -2239,7 +2239,7 @@ Help ons problemen te identificeren en Element te verbeteren door anonieme gebruiksgegevens te delen. Om inzicht te krijgen in hoe mensen meerdere apparaten gebruiken, genereren we een willekeurige identificatie die door uw apparaten wordt gedeeld. \n \nU kunt al onze voorwaarden %s lezen. - Help Element verbeteren + Help ${app_name} verbeteren Dit zal uw huidige sleutel of zin vervangen. Genereer een nieuwe beveiligingssleutel of stel een nieuwe beveiligingszin in voor uw bestaande back-up. Bescherm uzelf tegen verlies van toegang tot versleutelde berichten en gegevens door een back-up te maken van versleutelingssleutels op uw server. diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index 04ef105f60..7caf382e55 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -3046,7 +3046,7 @@ Pomóż nam znaleźć błędy i ulepszyć Element poprzez udostępnianie anonimowych danych użytkowania. Aby lepiej zrozumieć jak użytkownicy wykorzystują wiele urządzeń wygenerujemy losowy identyfikator dzielony pomiędzy Twoimi urządzeniami. \n \nWięcej informacji %s. - Pomóż usprawnić Element + Pomóż usprawnić ${app_name} Nie teraz Włącz diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index 4f529b08e7..ba12e21a28 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -3032,7 +3032,7 @@ Ajude-nos a identificar problemas e melhorar Element ao compartilhar dados de uso anônimos. Para entender como pessoas usam seus múltiplos dispositivos, nós vamos gerar um identificador aleatório, compartilhado por seus dispositivos. \n \nVocê pode ler todos os nossos termos %s. - Ajude a melhorar Element + Ajude a melhorar ${app_name} Configurações de sistema Ajuda e suporte Ajuda diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index 6a9498a564..e57cfa8e1f 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -3176,7 +3176,7 @@ Помогите нам выявить проблемы и улучшить Element, поделившись анонимными данными об использовании. Чтобы понять, как люди используют несколько устройств, мы сгенерируем случайный идентификатор, общий для всех ваших устройств. \n \nВы можете ознакомиться со всеми нашими условиями %s. - Помогите улучшить Element + Помогите улучшить ${app_name} Сессия завершена! Комната покинута! Шифрование неправильно настроено, поэтому вы не можете отправлять сообщения. Нажмите, чтобы открыть настройки. diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml index 14ee5d9356..3d8b2b830c 100644 --- a/vector/src/main/res/values-sk/strings.xml +++ b/vector/src/main/res/values-sk/strings.xml @@ -2628,7 +2628,7 @@ Pomôžte nám identifikovať problémy a zlepšiť Element zdieľaním anonymných údajov o používaní. Aby sme pochopili, ako ľudia používajú viacero zariadení, vygenerujeme náhodný identifikátor, ktorý zdieľajú vaše zariadenia. \n \nMôžete si prečítať všetky naše podmienky %s. - Pomôžte zlepšiť Element + Pomôžte zlepšiť ${app_name} %1$s Ťuknite pre návrat Aktívny hovor (%1$s) · diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index 6dfa7b928b..03911e18f0 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -3022,7 +3022,7 @@ Ndihmonani të identifikojmë probleme dhe të përmirësojmë Element-in, duke ndarë me ne të dhëna anonime përdorimi. Për të kuptuar se si i përdorin njerëzit disa pajisje njëherësh, do të prodhojmë një identifikues kuturu, të përbashkët për pajisjet tuaja. \n \nMund të lexoni krejt kushtet tona %s. - Ndihmoni të përmirësohet Element-in + Ndihmoni të përmirësohet ${app_name}-in Aktivizoje %1$d votë e hedhur. Votoni, që të shihni përfundimet diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 5fc5ab9312..84d58a080f 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -3002,7 +3002,7 @@ Hjälp oss att identifiera problem och förbättra Element genom att dela anonym användningsdata. För att förstå hur personer använder multipla enheter så generar vi en slumpmässig identifierare som delas mellan dina enheter. \n \nDu kan läsa alla våra villkor %s. - Hjälp att förbättra Element + Hjälp att förbättra ${app_name} Aktivera Är du säker på att du vill ta bort den här omröstningen\? Du kommer inte kunna få tillbaka den när den har tagits bort. Ta bort omröstning diff --git a/vector/src/main/res/values-tr/strings.xml b/vector/src/main/res/values-tr/strings.xml index b2ca20d871..1ca6bfedb0 100644 --- a/vector/src/main/res/values-tr/strings.xml +++ b/vector/src/main/res/values-tr/strings.xml @@ -2077,7 +2077,7 @@ Anonim kullanım verilerini paylaşarak sorunları belirlememize ve Element\'i iyileştirmemize yardımcı olun. İnsanların birden fazla cihazı nasıl kullandığını anlamak için, cihazlarınız tarafından paylaşılan rastgele bir tanımlayıcı oluşturacağız. \n \n Tüm şartlarımızı %s okuyabilirsiniz. - Öğeyi iyileştirmeye yardımcı olun + Öğeyi iyileştirmeye yardımcı olun Mobil cihazlarda şifreli odalarda bahsedilenler ve anahtar kelimeler için bildirim almayacaksınız. Oda yükseltmeleri Bot tarafından gönderilen mesajlar diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index 56d95e711a..e38e676db9 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -3140,7 +3140,7 @@ Допомагайте нам визначати проблеми й удосконалювати Element, надсилаючи анонімні дані про використання. Щоб розуміти, як люди використовують кілька пристроїв, ми створимо спільний для ваших пристроїв випадковий ідентифікатор. \n \nМожете прочитати всі наші умови %s. - Допоможіть покращити Element + Допоможіть покращити ${app_name} Увімкнути Перезапустіть застосунок, щоб зміни набули чинності. Увімкнути підтримку LaTeX diff --git a/vector/src/main/res/values-vi/strings.xml b/vector/src/main/res/values-vi/strings.xml index 94147d6e45..79ae77cc5a 100644 --- a/vector/src/main/res/values-vi/strings.xml +++ b/vector/src/main/res/values-vi/strings.xml @@ -2914,7 +2914,7 @@ Giúp chúng tôi xác định các vấn đề và cải thiện Element bằng cách chia sẻ dữ liệu sử dụng ẩn danh. Để hiểu cách mọi người sử dụng nhiều thiết bị, chúng tôi sẽ tạo ra một mã định danh ngẫu nhiên, được chia sẻ bởi các thiết bị của bạn. \n \nBạn có thể đọc tất cả các thuật ngữ của chúng tôi %s. - Giúp cải thiện Element + Giúp cải thiện ${app_name} Thiết bị đã bị đăng xuất! Căn phòng đã bị bỏ lại! Chọn homeerver diff --git a/vector/src/main/res/values-zh-rCN/strings.xml b/vector/src/main/res/values-zh-rCN/strings.xml index afafabf60d..0cc008faac 100644 --- a/vector/src/main/res/values-zh-rCN/strings.xml +++ b/vector/src/main/res/values-zh-rCN/strings.xml @@ -2979,6 +2979,6 @@ 通过共享匿名使用数据,帮助我们识别问题并改进 Element。为了理解人们如何使用多台设备,我们将生成一个随机标识符,由您的设备共享。 \n \n你可以阅读我们所有的条款 %s。 - 帮助改进 Element + 帮助改进 ${app_name} 启用 \ No newline at end of file diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index 79329d7534..12002a52f7 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -2979,7 +2979,7 @@ 透過分享匿名使用資料協助我們找出問題並改善 Element。為了了解人們如何使用多裝置,我們將會產生隨機識別字串,在您的裝置間共享。 \n \n您可以閱讀我們的條款 %s。 - 協助改善 Element + 協助改善 ${app_name} 啟用 重新啟動應用程式以讓變更生效。 啟用 LaTeX 數學 diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index a1152dbb8f..5f2f2dabb2 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1386,8 +1386,7 @@ Please enable analytics to help us improve ${app_name}. Yes, I want to help! - - Help improve Element + Help improve ${app_name} Help us identify issues and improve Element by sharing anonymous usage data. To understand how people use multiple devices, we’ll generate a random identifier, shared by your devices.\n\nYou can read all our terms %s. From 9cd4b5d3b862ca392a6c1ae963e528dc4ffbe123 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 15:45:47 +0100 Subject: [PATCH 292/302] Create template with the app name --- vector/src/main/res/values-cs/strings.xml | 2 +- vector/src/main/res/values-de/strings.xml | 2 +- vector/src/main/res/values-et/strings.xml | 2 +- vector/src/main/res/values-fa/strings.xml | 2 +- vector/src/main/res/values-fr/strings.xml | 2 +- vector/src/main/res/values-hu/strings.xml | 2 +- vector/src/main/res/values-in/strings.xml | 2 +- vector/src/main/res/values-it/strings.xml | 2 +- vector/src/main/res/values-ja/strings.xml | 2 +- vector/src/main/res/values-nl/strings.xml | 2 +- vector/src/main/res/values-pl/strings.xml | 2 +- vector/src/main/res/values-pt-rBR/strings.xml | 2 +- vector/src/main/res/values-ru/strings.xml | 2 +- vector/src/main/res/values-sk/strings.xml | 2 +- vector/src/main/res/values-sq/strings.xml | 2 +- vector/src/main/res/values-sv/strings.xml | 2 +- vector/src/main/res/values-tr/strings.xml | 2 +- vector/src/main/res/values-uk/strings.xml | 2 +- vector/src/main/res/values-vi/strings.xml | 2 +- vector/src/main/res/values-zh-rCN/strings.xml | 2 +- vector/src/main/res/values-zh-rTW/strings.xml | 2 +- vector/src/main/res/values/strings.xml | 3 +-- 22 files changed, 22 insertions(+), 23 deletions(-) diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index 871b6df78b..8284a5de6a 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -3094,7 +3094,7 @@ Nesdílíme informace s třetími stranami Nezaznamenáváme ani neprofilujeme žádné údaje o účtu zde - Pomozte nám identifikovat problémy a vylepšit Element sdílením anonymních údajů o používání. Abychom pochopili, jak lidé používají více zařízení, vygenerujeme náhodný identifikátor sdílený vašimi zařízeními. + Pomozte nám identifikovat problémy a vylepšit ${app_name} sdílením anonymních údajů o používání. Abychom pochopili, jak lidé používají více zařízení, vygenerujeme náhodný identifikátor sdílený vašimi zařízeními. \n \nMůžete si přečíst všechny naše podmínky %s. Pomozte vylepšit ${app_name} diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index e9f621f2c6..3236332085 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2975,7 +2975,7 @@ Du kannst dies jederzeit in den Einstellungen deaktivieren Wir teilen keine Informationen mit Drittpersonen Wir erfassen und analysieren keine Accountdaten - Hilf uns dabei Probleme zu identifizieren und Element zu verbessern, indem du anonyme Nutzungsdaten teilst. Um zu verstehen, wie Personen mehrere Geräte benutzen, werden wir eine zufällige Kennung generieren, die zwischen deinen Geräten geteilt wird. + Hilf uns dabei Probleme zu identifizieren und ${app_name} zu verbessern, indem du anonyme Nutzungsdaten teilst. Um zu verstehen, wie Personen mehrere Geräte benutzen, werden wir eine zufällige Kennung generieren, die zwischen deinen Geräten geteilt wird. \n \n%s kannst du alle unsere Bedingungen lesen. Stelle sicher, dass die richtigen Personen Zugriff auf %s haben. Du kannst jederzeit weitere Personen einladen. diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index bf57e8e16b..bf486045be 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -3034,7 +3034,7 @@ Meie ei jaga teavet kolmandate osapooltega Meie ei salvesta ega profileeri sinu kasutajakonto andmeid siit - Võimalike vigade leidmiseks ja Element\'i arendamiseks jaga meiega anonüümseid andmeid. Selleks, et mõistaksime, kuidas kasutajad erinevaid seadmeid pruugivad me loome sinu seadmetele ühise juhusliku tunnuse. + Võimalike vigade leidmiseks ja ${app_name}\'i arendamiseks jaga meiega anonüümseid andmeid. Selleks, et mõistaksime, kuidas kasutajad erinevaid seadmeid pruugivad me loome sinu seadmetele ühise juhusliku tunnuse. \n \nMeie kasutustingimused leiad siit - %s. Aita ${app_name}\'i arendamisel diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index 59440e3343..c5e92e18f3 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -2995,7 +2995,7 @@ با فرستادن این اطّلاعات موافقید؟ اکنون نه برای کشف آشنایان موجود، لازم است اطلاعات آشنایان (رایانامه‌ها و شماره تلفن‌ها) را به کارساز هویتتان بفرستید. برای محرمانگیتان، داده‌هایتان را پیش از فرستادن، در هم می‌ریزیم. - با هم‌رسانی داده‌ّای استفادهٔ ناشناس، در تشخیص مشکل‌ها و بهبود المنت یاریمان کنید. برای درک چگونگی استفادهٔ مردم از چندین افزاره، شناسه‌ای کاتوره‌ای بین افزاره‌هایتان هم‌رسانی خواهیم کرد. + با هم‌رسانی داده‌ّای استفادهٔ ناشناس، در تشخیص مشکل‌ها و بهبود المنت یاریمان کنید. برای درک چگونگی استفادهٔ مردم از چندین افزاره، شناسه‌ای کاتوره‌ای بین افزاره‌هایتان هم‌رسانی خواهیم کرد. \n \nمی‌توانید از %s قوانینمان را بخوانید. مطمئنید که می خواهید این نظرسنجی را بردارید؟ پس از این کار، قادر به بازگردانیش نیستید. diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index e664ff63d1..ef55b09cc5 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -3036,7 +3036,7 @@ Nous ne partageons aucune information avec des tiers Nous n’enregistrons ou ne profilons aucune donnée du compte ici - Aidez nous à identifier les problèmes et améliorer Element en envoyant des rapports d’usage anonymes. Pour comprendre de quelle manière les gens utilisent Element sur plusieurs appareils, nous créeront un identifiant aléatoire commun à tous vos appareils. + Aidez nous à identifier les problèmes et améliorer ${app_name} en envoyant des rapports d’usage anonymes. Pour comprendre de quelle manière les gens utilisent Element sur plusieurs appareils, nous créeront un identifiant aléatoire commun à tous vos appareils. \n \nVous pouvez lire toutes les conditions %s. Aider à améliorer ${app_name} diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index 6d85204172..574386c0b4 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -3031,7 +3031,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Nem osztjuk meg az információt harmadik féllel Nem küldünk és nem profilozunk semmilyen fiók adatot itt - Segíts észrevennünk a hibákat, és jobbá tenni az Element-et a névtelen használati adatok küldése által. Ahhoz, hogy megértsük, hogyan használnak a felhasználók egyszerre több eszközt, egy véletlenszerű azonosítót generálunk, ami az eszközeid között meg lesz osztva. + Segíts észrevennünk a hibákat, és jobbá tenni az ${app_name}-et a névtelen használati adatok küldése által. Ahhoz, hogy megértsük, hogyan használnak a felhasználók egyszerre több eszközt, egy véletlenszerű azonosítót generálunk, ami az eszközeid között meg lesz osztva. \n \nElolvashatod a feltételeinket %s. Segíts az ${app_name}-et jobbá tenni diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index c45f2f54ae..c4c20b3a24 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -2980,7 +2980,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Kami tidak membagikan informasi ini dengan pihak ketiga Kami tidak merekam atau memprofil data akun apapun di sini - Bantu kami mengidentifikasi masalah-masalah dan membuat Element lebih baik dengan membagikan data penggunaan anonim. Untuk memahami bagaimana orang-orang menggunakan beberapa perangkat-perangkat, kami akan membuat pengenal acak, yang dibagikan oleh perangkat Anda. + Bantu kami mengidentifikasi masalah-masalah dan membuat ${app_name} lebih baik dengan membagikan data penggunaan anonim. Untuk memahami bagaimana orang-orang menggunakan beberapa perangkat-perangkat, kami akan membuat pengenal acak, yang dibagikan oleh perangkat Anda. \n \nAnda dapat membaca semua kebijakan kami %s. Bantu buat ${app_name} lebih baik diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index d6768d2a04..b5b0c09b62 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -3025,7 +3025,7 @@ Non condividiamo informazioni con terze parti Non registriamo o profiliamo alcun dato dell\'account qui - Aiutaci a identificare problemi e a migliorare Element condividendo dati di utilizzo anonimi. Per capire come le persone usano diversi dispositivi, genereremo un identificativo casuale, condiviso dai tuoi dispositivi. + Aiutaci a identificare problemi e a migliorare ${app_name} condividendo dati di utilizzo anonimi. Per capire come le persone usano diversi dispositivi, genereremo un identificativo casuale, condiviso dai tuoi dispositivi. \n \nPuoi leggere i nostri termini di servizio %s. Aiuta a migliorare ${app_name} diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 84b2c3263b..64bf6859e7 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2704,7 +2704,7 @@ 次の絵文字が相手の画面にも同じ順番で現れるのを確認し、このユーザーを検証してください。 信頼できないサインイン 使用できない文字が含まれています - Elementの改善と課題抽出のために、匿名の使用状況データの送信をお願いします。複数の端末での使用を分析するために、あなたの全端末共通のランダムな識別子を生成します。 + ${app_name}の改善と課題抽出のために、匿名の使用状況データの送信をお願いします。複数の端末での使用を分析するために、あなたの全端末共通のランダムな識別子を生成します。 \n \n%sで利用規約を閲覧できます。 最初の検索結果のみ表示しています。文字をもっと入力してください… diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index 8a4c267011..d3cd933e16 100644 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -2236,7 +2236,7 @@ We delen geen informatie met derden We registreren of profileren geen accountgegevens hier - Help ons problemen te identificeren en Element te verbeteren door anonieme gebruiksgegevens te delen. Om inzicht te krijgen in hoe mensen meerdere apparaten gebruiken, genereren we een willekeurige identificatie die door uw apparaten wordt gedeeld. + Help ons problemen te identificeren en ${app_name} te verbeteren door anonieme gebruiksgegevens te delen. Om inzicht te krijgen in hoe mensen meerdere apparaten gebruiken, genereren we een willekeurige identificatie die door uw apparaten wordt gedeeld. \n \nU kunt al onze voorwaarden %s lezen. Help ${app_name} verbeteren diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index 7caf382e55..26d01b81ca 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -3043,7 +3043,7 @@ Nie udostępniamy informacji podmiotom trzecim Nie zbieramy i nie profilujemy danych użytkownika tutaj - Pomóż nam znaleźć błędy i ulepszyć Element poprzez udostępnianie anonimowych danych użytkowania. Aby lepiej zrozumieć jak użytkownicy wykorzystują wiele urządzeń wygenerujemy losowy identyfikator dzielony pomiędzy Twoimi urządzeniami. + Pomóż nam znaleźć błędy i ulepszyć ${app_name} poprzez udostępnianie anonimowych danych użytkowania. Aby lepiej zrozumieć jak użytkownicy wykorzystują wiele urządzeń wygenerujemy losowy identyfikator dzielony pomiędzy Twoimi urządzeniami. \n \nWięcej informacji %s. Pomóż usprawnić ${app_name} diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index ba12e21a28..d3fdd8ee05 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -3029,7 +3029,7 @@ A política de seu servidorcasa Política de ${app_name} Nós não gravamos ou perfilamos quaisquer dados de conta - Ajude-nos a identificar problemas e melhorar Element ao compartilhar dados de uso anônimos. Para entender como pessoas usam seus múltiplos dispositivos, nós vamos gerar um identificador aleatório, compartilhado por seus dispositivos. + Ajude-nos a identificar problemas e melhorar ${app_name} ao compartilhar dados de uso anônimos. Para entender como pessoas usam seus múltiplos dispositivos, nós vamos gerar um identificador aleatório, compartilhado por seus dispositivos. \n \nVocê pode ler todos os nossos termos %s. Ajude a melhorar ${app_name} diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index e57cfa8e1f..4ab6e3a75f 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -3173,7 +3173,7 @@ Мы не передаем информацию третьим лицам Мы не записываем и не профилируем любые данные учетной записи тут - Помогите нам выявить проблемы и улучшить Element, поделившись анонимными данными об использовании. Чтобы понять, как люди используют несколько устройств, мы сгенерируем случайный идентификатор, общий для всех ваших устройств. + Помогите нам выявить проблемы и улучшить ${app_name}, поделившись анонимными данными об использовании. Чтобы понять, как люди используют несколько устройств, мы сгенерируем случайный идентификатор, общий для всех ваших устройств. \n \nВы можете ознакомиться со всеми нашими условиями %s. Помогите улучшить ${app_name} diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml index 3d8b2b830c..89f05c0360 100644 --- a/vector/src/main/res/values-sk/strings.xml +++ b/vector/src/main/res/values-sk/strings.xml @@ -2625,7 +2625,7 @@ Nezaznamenávame ani neprofilujeme žiadne údaje o účte Potvrďte svoju totožnosť overením tohto prihlasovacieho mena, čím mu udelíte prístup k zašifrovaným správam. Potvrďte svoju totožnosť overením tohto prihlásenia z jednej z vašich ďalších relácií, čím jej udelíte prístup k zašifrovaným správam. - Pomôžte nám identifikovať problémy a zlepšiť Element zdieľaním anonymných údajov o používaní. Aby sme pochopili, ako ľudia používajú viacero zariadení, vygenerujeme náhodný identifikátor, ktorý zdieľajú vaše zariadenia. + Pomôžte nám identifikovať problémy a zlepšiť ${app_name} zdieľaním anonymných údajov o používaní. Aby sme pochopili, ako ľudia používajú viacero zariadení, vygenerujeme náhodný identifikátor, ktorý zdieľajú vaše zariadenia. \n \nMôžete si prečítať všetky naše podmienky %s. Pomôžte zlepšiť ${app_name} diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index 03911e18f0..d6c796cfa5 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -3019,7 +3019,7 @@ Nuk u japin hollësi palëve të treta Nuk regjistrojmë ose profilizojmë ndonjë të dhënë llogarie këtu - Ndihmonani të identifikojmë probleme dhe të përmirësojmë Element-in, duke ndarë me ne të dhëna anonime përdorimi. Për të kuptuar se si i përdorin njerëzit disa pajisje njëherësh, do të prodhojmë një identifikues kuturu, të përbashkët për pajisjet tuaja. + Ndihmonani të identifikojmë probleme dhe të përmirësojmë ${app_name}-in, duke ndarë me ne të dhëna anonime përdorimi. Për të kuptuar se si i përdorin njerëzit disa pajisje njëherësh, do të prodhojmë një identifikues kuturu, të përbashkët për pajisjet tuaja. \n \nMund të lexoni krejt kushtet tona %s. Ndihmoni të përmirësohet ${app_name}-in diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 84d58a080f..fcdbbc481a 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -2999,7 +2999,7 @@ Vi delar inte information med tredje parter Vi spelar inte in eller profilerar någon kontodata här - Hjälp oss att identifiera problem och förbättra Element genom att dela anonym användningsdata. För att förstå hur personer använder multipla enheter så generar vi en slumpmässig identifierare som delas mellan dina enheter. + Hjälp oss att identifiera problem och förbättra ${app_name} genom att dela anonym användningsdata. För att förstå hur personer använder multipla enheter så generar vi en slumpmässig identifierare som delas mellan dina enheter. \n \nDu kan läsa alla våra villkor %s. Hjälp att förbättra ${app_name} diff --git a/vector/src/main/res/values-tr/strings.xml b/vector/src/main/res/values-tr/strings.xml index 1ca6bfedb0..88928e86c3 100644 --- a/vector/src/main/res/values-tr/strings.xml +++ b/vector/src/main/res/values-tr/strings.xml @@ -2074,7 +2074,7 @@ Bilgileri üçüncü taraflarla paylaşmayız Herhangi bir hesap verisini kaydetmiyoruz burada - Anonim kullanım verilerini paylaşarak sorunları belirlememize ve Element\'i iyileştirmemize yardımcı olun. İnsanların birden fazla cihazı nasıl kullandığını anlamak için, cihazlarınız tarafından paylaşılan rastgele bir tanımlayıcı oluşturacağız. + Anonim kullanım verilerini paylaşarak sorunları belirlememize ve ${app_name}\'i iyileştirmemize yardımcı olun. İnsanların birden fazla cihazı nasıl kullandığını anlamak için, cihazlarınız tarafından paylaşılan rastgele bir tanımlayıcı oluşturacağız. \n \n Tüm şartlarımızı %s okuyabilirsiniz. Öğeyi iyileştirmeye yardımcı olun diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index e38e676db9..4d92411188 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -3137,7 +3137,7 @@ Ми не передаємо даних стороннім особам Ми не записуємо й не аналізуємо жодних даних облікового запису тут - Допомагайте нам визначати проблеми й удосконалювати Element, надсилаючи анонімні дані про використання. Щоб розуміти, як люди використовують кілька пристроїв, ми створимо спільний для ваших пристроїв випадковий ідентифікатор. + Допомагайте нам визначати проблеми й удосконалювати ${app_name}, надсилаючи анонімні дані про використання. Щоб розуміти, як люди використовують кілька пристроїв, ми створимо спільний для ваших пристроїв випадковий ідентифікатор. \n \nМожете прочитати всі наші умови %s. Допоможіть покращити ${app_name} diff --git a/vector/src/main/res/values-vi/strings.xml b/vector/src/main/res/values-vi/strings.xml index 79ae77cc5a..99aa236178 100644 --- a/vector/src/main/res/values-vi/strings.xml +++ b/vector/src/main/res/values-vi/strings.xml @@ -2911,7 +2911,7 @@ Chúng tôi không chia sẻ thông tin với bên thứ ba Chúng tôi không ghi âm hoặc tạo hồ sơ bất kỳ dữ liệu tài khoản nào ở đây - Giúp chúng tôi xác định các vấn đề và cải thiện Element bằng cách chia sẻ dữ liệu sử dụng ẩn danh. Để hiểu cách mọi người sử dụng nhiều thiết bị, chúng tôi sẽ tạo ra một mã định danh ngẫu nhiên, được chia sẻ bởi các thiết bị của bạn. + Giúp chúng tôi xác định các vấn đề và cải thiện ${app_name} bằng cách chia sẻ dữ liệu sử dụng ẩn danh. Để hiểu cách mọi người sử dụng nhiều thiết bị, chúng tôi sẽ tạo ra một mã định danh ngẫu nhiên, được chia sẻ bởi các thiết bị của bạn. \n \nBạn có thể đọc tất cả các thuật ngữ của chúng tôi %s. Giúp cải thiện ${app_name} diff --git a/vector/src/main/res/values-zh-rCN/strings.xml b/vector/src/main/res/values-zh-rCN/strings.xml index 0cc008faac..e333980710 100644 --- a/vector/src/main/res/values-zh-rCN/strings.xml +++ b/vector/src/main/res/values-zh-rCN/strings.xml @@ -2976,7 +2976,7 @@ 你可以随时在设置中关闭它 我们与第三方共享信息 此处 - 通过共享匿名使用数据,帮助我们识别问题并改进 Element。为了理解人们如何使用多台设备,我们将生成一个随机标识符,由您的设备共享。 + 通过共享匿名使用数据,帮助我们识别问题并改进 ${app_name}。为了理解人们如何使用多台设备,我们将生成一个随机标识符,由您的设备共享。 \n \n你可以阅读我们所有的条款 %s。 帮助改进 ${app_name} diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index 12002a52f7..0a0f38ec66 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -2976,7 +2976,7 @@ 我們不會與第三方分享資訊 我們不會記錄或分析任何帳號資料 這裡 - 透過分享匿名使用資料協助我們找出問題並改善 Element。為了了解人們如何使用多裝置,我們將會產生隨機識別字串,在您的裝置間共享。 + 透過分享匿名使用資料協助我們找出問題並改善 ${app_name}。為了了解人們如何使用多裝置,我們將會產生隨機識別字串,在您的裝置間共享。 \n \n您可以閱讀我們的條款 %s。 協助改善 ${app_name} diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 5f2f2dabb2..a397b1d03f 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1387,9 +1387,8 @@ Yes, I want to help! Help improve ${app_name} - - Help us identify issues and improve Element by sharing anonymous usage data. To understand how people use multiple devices, we’ll generate a random identifier, shared by your devices.\n\nYou can read all our terms %s. + Help us identify issues and improve ${app_name} by sharing anonymous usage data. To understand how people use multiple devices, we’ll generate a random identifier, shared by your devices.\n\nYou can read all our terms %s. here We don\'t record or profile any account data We don\'t share information with third parties From fa66f1007581117cb33e6987b1a2cf6ff22c636a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 15:47:15 +0100 Subject: [PATCH 293/302] Create template with the app name --- vector/src/main/res/values-cs/strings.xml | 2 +- vector/src/main/res/values-de/strings.xml | 2 +- vector/src/main/res/values-et/strings.xml | 2 +- vector/src/main/res/values-fa/strings.xml | 2 +- vector/src/main/res/values-fr/strings.xml | 2 +- vector/src/main/res/values-hu/strings.xml | 2 +- vector/src/main/res/values-in/strings.xml | 2 +- vector/src/main/res/values-it/strings.xml | 2 +- vector/src/main/res/values-ja/strings.xml | 2 +- vector/src/main/res/values-nl/strings.xml | 2 +- vector/src/main/res/values-pl/strings.xml | 2 +- vector/src/main/res/values-pt-rBR/strings.xml | 2 +- vector/src/main/res/values-ru/strings.xml | 2 +- vector/src/main/res/values-sk/strings.xml | 2 +- vector/src/main/res/values-sq/strings.xml | 2 +- vector/src/main/res/values-sv/strings.xml | 2 +- vector/src/main/res/values-tr/strings.xml | 2 +- vector/src/main/res/values-uk/strings.xml | 2 +- vector/src/main/res/values-vi/strings.xml | 2 +- vector/src/main/res/values-zh-rCN/strings.xml | 2 +- vector/src/main/res/values-zh-rTW/strings.xml | 2 +- vector/src/main/res/values/strings.xml | 3 +-- 22 files changed, 22 insertions(+), 23 deletions(-) diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index 8284a5de6a..6fb17ebb00 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -3081,7 +3081,7 @@ Systémová nastavení Verze - Získejte pomoc při používání Elementu + Získejte pomoc při používání ${app_name}u Nápověda a podpora Nápověda Právní dokumenty diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 3236332085..195b831141 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2985,7 +2985,7 @@ Bedingungen des Identitätsservers anzeigen Systemeinstellungen Versionen - Erhalte Hilfe bei der Bedienung von Element + Erhalte Hilfe bei der Bedienung von ${app_name} Hilfe und Unterstützung Hilfe Rechtliches diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index bf486045be..a9ac3c3bf5 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -3021,7 +3021,7 @@ Süsteemiseadistused Versioonid - Element\'i kasutamiseks vajalik abiteave + ${app_name}\'i kasutamiseks vajalik abiteave Abiteave ja kasutajatugi Abiteave Juriidiline teave diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index c5e92e18f3..47af4f0a1c 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -3025,7 +3025,7 @@ تنظیمات سامانه نگارش‌ها - کمک در استفاده از المنت + کمک در استفاده از المنت کمک و پشتیانی کمک موارد حقوقی diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index ef55b09cc5..fdc20b2bbd 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -3023,7 +3023,7 @@ Paramètres système Versions - Obtenir de l’aide pour utiliser Element + Obtenir de l’aide pour utiliser ${app_name} Aide et support Aide Mentions légales diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index 574386c0b4..01ddffed6c 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -3019,7 +3019,7 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze Rendszerbeállítások Verziók - Segítség az Element használatában + Segítség az ${app_name} használatában Segítség és támogatás Segítség Ez a szerver nem adott meg szabályzatot. diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index c4c20b3a24..e99c91037f 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -2967,7 +2967,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Pengaturan sistem Versi - Dapatkan bantuan dalam menggunakan Element + Dapatkan bantuan dalam menggunakan ${app_name} Bantuan dan dukungan Bantuan Hukum diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index b5b0c09b62..d0645c1dfd 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -3012,7 +3012,7 @@ Impostazioni di sistema Versioni - Ricevi aiuto nell\'uso di Element + Ricevi aiuto nell\'uso di ${app_name} Aiuto e supporto Aiuto Informazioni legali diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 64bf6859e7..0b6fcfded6 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -2508,7 +2508,7 @@ お宅での対面会話と同じぐらいのプライバシーを提供する、セキュアで独立したコミュニケーション。 セキュアメッセージング 管理権を握るのは、あなたです。 - Elementの使用に関するヘルプ + ${app_name}の使用に関するヘルプ 詳細なログは、イライラシェイクでログを送信する際に、より多くのログを提供することで、開発者にとっての助けになります。有効にした場合でも、メッセージの内容やその他のプライベートな情報は記録されません。 ルームのアップグレードは高度な作業であり、不具合や欠けている機能、セキュリティー上の脆弱性がある場合に推奨されます。 \nアップグレードは通常、ルームがサーバー上で処理される仕方にだけ影響します。 diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index d3cd933e16..7f586c1cb6 100644 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -2126,7 +2126,7 @@ Doe een suggestie Systeem instellingen Versies - Hulp bij het gebruik van Element + Hulp bij het gebruik van ${app_name} Hulp en ondersteuning Hulp Juridisch diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index 26d01b81ca..2925d00a35 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -3061,7 +3061,7 @@ Ty jesteś w kontroli. Przejmij swoje konwersacje. By odkryć istniejące kontakty, musisz najpierw przesłać swoje dane kontaktowe (adresy e-mail i numer telefonu) do serwera tożsamości. Przed wysłaniem Twoje dane zostaną zaszyfrowane w celu zachowania prywatności. - Uzyskaj pomoc w korzystaniu z Element + Uzyskaj pomoc w korzystaniu z ${app_name} Nie masz uprawnień by dołączyć do tego pokoju Typ Niedostępny diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index d3fdd8ee05..ee332d3aa8 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -3021,7 +3021,7 @@ %1$d votos Versões - Conseguir ajuda com uso de Element + Conseguir ajuda com uso de ${app_name} Jurídicos Este servidor não provê nenhuma política. Bibliotecas de terceiros diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index 4ab6e3a75f..d71debde63 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -3160,7 +3160,7 @@ Ваши контакты приватны. Чтобы обнаружить пользователей из ваших контактов, нам необходимо ваше разрешение на отправку контактной информации на ваш сервер обнаружения. Системные настройки Версии - Получите помощь в использовании Element + Получите помощь в использовании ${app_name} Помощь и поддержка Помощь Правовые положения diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml index 89f05c0360..4d253b61e2 100644 --- a/vector/src/main/res/values-sk/strings.xml +++ b/vector/src/main/res/values-sk/strings.xml @@ -2508,7 +2508,7 @@ Nepoznáte svoju prístupovú frázu pre zálohovanie kľúčov, môžete %s. Overte tohto používateľa potvrdením, že sa na jeho obrazovke zobrazujú nasledujúce jedinečné emotikony v rovnakom poradí. Zobrazenie niektorých užitočných informácií na pomoc pri ladení aplikácie - Získajte pomoc s používaním aplikácie Element + Získajte pomoc s používaním aplikácie ${app_name} Všetky miestnosti, v ktorých sa nachádzate, sa zobrazia v časti Domov. Zobraziť všetky miestnosti v časti Domov Riešenie problémov diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index d6c796cfa5..f86b0515c7 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -3006,7 +3006,7 @@ Pyetësor Rregullime sistemi Versione - Merrni ndihmë për përdorimin e Element-it + Merrni ndihmë për përdorimin e ${app_name}-it Ndihmë dhe asistencë Ndihmë Ligjore diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index fcdbbc481a..b5f0313e36 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -3027,7 +3027,7 @@ Systeminställningar Versioner - Få hjälp med att använda Element + Få hjälp med att använda ${app_name} Hjälp och support Hjälp Legalt diff --git a/vector/src/main/res/values-tr/strings.xml b/vector/src/main/res/values-tr/strings.xml index 88928e86c3..e27861035a 100644 --- a/vector/src/main/res/values-tr/strings.xml +++ b/vector/src/main/res/values-tr/strings.xml @@ -2306,7 +2306,7 @@ Kayıt belirteci Sistem ayarları Sürümler - Element\'i kullanma konusunda yardım alın + ${app_name}\'i kullanma konusunda yardım alın Yardım ve Destek Yardım Yasal diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index 4d92411188..f392c6fd9a 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -3124,7 +3124,7 @@ Системні налаштування Версії - Отримати допомогу в використанні Element + Отримати допомогу в використанні ${app_name} Довідка й підтримка Довідка Правові положення diff --git a/vector/src/main/res/values-vi/strings.xml b/vector/src/main/res/values-vi/strings.xml index 99aa236178..24156706ef 100644 --- a/vector/src/main/res/values-vi/strings.xml +++ b/vector/src/main/res/values-vi/strings.xml @@ -2962,7 +2962,7 @@ Token đăng ký Cài đặt hệ thống Phiên bản - Nhận trợ giúp về việc sử dụng Element + Nhận trợ giúp về việc sử dụng ${app_name} Trợ giúp và hỗ trợ Trợ giúp Pháp lý diff --git a/vector/src/main/res/values-zh-rCN/strings.xml b/vector/src/main/res/values-zh-rCN/strings.xml index e333980710..27d9e805e1 100644 --- a/vector/src/main/res/values-zh-rCN/strings.xml +++ b/vector/src/main/res/values-zh-rCN/strings.xml @@ -2963,7 +2963,7 @@ 系统设置 版本 - 获取使用 Element 的帮助 + 获取使用 ${app_name} 的帮助 帮助和支持 帮助 法律 diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index 0a0f38ec66..b40f4fd893 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -2963,7 +2963,7 @@ 系統設定 版本 - 取得關於使用 Element 的協助 + 取得關於使用 ${app_name} 的協助 說明與支援 說明 法律 diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index a397b1d03f..ec0ba07c26 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2296,8 +2296,7 @@ Help Help and support - - Get help with using Element + Get help with using ${app_name} Versions System settings From a9702c63d2594075bb4140cc407155703a3886ba Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 16:00:40 +0100 Subject: [PATCH 294/302] Fix lint issue --- vector/src/main/res/values-ja/strings.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index 0b6fcfded6..a110a7f379 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -1409,8 +1409,6 @@ %1$s、%2$s、%3$sと%4$s %1$s、%2$sと%3$s %1$sの権限レベルを%2$sから%3$sへ変更しました。 - %1$sが - あなたは カスタム カスタム (%1$d) デフォルト @@ -2842,7 +2840,7 @@ 新しいログイン。あなたですか? ${app_name} Android 部屋の管理者によって削除されています、理由:%1$s - ユーザーによって削除されています、理由: + ユーザーによって削除されています、理由:%1$s 削除した理由 この添付ファイルを%1$sに送信しますか? 秘密ストレージは信頼されている端末でのみアクセスしましょう From 17fa463bc8146203b76f3092831fdf2d46f749c2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 16:05:40 +0100 Subject: [PATCH 295/302] Delete unused resource --- .../main/res/layout/dialog_event_content.xml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 vector/src/main/res/layout/dialog_event_content.xml diff --git a/vector/src/main/res/layout/dialog_event_content.xml b/vector/src/main/res/layout/dialog_event_content.xml deleted file mode 100644 index d3c52a61ed..0000000000 --- a/vector/src/main/res/layout/dialog_event_content.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - \ No newline at end of file From 1ce65d7f87a4dbf76b956234868fce4f8a49a30f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 16:08:08 +0100 Subject: [PATCH 296/302] Use plurals for message_reaction_show_more. Fixes #5227 --- .../home/room/detail/timeline/item/AbsBaseMessageItem.kt | 2 +- vector/src/main/res/values/strings.xml | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt index 23f2aceff5..430e0970bb 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt @@ -124,7 +124,7 @@ abstract class AbsBaseMessageItem : BaseEventItem showReactionsTextView.onClick { reactionsSummary.onShowLessClicked() } } else { val moreCount = reactions.count() - MAX_REACTIONS_TO_SHOW - showReactionsTextView.text = holder.view.resources.getString(R.string.message_reaction_show_more, moreCount) + showReactionsTextView.text = holder.view.resources.getQuantityString(R.plurals.message_reaction_show_more, moreCount, moreCount) showReactionsTextView.onClick { reactionsSummary.onShowMoreClicked() } } holder.reactionsContainer.addView(showReactionsTextView) diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index ec0ba07c26..800d1092f8 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -3761,7 +3761,10 @@ Share location Show less - "%1$d more" + + "%1$d more" + "%1$d more" + Notify the whole room Users From 21fa0267f6b0e2a823e0e85bc754bdc755211cf2 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Tue, 22 Feb 2022 17:44:59 +0100 Subject: [PATCH 297/302] Removing TODOs --- .../java/im/vector/app/features/login/LoginWebFragment.kt | 2 -- .../java/im/vector/app/features/login2/LoginWebFragment2.kt | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt index f1558518f7..bb73ed79b2 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt @@ -51,8 +51,6 @@ class LoginWebFragment @Inject constructor( private val assetReader: AssetReader ) : AbstractLoginFragment() { - // TODO I noticed in the Git history this variable was a local variable inside notifyViewModel method - // TODO was there any reason ? To be able to create this ViewModel we must be sure we will have a valid session private val softLogoutViewModel: SoftLogoutViewModel by activityViewModel() override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginWebBinding { diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt index 4e28d8e56c..4427f08309 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt @@ -56,8 +56,6 @@ class LoginWebFragment2 @Inject constructor( return FragmentLoginWebBinding.inflate(inflater, container, false) } - // TODO I noticed in the Git history this variable was a local variable inside notifyViewModel method - // TODO was there any reason ? To be able to create this ViewModel we must be sure we will have a valid session private val softLogoutViewModel: SoftLogoutViewModel by activityViewModel() private var isWebViewLoaded = false @@ -84,7 +82,7 @@ class LoginWebFragment2 @Inject constructor( private fun setupTitle(state: LoginViewState2) { toolbar?.title = when (state.signMode) { SignMode2.SignIn -> getString(R.string.login_signin) - else -> getString(R.string.login_signup) + else -> getString(R.string.login_signup) } } From ed80fe517d38f72989613d64b4269fd814359485 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 21:06:41 +0100 Subject: [PATCH 298/302] Revert recent change to fix a crash `readReceiptsSummaryEntity.realm` is null --- .../mapper/ReadReceiptsSummaryMapper.kt | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/ReadReceiptsSummaryMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/ReadReceiptsSummaryMapper.kt index 5aaa49b9e8..f3770e4afe 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/ReadReceiptsSummaryMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/ReadReceiptsSummaryMapper.kt @@ -23,18 +23,23 @@ import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity import org.matrix.android.sdk.internal.database.query.where import javax.inject.Inject -internal class ReadReceiptsSummaryMapper @Inject constructor(private val realmSessionProvider: RealmSessionProvider) { +internal class ReadReceiptsSummaryMapper @Inject constructor( + private val realmSessionProvider: RealmSessionProvider +) { fun map(readReceiptsSummaryEntity: ReadReceiptsSummaryEntity?): List { if (readReceiptsSummaryEntity == null) { return emptyList() } val readReceipts = readReceiptsSummaryEntity.readReceipts - return readReceipts - .mapNotNull { - val roomMember = RoomMemberSummaryEntity.where(readReceiptsSummaryEntity.realm, roomId = it.roomId, userId = it.userId).findFirst() - ?: return@mapNotNull null - ReadReceipt(roomMember.asDomain(), it.originServerTs.toLong()) - } + + return realmSessionProvider.withRealm { realm -> + readReceipts + .mapNotNull { + val roomMember = RoomMemberSummaryEntity.where(realm, roomId = it.roomId, userId = it.userId).findFirst() + ?: return@mapNotNull null + ReadReceipt(roomMember.asDomain(), it.originServerTs.toLong()) + } + } } } From 6fd14c9ebc85d07fd8d1b9dd558027dce4fefbbf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 21:21:24 +0100 Subject: [PATCH 299/302] Typo in the filename --- changelog.d/{5198.buxfix => 5198.bugfix} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog.d/{5198.buxfix => 5198.bugfix} (100%) diff --git a/changelog.d/5198.buxfix b/changelog.d/5198.bugfix similarity index 100% rename from changelog.d/5198.buxfix rename to changelog.d/5198.bugfix From b746321bad42eab53eb2126cddddc3d0f3938912 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 21:21:40 +0100 Subject: [PATCH 300/302] Towncrier --- CHANGES.md | 44 ++++++++++++++++++++++++++++++++++++++++ changelog.d/2782.misc | 1 - changelog.d/3771.feature | 1 - changelog.d/4640.bugfix | 1 - changelog.d/4643.misc | 1 - changelog.d/5104.misc | 1 - changelog.d/5123.feature | 1 - changelog.d/5136.misc | 1 - changelog.d/5178.bugfix | 1 - changelog.d/5183.sdk | 1 - changelog.d/5185.sdk | 1 - changelog.d/5195.bugfix | 1 - changelog.d/5198.bugfix | 1 - changelog.d/5201.bugfix | 1 - changelog.d/5204.feature | 1 - changelog.d/5207.sdk | 1 - changelog.d/5209.misc | 1 - changelog.d/5210.misc | 1 - changelog.d/5218.bugfix | 1 - changelog.d/5225.misc | 1 - changelog.d/5234.bugfix | 1 - changelog.d/5243.bugfix | 1 - changelog.d/5254.misc | 1 - changelog.d/5256.misc | 1 - changelog.d/5276.misc | 1 - changelog.d/5290.feature | 1 - changelog.d/5294.misc | 1 - changelog.d/5295.bugfix | 1 - changelog.d/5297.misc | 1 - 29 files changed, 44 insertions(+), 28 deletions(-) delete mode 100644 changelog.d/2782.misc delete mode 100644 changelog.d/3771.feature delete mode 100644 changelog.d/4640.bugfix delete mode 100644 changelog.d/4643.misc delete mode 100644 changelog.d/5104.misc delete mode 100644 changelog.d/5123.feature delete mode 100644 changelog.d/5136.misc delete mode 100644 changelog.d/5178.bugfix delete mode 100644 changelog.d/5183.sdk delete mode 100644 changelog.d/5185.sdk delete mode 100644 changelog.d/5195.bugfix delete mode 100644 changelog.d/5198.bugfix delete mode 100644 changelog.d/5201.bugfix delete mode 100644 changelog.d/5204.feature delete mode 100644 changelog.d/5207.sdk delete mode 100644 changelog.d/5209.misc delete mode 100644 changelog.d/5210.misc delete mode 100644 changelog.d/5218.bugfix delete mode 100644 changelog.d/5225.misc delete mode 100644 changelog.d/5234.bugfix delete mode 100644 changelog.d/5243.bugfix delete mode 100644 changelog.d/5254.misc delete mode 100644 changelog.d/5256.misc delete mode 100644 changelog.d/5276.misc delete mode 100644 changelog.d/5290.feature delete mode 100644 changelog.d/5294.misc delete mode 100644 changelog.d/5295.bugfix delete mode 100644 changelog.d/5297.misc diff --git a/CHANGES.md b/CHANGES.md index 3e0c5ff4ae..5ea3859177 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,47 @@ +Changes in Element v1.4.2 (2022-02-22) +====================================== + +Features ✨ +---------- + - Open the room when user accepts an invite from the room list ([#3771](https://github.com/vector-im/element-android/issues/3771)) + - Add completion for @room to notify everyone in a room ([#5123](https://github.com/vector-im/element-android/issues/5123)) + - Improve UI of reactions in timeline, including quick add reaction. ([#5204](https://github.com/vector-im/element-android/issues/5204)) + - Support creating disclosed polls ([#5290](https://github.com/vector-im/element-android/issues/5290)) + +Bugfixes 🐛 +---------- + - Right align the notifications badge in the rooms list (and DMs) so that it's always in a consistent place on the screen. ([#4640](https://github.com/vector-im/element-android/issues/4640)) + - Remove redundant highlight on add poll option button ([#5178](https://github.com/vector-im/element-android/issues/5178)) + - Reliably display crash report prompt ([#5195](https://github.com/vector-im/element-android/issues/5195)) + - Fix for rooms with virtual rooms not showing call status events in the timeline. ([#5198](https://github.com/vector-im/element-android/issues/5198)) + - Fix for call transfer with consult failing to make outgoing consultation call. ([#5201](https://github.com/vector-im/element-android/issues/5201)) + - Fix crash during account registration when redirecting to Web View ([#5218](https://github.com/vector-im/element-android/issues/5218)) + - Analytics: Fixes missing use case identity values from within the onboarding flow ([#5234](https://github.com/vector-im/element-android/issues/5234)) + - Increments database schema to take advantage of homeserver capabilities entity migration (fixes crash in pre-release builds) ([#5243](https://github.com/vector-im/element-android/issues/5243)) + - Fixing crash when adding room by QR code after accepting the camera permission for the first time ([#5295](https://github.com/vector-im/element-android/issues/5295)) + +SDK API changes ⚠️ +------------------ + - `join` and `leave` methods moved from MembershipService to RoomService and SpaceService to split logic for rooms and spaces ([#5183](https://github.com/vector-im/element-android/issues/5183)) + - Deprecates Matrix.initialize and Matrix.getInstance in favour of the client providing its own singleton instance via Matrix.createInstance ([#5185](https://github.com/vector-im/element-android/issues/5185)) + - Adds support for MSC3283, additional homeserver capabilities ([#5207](https://github.com/vector-im/element-android/issues/5207)) + +Other changes +------------- + - Collapse successive ACLs events in room timeline ([#2782](https://github.com/vector-im/element-android/issues/2782)) + - Home screen: Replacing search icon by filter icon in the top right menu ([#4643](https://github.com/vector-im/element-android/issues/4643)) + - Make Space creation screens more consistent ([#5104](https://github.com/vector-im/element-android/issues/5104)) + - Defensive coding to ensure encryption when room was once e2e ([#5136](https://github.com/vector-im/element-android/issues/5136)) + - Reduce verbosity of debug logging, ([#5209](https://github.com/vector-im/element-android/issues/5209)) + - Standardise emulator versions of GHA integration tests. ([#5210](https://github.com/vector-im/element-android/issues/5210)) + - Replacing color "vctr_unread_room_badge" by "vctr_content_secondary" ([#5225](https://github.com/vector-im/element-android/issues/5225)) + - Change preferred jitsi domain from `jitsi.riot.im` to `meet.element.io` ([#5254](https://github.com/vector-im/element-android/issues/5254)) + - Analytics screen events are now tracked on screen enter instead of screen leave ([#5256](https://github.com/vector-im/element-android/issues/5256)) + - Improves bitmap memory usage by caching the shortcut images ([#5276](https://github.com/vector-im/element-android/issues/5276)) + - Changes unread marker in room list from green to grey ([#5294](https://github.com/vector-im/element-android/issues/5294)) + - Improve some internal realm usages. ([#5297](https://github.com/vector-im/element-android/issues/5297)) + + Changes in Element v1.4.0 (2022-02-09) ====================================== diff --git a/changelog.d/2782.misc b/changelog.d/2782.misc deleted file mode 100644 index dc20050369..0000000000 --- a/changelog.d/2782.misc +++ /dev/null @@ -1 +0,0 @@ -Collapse successive ACLs events in room timeline diff --git a/changelog.d/3771.feature b/changelog.d/3771.feature deleted file mode 100644 index c480bb649d..0000000000 --- a/changelog.d/3771.feature +++ /dev/null @@ -1 +0,0 @@ -Open the room when user accepts an invite from the room list \ No newline at end of file diff --git a/changelog.d/4640.bugfix b/changelog.d/4640.bugfix deleted file mode 100644 index f5fa5a5bde..0000000000 --- a/changelog.d/4640.bugfix +++ /dev/null @@ -1 +0,0 @@ -Right align the notifications badge in the rooms list (and DMs) so that it's always in a consistent place on the screen. \ No newline at end of file diff --git a/changelog.d/4643.misc b/changelog.d/4643.misc deleted file mode 100644 index 3d86baa1a2..0000000000 --- a/changelog.d/4643.misc +++ /dev/null @@ -1 +0,0 @@ -Home screen: Replacing search icon by filter icon in the top right menu diff --git a/changelog.d/5104.misc b/changelog.d/5104.misc deleted file mode 100644 index 673614955b..0000000000 --- a/changelog.d/5104.misc +++ /dev/null @@ -1 +0,0 @@ -Make Space creation screens more consistent diff --git a/changelog.d/5123.feature b/changelog.d/5123.feature deleted file mode 100644 index cb1a7adf08..0000000000 --- a/changelog.d/5123.feature +++ /dev/null @@ -1 +0,0 @@ -Add completion for @room to notify everyone in a room diff --git a/changelog.d/5136.misc b/changelog.d/5136.misc deleted file mode 100644 index 43404acc31..0000000000 --- a/changelog.d/5136.misc +++ /dev/null @@ -1 +0,0 @@ -Defensive coding to ensure encryption when room was once e2e \ No newline at end of file diff --git a/changelog.d/5178.bugfix b/changelog.d/5178.bugfix deleted file mode 100644 index 73021a0485..0000000000 --- a/changelog.d/5178.bugfix +++ /dev/null @@ -1 +0,0 @@ -Remove redundant highlight on add poll option button \ No newline at end of file diff --git a/changelog.d/5183.sdk b/changelog.d/5183.sdk deleted file mode 100644 index 66d2c3793d..0000000000 --- a/changelog.d/5183.sdk +++ /dev/null @@ -1 +0,0 @@ -`join` and `leave` methods moved from MembershipService to RoomService and SpaceService to split logic for rooms and spaces \ No newline at end of file diff --git a/changelog.d/5185.sdk b/changelog.d/5185.sdk deleted file mode 100644 index 9eda2e7c9b..0000000000 --- a/changelog.d/5185.sdk +++ /dev/null @@ -1 +0,0 @@ -Deprecates Matrix.initialize and Matrix.getInstance in favour of the client providing its own singleton instance via Matrix.createInstance \ No newline at end of file diff --git a/changelog.d/5195.bugfix b/changelog.d/5195.bugfix deleted file mode 100644 index 50d47e089e..0000000000 --- a/changelog.d/5195.bugfix +++ /dev/null @@ -1 +0,0 @@ -Reliably display crash report prompt diff --git a/changelog.d/5198.bugfix b/changelog.d/5198.bugfix deleted file mode 100644 index 3fce6906d5..0000000000 --- a/changelog.d/5198.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix for rooms with virtual rooms not showing call status events in the timeline. \ No newline at end of file diff --git a/changelog.d/5201.bugfix b/changelog.d/5201.bugfix deleted file mode 100644 index f77ddcce84..0000000000 --- a/changelog.d/5201.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix for call transfer with consult failing to make outgoing consultation call. \ No newline at end of file diff --git a/changelog.d/5204.feature b/changelog.d/5204.feature deleted file mode 100644 index a107342de7..0000000000 --- a/changelog.d/5204.feature +++ /dev/null @@ -1 +0,0 @@ -Improve UI of reactions in timeline, including quick add reaction. \ No newline at end of file diff --git a/changelog.d/5207.sdk b/changelog.d/5207.sdk deleted file mode 100644 index 3ba3e06fb7..0000000000 --- a/changelog.d/5207.sdk +++ /dev/null @@ -1 +0,0 @@ -Adds support for MSC3283, additional homeserver capabilities \ No newline at end of file diff --git a/changelog.d/5209.misc b/changelog.d/5209.misc deleted file mode 100644 index a238da9d22..0000000000 --- a/changelog.d/5209.misc +++ /dev/null @@ -1 +0,0 @@ -Reduce verbosity of debug logging, diff --git a/changelog.d/5210.misc b/changelog.d/5210.misc deleted file mode 100644 index 0b68e8b23a..0000000000 --- a/changelog.d/5210.misc +++ /dev/null @@ -1 +0,0 @@ -Standardise emulator versions of GHA integration tests. diff --git a/changelog.d/5218.bugfix b/changelog.d/5218.bugfix deleted file mode 100644 index 4f92338a4f..0000000000 --- a/changelog.d/5218.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix crash during account registration when redirecting to Web View diff --git a/changelog.d/5225.misc b/changelog.d/5225.misc deleted file mode 100644 index 799a3a4d81..0000000000 --- a/changelog.d/5225.misc +++ /dev/null @@ -1 +0,0 @@ -Replacing color "vctr_unread_room_badge" by "vctr_content_secondary" diff --git a/changelog.d/5234.bugfix b/changelog.d/5234.bugfix deleted file mode 100644 index 2b5d4dee37..0000000000 --- a/changelog.d/5234.bugfix +++ /dev/null @@ -1 +0,0 @@ -Analytics: Fixes missing use case identity values from within the onboarding flow \ No newline at end of file diff --git a/changelog.d/5243.bugfix b/changelog.d/5243.bugfix deleted file mode 100644 index eb323c1ca4..0000000000 --- a/changelog.d/5243.bugfix +++ /dev/null @@ -1 +0,0 @@ -Increments database schema to take advantage of homeserver capabilities entity migration (fixes crash in pre-release builds) \ No newline at end of file diff --git a/changelog.d/5254.misc b/changelog.d/5254.misc deleted file mode 100644 index 2ae642e9b7..0000000000 --- a/changelog.d/5254.misc +++ /dev/null @@ -1 +0,0 @@ -Change preferred jitsi domain from `jitsi.riot.im` to `meet.element.io` \ No newline at end of file diff --git a/changelog.d/5256.misc b/changelog.d/5256.misc deleted file mode 100644 index e20f52c7aa..0000000000 --- a/changelog.d/5256.misc +++ /dev/null @@ -1 +0,0 @@ -Analytics screen events are now tracked on screen enter instead of screen leave \ No newline at end of file diff --git a/changelog.d/5276.misc b/changelog.d/5276.misc deleted file mode 100644 index 437bd28eb6..0000000000 --- a/changelog.d/5276.misc +++ /dev/null @@ -1 +0,0 @@ -Improves bitmap memory usage by caching the shortcut images \ No newline at end of file diff --git a/changelog.d/5290.feature b/changelog.d/5290.feature deleted file mode 100644 index 6f7e9aea7f..0000000000 --- a/changelog.d/5290.feature +++ /dev/null @@ -1 +0,0 @@ -Support creating disclosed polls \ No newline at end of file diff --git a/changelog.d/5294.misc b/changelog.d/5294.misc deleted file mode 100644 index 857110efab..0000000000 --- a/changelog.d/5294.misc +++ /dev/null @@ -1 +0,0 @@ -Changes unread marker in room list from green to grey \ No newline at end of file diff --git a/changelog.d/5295.bugfix b/changelog.d/5295.bugfix deleted file mode 100644 index c5e55cde5d..0000000000 --- a/changelog.d/5295.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixing crash when adding room by QR code after accepting the camera permission for the first time \ No newline at end of file diff --git a/changelog.d/5297.misc b/changelog.d/5297.misc deleted file mode 100644 index f45490ce3d..0000000000 --- a/changelog.d/5297.misc +++ /dev/null @@ -1 +0,0 @@ -Improve some internal realm usages. \ No newline at end of file From 70bb1004c146cceadb384c63747cb7fe75991c8b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 21:27:06 +0100 Subject: [PATCH 301/302] Tidy up the changelog --- CHANGES.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5ea3859177..255792f800 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,14 +10,12 @@ Features ✨ Bugfixes 🐛 ---------- - - Right align the notifications badge in the rooms list (and DMs) so that it's always in a consistent place on the screen. ([#4640](https://github.com/vector-im/element-android/issues/4640)) - Remove redundant highlight on add poll option button ([#5178](https://github.com/vector-im/element-android/issues/5178)) - Reliably display crash report prompt ([#5195](https://github.com/vector-im/element-android/issues/5195)) - Fix for rooms with virtual rooms not showing call status events in the timeline. ([#5198](https://github.com/vector-im/element-android/issues/5198)) - Fix for call transfer with consult failing to make outgoing consultation call. ([#5201](https://github.com/vector-im/element-android/issues/5201)) - Fix crash during account registration when redirecting to Web View ([#5218](https://github.com/vector-im/element-android/issues/5218)) - Analytics: Fixes missing use case identity values from within the onboarding flow ([#5234](https://github.com/vector-im/element-android/issues/5234)) - - Increments database schema to take advantage of homeserver capabilities entity migration (fixes crash in pre-release builds) ([#5243](https://github.com/vector-im/element-android/issues/5243)) - Fixing crash when adding room by QR code after accepting the camera permission for the first time ([#5295](https://github.com/vector-im/element-android/issues/5295)) SDK API changes ⚠️ @@ -28,6 +26,7 @@ SDK API changes ⚠️ Other changes ------------- + - Right align the notifications badge in the rooms list (and DMs) so that it's always in a consistent place on the screen. ([#4640](https://github.com/vector-im/element-android/issues/4640)) - Collapse successive ACLs events in room timeline ([#2782](https://github.com/vector-im/element-android/issues/2782)) - Home screen: Replacing search icon by filter icon in the top right menu ([#4643](https://github.com/vector-im/element-android/issues/4643)) - Make Space creation screens more consistent ([#5104](https://github.com/vector-im/element-android/issues/5104)) @@ -41,6 +40,10 @@ Other changes - Changes unread marker in room list from green to grey ([#5294](https://github.com/vector-im/element-android/issues/5294)) - Improve some internal realm usages. ([#5297](https://github.com/vector-im/element-android/issues/5297)) +Translations 🗣 +-------------- + - Improved Japanese translations (special thanks to Suguru Hirahara!) + Changes in Element v1.4.0 (2022-02-09) ====================================== From bb0955f809a3928fbda2d7a814d84472b2aaedcf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 22 Feb 2022 21:29:16 +0100 Subject: [PATCH 302/302] change for fastlane --- fastlane/metadata/android/en-US/changelogs/40104000.txt | 2 +- fastlane/metadata/android/en-US/changelogs/40104020.txt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/40104020.txt diff --git a/fastlane/metadata/android/en-US/changelogs/40104000.txt b/fastlane/metadata/android/en-US/changelogs/40104000.txt index e102edbaad..4492b78882 100644 --- a/fastlane/metadata/android/en-US/changelogs/40104000.txt +++ b/fastlane/metadata/android/en-US/changelogs/40104000.txt @@ -1,2 +1,2 @@ -Main changes in this version: Initial implementation of thread messages. Message bubbles. +Main changes in this version: Initial implementation of thread messages. Message bubbles. Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.4.0 \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/40104020.txt b/fastlane/metadata/android/en-US/changelogs/40104020.txt new file mode 100644 index 0000000000..82d3197db3 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40104020.txt @@ -0,0 +1,2 @@ +Main changes in this version: add support to @room and undisclosed polls among many other little changes. +Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.4.2 \ No newline at end of file