mirror of
https://github.com/element-hq/element-web
synced 2024-11-28 12:28:50 +03:00
Merge branches 'develop' and 't3chguy/missing_dep' of https://github.com/matrix-org/matrix-react-sdk into t3chguy/missing_dep
This commit is contained in:
commit
3dd5986656
147 changed files with 2992 additions and 4991 deletions
|
@ -128,7 +128,6 @@
|
|||
@import "./views/messages/_MEmoteBody.scss";
|
||||
@import "./views/messages/_MFileBody.scss";
|
||||
@import "./views/messages/_MImageBody.scss";
|
||||
@import "./views/messages/_MKeyVerificationRequest.scss";
|
||||
@import "./views/messages/_MNoticeBody.scss";
|
||||
@import "./views/messages/_MStickerBody.scss";
|
||||
@import "./views/messages/_MTextBody.scss";
|
||||
|
@ -143,7 +142,10 @@
|
|||
@import "./views/messages/_TextualEvent.scss";
|
||||
@import "./views/messages/_UnknownBody.scss";
|
||||
@import "./views/messages/_ViewSourceEvent.scss";
|
||||
@import "./views/messages/_common_CryptoEvent.scss";
|
||||
@import "./views/right_panel/_EncryptionInfo.scss";
|
||||
@import "./views/right_panel/_UserInfo.scss";
|
||||
@import "./views/right_panel/_VerificationPanel.scss";
|
||||
@import "./views/room_settings/_AliasSettings.scss";
|
||||
@import "./views/room_settings/_ColorSettings.scss";
|
||||
@import "./views/rooms/_AppsDrawer.scss";
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -18,7 +19,7 @@ limitations under the License.
|
|||
overflow-x: hidden;
|
||||
flex: 0 0 auto;
|
||||
position: relative;
|
||||
min-width: 250px;
|
||||
min-width: 264px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
|
|
@ -98,5 +98,9 @@ limitations under the License.
|
|||
margin: 4px 0 11px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.mx_Toast_deviceID {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,34 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_CreateSecretStorageDialog {
|
||||
// Why you ask? Because CompleteSecurityBody is 600px so this is the width
|
||||
// we end up when in there, but when in our own dialog we set our own width
|
||||
// so need to fix it to something sensible as otherwise we'd end up either
|
||||
// really wide or really narrow depending on the phase. I bet you wish you
|
||||
// never asked.
|
||||
width: 560px;
|
||||
|
||||
.mx_SettingsFlag {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.mx_SettingsFlag_label {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.mx_ToggleSwitch {
|
||||
flex: 0 0 auto;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
details .mx_AccessibleButton {
|
||||
margin: 1em 0; // emulate paragraph spacing because we can't put this button in a paragraph due to HTML rules
|
||||
}
|
||||
}
|
||||
|
||||
.mx_CreateSecretStorageDialog .mx_Dialog_title {
|
||||
/* TODO: Consider setting this for all dialog titles. */
|
||||
margin-bottom: 1em;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -14,60 +14,62 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_KeyVerification {
|
||||
.mx_cryptoEvent {
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 24px minmax(0, 1fr) min-content;
|
||||
|
||||
&.mx_KeyVerification_icon::after {
|
||||
&.mx_cryptoEvent_icon::after {
|
||||
grid-column: 1;
|
||||
grid-row: 1 / 3;
|
||||
width: 12px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
content: "";
|
||||
mask-image: url("$(res)/img/e2e/normal.svg");
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 100%;
|
||||
background-image: url("$(res)/img/e2e/normal.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100%;
|
||||
margin-top: 4px;
|
||||
background-color: $primary-fg-color;
|
||||
}
|
||||
|
||||
&.mx_KeyVerification_icon_verified::after {
|
||||
mask-image: url("$(res)/img/e2e/verified.svg");
|
||||
background-color: $accent-color;
|
||||
&.mx_cryptoEvent_icon_verified::after {
|
||||
background-image: url("$(res)/img/e2e/verified.svg");
|
||||
}
|
||||
|
||||
.mx_KeyVerification_title, .mx_KeyVerification_subtitle, .mx_KeyVerification_state {
|
||||
&.mx_cryptoEvent_icon_warning::after {
|
||||
background-image: url("$(res)/img/e2e/warning.svg");
|
||||
}
|
||||
|
||||
.mx_cryptoEvent_title, .mx_cryptoEvent_subtitle, .mx_cryptoEvent_state {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.mx_KeyVerification_title {
|
||||
.mx_cryptoEvent_title {
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.mx_KeyVerification_subtitle {
|
||||
.mx_cryptoEvent_subtitle {
|
||||
grid-column: 2;
|
||||
grid-row: 2;
|
||||
}
|
||||
|
||||
.mx_KeyVerification_state, .mx_KeyVerification_subtitle {
|
||||
.mx_cryptoEvent_state, .mx_cryptoEvent_subtitle {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.mx_KeyVerification_state, .mx_KeyVerification_buttons {
|
||||
.mx_cryptoEvent_state, .mx_cryptoEvent_buttons {
|
||||
grid-column: 3;
|
||||
grid-row: 1 / 3;
|
||||
}
|
||||
|
||||
.mx_KeyVerification_buttons {
|
||||
.mx_cryptoEvent_buttons {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.mx_KeyVerification_state {
|
||||
.mx_cryptoEvent_state {
|
||||
width: 130px;
|
||||
padding: 10px 20px;
|
||||
margin: auto 0;
|
26
res/css/views/right_panel/_EncryptionInfo.scss
Normal file
26
res/css/views/right_panel/_EncryptionInfo.scss
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_UserInfo {
|
||||
.mx_EncryptionInfo_spinner {
|
||||
.mx_Spinner {
|
||||
margin-top: 25px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
}
|
|
@ -49,12 +49,17 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_UserInfo_container {
|
||||
padding: 0 16px 16px 16px;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
.mx_UserInfo_separator {
|
||||
border-bottom: 1px solid lightgray;
|
||||
}
|
||||
|
||||
.mx_UserInfo_memberDetailsContainer {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.mx_RoomTile_nameContainer {
|
||||
|
@ -76,6 +81,7 @@ limitations under the License.
|
|||
.mx_UserInfo_avatar > div {
|
||||
max-width: 30vh;
|
||||
margin: 0 auto;
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.mx_UserInfo_avatar > div > div {
|
||||
|
@ -105,6 +111,7 @@ limitations under the License.
|
|||
// override the calculated sizes so that the letter isn't HUGE
|
||||
font-size: 56px !important;
|
||||
width: 100% !important;
|
||||
transition: font-size 0.5s;
|
||||
}
|
||||
|
||||
.mx_UserInfo_avatar .mx_BaseAvatar.mx_BaseAvatar_image {
|
||||
|
@ -204,10 +211,9 @@ limitations under the License.
|
|||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.mx_UserInfo_scrollContainer .mx_UserInfo_container {
|
||||
.mx_UserInfo_container:not(.mx_UserInfo_separator) {
|
||||
padding-top: 16px;
|
||||
padding-bottom: 0;
|
||||
border-bottom: none;
|
||||
|
||||
> :not(h3) {
|
||||
margin-left: 8px;
|
||||
|
@ -250,17 +256,25 @@ limitations under the License.
|
|||
.mx_UserInfo_expand {
|
||||
display: flex;
|
||||
margin-top: 11px;
|
||||
color: $accent-color;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_UserInfo_verify {
|
||||
.mx_UserInfo_wideButton {
|
||||
display: block;
|
||||
background-color: $accent-color;
|
||||
color: $accent-fg-color;
|
||||
border-radius: 4px;
|
||||
padding: 7px 1.5em;
|
||||
text-align: center;
|
||||
margin: 16px 0;
|
||||
}
|
||||
button.mx_UserInfo_wideButton {
|
||||
width: 100%; // FIXME get rid of this once we get rid of DialogButtons here
|
||||
}
|
||||
}
|
||||
|
||||
.mx_UserInfo.mx_UserInfo_smallAvatar {
|
||||
.mx_UserInfo_avatar > div {
|
||||
max-width: 72px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.mx_UserInfo_avatar .mx_BaseAvatar_initial {
|
||||
font-size: 40px !important; // override the other override because here the avatar is smaller
|
||||
}
|
||||
}
|
||||
|
|
39
res/css/views/right_panel/_VerificationPanel.scss
Normal file
39
res/css/views/right_panel/_VerificationPanel.scss
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_UserInfo {
|
||||
.mx_VerificationPanel_verified_section .mx_E2EIcon {
|
||||
// Override general user info margin
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
|
||||
.mx_VerificationPanel_qrCode {
|
||||
padding: 4px 4px 0 4px;
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
width: max-content;
|
||||
max-width: 100%;
|
||||
// Override general user info margin
|
||||
margin: 0 auto !important;
|
||||
|
||||
canvas {
|
||||
// override height and width which are set on the element directly
|
||||
height: auto !important;
|
||||
width: 100% !important;
|
||||
max-width: 240px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -19,6 +20,15 @@ limitations under the License.
|
|||
align-items: center;
|
||||
color: $primary-fg-color;
|
||||
cursor: pointer;
|
||||
|
||||
.mx_E2EIcon {
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
bottom: 2px;
|
||||
right: 7px;
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_EntityTile:hover {
|
||||
|
@ -30,7 +40,7 @@ limitations under the License.
|
|||
content: "";
|
||||
position: absolute;
|
||||
top: calc(50% - 8px); // center
|
||||
right: 10px;
|
||||
right: -8px;
|
||||
mask: url('$(res)/img/member_chevron.png');
|
||||
mask-repeat: no-repeat;
|
||||
width: 16px;
|
||||
|
@ -64,14 +74,6 @@ limitations under the License.
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.mx_EntityTile_power {
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 17px;
|
||||
top: 0px;
|
||||
right: 6px;
|
||||
}
|
||||
|
||||
.mx_EntityTile_name,
|
||||
.mx_GroupRoomTile_name {
|
||||
flex: 1 1 0;
|
||||
|
@ -83,6 +85,7 @@ limitations under the License.
|
|||
|
||||
.mx_EntityTile_details {
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mx_EntityTile_ellipsis .mx_EntityTile_name {
|
||||
|
@ -112,10 +115,6 @@ limitations under the License.
|
|||
opacity: 0.25;
|
||||
}
|
||||
|
||||
.mx_EntityTile:not(.mx_EntityTile_noHover):hover .mx_EntityTile_name {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.mx_EntityTile_subtext {
|
||||
font-size: 11px;
|
||||
opacity: 0.5;
|
||||
|
@ -123,3 +122,17 @@ limitations under the License.
|
|||
white-space: nowrap;
|
||||
text-overflow: clip;
|
||||
}
|
||||
|
||||
.mx_EntityTile_power {
|
||||
padding-inline-start: 6px;
|
||||
font-size: 10px;
|
||||
color: $notice-secondary-color;
|
||||
max-width: 6em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mx_EntityTile:hover .mx_EntityTile_power {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ limitations under the License.
|
|||
position: relative;
|
||||
display: block !important;
|
||||
// Align the padlock with unencrypted room names
|
||||
margin-left: 6px;
|
||||
margin: 0 4px;
|
||||
|
||||
&::before {
|
||||
background-color: $roomtile-name-color;
|
||||
|
@ -34,5 +34,7 @@ limitations under the License.
|
|||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,8 +76,8 @@ limitations under the License.
|
|||
left: 60px;
|
||||
margin-right: 0; // Counteract the E2EIcon class
|
||||
margin-left: 3px; // Counteract the E2EIcon class
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.mx_MessageComposer_noperm_error {
|
||||
|
|
|
@ -21,10 +21,10 @@ limitations under the License.
|
|||
.mx_E2EIcon {
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
right: -2px;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
bottom: -2px;
|
||||
right: -6px;
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -101,19 +101,19 @@ limitations under the License.
|
|||
// Note we match .mx_E2EIcon to make sure this matches more tightly than just
|
||||
// .mx_E2EIcon on its own
|
||||
.mx_RoomTile_e2eIcon.mx_E2EIcon {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
right: -2px;
|
||||
bottom: -2px;
|
||||
right: -5px;
|
||||
z-index: 1;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.mx_RoomTile_name {
|
||||
font-size: 14px;
|
||||
padding: 0 6px;
|
||||
padding: 0 4px;
|
||||
color: $roomtile-name-color;
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
|
@ -214,8 +214,3 @@ limitations under the License.
|
|||
.mx_GroupInviteTile .mx_RoomTile_name {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mx_InviteOnlyIcon + .mx_RoomTile_nameContainer .mx_RoomTile_name {
|
||||
// Scoot the padding in a bit from 6px to make it look better
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright 2019 New Vector Ltd.
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -28,21 +29,35 @@ limitations under the License.
|
|||
|
||||
.mx_VerificationShowSas_emojiSas {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.mx_VerificationShowSas_emojiSas_block {
|
||||
display: inline-block;
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 16px;
|
||||
position: relative;
|
||||
width: 52px;
|
||||
}
|
||||
|
||||
.mx_Dialog .mx_VerificationShowSas_emojiSas_block,
|
||||
.mx_AuthPage_modal .mx_VerificationShowSas_emojiSas_block {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.mx_VerificationShowSas_emojiSas_emoji {
|
||||
font-size: 48px;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.mx_VerificationShowSas_emojiSas_label {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.mx_VerificationShowSas_emojiSas_break {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="16px" height="17px" viewBox="-1 -1 15 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: sketchtool 3.4.4 (395) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>icons_owner</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="02_19-Room-contextual-menu-hover" sketch:type="MSArtboardGroup" transform="translate(-1000.000000, -128.000000)">
|
||||
<g id="people_open" sketch:type="MSLayerGroup" transform="translate(966.000000, 59.000000)">
|
||||
<g id="icons_owner" transform="translate(35.000000, 70.000000)" sketch:type="MSShapeGroup">
|
||||
<path d="M0.441894529,1.80537109 C2.59277353,3.03442388 4.25305977,2.17675781 5.9832796,0.805371094 C8.01666135,2.17675787 9.50756797,3.12670903 11.6293941,1.80537109 C11.6293941,7.01538067 11.9379879,12.2253912 5.9832796,12.2253906 C0.0285712975,12.2253901 0.441894531,7.01538067 0.441894529,1.80537109 Z" id="Path-2-Copy" stroke="#FFFFFF" fill="#F6A623"></path>
|
||||
<polygon id="Star-1" fill="#FFFFFF" points="6 8.8 3.88397309 9.91246118 4.28809827 7.55623059 2.57619654 5.88753882 4.94198655 5.54376941 6 3.4 7.05801345 5.54376941 9.42380346 5.88753882 7.71190173 7.55623059 8.11602691 9.91246118 "></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.6 KiB |
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="16px" height="17px" viewBox="-1 -1 15 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: sketchtool 3.4.4 (395) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>icons_admin</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="02_19-Room-contextual-menu-hover" sketch:type="MSArtboardGroup" transform="translate(-1000.000000, -172.000000)" stroke="#FFFFFF" fill="#C2C5AF">
|
||||
<g id="people_open" sketch:type="MSLayerGroup" transform="translate(966.000000, 59.000000)">
|
||||
<g id="icons_admin" transform="translate(35.000000, 114.000000)" sketch:type="MSShapeGroup">
|
||||
<path d="M0.441894529,1.80537109 C2.59277353,3.03442388 4.25305977,2.17675781 5.9832796,0.805371094 C8.01666135,2.17675787 9.50756797,3.12670903 11.6293941,1.80537109 C11.6293941,7.01538067 11.9379879,12.2253912 5.9832796,12.2253906 C0.0285712975,12.2253901 0.441894531,7.01538067 0.441894529,1.80537109 Z" id="Path-2-Copy-2"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.3 KiB |
|
@ -139,7 +139,7 @@ function _setCallListeners(call) {
|
|||
Modal.createTrackedDialog('Call Failed', '', QuestionDialog, {
|
||||
title: _t('Call Failed'),
|
||||
description: _t(
|
||||
"There are unknown devices in this room: "+
|
||||
"There are unknown sessions in this room: "+
|
||||
"if you proceed without verifying them, it will be "+
|
||||
"possible for someone to eavesdrop on your call.",
|
||||
),
|
||||
|
|
|
@ -20,6 +20,7 @@ import {MatrixClientPeg} from './MatrixClientPeg';
|
|||
import { deriveKey } from 'matrix-js-sdk/src/crypto/key_passphrase';
|
||||
import { decodeRecoveryKey } from 'matrix-js-sdk/src/crypto/recoverykey';
|
||||
import { _t } from './languageHandler';
|
||||
import SettingsStore from './settings/SettingsStore';
|
||||
|
||||
// This stores the secret storage private keys in memory for the JS SDK. This is
|
||||
// only meant to act as a cache to avoid prompting the user multiple times
|
||||
|
@ -27,7 +28,20 @@ import { _t } from './languageHandler';
|
|||
// single secret storage operation, as it will clear the cached keys once the
|
||||
// operation ends.
|
||||
let secretStorageKeys = {};
|
||||
let cachingAllowed = false;
|
||||
let secretStorageBeingAccessed = false;
|
||||
|
||||
function isCachingAllowed() {
|
||||
return (
|
||||
secretStorageBeingAccessed ||
|
||||
SettingsStore.getValue("keepSecretStoragePassphraseForSession")
|
||||
);
|
||||
}
|
||||
|
||||
export class AccessCancelledError extends Error {
|
||||
constructor() {
|
||||
super("Secret storage access canceled");
|
||||
}
|
||||
}
|
||||
|
||||
async function getSecretStorageKey({ keys: keyInfos }) {
|
||||
const keyInfoEntries = Object.entries(keyInfos);
|
||||
|
@ -37,7 +51,7 @@ async function getSecretStorageKey({ keys: keyInfos }) {
|
|||
const [name, info] = keyInfoEntries[0];
|
||||
|
||||
// Check the in-memory cache
|
||||
if (cachingAllowed && secretStorageKeys[name]) {
|
||||
if (isCachingAllowed() && secretStorageKeys[name]) {
|
||||
return [name, secretStorageKeys[name]];
|
||||
}
|
||||
|
||||
|
@ -66,12 +80,12 @@ async function getSecretStorageKey({ keys: keyInfos }) {
|
|||
);
|
||||
const [input] = await finished;
|
||||
if (!input) {
|
||||
throw new Error("Secret storage access canceled");
|
||||
throw new AccessCancelledError();
|
||||
}
|
||||
const key = await inputToKey(input);
|
||||
|
||||
// Save to cache to avoid future prompts in the current session
|
||||
if (cachingAllowed) {
|
||||
if (isCachingAllowed()) {
|
||||
secretStorageKeys[name] = key;
|
||||
}
|
||||
|
||||
|
@ -104,7 +118,7 @@ export const crossSigningCallbacks = {
|
|||
*/
|
||||
export async function accessSecretStorage(func = async () => { }) {
|
||||
const cli = MatrixClientPeg.get();
|
||||
cachingAllowed = true;
|
||||
secretStorageBeingAccessed = true;
|
||||
|
||||
try {
|
||||
if (!await cli.hasSecretStorageKey()) {
|
||||
|
@ -125,7 +139,7 @@ export async function accessSecretStorage(func = async () => { }) {
|
|||
const { finished } = Modal.createTrackedDialog(
|
||||
'Cross-signing keys dialog', '', InteractiveAuthDialog,
|
||||
{
|
||||
title: _t("Send cross-signing keys to homeserver"),
|
||||
title: _t("Setting up keys"),
|
||||
matrixClient: MatrixClientPeg.get(),
|
||||
makeRequest,
|
||||
},
|
||||
|
@ -143,7 +157,9 @@ export async function accessSecretStorage(func = async () => { }) {
|
|||
return await func();
|
||||
} finally {
|
||||
// Clear secret storage key cache now that work is complete
|
||||
cachingAllowed = false;
|
||||
secretStorageKeys = {};
|
||||
secretStorageBeingAccessed = false;
|
||||
if (!isCachingAllowed()) {
|
||||
secretStorageKeys = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import { _t } from './languageHandler';
|
|||
import ToastStore from './stores/ToastStore';
|
||||
|
||||
function toastKey(deviceId) {
|
||||
return 'newsession_' + deviceId;
|
||||
return 'unverified_session_' + deviceId;
|
||||
}
|
||||
|
||||
const KEY_BACKUP_POLL_INTERVAL = 5 * 60 * 1000;
|
||||
|
@ -77,8 +77,8 @@ export default class DeviceListener {
|
|||
this._recheck();
|
||||
}
|
||||
|
||||
_onDeviceVerificationChanged = (users) => {
|
||||
if (!users.includes(MatrixClientPeg.get().getUserId())) return;
|
||||
_onDeviceVerificationChanged = (userId) => {
|
||||
if (userId !== MatrixClientPeg.get().getUserId()) return;
|
||||
this._recheck();
|
||||
}
|
||||
|
||||
|
@ -160,10 +160,10 @@ export default class DeviceListener {
|
|||
this._activeNagToasts.add(device.deviceId);
|
||||
ToastStore.sharedInstance().addOrReplaceToast({
|
||||
key: toastKey(device.deviceId),
|
||||
title: _t("New Session"),
|
||||
title: _t("Unverified session"),
|
||||
icon: "verification_warning",
|
||||
props: {deviceId: device.deviceId},
|
||||
component: sdk.getComponent("toasts.NewSessionToast"),
|
||||
props: { device },
|
||||
component: sdk.getComponent("toasts.UnverifiedSessionToast"),
|
||||
});
|
||||
newActiveToasts.add(device.deviceId);
|
||||
}
|
||||
|
|
137
src/Entities.js
137
src/Entities.js
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket 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.
|
||||
*/
|
||||
|
||||
import * as sdk from './index';
|
||||
|
||||
function isMatch(query, name, uid) {
|
||||
query = query.toLowerCase();
|
||||
name = name.toLowerCase();
|
||||
uid = uid.toLowerCase();
|
||||
|
||||
// direct prefix matches
|
||||
if (name.indexOf(query) === 0 || uid.indexOf(query) === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// strip @ on uid and try matching again
|
||||
if (uid.length > 1 && uid[0] === "@" && uid.substring(1).indexOf(query) === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// split spaces in name and try matching constituent parts
|
||||
const parts = name.split(" ");
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
if (parts[i].indexOf(query) === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts various data models to Entity objects.
|
||||
*
|
||||
* Entity objects provide an interface for UI components to use to display
|
||||
* members in a data-agnostic way. This means they don't need to care if the
|
||||
* underlying data model is a RoomMember, User or 3PID data structure, it just
|
||||
* cares about rendering.
|
||||
*/
|
||||
|
||||
class Entity {
|
||||
constructor(model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
getJsx() {
|
||||
return null;
|
||||
}
|
||||
|
||||
matches(queryString) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class MemberEntity extends Entity {
|
||||
getJsx() {
|
||||
const MemberTile = sdk.getComponent("rooms.MemberTile");
|
||||
return (
|
||||
<MemberTile key={this.model.userId} member={this.model} />
|
||||
);
|
||||
}
|
||||
|
||||
matches(queryString) {
|
||||
return isMatch(queryString, this.model.name, this.model.userId);
|
||||
}
|
||||
}
|
||||
|
||||
class UserEntity extends Entity {
|
||||
constructor(model, showInviteButton, inviteFn) {
|
||||
super(model);
|
||||
this.showInviteButton = Boolean(showInviteButton);
|
||||
this.inviteFn = inviteFn;
|
||||
this.onClick = this.onClick.bind(this);
|
||||
}
|
||||
|
||||
onClick() {
|
||||
if (this.inviteFn) {
|
||||
this.inviteFn(this.model.userId);
|
||||
}
|
||||
}
|
||||
|
||||
getJsx() {
|
||||
const UserTile = sdk.getComponent("rooms.UserTile");
|
||||
return (
|
||||
<UserTile key={this.model.userId} user={this.model}
|
||||
showInviteButton={this.showInviteButton} onClick={this.onClick} />
|
||||
);
|
||||
}
|
||||
|
||||
matches(queryString) {
|
||||
const name = this.model.displayName || this.model.userId;
|
||||
return isMatch(queryString, name, this.model.userId);
|
||||
}
|
||||
}
|
||||
|
||||
export function newEntity(jsx, matchFn) {
|
||||
const entity = new Entity();
|
||||
entity.getJsx = function() {
|
||||
return jsx;
|
||||
};
|
||||
entity.matches = matchFn;
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {RoomMember[]} members
|
||||
* @return {Entity[]}
|
||||
*/
|
||||
export function fromRoomMembers(members) {
|
||||
return members.map(function(m) {
|
||||
return new MemberEntity(m);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {User[]} users
|
||||
* @param {boolean} showInviteButton
|
||||
* @param {Function} inviteFn Called with the user ID.
|
||||
* @return {Entity[]}
|
||||
*/
|
||||
export function fromUsers(users, showInviteButton, inviteFn) {
|
||||
return users.map(function(u) {
|
||||
return new UserEntity(u, showInviteButton, inviteFn);
|
||||
});
|
||||
}
|
|
@ -378,7 +378,7 @@ export function hydrateSession(credentials) {
|
|||
|
||||
const overwrite = credentials.userId !== oldUserId || credentials.deviceId !== oldDeviceId;
|
||||
if (overwrite) {
|
||||
console.warn("Clearing all data: Old session belongs to a different user/device");
|
||||
console.warn("Clearing all data: Old session belongs to a different user/session");
|
||||
}
|
||||
|
||||
return _doSetLoggedIn(credentials, overwrite);
|
||||
|
|
|
@ -32,6 +32,7 @@ import MatrixClientBackedSettingsHandler from "./settings/handlers/MatrixClientB
|
|||
import * as StorageManager from './utils/StorageManager';
|
||||
import IdentityAuthClient from './IdentityAuthClient';
|
||||
import { crossSigningCallbacks } from './CrossSigningManager';
|
||||
import {SCAN_QR_CODE_METHOD, SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode";
|
||||
|
||||
interface MatrixClientCreds {
|
||||
homeserverUrl: string,
|
||||
|
@ -217,7 +218,12 @@ class _MatrixClientPeg {
|
|||
timelineSupport: true,
|
||||
forceTURN: !SettingsStore.getValue('webRtcAllowPeerToPeer', false),
|
||||
fallbackICEServerAllowed: !!SettingsStore.getValue('fallbackICEServerAllowed'),
|
||||
verificationMethods: [verificationMethods.SAS, verificationMethods.QR_CODE_SHOW],
|
||||
verificationMethods: [
|
||||
verificationMethods.SAS,
|
||||
SHOW_QR_CODE_METHOD,
|
||||
SCAN_QR_CODE_METHOD, // XXX: We don't actually support scanning yet!
|
||||
verificationMethods.RECIPROCATE_QR_CODE,
|
||||
],
|
||||
unstableClientRelationAggregation: true,
|
||||
identityServer: new IdentityAuthClient(),
|
||||
};
|
||||
|
|
|
@ -771,7 +771,7 @@ export const CommandMap = {
|
|||
verify: new Command({
|
||||
name: 'verify',
|
||||
args: '<user-id> <device-id> <device-signing-key>',
|
||||
description: _td('Verifies a user, device, and pubkey tuple'),
|
||||
description: _td('Verifies a user, session, and pubkey tuple'),
|
||||
runFn: function(roomId, args) {
|
||||
if (args) {
|
||||
const matches = args.match(/^(\S+) +(\S+) +(\S+)$/);
|
||||
|
@ -785,22 +785,22 @@ export const CommandMap = {
|
|||
return success((async () => {
|
||||
const device = await cli.getStoredDevice(userId, deviceId);
|
||||
if (!device) {
|
||||
throw new Error(_t('Unknown (user, device) pair:') + ` (${userId}, ${deviceId})`);
|
||||
throw new Error(_t('Unknown (user, session) pair:') + ` (${userId}, ${deviceId})`);
|
||||
}
|
||||
const deviceTrust = await cli.checkDeviceTrust(userId, deviceId);
|
||||
|
||||
if (deviceTrust.isVerified()) {
|
||||
if (device.getFingerprint() === fingerprint) {
|
||||
throw new Error(_t('Device already verified!'));
|
||||
throw new Error(_t('Session already verified!'));
|
||||
} else {
|
||||
throw new Error(_t('WARNING: Device already verified, but keys do NOT MATCH!'));
|
||||
throw new Error(_t('WARNING: Session already verified, but keys do NOT MATCH!'));
|
||||
}
|
||||
}
|
||||
|
||||
if (device.getFingerprint() !== fingerprint) {
|
||||
const fprint = device.getFingerprint();
|
||||
throw new Error(
|
||||
_t('WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device' +
|
||||
_t('WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session' +
|
||||
' %(deviceId)s is "%(fprint)s" which does not match the provided key ' +
|
||||
'"%(fingerprint)s". This could mean your communications are being intercepted!',
|
||||
{
|
||||
|
@ -821,7 +821,7 @@ export const CommandMap = {
|
|||
<p>
|
||||
{
|
||||
_t('The signing key you provided matches the signing key you received ' +
|
||||
'from %(userId)s\'s device %(deviceId)s. Device marked as verified.',
|
||||
'from %(userId)s\'s session %(deviceId)s. Session marked as verified.',
|
||||
{userId, deviceId})
|
||||
}
|
||||
</p>
|
||||
|
|
|
@ -442,23 +442,6 @@ function textForHistoryVisibilityEvent(event) {
|
|||
}
|
||||
}
|
||||
|
||||
function textForEncryptionEvent(event) {
|
||||
const senderName = event.sender ? event.sender.name : event.getSender();
|
||||
if (event.getContent().algorithm === "m.megolm.v1.aes-sha2") {
|
||||
return _t('%(senderName)s turned on end-to-end encryption.', {
|
||||
senderName,
|
||||
});
|
||||
}
|
||||
return _t(
|
||||
'%(senderName)s turned on end-to-end encryption ' +
|
||||
'(unrecognised algorithm %(algorithm)s).',
|
||||
{
|
||||
senderName,
|
||||
algorithm: event.getContent().algorithm,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Currently will only display a change if a user's power level is changed
|
||||
function textForPowerEvent(event) {
|
||||
const senderName = event.sender ? event.sender.name : event.getSender();
|
||||
|
@ -636,7 +619,6 @@ const stateHandlers = {
|
|||
'm.room.member': textForMemberEvent,
|
||||
'm.room.third_party_invite': textForThreePidInviteEvent,
|
||||
'm.room.history_visibility': textForHistoryVisibilityEvent,
|
||||
'm.room.encryption': textForEncryptionEvent,
|
||||
'm.room.power_levels': textForPowerEvent,
|
||||
'm.room.pinned_events': textForPinnedEvent,
|
||||
'm.room.server_acl': textForServerACLEvent,
|
||||
|
|
|
@ -191,7 +191,7 @@ export default createReactClass({
|
|||
<h4>{ _t('Event information') }</h4>
|
||||
{ this._renderEventInfo() }
|
||||
|
||||
<h4>{ _t('Sender device information') }</h4>
|
||||
<h4>{ _t('Sender session information') }</h4>
|
||||
{ this._renderDeviceInfo() }
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
|
|
|
@ -18,6 +18,7 @@ import React from 'react';
|
|||
import * as sdk from '../../../../index';
|
||||
import PropTypes from 'prop-types';
|
||||
import { _t } from '../../../../languageHandler';
|
||||
import SettingsStore, {SettingLevel} from "../../../../settings/SettingsStore";
|
||||
|
||||
import Modal from '../../../../Modal';
|
||||
import {formatBytes, formatCountLong} from "../../../../utils/FormattingUtils";
|
||||
|
@ -37,8 +38,11 @@ export default class ManageEventIndexDialog extends React.Component {
|
|||
this.state = {
|
||||
eventIndexSize: 0,
|
||||
eventCount: 0,
|
||||
crawlingRoomsCount: 0,
|
||||
roomCount: 0,
|
||||
currentRoom: null,
|
||||
crawlerSleepTime:
|
||||
SettingsStore.getValueAt(SettingLevel.DEVICE, 'crawlerSleepTime'),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -48,11 +52,15 @@ export default class ManageEventIndexDialog extends React.Component {
|
|||
let currentRoom = null;
|
||||
|
||||
if (room) currentRoom = room.name;
|
||||
const roomStats = eventIndex.crawlingRooms();
|
||||
const crawlingRoomsCount = roomStats.crawlingRooms.size;
|
||||
const roomCount = roomStats.totalRooms.size;
|
||||
|
||||
this.setState({
|
||||
eventIndexSize: stats.size,
|
||||
roomCount: stats.roomCount,
|
||||
eventCount: stats.eventCount,
|
||||
crawlingRoomsCount: crawlingRoomsCount,
|
||||
roomCount: roomCount,
|
||||
currentRoom: currentRoom,
|
||||
});
|
||||
}
|
||||
|
@ -67,6 +75,7 @@ export default class ManageEventIndexDialog extends React.Component {
|
|||
|
||||
async componentWillMount(): void {
|
||||
let eventIndexSize = 0;
|
||||
let crawlingRoomsCount = 0;
|
||||
let roomCount = 0;
|
||||
let eventCount = 0;
|
||||
let currentRoom = null;
|
||||
|
@ -77,8 +86,10 @@ export default class ManageEventIndexDialog extends React.Component {
|
|||
eventIndex.on("changedCheckpoint", this.updateCurrentRoom.bind(this));
|
||||
|
||||
const stats = await eventIndex.getStats();
|
||||
const roomStats = eventIndex.crawlingRooms();
|
||||
eventIndexSize = stats.size;
|
||||
roomCount = stats.roomCount;
|
||||
crawlingRoomsCount = roomStats.crawlingRooms.size;
|
||||
roomCount = roomStats.totalRooms.size;
|
||||
eventCount = stats.eventCount;
|
||||
|
||||
const room = eventIndex.currentRoom();
|
||||
|
@ -88,6 +99,7 @@ export default class ManageEventIndexDialog extends React.Component {
|
|||
this.setState({
|
||||
eventIndexSize,
|
||||
eventCount,
|
||||
crawlingRoomsCount,
|
||||
roomCount,
|
||||
currentRoom,
|
||||
});
|
||||
|
@ -104,6 +116,11 @@ export default class ManageEventIndexDialog extends React.Component {
|
|||
this.props.onFinished(true);
|
||||
}
|
||||
|
||||
_onCrawlerSleepTimeChange = (e) => {
|
||||
this.setState({crawlerSleepTime: e.target.value});
|
||||
SettingsStore.setValue("crawlerSleepTime", null, SettingLevel.DEVICE, e.target.value);
|
||||
}
|
||||
|
||||
render() {
|
||||
let crawlerState;
|
||||
|
||||
|
@ -115,6 +132,8 @@ export default class ManageEventIndexDialog extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
const Field = sdk.getComponent('views.elements.Field');
|
||||
|
||||
const eventIndexingSettings = (
|
||||
<div>
|
||||
{
|
||||
|
@ -125,8 +144,15 @@ export default class ManageEventIndexDialog extends React.Component {
|
|||
<div className='mx_SettingsTab_subsectionText'>
|
||||
{_t("Space used:")} {formatBytes(this.state.eventIndexSize, 0)}<br />
|
||||
{_t("Indexed messages:")} {formatCountLong(this.state.eventCount)}<br />
|
||||
{_t("Number of rooms:")} {formatCountLong(this.state.roomCount)}<br />
|
||||
{_t("Number of rooms:")} {formatCountLong(this.state.crawlingRoomsCount)} {_t("of ")}
|
||||
{formatCountLong(this.state.roomCount)}<br />
|
||||
{crawlerState}<br />
|
||||
<Field
|
||||
id={"crawlerSleepTimeMs"}
|
||||
label={_t('Message downloading sleep time(ms)')}
|
||||
type='number'
|
||||
value={this.state.crawlerSleepTime}
|
||||
onChange={this._onCrawlerSleepTimeChange} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -71,7 +71,6 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
copied: false,
|
||||
downloaded: false,
|
||||
zxcvbnResult: null,
|
||||
setPassPhrase: false,
|
||||
};
|
||||
|
||||
if (this.state.secureSecretStorage === undefined) {
|
||||
|
@ -219,7 +218,6 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
_onPassPhraseConfirmNextClick = async () => {
|
||||
this._keyBackupInfo = await MatrixClientPeg.get().prepareKeyBackupVersion(this.state.passPhrase);
|
||||
this.setState({
|
||||
setPassPhrase: true,
|
||||
copied: false,
|
||||
downloaded: false,
|
||||
phase: PHASE_SHOWKEY,
|
||||
|
@ -338,7 +336,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
<details>
|
||||
<summary>{_t("Advanced")}</summary>
|
||||
<p><button onClick={this._onSkipPassPhraseClick} >
|
||||
{_t("Set up with a Recovery Key")}
|
||||
{_t("Set up with a recovery key")}
|
||||
</button></p>
|
||||
</details>
|
||||
</div>;
|
||||
|
@ -401,28 +399,17 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
}
|
||||
|
||||
_renderPhaseShowKey() {
|
||||
let bodyText;
|
||||
if (this.state.setPassPhrase) {
|
||||
bodyText = _t(
|
||||
"As a safety net, you can use it to restore your encrypted message " +
|
||||
"history if you forget your Recovery Passphrase.",
|
||||
);
|
||||
} else {
|
||||
bodyText = _t("As a safety net, you can use it to restore your encrypted message history.");
|
||||
}
|
||||
|
||||
return <div>
|
||||
<p>{_t(
|
||||
"Your recovery key is a safety net - you can use it to restore " +
|
||||
"access to your encrypted messages if you forget your passphrase.",
|
||||
)}</p>
|
||||
<p>{_t(
|
||||
"Keep your recovery key somewhere very secure, like a password manager (or a safe).",
|
||||
"Keep a copy of it somewhere secure, like a password manager or even a safe.",
|
||||
)}</p>
|
||||
<p>{bodyText}</p>
|
||||
<div className="mx_CreateKeyBackupDialog_primaryContainer">
|
||||
<div className="mx_CreateKeyBackupDialog_recoveryKeyHeader">
|
||||
{_t("Your Recovery Key")}
|
||||
{_t("Your recovery key")}
|
||||
</div>
|
||||
<div className="mx_CreateKeyBackupDialog_recoveryKeyContainer">
|
||||
<div className="mx_CreateKeyBackupDialog_recoveryKey">
|
||||
|
@ -430,7 +417,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
</div>
|
||||
<div className="mx_CreateKeyBackupDialog_recoveryKeyButtons">
|
||||
<button className="mx_Dialog_primary" onClick={this._onCopyClick}>
|
||||
{_t("Copy to clipboard")}
|
||||
{_t("Copy")}
|
||||
</button>
|
||||
<button className="mx_Dialog_primary" onClick={this._onDownloadClick}>
|
||||
{_t("Download")}
|
||||
|
@ -462,7 +449,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
<li>{_t("<b>Save it</b> on a USB key or backup drive", {}, {b: s => <b>{s}</b>})}</li>
|
||||
<li>{_t("<b>Copy it</b> to your personal cloud storage", {}, {b: s => <b>{s}</b>})}</li>
|
||||
</ul>
|
||||
<DialogButtons primaryButton={_t("OK")}
|
||||
<DialogButtons primaryButton={_t("Continue")}
|
||||
onPrimaryButtonClick={this._createBackup}
|
||||
hasCancel={false}>
|
||||
<button onClick={this._onKeepItSafeBackClick}>{_t("Back")}</button>
|
||||
|
@ -495,7 +482,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
return <div>
|
||||
{_t(
|
||||
"Without setting up Secure Message Recovery, you won't be able to restore your " +
|
||||
"encrypted message history if you log out or use another device.",
|
||||
"encrypted message history if you log out or use another session.",
|
||||
)}
|
||||
<DialogButtons primaryButton={_t('Set up Secure Message Recovery')}
|
||||
onPrimaryButtonClick={this._onSetUpClick}
|
||||
|
@ -515,15 +502,14 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
case PHASE_OPTOUT_CONFIRM:
|
||||
return _t('Warning!');
|
||||
case PHASE_SHOWKEY:
|
||||
return _t('Recovery key');
|
||||
case PHASE_KEEPITSAFE:
|
||||
return _t('Keep it safe');
|
||||
return _t('Make a copy of your recovery key');
|
||||
case PHASE_BACKINGUP:
|
||||
return _t('Starting backup...');
|
||||
case PHASE_DONE:
|
||||
return _t('Success!');
|
||||
default:
|
||||
return _t("Create Key Backup");
|
||||
return _t("Create key backup");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ export default class NewRecoveryMethodDialog extends React.PureComponent {
|
|||
content = <div>
|
||||
{newMethodDetected}
|
||||
<p>{_t(
|
||||
"This device is encrypting history using the new recovery method.",
|
||||
"This session is encrypting history using the new recovery method.",
|
||||
)}</p>
|
||||
{hackWarning}
|
||||
<DialogButtons
|
||||
|
|
|
@ -55,12 +55,12 @@ export default class RecoveryMethodRemovedDialog extends React.PureComponent {
|
|||
>
|
||||
<div>
|
||||
<p>{_t(
|
||||
"This device has detected that your recovery passphrase and key " +
|
||||
"This session has detected that your recovery passphrase and key " +
|
||||
"for Secure Messages have been removed.",
|
||||
)}</p>
|
||||
<p>{_t(
|
||||
"If you did this accidentally, you can setup Secure Messages on " +
|
||||
"this device which will re-encrypt this device's message " +
|
||||
"this session which will re-encrypt this session's message " +
|
||||
"history with a new recovery method.",
|
||||
)}</p>
|
||||
<p className="warning">{_t(
|
||||
|
|
|
@ -76,7 +76,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
copied: false,
|
||||
downloaded: false,
|
||||
zxcvbnResult: null,
|
||||
setPassPhrase: false,
|
||||
backupInfo: null,
|
||||
backupSigStatus: null,
|
||||
// does the server offer a UI auth flow with just m.login.password
|
||||
|
@ -84,9 +83,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
canUploadKeysWithPasswordOnly: null,
|
||||
accountPassword: props.accountPassword,
|
||||
accountPasswordCorrect: null,
|
||||
// set if we are 'upgrading' encryption (making an SSSS store from
|
||||
// an existing key backup secret).
|
||||
doingUpgrade: null,
|
||||
// status of the key backup toggle switch
|
||||
useKeyBackup: true,
|
||||
};
|
||||
|
||||
this._fetchBackupInfo();
|
||||
|
@ -115,8 +113,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
phase,
|
||||
backupInfo,
|
||||
backupSigStatus,
|
||||
// remember this after this phase so we can use appropriate copy
|
||||
doingUpgrade: phase === PHASE_MIGRATE,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -141,13 +137,19 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
}
|
||||
|
||||
_onKeyBackupStatusChange = () => {
|
||||
this._fetchBackupInfo();
|
||||
if (this.state.phase === PHASE_MIGRATE) this._fetchBackupInfo();
|
||||
}
|
||||
|
||||
_collectRecoveryKeyNode = (n) => {
|
||||
this._recoveryKeyNode = n;
|
||||
}
|
||||
|
||||
_onUseKeyBackupChange = (enabled) => {
|
||||
this.setState({
|
||||
useKeyBackup: enabled,
|
||||
});
|
||||
}
|
||||
|
||||
_onMigrateFormSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
if (this.state.backupSigStatus.usable) {
|
||||
|
@ -197,7 +199,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
const { finished } = Modal.createTrackedDialog(
|
||||
'Cross-signing keys dialog', '', InteractiveAuthDialog,
|
||||
{
|
||||
title: _t("Send cross-signing keys to homeserver"),
|
||||
title: _t("Setting up keys"),
|
||||
matrixClient: MatrixClientPeg.get(),
|
||||
makeRequest,
|
||||
},
|
||||
|
@ -222,6 +224,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
authUploadDeviceSigningKeys: this._doBootstrapUIAuth,
|
||||
createSecretStorageKey: async () => this._keyInfo,
|
||||
keyBackupInfo: this.state.backupInfo,
|
||||
setupNewKeyBackup: !this.state.backupInfo && this.state.useKeyBackup,
|
||||
});
|
||||
this.setState({
|
||||
phase: PHASE_DONE,
|
||||
|
@ -316,7 +319,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
this._keyInfo = keyInfo;
|
||||
this._encodedRecoveryKey = encodedRecoveryKey;
|
||||
this.setState({
|
||||
setPassPhrase: true,
|
||||
copied: false,
|
||||
downloaded: false,
|
||||
phase: PHASE_SHOWKEY,
|
||||
|
@ -415,7 +417,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
|
||||
return <form onSubmit={this._onMigrateFormSubmit}>
|
||||
<p>{_t(
|
||||
"Upgrade this device to allow it to verify other devices, " +
|
||||
"Upgrade this session to allow it to verify other sessions, " +
|
||||
"granting them access to encrypted messages and marking them " +
|
||||
"as trusted for other users.",
|
||||
)}</p>
|
||||
|
@ -425,7 +427,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
hasCancel={false}
|
||||
primaryDisabled={this.state.canUploadKeysWithPasswordOnly && !this.state.accountPassword}
|
||||
>
|
||||
<button type="button" className="danger" onClick={this._onSkipClick}>
|
||||
<button type="button" className="danger" onClick={this._onSkipSetupClick}>
|
||||
{_t('Skip')}
|
||||
</button>
|
||||
</DialogButtons>
|
||||
|
@ -436,6 +438,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||
const Field = sdk.getComponent('views.elements.Field');
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
const LabelledToggleSwitch = sdk.getComponent('views.elements.LabelledToggleSwitch');
|
||||
|
||||
let strengthMeter;
|
||||
let helpText;
|
||||
|
@ -443,14 +446,19 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
if (this.state.zxcvbnResult.score >= PASSWORD_MIN_SCORE) {
|
||||
helpText = _t("Great! This passphrase looks strong enough.");
|
||||
} else {
|
||||
const suggestions = [];
|
||||
for (let i = 0; i < this.state.zxcvbnResult.feedback.suggestions.length; ++i) {
|
||||
suggestions.push(<div key={i}>{this.state.zxcvbnResult.feedback.suggestions[i]}</div>);
|
||||
}
|
||||
const suggestionBlock = <div>{suggestions.length > 0 ? suggestions : _t("Keep going...")}</div>;
|
||||
// We take the warning from zxcvbn or failing that, the first
|
||||
// suggestion. In practice The first is generally the most relevant
|
||||
// and it's probably better to present the user with one thing to
|
||||
// improve about their password than a whole collection - it can
|
||||
// spit out a warning and multiple suggestions which starts getting
|
||||
// very information-dense.
|
||||
const suggestion = (
|
||||
this.state.zxcvbnResult.feedback.warning ||
|
||||
this.state.zxcvbnResult.feedback.suggestions[0]
|
||||
);
|
||||
const suggestionBlock = <div>{suggestion || _t("Keep going...")}</div>;
|
||||
|
||||
helpText = <div>
|
||||
{this.state.zxcvbnResult.feedback.warning}
|
||||
{suggestionBlock}
|
||||
</div>;
|
||||
}
|
||||
|
@ -461,7 +469,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
|
||||
return <div>
|
||||
<p>{_t(
|
||||
"Set up encryption on this device to allow it to verify other devices, " +
|
||||
"Set up encryption on this session to allow it to verify other sessions, " +
|
||||
"granting them access to encrypted messages and marking them as trusted for other users.",
|
||||
)}</p>
|
||||
<p>{_t(
|
||||
|
@ -470,7 +478,9 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
)}</p>
|
||||
|
||||
<div className="mx_CreateSecretStorageDialog_passPhraseContainer">
|
||||
<Field type="password"
|
||||
<Field
|
||||
type="password"
|
||||
id="mx_CreateSecretStorageDialog_passPhraseField"
|
||||
className="mx_CreateSecretStorageDialog_passPhraseField"
|
||||
onChange={this._onPassPhraseChange}
|
||||
onKeyPress={this._onPassPhraseKeyPress}
|
||||
|
@ -484,6 +494,11 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<LabelledToggleSwitch
|
||||
label={ _t("Back up my encryption keys, securing them with the same passphrase")}
|
||||
onChange={this._onUseKeyBackupChange} value={this.state.useKeyBackup}
|
||||
/>
|
||||
|
||||
<DialogButtons primaryButton={_t('Continue')}
|
||||
onPrimaryButtonClick={this._onPassPhraseNextClick}
|
||||
hasCancel={false}
|
||||
|
@ -497,9 +512,9 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
|
||||
<details>
|
||||
<summary>{_t("Advanced")}</summary>
|
||||
<p><AccessibleButton kind='primary' onClick={this._onSkipPassPhraseClick} >
|
||||
<AccessibleButton kind='primary' onClick={this._onSkipPassPhraseClick} >
|
||||
{_t("Set up with a recovery key")}
|
||||
</AccessibleButton></p>
|
||||
</AccessibleButton>
|
||||
</details>
|
||||
</div>;
|
||||
}
|
||||
|
@ -566,19 +581,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
}
|
||||
|
||||
_renderPhaseShowKey() {
|
||||
let bodyText;
|
||||
if (this.state.setPassPhrase) {
|
||||
bodyText = _t(
|
||||
"As a safety net, you can use it to restore your access to encrypted " +
|
||||
"messages if you forget your passphrase.",
|
||||
);
|
||||
} else {
|
||||
bodyText = _t(
|
||||
"As a safety net, you can use it to restore your access to encrypted " +
|
||||
"messages.",
|
||||
);
|
||||
}
|
||||
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
return <div>
|
||||
<p>{_t(
|
||||
|
@ -586,12 +588,11 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
"access to your encrypted messages if you forget your passphrase.",
|
||||
)}</p>
|
||||
<p>{_t(
|
||||
"Keep your recovery key somewhere very secure, like a password manager (or a safe).",
|
||||
"Keep a copy of it somewhere secure, like a password manager or even a safe.",
|
||||
)}</p>
|
||||
<p>{bodyText}</p>
|
||||
<div className="mx_CreateSecretStorageDialog_primaryContainer">
|
||||
<div className="mx_CreateSecretStorageDialog_recoveryKeyHeader">
|
||||
{_t("Your Recovery Key")}
|
||||
{_t("Your recovery key")}
|
||||
</div>
|
||||
<div className="mx_CreateSecretStorageDialog_recoveryKeyContainer">
|
||||
<div className="mx_CreateSecretStorageDialog_recoveryKey">
|
||||
|
@ -599,7 +600,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
</div>
|
||||
<div className="mx_CreateSecretStorageDialog_recoveryKeyButtons">
|
||||
<AccessibleButton kind='primary' className="mx_Dialog_primary" onClick={this._onCopyClick}>
|
||||
{_t("Copy to clipboard")}
|
||||
{_t("Copy")}
|
||||
</AccessibleButton>
|
||||
<AccessibleButton kind='primary' className="mx_Dialog_primary" onClick={this._onDownloadClick}>
|
||||
{_t("Download")}
|
||||
|
@ -631,7 +632,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
<li>{_t("<b>Save it</b> on a USB key or backup drive", {}, {b: s => <b>{s}</b>})}</li>
|
||||
<li>{_t("<b>Copy it</b> to your personal cloud storage", {}, {b: s => <b>{s}</b>})}</li>
|
||||
</ul>
|
||||
<DialogButtons primaryButton={_t("OK")}
|
||||
<DialogButtons primaryButton={_t("Continue")}
|
||||
onPrimaryButtonClick={this._bootstrapSecretStorage}
|
||||
hasCancel={false}>
|
||||
<button onClick={this._onKeepItSafeBackClick}>{_t("Back")}</button>
|
||||
|
@ -650,11 +651,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||
return <div>
|
||||
<p>{_t(
|
||||
"This device can now verify other devices, granting them access " +
|
||||
"to encrypted messages and marking them as trusted for other users.",
|
||||
)}</p>
|
||||
<p>{_t(
|
||||
"Verify other users in their profile.",
|
||||
"You can now verify your other devices, " +
|
||||
"and other users to keep your chats safe.",
|
||||
)}</p>
|
||||
<DialogButtons primaryButton={_t('OK')}
|
||||
onPrimaryButtonClick={this._onDone}
|
||||
|
@ -667,7 +665,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||
return <div>
|
||||
{_t(
|
||||
"Without completing security on this device, it won’t have " +
|
||||
"Without completing security on this session, it won’t have " +
|
||||
"access to encrypted messages.",
|
||||
)}
|
||||
<DialogButtons primaryButton={_t('Go back')}
|
||||
|
@ -690,13 +688,12 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
case PHASE_CONFIRM_SKIP:
|
||||
return _t('Are you sure?');
|
||||
case PHASE_SHOWKEY:
|
||||
return _t('Recovery key');
|
||||
case PHASE_KEEPITSAFE:
|
||||
return _t('Keep it safe');
|
||||
return _t('Make a copy of your recovery key');
|
||||
case PHASE_STORING:
|
||||
return _t('Storing secrets...');
|
||||
return _t('Setting up keys');
|
||||
case PHASE_DONE:
|
||||
return this.state.doingUpgrade ? _t('Encryption upgraded') : _t('Encryption setup complete');
|
||||
return _t("You're done!");
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ export default class RoomProvider extends AutocompleteProvider {
|
|||
const {command, range} = this.getCurrentCommand(query, selection, force);
|
||||
if (command) {
|
||||
// the only reason we need to do this is because Fuse only matches on properties
|
||||
let matcherObjects = client.getRooms().filter(
|
||||
let matcherObjects = client.getVisibleRooms().filter(
|
||||
(room) => !!room && !!getDisplayAliasForRoom(room),
|
||||
).map((room) => {
|
||||
return {
|
||||
|
|
|
@ -53,6 +53,7 @@ import createRoom from "../../createRoom";
|
|||
import KeyRequestHandler from '../../KeyRequestHandler';
|
||||
import { _t, getCurrentLanguage } from '../../languageHandler';
|
||||
import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
|
||||
import ThemeController from "../../settings/controllers/ThemeController";
|
||||
import { startAnyRegistrationFlow } from "../../Registration.js";
|
||||
import { messageForSyncError } from '../../utils/ErrorUtils';
|
||||
import ResizeNotifier from "../../utils/ResizeNotifier";
|
||||
|
@ -506,6 +507,8 @@ export default createReactClass({
|
|||
view: VIEWS.LOGIN,
|
||||
});
|
||||
this.notifyNewScreen('login');
|
||||
ThemeController.isLogin = true;
|
||||
this._themeWatcher.recheck();
|
||||
break;
|
||||
case 'start_post_registration':
|
||||
this.setState({
|
||||
|
@ -760,6 +763,8 @@ export default createReactClass({
|
|||
}
|
||||
|
||||
this.setStateForNewView(newState);
|
||||
ThemeController.isLogin = true;
|
||||
this._themeWatcher.recheck();
|
||||
this.notifyNewScreen('register');
|
||||
},
|
||||
|
||||
|
@ -910,6 +915,8 @@ export default createReactClass({
|
|||
view: VIEWS.WELCOME,
|
||||
});
|
||||
this.notifyNewScreen('welcome');
|
||||
ThemeController.isLogin = true;
|
||||
this._themeWatcher.recheck();
|
||||
},
|
||||
|
||||
_viewHome: function() {
|
||||
|
@ -919,6 +926,8 @@ export default createReactClass({
|
|||
});
|
||||
this._setPage(PageTypes.HomePage);
|
||||
this.notifyNewScreen('home');
|
||||
ThemeController.isLogin = false;
|
||||
this._themeWatcher.recheck();
|
||||
},
|
||||
|
||||
_viewUser: function(userId, subAction) {
|
||||
|
@ -1231,6 +1240,8 @@ export default createReactClass({
|
|||
});
|
||||
this.subTitleStatus = '';
|
||||
this._setPageSubtitle();
|
||||
ThemeController.isLogin = true;
|
||||
this._themeWatcher.recheck();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1864,7 +1875,9 @@ export default createReactClass({
|
|||
try {
|
||||
masterKeyInStorage = !!await cli.getAccountDataFromServer("m.cross_signing.master");
|
||||
} catch (e) {
|
||||
if (e.errcode !== "M_NOT_FOUND") throw e;
|
||||
if (e.errcode !== "M_NOT_FOUND") {
|
||||
console.warn("Secret storage account data check failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (masterKeyInStorage) {
|
||||
|
@ -1983,6 +1996,7 @@ export default createReactClass({
|
|||
onLoggedIn={this.onRegisterFlowComplete}
|
||||
onLoginClick={this.onLoginClick}
|
||||
onServerConfigChange={this.onServerConfigChange}
|
||||
defaultDeviceDisplayName={this.props.defaultDeviceDisplayName}
|
||||
{...this.getServerProperties()}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -465,6 +465,12 @@ export default class MessagePanel extends React.Component {
|
|||
}
|
||||
return false;
|
||||
};
|
||||
// events that we include in the group but then eject out and place
|
||||
// above the group.
|
||||
const shouldEject = (ev) => {
|
||||
if (ev.getType() === "m.room.encryption") return true;
|
||||
return false;
|
||||
};
|
||||
if (mxEv.getType() === "m.room.create") {
|
||||
let summaryReadMarker = null;
|
||||
const ts1 = mxEv.getTs();
|
||||
|
@ -484,6 +490,7 @@ export default class MessagePanel extends React.Component {
|
|||
}
|
||||
|
||||
const summarisedEvents = []; // Don't add m.room.create here as we don't want it inside the summary
|
||||
const ejectedEvents = [];
|
||||
for (;i + 1 < this.props.events.length; i++) {
|
||||
const collapsedMxEv = this.props.events[i + 1];
|
||||
|
||||
|
@ -501,7 +508,11 @@ export default class MessagePanel extends React.Component {
|
|||
// If RM event is in the summary, mark it as such and the RM will be appended after the summary.
|
||||
summaryReadMarker = summaryReadMarker || this._readMarkerForEvent(collapsedMxEv.getId());
|
||||
|
||||
summarisedEvents.push(collapsedMxEv);
|
||||
if (shouldEject(collapsedMxEv)) {
|
||||
ejectedEvents.push(collapsedMxEv);
|
||||
} else {
|
||||
summarisedEvents.push(collapsedMxEv);
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, i = the index of the last event in the summary sequence
|
||||
|
@ -513,6 +524,10 @@ export default class MessagePanel extends React.Component {
|
|||
return this._getTilesForEvent(e, e, e === lastShownEvent);
|
||||
}).reduce((a, b) => a.concat(b), []);
|
||||
|
||||
for (const ejected of ejectedEvents) {
|
||||
ret.push(...this._getTilesForEvent(mxEv, ejected, last));
|
||||
}
|
||||
|
||||
// Get sender profile from the latest event in the summary as the m.room.create doesn't contain one
|
||||
const ev = this.props.events[i];
|
||||
ret.push(<EventListSummary
|
||||
|
|
|
@ -48,6 +48,7 @@ export default class RightPanel extends React.Component {
|
|||
phase: this._getPhaseFromProps(),
|
||||
isUserPrivilegedInGroup: null,
|
||||
member: this._getUserForPanel(),
|
||||
verificationRequest: RightPanelStore.getSharedInstance().roomPanelPhaseParams.verificationRequest,
|
||||
};
|
||||
this.onAction = this.onAction.bind(this);
|
||||
this.onRoomStateMember = this.onRoomStateMember.bind(this);
|
||||
|
@ -68,15 +69,34 @@ export default class RightPanel extends React.Component {
|
|||
return this.props.user || lastParams['member'];
|
||||
}
|
||||
|
||||
// gets the current phase from the props and also maybe the store
|
||||
_getPhaseFromProps() {
|
||||
const rps = RightPanelStore.getSharedInstance();
|
||||
const userForPanel = this._getUserForPanel();
|
||||
if (this.props.groupId) {
|
||||
if (!RIGHT_PANEL_PHASES_NO_ARGS.includes(rps.groupPanelPhase)) {
|
||||
dis.dispatch({action: "set_right_panel_phase", phase: RIGHT_PANEL_PHASES.GroupMemberList});
|
||||
return RIGHT_PANEL_PHASES.GroupMemberList;
|
||||
}
|
||||
return rps.groupPanelPhase;
|
||||
} else if (this._getUserForPanel()) {
|
||||
} else if (userForPanel) {
|
||||
// XXX FIXME AAAAAARGH: What is going on with this class!? It takes some of its state
|
||||
// from its props and some from a store, except if the contents of the store changes
|
||||
// while it's mounted in which case it replaces all of its state with that of the store,
|
||||
// except it uses a dispatch instead of a normal store listener?
|
||||
// Unfortunately rewriting this would almost certainly break showing the right panel
|
||||
// in some of the many cases, and I don't have time to re-architect it and test all
|
||||
// the flows now, so adding yet another special case so if the store thinks there is
|
||||
// a verification going on for the member we're displaying, we show that, otherwise
|
||||
// we race if a verification is started while the panel isn't displayed because we're
|
||||
// not mounted in time to get the dispatch.
|
||||
// Until then, let this code serve as a warning from history.
|
||||
if (
|
||||
userForPanel.userId === rps.roomPanelPhaseParams.member.userId &&
|
||||
rps.roomPanelPhaseParams.verificationRequest
|
||||
) {
|
||||
return rps.roomPanelPhase;
|
||||
}
|
||||
return RIGHT_PANEL_PHASES.RoomMemberInfo;
|
||||
} else {
|
||||
if (!RIGHT_PANEL_PHASES_NO_ARGS.includes(rps.roomPanelPhase)) {
|
||||
|
@ -169,7 +189,6 @@ export default class RightPanel extends React.Component {
|
|||
const MemberList = sdk.getComponent('rooms.MemberList');
|
||||
const MemberInfo = sdk.getComponent('rooms.MemberInfo');
|
||||
const UserInfo = sdk.getComponent('right_panel.UserInfo');
|
||||
const EncryptionPanel = sdk.getComponent('right_panel.EncryptionPanel');
|
||||
const ThirdPartyMemberInfo = sdk.getComponent('rooms.ThirdPartyMemberInfo');
|
||||
const NotificationPanel = sdk.getComponent('structures.NotificationPanel');
|
||||
const FilePanel = sdk.getComponent('structures.FilePanel');
|
||||
|
@ -181,64 +200,82 @@ export default class RightPanel extends React.Component {
|
|||
|
||||
let panel = <div />;
|
||||
|
||||
if (this.props.roomId && this.state.phase === RIGHT_PANEL_PHASES.RoomMemberList) {
|
||||
panel = <MemberList roomId={this.props.roomId} key={this.props.roomId} />;
|
||||
} else if (this.props.groupId && this.state.phase === RIGHT_PANEL_PHASES.GroupMemberList) {
|
||||
panel = <GroupMemberList groupId={this.props.groupId} key={this.props.groupId} />;
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.GroupRoomList) {
|
||||
panel = <GroupRoomList groupId={this.props.groupId} key={this.props.groupId} />;
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.RoomMemberInfo) {
|
||||
if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
|
||||
const onClose = () => {
|
||||
dis.dispatch({
|
||||
action: "view_user",
|
||||
member: null,
|
||||
});
|
||||
};
|
||||
panel = <UserInfo
|
||||
user={this.state.member}
|
||||
roomId={this.props.roomId}
|
||||
key={this.props.roomId || this.state.member.userId}
|
||||
onClose={onClose}
|
||||
/>;
|
||||
} else {
|
||||
panel = <MemberInfo member={this.state.member} key={this.props.roomId || this.state.member.userId} />;
|
||||
}
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.Room3pidMemberInfo) {
|
||||
panel = <ThirdPartyMemberInfo event={this.state.event} key={this.props.roomId} />;
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.GroupMemberInfo) {
|
||||
if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
|
||||
const onClose = () => {
|
||||
dis.dispatch({
|
||||
action: "view_user",
|
||||
member: null,
|
||||
});
|
||||
};
|
||||
panel = <UserInfo
|
||||
user={this.state.member}
|
||||
groupId={this.props.groupId}
|
||||
key={this.state.member.userId}
|
||||
onClose={onClose} />;
|
||||
} else {
|
||||
panel = (
|
||||
<GroupMemberInfo
|
||||
groupMember={this.state.member}
|
||||
switch (this.state.phase) {
|
||||
case RIGHT_PANEL_PHASES.RoomMemberList:
|
||||
if (this.props.roomId) {
|
||||
panel = <MemberList roomId={this.props.roomId} key={this.props.roomId} />;
|
||||
}
|
||||
break;
|
||||
case RIGHT_PANEL_PHASES.GroupMemberList:
|
||||
if (this.props.groupId) {
|
||||
panel = <GroupMemberList groupId={this.props.groupId} key={this.props.groupId} />;
|
||||
}
|
||||
break;
|
||||
case RIGHT_PANEL_PHASES.GroupRoomList:
|
||||
panel = <GroupRoomList groupId={this.props.groupId} key={this.props.groupId} />;
|
||||
break;
|
||||
case RIGHT_PANEL_PHASES.RoomMemberInfo:
|
||||
case RIGHT_PANEL_PHASES.EncryptionPanel:
|
||||
if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
|
||||
const onClose = () => {
|
||||
dis.dispatch({
|
||||
action: "view_user",
|
||||
member: this.state.phase === RIGHT_PANEL_PHASES.EncryptionPanel ? this.state.member : null,
|
||||
});
|
||||
};
|
||||
panel = <UserInfo
|
||||
user={this.state.member}
|
||||
roomId={this.props.roomId}
|
||||
key={this.props.roomId || this.state.member.userId}
|
||||
onClose={onClose}
|
||||
phase={this.state.phase}
|
||||
verificationRequest={this.state.verificationRequest}
|
||||
/>;
|
||||
} else {
|
||||
panel = <MemberInfo
|
||||
member={this.state.member}
|
||||
key={this.props.roomId || this.state.member.userId}
|
||||
/>;
|
||||
}
|
||||
break;
|
||||
case RIGHT_PANEL_PHASES.Room3pidMemberInfo:
|
||||
panel = <ThirdPartyMemberInfo event={this.state.event} key={this.props.roomId} />;
|
||||
break;
|
||||
case RIGHT_PANEL_PHASES.GroupMemberInfo:
|
||||
if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
|
||||
const onClose = () => {
|
||||
dis.dispatch({
|
||||
action: "view_user",
|
||||
member: null,
|
||||
});
|
||||
};
|
||||
panel = <UserInfo
|
||||
user={this.state.member}
|
||||
groupId={this.props.groupId}
|
||||
key={this.state.member.user_id}
|
||||
/>
|
||||
);
|
||||
}
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.GroupRoomInfo) {
|
||||
panel = <GroupRoomInfo
|
||||
groupRoomId={this.state.groupRoomId}
|
||||
groupId={this.props.groupId}
|
||||
key={this.state.groupRoomId} />;
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.NotificationPanel) {
|
||||
panel = <NotificationPanel />;
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.FilePanel) {
|
||||
panel = <FilePanel roomId={this.props.roomId} resizeNotifier={this.props.resizeNotifier} />;
|
||||
} else if (this.state.phase === RIGHT_PANEL_PHASES.EncryptionPanel) {
|
||||
panel = <EncryptionPanel member={this.state.member} verificationRequest={this.state.verificationRequest} />;
|
||||
key={this.state.member.userId}
|
||||
onClose={onClose} />;
|
||||
} else {
|
||||
panel = (
|
||||
<GroupMemberInfo
|
||||
groupMember={this.state.member}
|
||||
groupId={this.props.groupId}
|
||||
key={this.state.member.user_id}
|
||||
/>
|
||||
);
|
||||
}
|
||||
break;
|
||||
case RIGHT_PANEL_PHASES.GroupRoomInfo:
|
||||
panel = <GroupRoomInfo
|
||||
groupRoomId={this.state.groupRoomId}
|
||||
groupId={this.props.groupId}
|
||||
key={this.state.groupRoomId} />;
|
||||
break;
|
||||
case RIGHT_PANEL_PHASES.NotificationPanel:
|
||||
panel = <NotificationPanel />;
|
||||
break;
|
||||
case RIGHT_PANEL_PHASES.FilePanel:
|
||||
panel = <FilePanel roomId={this.props.roomId} resizeNotifier={this.props.resizeNotifier} />;
|
||||
break;
|
||||
}
|
||||
|
||||
const classes = classNames("mx_RightPanel", "mx_fadable", {
|
||||
|
|
|
@ -155,7 +155,7 @@ export default createReactClass({
|
|||
|
||||
this.nextBatch = data.next_batch;
|
||||
this.setState((s) => {
|
||||
s.publicRooms.push(...data.chunk);
|
||||
s.publicRooms.push(...(data.chunk || []));
|
||||
s.loading = false;
|
||||
return s;
|
||||
});
|
||||
|
|
|
@ -220,12 +220,12 @@ export default createReactClass({
|
|||
});
|
||||
|
||||
if (hasUDE) {
|
||||
title = _t("Message not sent due to unknown devices being present");
|
||||
title = _t("Message not sent due to unknown sessions being present");
|
||||
content = _t(
|
||||
"<showDevicesText>Show devices</showDevicesText>, <sendAnywayText>send anyway</sendAnywayText> or <cancelText>cancel</cancelText>.",
|
||||
"<showSessionsText>Show sessions</showSessionsText>, <sendAnywayText>send anyway</sendAnywayText> or <cancelText>cancel</cancelText>.",
|
||||
{},
|
||||
{
|
||||
'showDevicesText': (sub) => <a className="mx_RoomStatusBar_resend_link" key="resend" onClick={this._onShowDevicesClick}>{ sub }</a>,
|
||||
'showSessionsText': (sub) => <a className="mx_RoomStatusBar_resend_link" key="resend" onClick={this._onShowDevicesClick}>{ sub }</a>,
|
||||
'sendAnywayText': (sub) => <a className="mx_RoomStatusBar_resend_link" key="sendAnyway" onClick={this._onSendWithoutVerifyingClick}>{ sub }</a>,
|
||||
'cancelText': (sub) => <a className="mx_RoomStatusBar_resend_link" key="cancel" onClick={this._onCancelAllClick}>{ sub }</a>,
|
||||
},
|
||||
|
|
|
@ -820,7 +820,7 @@ export default createReactClass({
|
|||
this.setState({
|
||||
e2eStatus: "warning",
|
||||
});
|
||||
debuglog("e2e status set to warning as not all users trust all of their devices." +
|
||||
debuglog("e2e status set to warning as not all users trust all of their sessions." +
|
||||
" Aborted on user", userId);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright 2017, 2018 New Vector Ltd.
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -64,8 +65,8 @@ const TagPanel = createReactClass({
|
|||
this.unmounted = true;
|
||||
this.context.removeListener("Group.myMembership", this._onGroupMyMembership);
|
||||
this.context.removeListener("sync", this._onClientSync);
|
||||
if (this._filterStoreToken) {
|
||||
this._filterStoreToken.remove();
|
||||
if (this._tagOrderStoreToken) {
|
||||
this._tagOrderStoreToken.remove();
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -1171,28 +1171,40 @@ const TimelinePanel = createReactClass({
|
|||
// get the user's membership at the last event by getting the timeline
|
||||
// that the event belongs to, and traversing the timeline looking for
|
||||
// that event, while keeping track of the user's membership
|
||||
const lastEvent = events[events.length - 1];
|
||||
const timeline = room.getTimelineForEvent(lastEvent.getId());
|
||||
const userMembershipEvent =
|
||||
timeline.getState(EventTimeline.FORWARDS).getMember(userId);
|
||||
let userMembership = userMembershipEvent
|
||||
? userMembershipEvent.membership : "leave";
|
||||
const timelineEvents = timeline.getEvents();
|
||||
for (let i = timelineEvents.length - 1; i >= 0; i--) {
|
||||
const event = timelineEvents[i];
|
||||
if (event.getId() === lastEvent.getId()) {
|
||||
// found the last event, so we can stop looking through the timeline
|
||||
break;
|
||||
} else if (event.getStateKey() === userId
|
||||
&& event.getType() === "m.room.member") {
|
||||
const prevContent = event.getPrevContent();
|
||||
userMembership = prevContent.membership || "leave";
|
||||
let i;
|
||||
let userMembership = "leave";
|
||||
for (i = events.length - 1; i >= 0; i--) {
|
||||
const timeline = room.getTimelineForEvent(events[i].getId());
|
||||
if (!timeline) {
|
||||
// Somehow, it seems to be possible for live events to not have
|
||||
// a timeline, even though that should not happen. :(
|
||||
// https://github.com/vector-im/riot-web/issues/12120
|
||||
console.warn(
|
||||
`Event ${events[i].getId()} in room ${room.roomId} is live, ` +
|
||||
`but it does not have a timeline`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
const userMembershipEvent =
|
||||
timeline.getState(EventTimeline.FORWARDS).getMember(userId);
|
||||
userMembership = userMembershipEvent ? userMembershipEvent.membership : "leave";
|
||||
const timelineEvents = timeline.getEvents();
|
||||
for (let j = timelineEvents.length - 1; j >= 0; j--) {
|
||||
const event = timelineEvents[j];
|
||||
if (event.getId() === events[i].getId()) {
|
||||
break;
|
||||
} else if (event.getStateKey() === userId
|
||||
&& event.getType() === "m.room.member") {
|
||||
const prevContent = event.getPrevContent();
|
||||
userMembership = prevContent.membership || "leave";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// now go through the events that we have and find the first undecryptable
|
||||
// now go through the rest of the events and find the first undecryptable
|
||||
// one that was sent when the user wasn't in the room
|
||||
for (let i = events.length - 1; i >= 0; i--) {
|
||||
for (; i >= 0; i--) {
|
||||
const event = events[i];
|
||||
if (event.getStateKey() === userId
|
||||
&& event.getType() === "m.room.member") {
|
||||
|
|
|
@ -19,11 +19,12 @@ import PropTypes from 'prop-types';
|
|||
import { _t } from '../../../languageHandler';
|
||||
import * as sdk from '../../../index';
|
||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
import { accessSecretStorage } from '../../../CrossSigningManager';
|
||||
import { accessSecretStorage, AccessCancelledError } from '../../../CrossSigningManager';
|
||||
|
||||
const PHASE_INTRO = 0;
|
||||
const PHASE_DONE = 1;
|
||||
const PHASE_CONFIRM_SKIP = 2;
|
||||
const PHASE_BUSY = 1;
|
||||
const PHASE_DONE = 2;
|
||||
const PHASE_CONFIRM_SKIP = 3;
|
||||
|
||||
export default class CompleteSecurity extends React.Component {
|
||||
static propTypes = {
|
||||
|
@ -39,6 +40,7 @@ export default class CompleteSecurity extends React.Component {
|
|||
// the presence of it insidicating that we're in 'verify mode'.
|
||||
// Because of the latter, it lives in the state.
|
||||
verificationRequest: null,
|
||||
backupInfo: null,
|
||||
};
|
||||
MatrixClientPeg.get().on("crypto.verification.request", this.onVerificationRequest);
|
||||
}
|
||||
|
@ -53,10 +55,16 @@ export default class CompleteSecurity extends React.Component {
|
|||
}
|
||||
|
||||
onStartClick = async () => {
|
||||
this.setState({
|
||||
phase: PHASE_BUSY,
|
||||
});
|
||||
const cli = MatrixClientPeg.get();
|
||||
const backupInfo = await cli.getKeyBackupVersion();
|
||||
this.setState({backupInfo});
|
||||
try {
|
||||
await accessSecretStorage(async () => {
|
||||
await cli.checkOwnCrossSigningTrust();
|
||||
if (backupInfo) await cli.restoreKeyBackupWithSecretStorage(backupInfo);
|
||||
});
|
||||
|
||||
if (cli.getCrossSigningId()) {
|
||||
|
@ -65,7 +73,13 @@ export default class CompleteSecurity extends React.Component {
|
|||
});
|
||||
}
|
||||
} catch (e) {
|
||||
if (!(e instanceof AccessCancelledError)) {
|
||||
console.log(e);
|
||||
}
|
||||
// this will throw if the user hits cancel, so ignore
|
||||
this.setState({
|
||||
phase: PHASE_INTRO,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,13 +169,21 @@ export default class CompleteSecurity extends React.Component {
|
|||
} else if (phase === PHASE_DONE) {
|
||||
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_verified"></span>;
|
||||
title = _t("Session verified");
|
||||
let message;
|
||||
if (this.state.backupInfo) {
|
||||
message = <p>{_t(
|
||||
"Your new session is now verified. It has access to your " +
|
||||
"encrypted messages, and other users will see it as trusted.",
|
||||
)}</p>;
|
||||
} else {
|
||||
message = <p>{_t(
|
||||
"Your new session is now verified. Other users will see it as trusted.",
|
||||
)}</p>;
|
||||
}
|
||||
body = (
|
||||
<div>
|
||||
<div className="mx_CompleteSecurity_heroIcon mx_E2EIcon_verified"></div>
|
||||
<p>{_t(
|
||||
"Your new session is now verified. It has access to your " +
|
||||
"encrypted messages, and other users will see it as trusted.",
|
||||
)}</p>
|
||||
{message}
|
||||
<div className="mx_CompleteSecurity_actionRow">
|
||||
<AccessibleButton
|
||||
kind="primary"
|
||||
|
@ -178,7 +200,7 @@ export default class CompleteSecurity extends React.Component {
|
|||
body = (
|
||||
<div>
|
||||
<p>{_t(
|
||||
"Without completing security on this device, it won’t have " +
|
||||
"Without completing security on this session, it won’t have " +
|
||||
"access to encrypted messages.",
|
||||
)}</p>
|
||||
<div className="mx_CompleteSecurity_actionRow">
|
||||
|
@ -198,6 +220,11 @@ export default class CompleteSecurity extends React.Component {
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
} else if (phase === PHASE_BUSY) {
|
||||
const Spinner = sdk.getComponent('views.elements.Spinner');
|
||||
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_warning"></span>;
|
||||
title = _t("Complete security");
|
||||
body = <Spinner />;
|
||||
} else {
|
||||
throw new Error(`Unknown phase ${phase}`);
|
||||
}
|
||||
|
|
|
@ -152,8 +152,8 @@ export default createReactClass({
|
|||
<div>
|
||||
{ _t(
|
||||
"Changing your password will reset any end-to-end encryption keys " +
|
||||
"on all of your devices, making encrypted chat history unreadable. Set up " +
|
||||
"Key Backup or export your room keys from another device before resetting your " +
|
||||
"on all of your sessions, making encrypted chat history unreadable. Set up " +
|
||||
"Key Backup or export your room keys from another session before resetting your " +
|
||||
"password.",
|
||||
) }
|
||||
</div>,
|
||||
|
@ -358,7 +358,7 @@ export default createReactClass({
|
|||
return <div>
|
||||
<p>{_t("Your password has been reset.")}</p>
|
||||
<p>{_t(
|
||||
"You have been logged out of all devices and will no longer receive " +
|
||||
"You have been logged out of all sessions and will no longer receive " +
|
||||
"push notifications. To re-enable notifications, sign in again on each " +
|
||||
"device.",
|
||||
)}</p>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
Copyright 2018, 2019 New Vector Ltd
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -62,6 +62,7 @@ export default createReactClass({
|
|||
// registration shouldn't know or care how login is done.
|
||||
onLoginClick: PropTypes.func.isRequired,
|
||||
onServerConfigChange: PropTypes.func.isRequired,
|
||||
defaultDeviceDisplayName: PropTypes.string,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
|
@ -432,15 +433,14 @@ export default createReactClass({
|
|||
// session).
|
||||
if (!this.state.formVals.password) inhibitLogin = null;
|
||||
|
||||
return this.state.matrixClient.register(
|
||||
this.state.formVals.username,
|
||||
this.state.formVals.password,
|
||||
undefined, // session id: included in the auth dict already
|
||||
auth,
|
||||
null,
|
||||
null,
|
||||
inhibitLogin,
|
||||
);
|
||||
const registerParams = {
|
||||
username: this.state.formVals.username,
|
||||
password: this.state.formVals.password,
|
||||
initial_device_display_name: this.props.defaultDeviceDisplayName,
|
||||
};
|
||||
if (auth) registerParams.auth = auth;
|
||||
if (inhibitLogin !== undefined && inhibitLogin !== null) registerParams.inhibitLogin = inhibitLogin;
|
||||
return this.state.matrixClient.registerRequest(registerParams);
|
||||
},
|
||||
|
||||
_getUIAuthInputs: function() {
|
||||
|
|
|
@ -83,7 +83,7 @@ export default class SoftLogout extends React.Component {
|
|||
onFinished: (wipeData) => {
|
||||
if (!wipeData) return;
|
||||
|
||||
console.log("Clearing data from soft-logged-out device");
|
||||
console.log("Clearing data from soft-logged-out session");
|
||||
Lifecycle.logout();
|
||||
},
|
||||
});
|
||||
|
@ -212,8 +212,8 @@ export default class SoftLogout extends React.Component {
|
|||
let introText = null; // null is translated to something area specific in this function
|
||||
if (this.state.keyBackupNeeded) {
|
||||
introText = _t(
|
||||
"Regain access to your account and recover encryption keys stored on this device. " +
|
||||
"Without them, you won’t be able to read all of your secure messages on any device.");
|
||||
"Regain access to your account and recover encryption keys stored in this session. " +
|
||||
"Without them, you won’t be able to read all of your secure messages in any session.");
|
||||
}
|
||||
|
||||
if (this.state.loginView === LOGIN_VIEW.PASSWORD) {
|
||||
|
@ -306,7 +306,7 @@ export default class SoftLogout extends React.Component {
|
|||
<p>
|
||||
{_t(
|
||||
"Warning: Your personal data (including encryption keys) is still stored " +
|
||||
"on this device. Clear it if you're finished using this device, or want to sign " +
|
||||
"in this session. Clear it if you're finished using this session, or want to sign " +
|
||||
"in to another account.",
|
||||
)}
|
||||
</p>
|
||||
|
|
|
@ -142,7 +142,7 @@ export const PasswordAuthEntry = createReactClass({
|
|||
|
||||
return (
|
||||
<div>
|
||||
<p>{ _t("To continue, please enter your password.") }</p>
|
||||
<p>{ _t("Confirm your identity by entering your account password below.") }</p>
|
||||
<form onSubmit={this._onSubmit} className="mx_InteractiveAuthEntryComponents_passwordSection">
|
||||
<Field
|
||||
id="mx_InteractiveAuthEntryComponents_password"
|
||||
|
|
|
@ -202,6 +202,7 @@ export default class PasswordLogin extends React.Component {
|
|||
value={this.state.username}
|
||||
onChange={this.onUsernameChanged}
|
||||
onBlur={this.onUsernameBlur}
|
||||
disabled={this.props.disableSubmit}
|
||||
autoFocus
|
||||
/>;
|
||||
case PasswordLogin.LOGIN_FIELD_MXID:
|
||||
|
@ -216,6 +217,7 @@ export default class PasswordLogin extends React.Component {
|
|||
value={this.state.username}
|
||||
onChange={this.onUsernameChanged}
|
||||
onBlur={this.onUsernameBlur}
|
||||
disabled={this.props.disableSubmit}
|
||||
autoFocus
|
||||
/>;
|
||||
case PasswordLogin.LOGIN_FIELD_PHONE: {
|
||||
|
@ -240,6 +242,7 @@ export default class PasswordLogin extends React.Component {
|
|||
prefix={phoneCountry}
|
||||
onChange={this.onPhoneNumberChanged}
|
||||
onBlur={this.onPhoneNumberBlur}
|
||||
disabled={this.props.disableSubmit}
|
||||
autoFocus
|
||||
/>;
|
||||
}
|
||||
|
@ -291,6 +294,7 @@ export default class PasswordLogin extends React.Component {
|
|||
element="select"
|
||||
value={this.state.loginType}
|
||||
onChange={this.onLoginTypeChange}
|
||||
disabled={this.props.disableSubmit}
|
||||
>
|
||||
<option
|
||||
key={PasswordLogin.LOGIN_FIELD_MXID}
|
||||
|
@ -330,6 +334,7 @@ export default class PasswordLogin extends React.Component {
|
|||
label={_t('Password')}
|
||||
value={this.state.password}
|
||||
onChange={this.onPasswordChanged}
|
||||
disabled={this.props.disableSubmit}
|
||||
/>
|
||||
{forgotPasswordJsx}
|
||||
<input className="mx_Login_submit"
|
||||
|
|
|
@ -39,11 +39,11 @@ export default class ConfirmWipeDeviceDialog extends React.Component {
|
|||
return (
|
||||
<BaseDialog className='mx_ConfirmWipeDeviceDialog' hasCancel={true}
|
||||
onFinished={this.props.onFinished}
|
||||
title={_t("Clear all data on this device?")}>
|
||||
title={_t("Clear all data in this session?")}>
|
||||
<div className='mx_ConfirmWipeDeviceDialog_content'>
|
||||
<p>
|
||||
{_t(
|
||||
"Clearing all data from this device is permanent. Encrypted messages will be lost " +
|
||||
"Clearing all data from this session is permanent. Encrypted messages will be lost " +
|
||||
"unless their keys have been backed up.",
|
||||
)}
|
||||
</p>
|
||||
|
|
|
@ -172,7 +172,7 @@ export default class DeviceVerifyDialog extends React.Component {
|
|||
const BaseDialog = sdk.getComponent("dialogs.BaseDialog");
|
||||
return (
|
||||
<BaseDialog
|
||||
title={_t("Verify device")}
|
||||
title={_t("Verify session")}
|
||||
onFinished={this._onCancelClick}
|
||||
>
|
||||
{body}
|
||||
|
@ -194,10 +194,7 @@ export default class DeviceVerifyDialog extends React.Component {
|
|||
{ _t("Verify by comparing a short text string.") }
|
||||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
"For maximum security, we recommend you do this in person or " +
|
||||
"use another trusted means of communication.",
|
||||
)}
|
||||
{_t("To be secure, do this in person or use a trusted way to communicate.")}
|
||||
</p>
|
||||
<DialogButtons
|
||||
primaryButton={_t('Begin Verifying')}
|
||||
|
@ -236,6 +233,7 @@ export default class DeviceVerifyDialog extends React.Component {
|
|||
sas={this._showSasEvent.sas}
|
||||
onCancel={this._onCancelClick}
|
||||
onDone={this._onSasMatchesClick}
|
||||
isSelf={MatrixClientPeg.get().getUserId() === this.props.userId}
|
||||
/>;
|
||||
}
|
||||
|
||||
|
@ -265,12 +263,12 @@ export default class DeviceVerifyDialog extends React.Component {
|
|||
|
||||
let text;
|
||||
if (MatrixClientPeg.get().getUserId() === this.props.userId) {
|
||||
text = _t("To verify that this device can be trusted, please check that the key you see " +
|
||||
text = _t("To verify that this session can be trusted, please check that the key you see " +
|
||||
"in User Settings on that device matches the key below:");
|
||||
} else {
|
||||
text = _t("To verify that this device can be trusted, please contact its owner using some other " +
|
||||
text = _t("To verify that this session can be trusted, please contact its owner using some other " +
|
||||
"means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings " +
|
||||
"for this device matches the key below:");
|
||||
"for this session matches the key below:");
|
||||
}
|
||||
|
||||
const key = FormattingUtils.formatCryptoKey(this.props.device.getFingerprint());
|
||||
|
@ -286,14 +284,14 @@ export default class DeviceVerifyDialog extends React.Component {
|
|||
</p>
|
||||
<div className="mx_DeviceVerifyDialog_cryptoSection">
|
||||
<ul>
|
||||
<li><label>{ _t("Device name") }:</label> <span>{ this.props.device.getDisplayName() }</span></li>
|
||||
<li><label>{ _t("Device ID") }:</label> <span><code>{ this.props.device.deviceId }</code></span></li>
|
||||
<li><label>{ _t("Device key") }:</label> <span><code><b>{ key }</b></code></span></li>
|
||||
<li><label>{ _t("Session name") }:</label> <span>{ this.props.device.getDisplayName() }</span></li>
|
||||
<li><label>{ _t("Session ID") }:</label> <span><code>{ this.props.device.deviceId }</code></span></li>
|
||||
<li><label>{ _t("Session key") }:</label> <span><code><b>{ key }</b></code></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>
|
||||
{ _t("If it matches, press the verify button below. " +
|
||||
"If it doesn't, then someone else is intercepting this device " +
|
||||
"If it doesn't, then someone else is intercepting this session " +
|
||||
"and you probably want to press the blacklist button instead.") }
|
||||
</p>
|
||||
</div>
|
||||
|
@ -301,7 +299,7 @@ export default class DeviceVerifyDialog extends React.Component {
|
|||
|
||||
return (
|
||||
<QuestionDialog
|
||||
title={_t("Verify device")}
|
||||
title={_t("Verify session")}
|
||||
description={body}
|
||||
button={_t("I verify that the keys match")}
|
||||
onFinished={this._onLegacyFinished}
|
||||
|
@ -321,7 +319,7 @@ export default class DeviceVerifyDialog extends React.Component {
|
|||
}
|
||||
|
||||
async function ensureDMExistsAndOpen(userId) {
|
||||
const roomId = ensureDMExists(MatrixClientPeg.get(), userId);
|
||||
const roomId = await ensureDMExists(MatrixClientPeg.get(), userId);
|
||||
// don't use andView and spinner in createRoom, together, they cause this dialog to close and reopen,
|
||||
// we causes us to loose the verifier and restart, and we end up having two verification requests
|
||||
dis.dispatch({
|
||||
|
|
|
@ -42,6 +42,7 @@ export default createReactClass({
|
|||
button: PropTypes.string,
|
||||
focus: PropTypes.bool,
|
||||
onFinished: PropTypes.func.isRequired,
|
||||
headerImage: PropTypes.string,
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
|
@ -56,9 +57,12 @@ export default createReactClass({
|
|||
render: function() {
|
||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||
return (
|
||||
<BaseDialog className="mx_ErrorDialog" onFinished={this.props.onFinished}
|
||||
title={this.props.title || _t('Error')}
|
||||
contentId='mx_Dialog_content'
|
||||
<BaseDialog
|
||||
className="mx_ErrorDialog"
|
||||
onFinished={this.props.onFinished}
|
||||
title={this.props.title || _t('Error')}
|
||||
headerImage={this.props.headerImage}
|
||||
contentId='mx_Dialog_content'
|
||||
>
|
||||
<div className="mx_Dialog_content" id='mx_Dialog_content'>
|
||||
{ this.props.description || _t('An error has occurred.') }
|
||||
|
|
|
@ -121,6 +121,8 @@ export default class IncomingSasDialog extends React.Component {
|
|||
const Spinner = sdk.getComponent("views.elements.Spinner");
|
||||
const BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
||||
|
||||
const isSelf = this.props.verifier.userId == MatrixClientPeg.get().getUserId();
|
||||
|
||||
let profile;
|
||||
if (this.state.opponentProfile) {
|
||||
profile = <div className="mx_IncomingSasDialog_opponentProfile">
|
||||
|
@ -148,20 +150,36 @@ export default class IncomingSasDialog extends React.Component {
|
|||
profile = <Spinner />;
|
||||
}
|
||||
|
||||
const userDetailText = [
|
||||
<p key="p1">{_t(
|
||||
"Verify this user to mark them as trusted. " +
|
||||
"Trusting users gives you extra peace of mind when using " +
|
||||
"end-to-end encrypted messages.",
|
||||
)}</p>,
|
||||
<p key="p2">{_t(
|
||||
// NB. Below wording adjusted to singular 'session' until we have
|
||||
// cross-signing
|
||||
"Verifying this user will mark their session as trusted, and " +
|
||||
"also mark your session as trusted to them.",
|
||||
)}</p>,
|
||||
];
|
||||
|
||||
const selfDetailText = [
|
||||
<p key="p1">{_t(
|
||||
"Verify this device to mark it as trusted. " +
|
||||
"Trusting this device gives you and other users extra peace of mind when using " +
|
||||
"end-to-end encrypted messages.",
|
||||
)}</p>,
|
||||
<p key="p2">{_t(
|
||||
"Verifying this device will mark it as trusted, and users who have verified with " +
|
||||
"you will trust this device.",
|
||||
)}</p>,
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
{profile}
|
||||
<p>{_t(
|
||||
"Verify this user to mark them as trusted. " +
|
||||
"Trusting users gives you extra peace of mind when using " +
|
||||
"end-to-end encrypted messages.",
|
||||
)}</p>
|
||||
<p>{_t(
|
||||
// NB. Below wording adjusted to singular 'device' until we have
|
||||
// cross-signing
|
||||
"Verifying this user will mark their device as trusted, and " +
|
||||
"also mark your device as trusted to them.",
|
||||
)}</p>
|
||||
{isSelf ? selfDetailText : userDetailText}
|
||||
<DialogButtons
|
||||
primaryButton={_t('Continue')}
|
||||
hasCancel={true}
|
||||
|
@ -178,6 +196,7 @@ export default class IncomingSasDialog extends React.Component {
|
|||
sas={this._showSasEvent.sas}
|
||||
onCancel={this._onCancelClick}
|
||||
onDone={this._onSasMatchesClick}
|
||||
isSelf={this.props.verifier.userId == MatrixClientPeg.get().getUserId()}
|
||||
/>;
|
||||
}
|
||||
|
||||
|
@ -227,6 +246,7 @@ export default class IncomingSasDialog extends React.Component {
|
|||
<BaseDialog
|
||||
title={_t("Incoming Verification Request")}
|
||||
onFinished={this._onFinished}
|
||||
fixedWidth={false}
|
||||
>
|
||||
{body}
|
||||
</BaseDialog>
|
||||
|
|
|
@ -301,18 +301,16 @@ export default class InviteDialog extends React.PureComponent {
|
|||
throw new Error("When using KIND_INVITE a roomId is required for an InviteDialog");
|
||||
}
|
||||
|
||||
let alreadyInvited = [];
|
||||
const alreadyInvited = new Set([MatrixClientPeg.get().getUserId(), SdkConfig.get()['welcomeUserId']]);
|
||||
if (props.roomId) {
|
||||
const room = MatrixClientPeg.get().getRoom(props.roomId);
|
||||
if (!room) throw new Error("Room ID given to InviteDialog does not look like a room");
|
||||
alreadyInvited = [
|
||||
...room.getMembersWithMembership('invite'),
|
||||
...room.getMembersWithMembership('join'),
|
||||
...room.getMembersWithMembership('ban'), // so we don't try to invite them
|
||||
].map(m => m.userId);
|
||||
room.getMembersWithMembership('invite').forEach(m => alreadyInvited.add(m.userId));
|
||||
room.getMembersWithMembership('join').forEach(m => alreadyInvited.add(m.userId));
|
||||
// add banned users, so we don't try to invite them
|
||||
room.getMembersWithMembership('ban').forEach(m => alreadyInvited.add(m.userId));
|
||||
}
|
||||
|
||||
|
||||
this.state = {
|
||||
targets: [], // array of Member objects (see interface above)
|
||||
filterText: "",
|
||||
|
@ -333,12 +331,12 @@ export default class InviteDialog extends React.PureComponent {
|
|||
this._editorRef = createRef();
|
||||
}
|
||||
|
||||
_buildRecents(excludedTargetIds: string[]): {userId: string, user: RoomMember, lastActive: number} {
|
||||
_buildRecents(excludedTargetIds: Set<string>): {userId: string, user: RoomMember, lastActive: number} {
|
||||
const rooms = DMRoomMap.shared().getUniqueRoomsWithIndividuals();
|
||||
const recents = [];
|
||||
for (const userId in rooms) {
|
||||
// Filter out user IDs that are already in the room / should be excluded
|
||||
if (excludedTargetIds.includes(userId)) {
|
||||
if (excludedTargetIds.has(userId)) {
|
||||
console.warn(`[Invite:Recents] Excluding ${userId} from recents`);
|
||||
continue;
|
||||
}
|
||||
|
@ -351,9 +349,20 @@ export default class InviteDialog extends React.PureComponent {
|
|||
continue;
|
||||
}
|
||||
|
||||
const lastEventTs = room.timeline && room.timeline.length
|
||||
? room.timeline[room.timeline.length - 1].getTs()
|
||||
: 0;
|
||||
// Find the last timestamp for a message event
|
||||
const searchTypes = ["m.room.message", "m.room.encrypted", "m.sticker"];
|
||||
const maxSearchEvents = 20; // to prevent traversing history
|
||||
let lastEventTs = 0;
|
||||
if (room.timeline && room.timeline.length) {
|
||||
for (let i = room.timeline.length - 1; i >= 0; i--) {
|
||||
const ev = room.timeline[i];
|
||||
if (searchTypes.includes(ev.getType())) {
|
||||
lastEventTs = ev.getTs();
|
||||
break;
|
||||
}
|
||||
if (room.timeline.length - i > maxSearchEvents) break;
|
||||
}
|
||||
}
|
||||
if (!lastEventTs) {
|
||||
// something weird is going on with this room
|
||||
console.warn(`[Invite:Recents] ${userId} (${room.roomId}) has a weird last timestamp: ${lastEventTs}`);
|
||||
|
@ -370,13 +379,10 @@ export default class InviteDialog extends React.PureComponent {
|
|||
return recents;
|
||||
}
|
||||
|
||||
_buildSuggestions(excludedTargetIds: string[]): {userId: string, user: RoomMember} {
|
||||
_buildSuggestions(excludedTargetIds: Set<string>): {userId: string, user: RoomMember} {
|
||||
const maxConsideredMembers = 200;
|
||||
const client = MatrixClientPeg.get();
|
||||
const excludedUserIds = [client.getUserId(), SdkConfig.get()['welcomeUserId']];
|
||||
const joinedRooms = client.getRooms()
|
||||
.filter(r => r.getMyMembership() === 'join')
|
||||
.filter(r => r.getJoinedMemberCount() <= maxConsideredMembers);
|
||||
const joinedRooms = MatrixClientPeg.get().getRooms()
|
||||
.filter(r => r.getMyMembership() === 'join' && r.getJoinedMemberCount() <= maxConsideredMembers);
|
||||
|
||||
// Generates { userId: {member, rooms[]} }
|
||||
const memberRooms = joinedRooms.reduce((members, room) => {
|
||||
|
@ -385,10 +391,10 @@ export default class InviteDialog extends React.PureComponent {
|
|||
return members; // Do nothing
|
||||
}
|
||||
|
||||
const joinedMembers = room.getJoinedMembers().filter(u => !excludedUserIds.includes(u.userId));
|
||||
const joinedMembers = room.getJoinedMembers().filter(u => !excludedTargetIds.has(u.userId));
|
||||
for (const member of joinedMembers) {
|
||||
// Filter out user IDs that are already in the room / should be excluded
|
||||
if (excludedTargetIds.includes(member.userId)) {
|
||||
if (excludedTargetIds.has(member.userId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -429,7 +435,7 @@ export default class InviteDialog extends React.PureComponent {
|
|||
// room to see who has sent a message in the last few hours, and giving them a score
|
||||
// which correlates to the freshness of their message. In theory, this results in suggestions
|
||||
// which are closer to "continue this conversation" rather than "this person exists".
|
||||
const trueJoinedRooms = client.getRooms().filter(r => r.getMyMembership() === 'join');
|
||||
const trueJoinedRooms = MatrixClientPeg.get().getRooms().filter(r => r.getMyMembership() === 'join');
|
||||
const now = (new Date()).getTime();
|
||||
const earliestAgeConsidered = now - (60 * 60 * 1000); // 1 hour ago
|
||||
const maxMessagesConsidered = 50; // so we don't iterate over a huge amount of traffic
|
||||
|
@ -445,7 +451,7 @@ export default class InviteDialog extends React.PureComponent {
|
|||
const events = room.getLiveTimeline().getEvents(); // timelines are most recent last
|
||||
for (let i = events.length - 1; i >= Math.max(0, events.length - maxMessagesConsidered); i--) {
|
||||
const ev = events[i];
|
||||
if (excludedUserIds.includes(ev.getSender())) {
|
||||
if (excludedTargetIds.has(ev.getSender())) {
|
||||
continue;
|
||||
}
|
||||
if (ev.getTs() <= earliestAgeConsidered) {
|
||||
|
@ -747,6 +753,12 @@ export default class InviteDialog extends React.PureComponent {
|
|||
};
|
||||
|
||||
_onPaste = async (e) => {
|
||||
if (this.state.filterText) {
|
||||
// if the user has already typed something, just let them
|
||||
// paste normally.
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent the text being pasted into the textarea
|
||||
e.preventDefault();
|
||||
|
||||
|
@ -937,6 +949,7 @@ export default class InviteDialog extends React.PureComponent {
|
|||
value={this.state.filterText}
|
||||
ref={this._editorRef}
|
||||
onPaste={this._onPaste}
|
||||
autoFocus={true}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
|
|
|
@ -60,7 +60,7 @@ export default createReactClass({
|
|||
const deviceInfo = r[userId][deviceId];
|
||||
|
||||
if (!deviceInfo) {
|
||||
console.warn(`No details found for device ${userId}:${deviceId}`);
|
||||
console.warn(`No details found for session ${userId}:${deviceId}`);
|
||||
|
||||
this.props.onFinished(false);
|
||||
return;
|
||||
|
@ -121,10 +121,10 @@ export default createReactClass({
|
|||
|
||||
let text;
|
||||
if (this.state.wasNewDevice) {
|
||||
text = _td("You added a new device '%(displayName)s', which is"
|
||||
text = _td("You added a new session '%(displayName)s', which is"
|
||||
+ " requesting encryption keys.");
|
||||
} else {
|
||||
text = _td("Your unverified device '%(displayName)s' is requesting"
|
||||
text = _td("Your unverified session '%(displayName)s' is requesting"
|
||||
+ " encryption keys.");
|
||||
}
|
||||
text = _t(text, {displayName: displayName});
|
||||
|
@ -159,7 +159,7 @@ export default createReactClass({
|
|||
} else {
|
||||
content = (
|
||||
<div id='mx_Dialog_content'>
|
||||
<p>{ _t('Loading device info...') }</p>
|
||||
<p>{ _t('Loading session info...') }</p>
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -138,7 +138,7 @@ export default class LogoutDialog extends React.Component {
|
|||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||
let setupButtonCaption;
|
||||
if (this.state.backupInfo) {
|
||||
setupButtonCaption = _t("Connect this device to Key Backup");
|
||||
setupButtonCaption = _t("Connect this session to Key Backup");
|
||||
} else {
|
||||
// if there's an error fetching the backup info, we'll just assume there's
|
||||
// no backup for the purpose of the button caption
|
||||
|
|
|
@ -114,7 +114,7 @@ export default createReactClass({
|
|||
>
|
||||
<div className="mx_Dialog_content">
|
||||
<p>
|
||||
{ _t('This will allow you to return to your account after signing out, and sign in on other devices.') }
|
||||
{ _t('This will allow you to return to your account after signing out, and sign in on other sessions.') }
|
||||
</p>
|
||||
<ChangePassword
|
||||
className="mx_SetPasswordDialog_change_password"
|
||||
|
|
|
@ -132,8 +132,8 @@ export default createReactClass({
|
|||
if (SettingsStore.getValue("blacklistUnverifiedDevices", this.props.room.roomId)) {
|
||||
warning = (
|
||||
<h4>
|
||||
{ _t("You are currently blacklisting unverified devices; to send " +
|
||||
"messages to these devices you must verify them.") }
|
||||
{ _t("You are currently blacklisting unverified sessions; to send " +
|
||||
"messages to these sessions you must verify them.") }
|
||||
</h4>
|
||||
);
|
||||
} else {
|
||||
|
@ -141,7 +141,7 @@ export default createReactClass({
|
|||
<div>
|
||||
<p>
|
||||
{ _t("We recommend you go through the verification process " +
|
||||
"for each device to confirm they belong to their legitimate owner, " +
|
||||
"for each session to confirm they belong to their legitimate owner, " +
|
||||
"but you can resend the message without verifying if you prefer.") }
|
||||
</p>
|
||||
</div>
|
||||
|
@ -165,15 +165,15 @@ export default createReactClass({
|
|||
return (
|
||||
<BaseDialog className='mx_UnknownDeviceDialog'
|
||||
onFinished={this.props.onFinished}
|
||||
title={_t('Room contains unknown devices')}
|
||||
title={_t('Room contains unknown sessions')}
|
||||
contentId='mx_Dialog_content'
|
||||
>
|
||||
<GeminiScrollbarWrapper autoshow={false} className="mx_Dialog_content" id='mx_Dialog_content'>
|
||||
<h4>
|
||||
{ _t('"%(RoomName)s" contains devices that you haven\'t seen before.', {RoomName: this.props.room.name}) }
|
||||
{ _t('"%(RoomName)s" contains sessions that you haven\'t seen before.', {RoomName: this.props.room.name}) }
|
||||
</h4>
|
||||
{ warning }
|
||||
{ _t("Unknown devices") }:
|
||||
{ _t("Unknown sessions") }:
|
||||
|
||||
<UnknownDeviceList devices={this.props.devices} />
|
||||
</GeminiScrollbarWrapper>
|
||||
|
|
|
@ -248,7 +248,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
|
|||
} else if (this.state.restoreError) {
|
||||
if (this.state.restoreError.errcode === MatrixClient.RESTORE_BACKUP_ERROR_BAD_KEY) {
|
||||
if (this.state.restoreType === RESTORE_TYPE_RECOVERYKEY) {
|
||||
title = _t("Recovery Key Mismatch");
|
||||
title = _t("Recovery key mismatch");
|
||||
content = <div>
|
||||
<p>{_t(
|
||||
"Backup could not be decrypted with this key: " +
|
||||
|
@ -256,7 +256,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
|
|||
)}</p>
|
||||
</div>;
|
||||
} else {
|
||||
title = _t("Incorrect Recovery Passphrase");
|
||||
title = _t("Incorrect recovery passphrase");
|
||||
content = <div>
|
||||
<p>{_t(
|
||||
"Backup could not be decrypted with this passphrase: " +
|
||||
|
@ -273,7 +273,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
|
|||
content = _t("No backup found!");
|
||||
} else if (this.state.recoverInfo) {
|
||||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||
title = _t("Backup Restored");
|
||||
title = _t("Backup restored");
|
||||
let failedToDecrypt;
|
||||
if (this.state.recoverInfo.total > this.state.recoverInfo.imported) {
|
||||
failedToDecrypt = <p>{_t(
|
||||
|
@ -293,7 +293,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
|
|||
} else if (backupHasPassphrase && !this.state.forceRecoveryKey) {
|
||||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
title = _t("Enter Recovery Passphrase");
|
||||
title = _t("Enter recovery passphrase");
|
||||
content = <div>
|
||||
<p>{_t(
|
||||
"<b>Warning</b>: you should only set up key backup " +
|
||||
|
@ -340,7 +340,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
|
|||
})}
|
||||
</div>;
|
||||
} else {
|
||||
title = _t("Enter Recovery Key");
|
||||
title = _t("Enter recovery key");
|
||||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
|||
)}</p>
|
||||
<p>{_t(
|
||||
"Access your secure message history and your cross-signing " +
|
||||
"identity for verifying other devices by entering your passphrase.",
|
||||
"identity for verifying other sessions by entering your passphrase.",
|
||||
)}</p>
|
||||
|
||||
<div className="mx_AccessSecretStorageDialog_primaryContainer">
|
||||
|
@ -218,7 +218,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
|||
)}</p>
|
||||
<p>{_t(
|
||||
"Access your secure message history and your cross-signing " +
|
||||
"identity for verifying other devices by entering your recovery key.",
|
||||
"identity for verifying other sessions by entering your recovery key.",
|
||||
)}</p>
|
||||
|
||||
<div className="mx_AccessSecretStorageDialog_primaryContainer">
|
||||
|
|
|
@ -51,6 +51,6 @@ export default class VerificationQRCode extends React.PureComponent {
|
|||
|
||||
const uri = `https://matrix.to/#/${this.props.keyholderUserId}?${qs.stringify(query)}`;
|
||||
|
||||
return <QRCode value={uri} size={256} logoWidth={48} logo={require("../../../../../res/img/matrix-m.svg")} />;
|
||||
return <QRCode value={uri} size={512} logoWidth={64} logo={require("../../../../../res/img/matrix-m.svg")} />;
|
||||
}
|
||||
}
|
||||
|
|
58
src/components/views/messages/EncryptionEvent.js
Normal file
58
src/components/views/messages/EncryptionEvent.js
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
|
||||
export default class EncryptionEvent extends React.Component {
|
||||
render() {
|
||||
const {mxEvent} = this.props;
|
||||
|
||||
let body;
|
||||
let classes = "mx_EventTile_bubble mx_cryptoEvent mx_cryptoEvent_icon";
|
||||
if (
|
||||
mxEvent.getContent().algorithm === 'm.megolm.v1.aes-sha2' &&
|
||||
MatrixClientPeg.get().isRoomEncrypted(mxEvent.getRoomId())
|
||||
) {
|
||||
body = <div>
|
||||
<div className="mx_cryptoEvent_title">{_t("Encryption enabled")}</div>
|
||||
<div className="mx_cryptoEvent_subtitle">
|
||||
{_t(
|
||||
"Messages in this room are end-to-end encrypted. " +
|
||||
"Learn more & verify this user in their user profile.",
|
||||
)}
|
||||
</div>
|
||||
</div>;
|
||||
} else {
|
||||
body = <div>
|
||||
<div className="mx_cryptoEvent_title">{_t("Encryption not enabled")}</div>
|
||||
<div className="mx_cryptoEvent_subtitle">{_t("The encryption used by this room isn't supported.")}</div>
|
||||
</div>;
|
||||
classes += " mx_cryptoEvent_icon_warning";
|
||||
}
|
||||
|
||||
return (<div className={classes}>
|
||||
{body}
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
|
||||
EncryptionEvent.propTypes = {
|
||||
/* the MatrixEvent to show */
|
||||
mxEvent: PropTypes.object.isRequired,
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -94,12 +94,12 @@ export default class MKeyVerificationConclusion extends React.Component {
|
|||
|
||||
if (title) {
|
||||
const subtitle = userLabelForEventRoom(request.otherUserId, mxEvent.getRoomId());
|
||||
const classes = classNames("mx_EventTile_bubble", "mx_KeyVerification", "mx_KeyVerification_icon", {
|
||||
mx_KeyVerification_icon_verified: request.done,
|
||||
const classes = classNames("mx_EventTile_bubble", "mx_cryptoEvent", "mx_cryptoEvent_icon", {
|
||||
mx_cryptoEvent_icon_verified: request.done,
|
||||
});
|
||||
return (<div className={classes}>
|
||||
<div className="mx_KeyVerification_title">{title}</div>
|
||||
<div className="mx_KeyVerification_subtitle">{subtitle}</div>
|
||||
<div className="mx_cryptoEvent_title">{title}</div>
|
||||
<div className="mx_cryptoEvent_subtitle">{subtitle}</div>
|
||||
</div>);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -45,10 +45,11 @@ export default class MKeyVerificationRequest extends React.Component {
|
|||
|
||||
_openRequest = () => {
|
||||
const {verificationRequest} = this.props.mxEvent;
|
||||
const member = MatrixClientPeg.get().getUser(verificationRequest.otherUserId);
|
||||
dis.dispatch({
|
||||
action: "set_right_panel_phase",
|
||||
phase: RIGHT_PANEL_PHASES.EncryptionPanel,
|
||||
refireParams: {verificationRequest},
|
||||
refireParams: {verificationRequest, member},
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -124,30 +125,30 @@ export default class MKeyVerificationRequest extends React.Component {
|
|||
} else {
|
||||
stateLabel = this._cancelledLabel(request.cancellingUserId);
|
||||
}
|
||||
stateNode = (<div className="mx_KeyVerification_state">{stateLabel}</div>);
|
||||
stateNode = (<div className="mx_cryptoEvent_state">{stateLabel}</div>);
|
||||
}
|
||||
|
||||
if (!request.initiatedByMe) {
|
||||
const name = getNameForEventRoom(request.requestingUserId, mxEvent.getRoomId());
|
||||
title = (<div className="mx_KeyVerification_title">{
|
||||
title = (<div className="mx_cryptoEvent_title">{
|
||||
_t("%(name)s wants to verify", {name})}</div>);
|
||||
subtitle = (<div className="mx_KeyVerification_subtitle">{
|
||||
subtitle = (<div className="mx_cryptoEvent_subtitle">{
|
||||
userLabelForEventRoom(request.requestingUserId, mxEvent.getRoomId())}</div>);
|
||||
if (request.requested && !request.observeOnly) {
|
||||
stateNode = (<div className="mx_KeyVerification_buttons">
|
||||
stateNode = (<div className="mx_cryptoEvent_buttons">
|
||||
<FormButton kind="danger" onClick={this._onRejectClicked} label={_t("Decline")} />
|
||||
<FormButton onClick={this._onAcceptClicked} label={_t("Accept")} />
|
||||
</div>);
|
||||
}
|
||||
} else { // request sent by us
|
||||
title = (<div className="mx_KeyVerification_title">{
|
||||
title = (<div className="mx_cryptoEvent_title">{
|
||||
_t("You sent a verification request")}</div>);
|
||||
subtitle = (<div className="mx_KeyVerification_subtitle">{
|
||||
subtitle = (<div className="mx_cryptoEvent_subtitle">{
|
||||
userLabelForEventRoom(request.receivingUserId, mxEvent.getRoomId())}</div>);
|
||||
}
|
||||
|
||||
if (title) {
|
||||
return (<div className="mx_EventTile_bubble mx_KeyVerification mx_KeyVerification_icon">
|
||||
return (<div className="mx_EventTile_bubble mx_cryptoEvent mx_cryptoEvent_icon">
|
||||
{title}
|
||||
{subtitle}
|
||||
{stateNode}
|
||||
|
|
|
@ -32,6 +32,13 @@ export default class ViewSourceEvent extends React.PureComponent {
|
|||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const {mxEvent} = this.props;
|
||||
if (mxEvent.isBeingDecrypted()) {
|
||||
mxEvent.once("Event.decrypted", () => this.forceUpdate());
|
||||
}
|
||||
}
|
||||
|
||||
onToggle = (ev) => {
|
||||
ev.preventDefault();
|
||||
const { expanded } = this.state;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -14,18 +14,58 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import * as sdk from '../../../index';
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import * as sdk from "../../../index";
|
||||
import {_t} from "../../../languageHandler";
|
||||
|
||||
export default class EncryptionInfo extends React.PureComponent {
|
||||
render() {
|
||||
export const PendingActionSpinner = ({text}) => {
|
||||
const Spinner = sdk.getComponent('elements.Spinner');
|
||||
return <div className="mx_EncryptionInfo_spinner">
|
||||
<Spinner />
|
||||
{ text }
|
||||
</div>;
|
||||
};
|
||||
|
||||
const EncryptionInfo = ({pending, member, onStartVerification}) => {
|
||||
let content;
|
||||
if (pending) {
|
||||
const text = _t("Waiting for %(displayName)s to accept…", {
|
||||
displayName: member.displayName || member.name || member.userId,
|
||||
});
|
||||
content = <PendingActionSpinner text={text} />;
|
||||
} else {
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
return (<div className="mx_UserInfo"><div className="mx_UserInfo_container">
|
||||
<h3>{_t("Verify User")}</h3>
|
||||
<p>{_t("For extra security, verify this user by checking a one-time code on both of your devices.")}</p>
|
||||
<p>{_t("For maximum security, do this in person.")}</p>
|
||||
<AccessibleButton kind="primary" onClick={this.props.onStartVerification}>{_t("Start Verification")}</AccessibleButton>
|
||||
</div></div>);
|
||||
content = (
|
||||
<AccessibleButton kind="primary" className="mx_UserInfo_wideButton" onClick={onStartVerification}>
|
||||
{_t("Start Verification")}
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return <React.Fragment>
|
||||
<div className="mx_UserInfo_container">
|
||||
<h3>{_t("Encryption")}</h3>
|
||||
<div>
|
||||
<p>{_t("Messages in this room are end-to-end encrypted.")}</p>
|
||||
<p>{_t("Your messages are secured and only you and the recipient have the unique keys to unlock them.")}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx_UserInfo_container">
|
||||
<h3>{_t("Verify User")}</h3>
|
||||
<div>
|
||||
<p>{_t("For extra security, verify this user by checking a one-time code on both of your devices.")}</p>
|
||||
<p>{_t("To be secure, do this in person or use a trusted way to communicate.")}</p>
|
||||
{ content }
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>;
|
||||
};
|
||||
EncryptionInfo.propTypes = {
|
||||
member: PropTypes.object.isRequired,
|
||||
onStartVerification: PropTypes.func.isRequired,
|
||||
request: PropTypes.object,
|
||||
};
|
||||
|
||||
export default EncryptionInfo;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -14,35 +14,81 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, {useCallback, useEffect, useState} from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import EncryptionInfo from "./EncryptionInfo";
|
||||
import VerificationPanel from "./VerificationPanel";
|
||||
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||
import {ensureDMExists} from "../../../createRoom";
|
||||
import {useEventEmitter} from "../../../hooks/useEventEmitter";
|
||||
import Modal from "../../../Modal";
|
||||
import {PHASE_REQUESTED} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
|
||||
import * as sdk from "../../../index";
|
||||
import {_t} from "../../../languageHandler";
|
||||
|
||||
export default class EncryptionPanel extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
// cancellation codes which constitute a key mismatch
|
||||
const MISMATCHES = ["m.key_mismatch", "m.user_error", "m.mismatched_sas"];
|
||||
|
||||
render() {
|
||||
const request = this.props.verificationRequest || this.state.verificationRequest;
|
||||
const {member} = this.props;
|
||||
if (request) {
|
||||
return <VerificationPanel request={request} key={request.channel.transactionId} />;
|
||||
} else if (member) {
|
||||
return <EncryptionInfo onStartVerification={this._onStartVerification} member={member} />;
|
||||
} else {
|
||||
return <p>Not a member nor request, not sure what to render</p>;
|
||||
const EncryptionPanel = ({verificationRequest, member, onClose}) => {
|
||||
const [request, setRequest] = useState(verificationRequest);
|
||||
useEffect(() => {
|
||||
setRequest(verificationRequest);
|
||||
}, [verificationRequest]);
|
||||
|
||||
const [phase, setPhase] = useState(request && request.phase);
|
||||
const changeHandler = useCallback(() => {
|
||||
// handle transitions -> cancelled for mismatches which fire a modal instead of showing a card
|
||||
if (request && request.cancelled && MISMATCHES.includes(request.cancellationCode)) {
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createTrackedDialog("Verification failed", "insecure", ErrorDialog, {
|
||||
headerImage: require("../../../../res/img/e2e/warning.svg"),
|
||||
title: _t("Your messages are not secure"),
|
||||
description: <div>
|
||||
{_t("One of the following may be compromised:")}
|
||||
<ul>
|
||||
<li>{_t("Your homeserver")}</li>
|
||||
<li>{_t("The homeserver the user you’re verifying is connected to")}</li>
|
||||
<li>{_t("Yours, or the other users’ internet connection")}</li>
|
||||
<li>{_t("Yours, or the other users’ session")}</li>
|
||||
</ul>
|
||||
</div>,
|
||||
onFinished: onClose,
|
||||
});
|
||||
return; // don't update phase here as we will be transitioning away from this view shortly
|
||||
}
|
||||
}
|
||||
|
||||
_onStartVerification = async () => {
|
||||
const client = MatrixClientPeg.get();
|
||||
const {member} = this.props;
|
||||
const roomId = await ensureDMExists(client, member.userId);
|
||||
const verificationRequest = await client.requestVerificationDM(member.userId, roomId);
|
||||
this.setState({verificationRequest});
|
||||
};
|
||||
}
|
||||
if (request) {
|
||||
setPhase(request.phase);
|
||||
}
|
||||
}, [onClose, request]);
|
||||
useEventEmitter(request, "change", changeHandler);
|
||||
|
||||
const onStartVerification = useCallback(async () => {
|
||||
const cli = MatrixClientPeg.get();
|
||||
const roomId = await ensureDMExists(cli, member.userId);
|
||||
const verificationRequest = await cli.requestVerificationDM(member.userId, roomId);
|
||||
setRequest(verificationRequest);
|
||||
}, [member.userId]);
|
||||
|
||||
const requested = request && (phase === PHASE_REQUESTED || phase === undefined);
|
||||
if (!request || requested) {
|
||||
return <EncryptionInfo onStartVerification={onStartVerification} member={member} pending={requested} />;
|
||||
} else {
|
||||
return (
|
||||
<VerificationPanel
|
||||
onClose={onClose}
|
||||
member={member}
|
||||
request={request}
|
||||
key={request.channel.transactionId}
|
||||
phase={phase} />
|
||||
);
|
||||
}
|
||||
};
|
||||
EncryptionPanel.propTypes = {
|
||||
member: PropTypes.object.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
verificationRequest: PropTypes.object,
|
||||
};
|
||||
|
||||
export default EncryptionPanel;
|
||||
|
|
|
@ -3,7 +3,7 @@ Copyright 2015, 2016 OpenMarket Ltd
|
|||
Copyright 2017 Vector Creations Ltd
|
||||
Copyright 2017 New Vector Ltd
|
||||
Copyright 2018 New Vector Ltd
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -23,7 +23,6 @@ import { _t } from '../../../languageHandler';
|
|||
import HeaderButton from './HeaderButton';
|
||||
import HeaderButtons, {HEADER_KIND_ROOM} from './HeaderButtons';
|
||||
import {RIGHT_PANEL_PHASES} from "../../../stores/RightPanelStorePhases";
|
||||
import RightPanelStore from "../../../stores/RightPanelStore";
|
||||
|
||||
const MEMBER_PHASES = [
|
||||
RIGHT_PANEL_PHASES.RoomMemberList,
|
||||
|
@ -60,7 +59,8 @@ export default class RoomHeaderButtons extends HeaderButtons {
|
|||
_onMembersClicked() {
|
||||
if (this.state.phase === RIGHT_PANEL_PHASES.RoomMemberInfo) {
|
||||
// send the active phase to trigger a toggle
|
||||
this.setPhase(RIGHT_PANEL_PHASES.RoomMemberInfo, RightPanelStore.getSharedInstance().roomPanelPhaseParams);
|
||||
// XXX: we should pass refireParams here but then it won't collapse as we desire it to
|
||||
this.setPhase(RIGHT_PANEL_PHASES.RoomMemberInfo);
|
||||
} else {
|
||||
// This toggles for us, if needed
|
||||
this.setPhase(RIGHT_PANEL_PHASES.RoomMemberList);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017, 2018 Vector Creations Ltd
|
||||
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -41,6 +41,7 @@ import {useEventEmitter} from "../../../hooks/useEventEmitter";
|
|||
import {textualPowerLevel} from '../../../Roles';
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import {RIGHT_PANEL_PHASES} from "../../../stores/RightPanelStorePhases";
|
||||
import EncryptionPanel from "./EncryptionPanel";
|
||||
|
||||
const _disambiguateDevices = (devices) => {
|
||||
const names = Object.create(null);
|
||||
|
@ -59,14 +60,16 @@ const _disambiguateDevices = (devices) => {
|
|||
}
|
||||
};
|
||||
|
||||
const _getE2EStatus = (cli, userId, devices) => {
|
||||
export const getE2EStatus = (cli, userId, devices) => {
|
||||
if (!SettingsStore.isFeatureEnabled("feature_cross_signing")) {
|
||||
const hasUnverifiedDevice = devices.some((device) => device.isUnverified());
|
||||
return hasUnverifiedDevice ? "warning" : "verified";
|
||||
}
|
||||
const isMe = userId === cli.getUserId();
|
||||
const userVerified = cli.checkUserTrust(userId).isCrossSigningVerified();
|
||||
const allDevicesVerified = devices.every(device => {
|
||||
if (!userVerified) return "normal";
|
||||
|
||||
const anyDeviceUnverified = devices.some(device => {
|
||||
const { deviceId } = device;
|
||||
// For your own devices, we use the stricter check of cross-signing
|
||||
// verification to encourage everyone to trust their own devices via
|
||||
|
@ -74,12 +77,9 @@ const _getE2EStatus = (cli, userId, devices) => {
|
|||
// For other people's devices, the more general verified check that
|
||||
// includes locally verified devices can be used.
|
||||
const deviceTrust = cli.checkDeviceTrust(userId, deviceId);
|
||||
return isMe ? deviceTrust.isCrossSigningVerified() : deviceTrust.isVerified();
|
||||
return isMe ? !deviceTrust.isCrossSigningVerified() : !deviceTrust.isVerified();
|
||||
});
|
||||
if (allDevicesVerified) {
|
||||
return userVerified ? "verified" : "normal";
|
||||
}
|
||||
return "warning";
|
||||
return anyDeviceUnverified ? "warning" : "verified";
|
||||
};
|
||||
|
||||
async function openDMForUser(matrixClient, userId) {
|
||||
|
@ -155,6 +155,7 @@ function DeviceItem({userId, device}) {
|
|||
const cli = useContext(MatrixClientContext);
|
||||
const isMe = userId === cli.getUserId();
|
||||
const deviceTrust = cli.checkDeviceTrust(userId, device.deviceId);
|
||||
const userTrust = cli.checkUserTrust(userId);
|
||||
// For your own devices, we use the stricter check of cross-signing
|
||||
// verification to encourage everyone to trust their own devices via
|
||||
// cross-signing so that other users can then safely trust you.
|
||||
|
@ -169,8 +170,9 @@ function DeviceItem({userId, device}) {
|
|||
mx_UserInfo_device_unverified: !isVerified,
|
||||
});
|
||||
const iconClasses = classNames("mx_E2EIcon", {
|
||||
mx_E2EIcon_normal: !userTrust.isVerified(),
|
||||
mx_E2EIcon_verified: isVerified,
|
||||
mx_E2EIcon_warning: !isVerified,
|
||||
mx_E2EIcon_warning: userTrust.isVerified() && !isVerified,
|
||||
});
|
||||
|
||||
const onDeviceClick = () => {
|
||||
|
@ -182,7 +184,8 @@ function DeviceItem({userId, device}) {
|
|||
const deviceName = device.ambiguous ?
|
||||
(device.getDisplayName() ? device.getDisplayName() : "") + " (" + device.deviceId + ")" :
|
||||
device.getDisplayName();
|
||||
const trustedLabel = isVerified ? _t("Trusted") : _t("Not trusted");
|
||||
let trustedLabel = null;
|
||||
if (userTrust.isVerified()) trustedLabel = isVerified ? _t("Trusted") : _t("Not trusted");
|
||||
return (
|
||||
<AccessibleButton
|
||||
className={classes}
|
||||
|
@ -199,6 +202,7 @@ function DeviceItem({userId, device}) {
|
|||
function DevicesSection({devices, userId, loading}) {
|
||||
const Spinner = sdk.getComponent("elements.Spinner");
|
||||
const cli = useContext(MatrixClientContext);
|
||||
const userTrust = cli.checkUserTrust(userId);
|
||||
|
||||
const [isExpanded, setExpanded] = useState(false);
|
||||
|
||||
|
@ -207,43 +211,61 @@ function DevicesSection({devices, userId, loading}) {
|
|||
return <Spinner />;
|
||||
}
|
||||
if (devices === null) {
|
||||
return _t("Unable to load device list");
|
||||
return _t("Unable to load session list");
|
||||
}
|
||||
const isMe = userId === cli.getUserId();
|
||||
const deviceTrusts = devices.map(d => cli.checkDeviceTrust(userId, d.deviceId));
|
||||
|
||||
let expandSectionDevices = [];
|
||||
const unverifiedDevices = [];
|
||||
const verifiedDevices = [];
|
||||
|
||||
for (let i = 0; i < devices.length; ++i) {
|
||||
const device = devices[i];
|
||||
const deviceTrust = deviceTrusts[i];
|
||||
// For your own devices, we use the stricter check of cross-signing
|
||||
// verification to encourage everyone to trust their own devices via
|
||||
// cross-signing so that other users can then safely trust you.
|
||||
// For other people's devices, the more general verified check that
|
||||
// includes locally verified devices can be used.
|
||||
const isVerified = (isMe && SettingsStore.isFeatureEnabled("feature_cross_signing")) ?
|
||||
deviceTrust.isCrossSigningVerified() :
|
||||
deviceTrust.isVerified();
|
||||
let expandCountCaption;
|
||||
let expandHideCaption;
|
||||
let expandIconClasses = "mx_E2EIcon";
|
||||
|
||||
if (isVerified) {
|
||||
verifiedDevices.push(device);
|
||||
} else {
|
||||
unverifiedDevices.push(device);
|
||||
if (userTrust.isVerified()) {
|
||||
for (let i = 0; i < devices.length; ++i) {
|
||||
const device = devices[i];
|
||||
const deviceTrust = deviceTrusts[i];
|
||||
// For your own devices, we use the stricter check of cross-signing
|
||||
// verification to encourage everyone to trust their own devices via
|
||||
// cross-signing so that other users can then safely trust you.
|
||||
// For other people's devices, the more general verified check that
|
||||
// includes locally verified devices can be used.
|
||||
const isVerified = (isMe && SettingsStore.isFeatureEnabled("feature_cross_signing")) ?
|
||||
deviceTrust.isCrossSigningVerified() :
|
||||
deviceTrust.isVerified();
|
||||
|
||||
if (isVerified) {
|
||||
expandSectionDevices.push(device);
|
||||
} else {
|
||||
unverifiedDevices.push(device);
|
||||
}
|
||||
}
|
||||
expandCountCaption = _t("%(count)s verified sessions", {count: expandSectionDevices.length});
|
||||
expandHideCaption = _t("Hide verified sessions");
|
||||
expandIconClasses += " mx_E2EIcon_verified";
|
||||
} else {
|
||||
expandSectionDevices = devices;
|
||||
expandCountCaption = _t("%(count)s sessions", {count: devices.length});
|
||||
expandHideCaption = _t("Hide sessions");
|
||||
expandIconClasses += " mx_E2EIcon_normal";
|
||||
}
|
||||
|
||||
let expandButton;
|
||||
if (verifiedDevices.length) {
|
||||
if (expandSectionDevices.length) {
|
||||
if (isExpanded) {
|
||||
expandButton = (<AccessibleButton className="mx_UserInfo_expand" onClick={() => setExpanded(false)}>
|
||||
<div>{_t("Hide verified sessions")}</div>
|
||||
expandButton = (<AccessibleButton className="mx_UserInfo_expand mx_linkButton"
|
||||
onClick={() => setExpanded(false)}
|
||||
>
|
||||
<div>{expandHideCaption}</div>
|
||||
</AccessibleButton>);
|
||||
} else {
|
||||
expandButton = (<AccessibleButton className="mx_UserInfo_expand" onClick={() => setExpanded(true)}>
|
||||
<div className="mx_E2EIcon mx_E2EIcon_verified" />
|
||||
<div>{_t("%(count)s verified sessions", {count: verifiedDevices.length})}</div>
|
||||
expandButton = (<AccessibleButton className="mx_UserInfo_expand mx_linkButton"
|
||||
onClick={() => setExpanded(true)}
|
||||
>
|
||||
<div className={expandIconClasses} />
|
||||
<div>{expandCountCaption}</div>
|
||||
</AccessibleButton>);
|
||||
}
|
||||
}
|
||||
|
@ -253,7 +275,7 @@ function DevicesSection({devices, userId, loading}) {
|
|||
});
|
||||
if (isExpanded) {
|
||||
const keyStart = unverifiedDevices.length;
|
||||
deviceList = deviceList.concat(verifiedDevices.map((device, i) => {
|
||||
deviceList = deviceList.concat(expandSectionDevices.map((device, i) => {
|
||||
return (<DeviceItem key={i + keyStart} userId={userId} device={device} />);
|
||||
}));
|
||||
}
|
||||
|
@ -1053,33 +1075,95 @@ const PowerLevelEditor = ({user, room, roomPermissions, onFinished}) => {
|
|||
);
|
||||
};
|
||||
|
||||
const UserInfo = ({user, groupId, roomId, onClose}) => {
|
||||
export const useDevices = (userId) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
|
||||
// Load room if we are given a room id and memoize it
|
||||
const room = useMemo(() => roomId ? cli.getRoom(roomId) : null, [cli, roomId]);
|
||||
// fetch latest room member if we have a room, so we don't show historical information, falling back to user
|
||||
const member = useMemo(() => room ? (room.getMember(user.userId) || user) : user, [room, user]);
|
||||
// undefined means yet to be loaded, null means failed to load, otherwise list of devices
|
||||
const [devices, setDevices] = useState(undefined);
|
||||
// Download device lists
|
||||
useEffect(() => {
|
||||
setDevices(undefined);
|
||||
|
||||
// only display the devices list if our client supports E2E
|
||||
const _enableDevices = cli.isCryptoEnabled();
|
||||
let cancelled = false;
|
||||
|
||||
async function _downloadDeviceList() {
|
||||
try {
|
||||
await cli.downloadKeys([userId], true);
|
||||
const devices = await cli.getStoredDevicesForUser(userId);
|
||||
|
||||
if (cancelled) {
|
||||
// we got cancelled - presumably a different user now
|
||||
return;
|
||||
}
|
||||
|
||||
_disambiguateDevices(devices);
|
||||
setDevices(devices);
|
||||
} catch (err) {
|
||||
setDevices(null);
|
||||
}
|
||||
}
|
||||
_downloadDeviceList();
|
||||
|
||||
// Handle being unmounted
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [cli, userId]);
|
||||
|
||||
// Listen to changes
|
||||
useEffect(() => {
|
||||
let cancel = false;
|
||||
const updateDevices = async () => {
|
||||
const newDevices = await cli.getStoredDevicesForUser(userId);
|
||||
if (cancel) return;
|
||||
setDevices(newDevices);
|
||||
};
|
||||
const onDevicesUpdated = (users) => {
|
||||
if (!users.includes(userId)) return;
|
||||
updateDevices();
|
||||
};
|
||||
const onDeviceVerificationChanged = (_userId, device) => {
|
||||
if (_userId !== userId) return;
|
||||
updateDevices();
|
||||
};
|
||||
const onUserTrustStatusChanged = (_userId, trustStatus) => {
|
||||
if (_userId !== userId) return;
|
||||
updateDevices();
|
||||
};
|
||||
cli.on("crypto.devicesUpdated", onDevicesUpdated);
|
||||
cli.on("deviceVerificationChanged", onDeviceVerificationChanged);
|
||||
cli.on("userTrustStatusChanged", onUserTrustStatusChanged);
|
||||
// Handle being unmounted
|
||||
return () => {
|
||||
cancel = true;
|
||||
cli.removeListener("crypto.devicesUpdated", onDevicesUpdated);
|
||||
cli.removeListener("deviceVerificationChanged", onDeviceVerificationChanged);
|
||||
cli.removeListener("userTrustStatusChanged", onUserTrustStatusChanged);
|
||||
};
|
||||
}, [cli, userId]);
|
||||
|
||||
return devices;
|
||||
};
|
||||
|
||||
const BasicUserInfo = ({room, member, groupId, devices, isRoomEncrypted}) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
|
||||
const powerLevels = useRoomPowerLevels(cli, room);
|
||||
// Load whether or not we are a Synapse Admin
|
||||
const isSynapseAdmin = useIsSynapseAdmin(cli);
|
||||
|
||||
// Check whether the user is ignored
|
||||
const [isIgnored, setIsIgnored] = useState(cli.isUserIgnored(user.userId));
|
||||
const [isIgnored, setIsIgnored] = useState(cli.isUserIgnored(member.userId));
|
||||
// Recheck if the user or client changes
|
||||
useEffect(() => {
|
||||
setIsIgnored(cli.isUserIgnored(user.userId));
|
||||
}, [cli, user.userId]);
|
||||
setIsIgnored(cli.isUserIgnored(member.userId));
|
||||
}, [cli, member.userId]);
|
||||
// Recheck also if we receive new accountData m.ignored_user_list
|
||||
const accountDataHandler = useCallback((ev) => {
|
||||
if (ev.getType() === "m.ignored_user_list") {
|
||||
setIsIgnored(cli.isUserIgnored(user.userId));
|
||||
setIsIgnored(cli.isUserIgnored(member.userId));
|
||||
}
|
||||
}, [cli, user.userId]);
|
||||
}, [cli, member.userId]);
|
||||
useEventEmitter(cli, "accountData", accountDataHandler);
|
||||
|
||||
// Count of how many operations are currently in progress, if > 0 then show a Spinner
|
||||
|
@ -1110,7 +1194,7 @@ const UserInfo = ({user, groupId, roomId, onClose}) => {
|
|||
const [accepted] = await finished;
|
||||
if (!accepted) return;
|
||||
try {
|
||||
await cli.deactivateSynapseUser(user.userId);
|
||||
await cli.deactivateSynapseUser(member.userId);
|
||||
} catch (err) {
|
||||
console.error("Failed to deactivate user");
|
||||
console.error(err);
|
||||
|
@ -1121,21 +1205,7 @@ const UserInfo = ({user, groupId, roomId, onClose}) => {
|
|||
description: ((err && err.message) ? err.message : _t("Operation failed")),
|
||||
});
|
||||
}
|
||||
}, [cli, user.userId]);
|
||||
|
||||
const onMemberAvatarClick = useCallback(() => {
|
||||
const avatarUrl = member.getMxcAvatarUrl ? member.getMxcAvatarUrl() : member.avatarUrl;
|
||||
if (!avatarUrl) return;
|
||||
|
||||
const httpUrl = cli.mxcUrlToHttp(avatarUrl);
|
||||
const ImageView = sdk.getComponent("elements.ImageView");
|
||||
const params = {
|
||||
src: httpUrl,
|
||||
name: member.name,
|
||||
};
|
||||
|
||||
Modal.createDialog(ImageView, params, "mx_Dialog_lightbox");
|
||||
}, [cli, member]);
|
||||
}, [cli, member.userId]);
|
||||
|
||||
let synapseDeactivateButton;
|
||||
let spinner;
|
||||
|
@ -1143,7 +1213,7 @@ const UserInfo = ({user, groupId, roomId, onClose}) => {
|
|||
// We don't need a perfect check here, just something to pass as "probably not our homeserver". If
|
||||
// someone does figure out how to bypass this check the worst that happens is an error.
|
||||
// FIXME this should be using cli instead of MatrixClientPeg.matrixClient
|
||||
if (isSynapseAdmin && user.userId.endsWith(`:${MatrixClientPeg.getHomeserverName()}`)) {
|
||||
if (isSynapseAdmin && member.userId.endsWith(`:${MatrixClientPeg.getHomeserverName()}`)) {
|
||||
synapseDeactivateButton = (
|
||||
<AccessibleButton onClick={onSynapseDeactivate} className="mx_UserInfo_field mx_UserInfo_destructive">
|
||||
{_t("Deactivate user")}
|
||||
|
@ -1167,7 +1237,7 @@ const UserInfo = ({user, groupId, roomId, onClose}) => {
|
|||
adminToolsContainer = (
|
||||
<GroupAdminToolsSection
|
||||
groupId={groupId}
|
||||
groupMember={user}
|
||||
groupMember={member}
|
||||
startUpdating={startUpdating}
|
||||
stopUpdating={stopUpdating}>
|
||||
{ synapseDeactivateButton }
|
||||
|
@ -1186,7 +1256,125 @@ const UserInfo = ({user, groupId, roomId, onClose}) => {
|
|||
spinner = <Loader imgClassName="mx_ContextualMenu_spinner" />;
|
||||
}
|
||||
|
||||
const displayName = member.name || member.displayname;
|
||||
const memberDetails = (
|
||||
<PowerLevelSection
|
||||
powerLevels={powerLevels}
|
||||
user={member}
|
||||
room={room}
|
||||
roomPermissions={roomPermissions}
|
||||
/>
|
||||
);
|
||||
|
||||
// only display the devices list if our client supports E2E
|
||||
const _enableDevices = cli.isCryptoEnabled();
|
||||
|
||||
let text;
|
||||
if (!isRoomEncrypted) {
|
||||
if (!_enableDevices) {
|
||||
text = _t("This client does not support end-to-end encryption.");
|
||||
} else if (room) {
|
||||
text = _t("Messages in this room are not end-to-end encrypted.");
|
||||
} else {
|
||||
// TODO what to render for GroupMember
|
||||
}
|
||||
} else {
|
||||
text = _t("Messages in this room are end-to-end encrypted.");
|
||||
}
|
||||
|
||||
const userTrust = cli.checkUserTrust(member.userId);
|
||||
const userVerified = SettingsStore.isFeatureEnabled("feature_cross_signing") ?
|
||||
userTrust.isCrossSigningVerified() :
|
||||
userTrust.isVerified();
|
||||
const isMe = member.userId === cli.getUserId();
|
||||
|
||||
let verifyButton;
|
||||
if (isRoomEncrypted && !userVerified && !isMe) {
|
||||
verifyButton = (
|
||||
<AccessibleButton className="mx_UserInfo_field" onClick={() => verifyUser(member)}>
|
||||
{_t("Verify")}
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
||||
let devicesSection;
|
||||
if (isRoomEncrypted) {
|
||||
devicesSection = <DevicesSection
|
||||
loading={devices === undefined}
|
||||
devices={devices}
|
||||
userId={member.userId} />;
|
||||
}
|
||||
|
||||
const securitySection = (
|
||||
<div className="mx_UserInfo_container">
|
||||
<h3>{ _t("Security") }</h3>
|
||||
<p>{ text }</p>
|
||||
{ verifyButton }
|
||||
{ devicesSection }
|
||||
</div>
|
||||
);
|
||||
|
||||
return <React.Fragment>
|
||||
{ memberDetails &&
|
||||
<div className="mx_UserInfo_container mx_UserInfo_separator mx_UserInfo_memberDetailsContainer">
|
||||
<div className="mx_UserInfo_memberDetails">
|
||||
{ memberDetails }
|
||||
</div>
|
||||
</div> }
|
||||
|
||||
{ securitySection }
|
||||
<UserOptionsSection
|
||||
devices={devices}
|
||||
canInvite={roomPermissions.canInvite}
|
||||
isIgnored={isIgnored}
|
||||
member={member} />
|
||||
|
||||
{ adminToolsContainer }
|
||||
|
||||
{ spinner }
|
||||
</React.Fragment>;
|
||||
};
|
||||
|
||||
const UserInfoHeader = ({onClose, member, e2eStatus}) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
|
||||
let closeButton;
|
||||
if (onClose) {
|
||||
closeButton = <AccessibleButton className="mx_UserInfo_cancel" onClick={onClose} title={_t('Close')}>
|
||||
<div />
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
const onMemberAvatarClick = useCallback(() => {
|
||||
const avatarUrl = member.getMxcAvatarUrl ? member.getMxcAvatarUrl() : member.avatarUrl;
|
||||
if (!avatarUrl) return;
|
||||
|
||||
const httpUrl = cli.mxcUrlToHttp(avatarUrl);
|
||||
const ImageView = sdk.getComponent("elements.ImageView");
|
||||
const params = {
|
||||
src: httpUrl,
|
||||
name: member.name,
|
||||
};
|
||||
|
||||
Modal.createDialog(ImageView, params, "mx_Dialog_lightbox");
|
||||
}, [cli, member]);
|
||||
|
||||
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||
const avatarElement = (
|
||||
<div className="mx_UserInfo_avatar">
|
||||
<div>
|
||||
<div>
|
||||
<MemberAvatar
|
||||
member={member}
|
||||
width={2 * 0.3 * window.innerHeight} // 2x@30vh
|
||||
height={2 * 0.3 * window.innerHeight} // 2x@30vh
|
||||
resizeMethod="scale"
|
||||
fallbackUserId={member.userId}
|
||||
onClick={onMemberAvatarClick}
|
||||
urls={member.avatarUrl ? [member.avatarUrl] : undefined} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
let presenceState;
|
||||
let presenceLastActiveAgo;
|
||||
|
@ -1222,181 +1410,79 @@ const UserInfo = ({user, groupId, roomId, onClose}) => {
|
|||
statusLabel = <span className="mx_UserInfo_statusMessage">{ statusMessage }</span>;
|
||||
}
|
||||
|
||||
// const avatarUrl = user.getMxcAvatarUrl ? user.getMxcAvatarUrl() : user.avatarUrl;
|
||||
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||
const avatarElement = (
|
||||
<div className="mx_UserInfo_avatar">
|
||||
<div>
|
||||
<div>
|
||||
<MemberAvatar
|
||||
member={member}
|
||||
width={2 * 0.3 * window.innerHeight} // 2x@30vh
|
||||
height={2 * 0.3 * window.innerHeight} // 2x@30vh
|
||||
resizeMethod="scale"
|
||||
fallbackUserId={member.userId}
|
||||
onClick={onMemberAvatarClick}
|
||||
urls={member.avatarUrl ? [member.avatarUrl] : undefined} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
let closeButton;
|
||||
if (onClose) {
|
||||
closeButton = <AccessibleButton className="mx_UserInfo_cancel" onClick={onClose} title={_t('Close')}>
|
||||
<div />
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
const memberDetails = (
|
||||
<PowerLevelSection
|
||||
powerLevels={powerLevels}
|
||||
user={member}
|
||||
room={room}
|
||||
roomPermissions={roomPermissions}
|
||||
/>
|
||||
);
|
||||
|
||||
const isRoomEncrypted = useIsEncrypted(cli, room);
|
||||
// undefined means yet to be loaded, null means failed to load, otherwise list of devices
|
||||
const [devices, setDevices] = useState(undefined);
|
||||
// Download device lists
|
||||
useEffect(() => {
|
||||
setDevices(undefined);
|
||||
|
||||
let cancelled = false;
|
||||
|
||||
async function _downloadDeviceList() {
|
||||
try {
|
||||
await cli.downloadKeys([user.userId], true);
|
||||
const devices = await cli.getStoredDevicesForUser(user.userId);
|
||||
|
||||
if (cancelled) {
|
||||
// we got cancelled - presumably a different user now
|
||||
return;
|
||||
}
|
||||
|
||||
_disambiguateDevices(devices);
|
||||
setDevices(devices);
|
||||
} catch (err) {
|
||||
setDevices(null);
|
||||
}
|
||||
}
|
||||
_downloadDeviceList();
|
||||
|
||||
// Handle being unmounted
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [cli, user.userId]);
|
||||
|
||||
// Listen to changes
|
||||
useEffect(() => {
|
||||
let cancel = false;
|
||||
const onDeviceVerificationChanged = (_userId, device) => {
|
||||
if (_userId === user.userId) {
|
||||
// no need to re-download the whole thing; just update our copy of the list.
|
||||
|
||||
// Promise.resolve to handle transition from static result to promise; can be removed in future
|
||||
Promise.resolve(cli.getStoredDevicesForUser(user.userId)).then((devices) => {
|
||||
if (cancel) return;
|
||||
setDevices(devices);
|
||||
});
|
||||
}
|
||||
};
|
||||
cli.on("deviceVerificationChanged", onDeviceVerificationChanged);
|
||||
// Handle being unmounted
|
||||
return () => {
|
||||
cancel = true;
|
||||
cli.removeListener("deviceVerificationChanged", onDeviceVerificationChanged);
|
||||
};
|
||||
}, [cli, user.userId]);
|
||||
|
||||
let text;
|
||||
if (!isRoomEncrypted) {
|
||||
if (!_enableDevices) {
|
||||
text = _t("This client does not support end-to-end encryption.");
|
||||
} else if (room) {
|
||||
text = _t("Messages in this room are not end-to-end encrypted.");
|
||||
} else {
|
||||
// TODO what to render for GroupMember
|
||||
}
|
||||
} else {
|
||||
text = _t("Messages in this room are end-to-end encrypted.");
|
||||
}
|
||||
|
||||
const userTrust = cli.checkUserTrust(user.userId);
|
||||
const userVerified = SettingsStore.isFeatureEnabled("feature_cross_signing") ?
|
||||
userTrust.isCrossSigningVerified() :
|
||||
userTrust.isVerified();
|
||||
const isMe = user.userId === cli.getUserId();
|
||||
let verifyButton;
|
||||
if (isRoomEncrypted && !userVerified && !isMe) {
|
||||
verifyButton = <AccessibleButton className="mx_UserInfo_verify" onClick={() => verifyUser(user)}>
|
||||
{_t("Verify")}
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
let devicesSection;
|
||||
if (isRoomEncrypted) {
|
||||
devicesSection = <DevicesSection
|
||||
loading={devices === undefined}
|
||||
devices={devices} userId={user.userId} />;
|
||||
}
|
||||
|
||||
const securitySection = (
|
||||
<div className="mx_UserInfo_container">
|
||||
<h3>{ _t("Security") }</h3>
|
||||
<p>{ text }</p>
|
||||
{ verifyButton }
|
||||
{ devicesSection }
|
||||
</div>
|
||||
);
|
||||
|
||||
let e2eIcon;
|
||||
if (isRoomEncrypted && devices) {
|
||||
const e2eStatus = _getE2EStatus(cli, user.userId, devices);
|
||||
if (e2eStatus) {
|
||||
e2eIcon = <E2EIcon size={18} status={e2eStatus} isUser={true} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_UserInfo" role="tabpanel">
|
||||
<AutoHideScrollbar className="mx_UserInfo_scrollContainer">
|
||||
{ closeButton }
|
||||
{ avatarElement }
|
||||
const displayName = member.name || member.displayname;
|
||||
return <React.Fragment>
|
||||
{ closeButton }
|
||||
{ avatarElement }
|
||||
|
||||
<div className="mx_UserInfo_container">
|
||||
<div className="mx_UserInfo_profile">
|
||||
<div>
|
||||
<h2 aria-label={displayName}>
|
||||
{ e2eIcon }
|
||||
{ displayName }
|
||||
</h2>
|
||||
</div>
|
||||
<div>{ user.userId }</div>
|
||||
<div className="mx_UserInfo_profileStatus">
|
||||
{presenceLabel}
|
||||
{statusLabel}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx_UserInfo_container mx_UserInfo_separator">
|
||||
<div className="mx_UserInfo_profile">
|
||||
<div>
|
||||
<h2 aria-label={displayName}>
|
||||
{ e2eIcon }
|
||||
{ displayName }
|
||||
</h2>
|
||||
</div>
|
||||
<div>{ member.userId }</div>
|
||||
<div className="mx_UserInfo_profileStatus">
|
||||
{presenceLabel}
|
||||
{statusLabel}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>;
|
||||
};
|
||||
|
||||
{ memberDetails && <div className="mx_UserInfo_container mx_UserInfo_memberDetailsContainer">
|
||||
<div className="mx_UserInfo_memberDetails">
|
||||
{ memberDetails }
|
||||
</div>
|
||||
</div> }
|
||||
const UserInfo = ({user, groupId, roomId, onClose, phase=RIGHT_PANEL_PHASES.RoomMemberInfo, ...props}) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
|
||||
{ securitySection }
|
||||
<UserOptionsSection
|
||||
// Load room if we are given a room id and memoize it
|
||||
const room = useMemo(() => roomId ? cli.getRoom(roomId) : null, [cli, roomId]);
|
||||
// fetch latest room member if we have a room, so we don't show historical information, falling back to user
|
||||
const member = useMemo(() => room ? (room.getMember(user.userId) || user) : user, [room, user]);
|
||||
|
||||
const isRoomEncrypted = useIsEncrypted(cli, room);
|
||||
const devices = useDevices(user.userId);
|
||||
|
||||
let e2eStatus;
|
||||
if (isRoomEncrypted && devices) {
|
||||
e2eStatus = getE2EStatus(cli, user.userId, devices);
|
||||
}
|
||||
|
||||
const classes = ["mx_UserInfo"];
|
||||
|
||||
let content;
|
||||
switch (phase) {
|
||||
case RIGHT_PANEL_PHASES.RoomMemberInfo:
|
||||
case RIGHT_PANEL_PHASES.GroupMemberInfo:
|
||||
content = (
|
||||
<BasicUserInfo
|
||||
room={room}
|
||||
member={member}
|
||||
groupId={groupId}
|
||||
devices={devices}
|
||||
canInvite={roomPermissions.canInvite}
|
||||
isIgnored={isIgnored}
|
||||
member={member} />
|
||||
isRoomEncrypted={isRoomEncrypted} />
|
||||
);
|
||||
break;
|
||||
case RIGHT_PANEL_PHASES.EncryptionPanel:
|
||||
classes.push("mx_UserInfo_smallAvatar");
|
||||
content = (
|
||||
<EncryptionPanel {...props} member={member} onClose={onClose} />
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
{ adminToolsContainer }
|
||||
return (
|
||||
<div className={classes.join(" ")} role="tabpanel">
|
||||
<AutoHideScrollbar className="mx_UserInfo_scrollContainer">
|
||||
<UserInfoHeader member={member} e2eStatus={e2eStatus} onClose={onClose} />
|
||||
|
||||
{ spinner }
|
||||
{ content }
|
||||
</AutoHideScrollbar>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -14,79 +14,185 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import * as sdk from '../../../index';
|
||||
import {verificationMethods} from 'matrix-js-sdk/src/crypto';
|
||||
import VerificationQRCode from "../elements/crypto/VerificationQRCode";
|
||||
import {VerificationRequest} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
|
||||
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||
import {_t} from "../../../languageHandler";
|
||||
import E2EIcon from "../rooms/E2EIcon";
|
||||
import {
|
||||
PHASE_UNSENT,
|
||||
PHASE_REQUESTED,
|
||||
PHASE_READY,
|
||||
PHASE_DONE,
|
||||
PHASE_STARTED,
|
||||
PHASE_CANCELLED,
|
||||
} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
|
||||
import Spinner from "../elements/Spinner";
|
||||
|
||||
export default class VerificationPanel extends React.PureComponent {
|
||||
static propTypes = {
|
||||
request: PropTypes.object.isRequired,
|
||||
member: PropTypes.object.isRequired,
|
||||
phase: PropTypes.oneOf([
|
||||
PHASE_UNSENT,
|
||||
PHASE_REQUESTED,
|
||||
PHASE_READY,
|
||||
PHASE_STARTED,
|
||||
PHASE_CANCELLED,
|
||||
PHASE_DONE,
|
||||
]).isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
this._hasVerifier = !!props.request.verifier;
|
||||
this._hasVerifier = false;
|
||||
}
|
||||
|
||||
renderQRPhase(pending) {
|
||||
const {member, request} = this.props;
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
|
||||
let button;
|
||||
if (pending) {
|
||||
button = <Spinner />;
|
||||
} else {
|
||||
button = (
|
||||
<AccessibleButton kind="primary" className="mx_UserInfo_wideButton" onClick={this._startSAS}>
|
||||
{_t("Verify by emoji")}
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
||||
const cli = MatrixClientPeg.get();
|
||||
const crossSigningInfo = cli.getStoredCrossSigningForUser(request.otherUserId);
|
||||
if (!crossSigningInfo || !request.requestEvent || !request.requestEvent.getId()) {
|
||||
// for whatever reason we can't generate a QR code, offer only SAS Verification
|
||||
return <div className="mx_UserInfo_container">
|
||||
<h3>Verify by emoji</h3>
|
||||
<p>{_t("Verify by comparing unique emoji.")}</p>
|
||||
|
||||
{ button }
|
||||
</div>;
|
||||
}
|
||||
|
||||
const myKeyId = cli.getCrossSigningId();
|
||||
const qrCodeKeys = [
|
||||
[cli.getDeviceId(), cli.getDeviceEd25519Key()],
|
||||
[myKeyId, myKeyId],
|
||||
];
|
||||
|
||||
// TODO: add way to open camera to scan a QR code
|
||||
return <React.Fragment>
|
||||
<div className="mx_UserInfo_container">
|
||||
<h3>Verify by scanning</h3>
|
||||
<p>{_t("Ask %(displayName)s to scan your code:", {
|
||||
displayName: member.displayName || member.name || member.userId,
|
||||
})}</p>
|
||||
|
||||
<div className="mx_VerificationPanel_qrCode">
|
||||
<VerificationQRCode
|
||||
keyholderUserId={MatrixClientPeg.get().getUserId()}
|
||||
requestEventId={request.requestEvent.getId()}
|
||||
otherUserKey={crossSigningInfo.getId("master")}
|
||||
secret={request.encodedSharedSecret}
|
||||
keys={qrCodeKeys}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mx_UserInfo_container">
|
||||
<h3>Verify by emoji</h3>
|
||||
<p>{_t("If you can't scan the code above, verify by comparing unique emoji.")}</p>
|
||||
|
||||
{ button }
|
||||
</div>
|
||||
</React.Fragment>;
|
||||
}
|
||||
|
||||
renderVerifiedPhase() {
|
||||
const {member} = this.props;
|
||||
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
return (
|
||||
<div className="mx_UserInfo_container mx_VerificationPanel_verified_section">
|
||||
<h3>Verified</h3>
|
||||
<p>{_t("You've successfully verified %(displayName)s!", {
|
||||
displayName: member.displayName || member.name || member.userId,
|
||||
})}</p>
|
||||
<E2EIcon isUser={true} status="verified" size={128} />
|
||||
<p>Verify all users in a room to ensure it's secure.</p>
|
||||
|
||||
<AccessibleButton kind="primary" className="mx_UserInfo_wideButton" onClick={this.props.onClose}>
|
||||
{_t("Got it")}
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderCancelledPhase() {
|
||||
const {member, request} = this.props;
|
||||
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
|
||||
let text;
|
||||
if (request.cancellationCode === "m.timeout") {
|
||||
text = _t("Verification timed out. Start verification again from their profile.");
|
||||
} else if (request.cancellingUserId === request.otherUserId) {
|
||||
text = _t("%(displayName)s cancelled verification. Start verification again from their profile.", {
|
||||
displayName: member.displayName || member.name || member.userId,
|
||||
});
|
||||
} else {
|
||||
text = _t("You cancelled verification. Start verification again from their profile.");
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_UserInfo_container">
|
||||
<h3>Verification cancelled</h3>
|
||||
<p>{ text }</p>
|
||||
|
||||
<AccessibleButton kind="primary" className="mx_UserInfo_wideButton" onClick={this.props.onClose}>
|
||||
{_t("Got it")}
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div className="mx_UserInfo">
|
||||
<div className="mx_UserInfo_container">
|
||||
{ this.renderStatus() }
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
const {member, phase} = this.props;
|
||||
|
||||
renderStatus() {
|
||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||
const Spinner = sdk.getComponent('elements.Spinner');
|
||||
const {request: req} = this.props;
|
||||
const request: VerificationRequest = req;
|
||||
const displayName = member.displayName || member.name || member.userId;
|
||||
|
||||
if (request.requested) {
|
||||
return (<p>Waiting for {request.otherUserId} to accept ... <Spinner /></p>);
|
||||
} else if (request.ready) {
|
||||
const verifyButton = <AccessibleButton kind="primary" onClick={this._startSAS}>
|
||||
Verify by emoji
|
||||
</AccessibleButton>;
|
||||
|
||||
const crossSigningInfo = MatrixClientPeg.get().getStoredCrossSigningForUser(request.otherUserId);
|
||||
const myKeyId = MatrixClientPeg.get().getCrossSigningId();
|
||||
if (request.requestEvent && request.requestEvent.getId() && crossSigningInfo) {
|
||||
const qrCodeKeys = [
|
||||
[MatrixClientPeg.get().getDeviceId(), MatrixClientPeg.get().getDeviceEd25519Key()],
|
||||
[myKeyId, myKeyId],
|
||||
];
|
||||
const qrCode = <VerificationQRCode
|
||||
keyholderUserId={MatrixClientPeg.get().getUserId()}
|
||||
requestEventId={request.requestEvent.getId()}
|
||||
otherUserKey={crossSigningInfo.getId("master")}
|
||||
secret={request.encodedSharedSecret}
|
||||
keys={qrCodeKeys}
|
||||
/>;
|
||||
return (<p>{request.otherUserId} is ready, start {verifyButton} or have them scan: {qrCode}</p>);
|
||||
}
|
||||
|
||||
return (<p>{request.otherUserId} is ready, start {verifyButton}</p>);
|
||||
} else if (request.started) {
|
||||
if (this.state.sasWaitingForOtherParty) {
|
||||
return <p>Waiting for {request.otherUserId} to confirm ...</p>;
|
||||
} else if (this.state.sasEvent) {
|
||||
const VerificationShowSas = sdk.getComponent('views.verification.VerificationShowSas');
|
||||
return (<div>
|
||||
<VerificationShowSas
|
||||
sas={this.state.sasEvent.sas}
|
||||
onCancel={this._onSasMismatchesClick}
|
||||
onDone={this._onSasMatchesClick}
|
||||
/>
|
||||
</div>);
|
||||
} else {
|
||||
return (<p>Setting up SAS verification...</p>);
|
||||
}
|
||||
} else if (request.done) {
|
||||
return <p>verified {request.otherUserId}!!</p>;
|
||||
} else if (request.cancelled) {
|
||||
return <p>cancelled by {request.cancellingUserId}!</p>;
|
||||
switch (phase) {
|
||||
case PHASE_READY:
|
||||
return this.renderQRPhase();
|
||||
case PHASE_STARTED:
|
||||
if (this.state.sasEvent) {
|
||||
const VerificationShowSas = sdk.getComponent('views.verification.VerificationShowSas');
|
||||
return <div className="mx_UserInfo_container">
|
||||
<h3>Compare emoji</h3>
|
||||
<VerificationShowSas
|
||||
displayName={displayName}
|
||||
sas={this.state.sasEvent.sas}
|
||||
onCancel={this._onSasMismatchesClick}
|
||||
onDone={this._onSasMatchesClick}
|
||||
/>
|
||||
</div>;
|
||||
} else {
|
||||
return this.renderQRPhase(true); // keep showing same phase but with a spinner
|
||||
}
|
||||
case PHASE_DONE:
|
||||
return this.renderVerifiedPhase();
|
||||
case PHASE_CANCELLED:
|
||||
return this.renderCancelledPhase();
|
||||
}
|
||||
console.error("VerificationPanel unhandled phase:", phase);
|
||||
return null;
|
||||
}
|
||||
|
||||
_startSAS = async () => {
|
||||
|
@ -95,18 +201,15 @@ export default class VerificationPanel extends React.PureComponent {
|
|||
await verifier.verify();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
} finally {
|
||||
this.setState({sasEvent: null});
|
||||
}
|
||||
};
|
||||
|
||||
_onSasMatchesClick = () => {
|
||||
this.setState({sasWaitingForOtherParty: true});
|
||||
this.state.sasEvent.confirm();
|
||||
};
|
||||
|
||||
_onSasMismatchesClick = () => {
|
||||
this.state.sasEvent.cancel();
|
||||
this.state.sasEvent.mismatch();
|
||||
};
|
||||
|
||||
_onVerifierShowSas = (sasEvent) => {
|
||||
|
@ -115,8 +218,10 @@ export default class VerificationPanel extends React.PureComponent {
|
|||
|
||||
_onRequestChange = async () => {
|
||||
const {request} = this.props;
|
||||
if (!this._hasVerifier && !!request.verifier) {
|
||||
request.verifier.on('show_sas', this._onVerifierShowSas);
|
||||
const hadVerifier = this._hasVerifier;
|
||||
this._hasVerifier = !!request.verifier;
|
||||
if (!hadVerifier && this._hasVerifier) {
|
||||
request.verifier.once('show_sas', this._onVerifierShowSas);
|
||||
try {
|
||||
// on the requester side, this is also awaited in _startSAS,
|
||||
// but that's ok as verify should return the same promise.
|
||||
|
@ -124,15 +229,12 @@ export default class VerificationPanel extends React.PureComponent {
|
|||
} catch (err) {
|
||||
console.error("error verify", err);
|
||||
}
|
||||
} else if (this._hasVerifier && !request.verifier) {
|
||||
request.verifier.removeListener('show_sas', this._onVerifierShowSas);
|
||||
}
|
||||
this._hasVerifier = !!request.verifier;
|
||||
this.forceUpdate();
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.props.request.on("change", this._onRequestChange);
|
||||
this._onRequestChange();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
|
|
@ -94,6 +94,17 @@ export default class BasicMessageEditor extends React.Component {
|
|||
this._emoticonSettingHandle = null;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.placeholder !== prevProps.placeholder && this.props.placeholder) {
|
||||
const {isEmpty} = this.props.model;
|
||||
if (isEmpty) {
|
||||
this._showPlaceholder();
|
||||
} else {
|
||||
this._hidePlaceholder();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_replaceEmoticon = (caretPosition, inputType, diff) => {
|
||||
const {model} = this.props;
|
||||
const range = model.startRange(caretPosition);
|
||||
|
|
|
@ -32,23 +32,23 @@ export const E2E_STATE = {
|
|||
};
|
||||
|
||||
const crossSigningUserTitles = {
|
||||
[E2E_STATE.WARNING]: _td("This user has not verified all of their devices."),
|
||||
[E2E_STATE.NORMAL]: _td("You have not verified this user. This user has verified all of their devices."),
|
||||
[E2E_STATE.VERIFIED]: _td("You have verified this user. This user has verified all of their devices."),
|
||||
[E2E_STATE.WARNING]: _td("This user has not verified all of their sessions."),
|
||||
[E2E_STATE.NORMAL]: _td("You have not verified this user."),
|
||||
[E2E_STATE.VERIFIED]: _td("You have verified this user. This user has verified all of their sessions."),
|
||||
};
|
||||
const crossSigningRoomTitles = {
|
||||
[E2E_STATE.WARNING]: _td("Someone is using an unknown device"),
|
||||
[E2E_STATE.WARNING]: _td("Someone is using an unknown session"),
|
||||
[E2E_STATE.NORMAL]: _td("This room is end-to-end encrypted"),
|
||||
[E2E_STATE.VERIFIED]: _td("Everyone in this room is verified"),
|
||||
};
|
||||
|
||||
const legacyUserTitles = {
|
||||
[E2E_STATE.WARNING]: _td("Some devices for this user are not trusted"),
|
||||
[E2E_STATE.VERIFIED]: _td("All devices for this user are trusted"),
|
||||
[E2E_STATE.WARNING]: _td("Some sessions for this user are not trusted"),
|
||||
[E2E_STATE.VERIFIED]: _td("All sessions for this user are trusted"),
|
||||
};
|
||||
const legacyRoomTitles = {
|
||||
[E2E_STATE.WARNING]: _td("Some devices in this encrypted room are not trusted"),
|
||||
[E2E_STATE.VERIFIED]: _td("All devices in this encrypted room are trusted"),
|
||||
[E2E_STATE.WARNING]: _td("Some sessions in this encrypted room are not trusted"),
|
||||
[E2E_STATE.VERIFIED]: _td("All sessions in this encrypted room are trusted"),
|
||||
};
|
||||
|
||||
const E2EIcon = ({isUser, status, className, size, onClick}) => {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2018 New Vector Ltd
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -22,7 +23,7 @@ import * as sdk from '../../../index';
|
|||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import classNames from "classnames";
|
||||
|
||||
import E2EIcon from './E2EIcon';
|
||||
|
||||
const PRESENCE_CLASS = {
|
||||
"offline": "mx_EntityTile_offline",
|
||||
|
@ -30,7 +31,6 @@ const PRESENCE_CLASS = {
|
|||
"unavailable": "mx_EntityTile_unavailable",
|
||||
};
|
||||
|
||||
|
||||
function presenceClassForMember(presenceState, lastActiveAgo, showPresence) {
|
||||
if (showPresence === false) {
|
||||
return 'mx_EntityTile_online_beenactive';
|
||||
|
@ -69,6 +69,7 @@ const EntityTile = createReactClass({
|
|||
suppressOnHover: PropTypes.bool,
|
||||
showPresence: PropTypes.bool,
|
||||
subtextLabel: PropTypes.string,
|
||||
e2eStatus: PropTypes.string,
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
|
@ -156,18 +157,20 @@ const EntityTile = createReactClass({
|
|||
);
|
||||
}
|
||||
|
||||
let power;
|
||||
let powerLabel;
|
||||
const powerStatus = this.props.powerStatus;
|
||||
if (powerStatus) {
|
||||
const src = {
|
||||
[EntityTile.POWER_STATUS_MODERATOR]: require("../../../../res/img/mod.svg"),
|
||||
[EntityTile.POWER_STATUS_ADMIN]: require("../../../../res/img/admin.svg"),
|
||||
}[powerStatus];
|
||||
const alt = {
|
||||
[EntityTile.POWER_STATUS_MODERATOR]: _t("Moderator"),
|
||||
const powerText = {
|
||||
[EntityTile.POWER_STATUS_MODERATOR]: _t("Mod"),
|
||||
[EntityTile.POWER_STATUS_ADMIN]: _t("Admin"),
|
||||
}[powerStatus];
|
||||
power = <img src={src} className="mx_EntityTile_power" width="16" height="17" alt={alt} />;
|
||||
powerLabel = <div className="mx_EntityTile_power">{powerText}</div>;
|
||||
}
|
||||
|
||||
let e2eIcon;
|
||||
const { e2eStatus } = this.props;
|
||||
if (e2eStatus) {
|
||||
e2eIcon = <E2EIcon status={e2eStatus} isUser={true} />;
|
||||
}
|
||||
|
||||
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
|
@ -181,9 +184,10 @@ const EntityTile = createReactClass({
|
|||
onClick={this.props.onClick}>
|
||||
<div className="mx_EntityTile_avatar">
|
||||
{ av }
|
||||
{ power }
|
||||
{ e2eIcon }
|
||||
</div>
|
||||
{ nameEl }
|
||||
{ powerLabel }
|
||||
{ inviteButton }
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
|
@ -194,5 +198,4 @@ const EntityTile = createReactClass({
|
|||
EntityTile.POWER_STATUS_MODERATOR = "moderator";
|
||||
EntityTile.POWER_STATUS_ADMIN = "admin";
|
||||
|
||||
|
||||
export default EntityTile;
|
||||
|
|
|
@ -40,12 +40,14 @@ const eventTileTypes = {
|
|||
'm.sticker': 'messages.MessageEvent',
|
||||
'm.key.verification.cancel': 'messages.MKeyVerificationConclusion',
|
||||
'm.key.verification.done': 'messages.MKeyVerificationConclusion',
|
||||
'm.room.encryption': 'messages.EncryptionEvent',
|
||||
'm.call.invite': 'messages.TextualEvent',
|
||||
'm.call.answer': 'messages.TextualEvent',
|
||||
'm.call.hangup': 'messages.TextualEvent',
|
||||
};
|
||||
|
||||
const stateEventTileTypes = {
|
||||
'm.room.encryption': 'messages.EncryptionEvent',
|
||||
'm.room.aliases': 'messages.TextualEvent',
|
||||
// 'm.room.aliases': 'messages.RoomAliasesEvent', // too complex
|
||||
'm.room.canonical_alias': 'messages.TextualEvent',
|
||||
|
@ -55,7 +57,6 @@ const stateEventTileTypes = {
|
|||
'm.room.avatar': 'messages.RoomAvatarEvent',
|
||||
'm.room.third_party_invite': 'messages.TextualEvent',
|
||||
'm.room.history_visibility': 'messages.TextualEvent',
|
||||
'm.room.encryption': 'messages.TextualEvent',
|
||||
'm.room.topic': 'messages.TextualEvent',
|
||||
'm.room.power_levels': 'messages.TextualEvent',
|
||||
'm.room.pinned_events': 'messages.TextualEvent',
|
||||
|
@ -600,7 +601,8 @@ export default createReactClass({
|
|||
|
||||
// Info messages are basically information about commands processed on a room
|
||||
const isBubbleMessage = eventType.startsWith("m.key.verification") ||
|
||||
(eventType === "m.room.message" && msgtype && msgtype.startsWith("m.key.verification"));
|
||||
(eventType === "m.room.message" && msgtype && msgtype.startsWith("m.key.verification")) ||
|
||||
(eventType === "m.room.encryption");
|
||||
let isInfoMessage = (
|
||||
!isBubbleMessage && eventType !== 'm.room.message' &&
|
||||
eventType !== 'm.sticker' && eventType !== 'm.room.create'
|
||||
|
@ -733,15 +735,15 @@ export default createReactClass({
|
|||
<div className="mx_EventTile_keyRequestInfo_tooltip_contents">
|
||||
<p>
|
||||
{ this.state.previouslyRequestedKeys ?
|
||||
_t( 'Your key share request has been sent - please check your other devices ' +
|
||||
_t( 'Your key share request has been sent - please check your other sessions ' +
|
||||
'for key share requests.') :
|
||||
_t( 'Key share requests are sent to your other devices automatically. If you ' +
|
||||
'rejected or dismissed the key share request on your other devices, click ' +
|
||||
_t( 'Key share requests are sent to your other sessions automatically. If you ' +
|
||||
'rejected or dismissed the key share request on your other sessions, click ' +
|
||||
'here to request the keys for this session again.')
|
||||
}
|
||||
</p>
|
||||
<p>
|
||||
{ _t( 'If your other devices do not have the key for this message you will not ' +
|
||||
{ _t( 'If your other sessions do not have the key for this message you will not ' +
|
||||
'be able to decrypt them.')
|
||||
}
|
||||
</p>
|
||||
|
@ -749,7 +751,7 @@ export default createReactClass({
|
|||
const keyRequestInfoContent = this.state.previouslyRequestedKeys ?
|
||||
_t('Key request sent.') :
|
||||
_t(
|
||||
'<requestLink>Re-request encryption keys</requestLink> from your other devices.',
|
||||
'<requestLink>Re-request encryption keys</requestLink> from your other sessions.',
|
||||
{},
|
||||
{'requestLink': (sub) => <a onClick={this.onRequestKeysClick}>{ sub }</a>},
|
||||
);
|
||||
|
@ -938,7 +940,7 @@ function E2ePadlockUndecryptable(props) {
|
|||
|
||||
function E2ePadlockUnverified(props) {
|
||||
return (
|
||||
<E2ePadlock title={_t("Encrypted by an unverified device")} icon="unverified" {...props} />
|
||||
<E2ePadlock title={_t("Encrypted by an unverified session")} icon="unverified" {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -950,7 +952,7 @@ function E2ePadlockUnencrypted(props) {
|
|||
|
||||
function E2ePadlockUnknown(props) {
|
||||
return (
|
||||
<E2ePadlock title={_t("Encrypted by a deleted device")} icon="unknown" {...props} />
|
||||
<E2ePadlock title={_t("Encrypted by a deleted session")} icon="unknown" {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import * as sdk from '../../../index';
|
||||
import SettingsStore from '../../../settings/SettingsStore';
|
||||
|
||||
export default class InviteOnlyIcon extends React.Component {
|
||||
constructor() {
|
||||
|
@ -36,6 +37,10 @@ export default class InviteOnlyIcon extends React.Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
if (!SettingsStore.isFeatureEnabled("feature_invite_only_padlocks")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const Tooltip = sdk.getComponent("elements.Tooltip");
|
||||
let tooltip;
|
||||
if (this.state.hover) {
|
||||
|
|
|
@ -260,7 +260,7 @@ export default createReactClass({
|
|||
e2eStatus: self._getE2EStatus(devices),
|
||||
});
|
||||
}, function(err) {
|
||||
console.log("Error downloading devices", err);
|
||||
console.log("Error downloading sessions", err);
|
||||
self.setState({devicesLoading: false});
|
||||
});
|
||||
},
|
||||
|
@ -766,9 +766,9 @@ export default createReactClass({
|
|||
// still loading
|
||||
devComponents = <Spinner />;
|
||||
} else if (devices === null) {
|
||||
devComponents = _t("Unable to load device list");
|
||||
devComponents = _t("Unable to load session list");
|
||||
} else if (devices.length === 0) {
|
||||
devComponents = _t("No devices with registered encryption keys");
|
||||
devComponents = _t("No sessions with registered encryption keys");
|
||||
} else {
|
||||
devComponents = [];
|
||||
for (let i = 0; i < devices.length; i++) {
|
||||
|
@ -780,7 +780,7 @@ export default createReactClass({
|
|||
|
||||
return (
|
||||
<div>
|
||||
<h3>{ _t("Devices") }</h3>
|
||||
<h3>{ _t("Sessions") }</h3>
|
||||
<div className="mx_MemberInfo_devices">
|
||||
{ devComponents }
|
||||
</div>
|
||||
|
@ -1113,7 +1113,8 @@ export default createReactClass({
|
|||
}
|
||||
}
|
||||
|
||||
const avatarUrl = this.props.member.getMxcAvatarUrl();
|
||||
const {member} = this.props;
|
||||
const avatarUrl = member.avatarUrl || (member.getMxcAvatarUrl && member.getMxcAvatarUrl());
|
||||
let avatarElement;
|
||||
if (avatarUrl) {
|
||||
const httpUrl = this.context.mxcUrlToHttp(avatarUrl, 800, 800);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -22,6 +22,7 @@ import createReactClass from 'create-react-class';
|
|||
import * as sdk from "../../../index";
|
||||
import dis from "../../../dispatcher";
|
||||
import { _t } from '../../../languageHandler';
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
|
||||
export default createReactClass({
|
||||
displayName: 'MemberTile',
|
||||
|
@ -40,29 +41,101 @@ export default createReactClass({
|
|||
getInitialState: function() {
|
||||
return {
|
||||
statusMessage: this.getStatusMessage(),
|
||||
isRoomEncrypted: false,
|
||||
e2eStatus: null,
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
if (!SettingsStore.isFeatureEnabled("feature_custom_status")) {
|
||||
return;
|
||||
const cli = MatrixClientPeg.get();
|
||||
|
||||
if (SettingsStore.isFeatureEnabled("feature_custom_status")) {
|
||||
const { user } = this.props.member;
|
||||
if (user) {
|
||||
user.on("User._unstable_statusMessage", this._onStatusMessageCommitted);
|
||||
}
|
||||
}
|
||||
const { user } = this.props.member;
|
||||
if (!user) {
|
||||
return;
|
||||
|
||||
if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
|
||||
const { roomId } = this.props.member;
|
||||
if (roomId) {
|
||||
const isRoomEncrypted = cli.isRoomEncrypted(roomId);
|
||||
this.setState({
|
||||
isRoomEncrypted,
|
||||
});
|
||||
if (isRoomEncrypted) {
|
||||
cli.on("userTrustStatusChanged", this.onUserTrustStatusChanged);
|
||||
this.updateE2EStatus();
|
||||
} else {
|
||||
// Listen for room to become encrypted
|
||||
cli.on("RoomState.events", this.onRoomStateEvents);
|
||||
}
|
||||
}
|
||||
}
|
||||
user.on("User._unstable_statusMessage", this._onStatusMessageCommitted);
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
const cli = MatrixClientPeg.get();
|
||||
|
||||
const { user } = this.props.member;
|
||||
if (!user) {
|
||||
if (user) {
|
||||
user.removeListener(
|
||||
"User._unstable_statusMessage",
|
||||
this._onStatusMessageCommitted,
|
||||
);
|
||||
}
|
||||
|
||||
if (cli) {
|
||||
cli.removeListener("RoomState.events", this.onRoomStateEvents);
|
||||
cli.removeListener("userTrustStatusChanged", this.onUserTrustStatusChanged);
|
||||
}
|
||||
},
|
||||
|
||||
onRoomStateEvents: function(ev) {
|
||||
if (ev.getType() !== "m.room.encryption") return;
|
||||
const { roomId } = this.props.member;
|
||||
if (ev.getRoomId() !== roomId) return;
|
||||
|
||||
// The room is encrypted now.
|
||||
const cli = MatrixClientPeg.get();
|
||||
cli.removeListener("RoomState.events", this.onRoomStateEvents);
|
||||
this.setState({
|
||||
isRoomEncrypted: true,
|
||||
});
|
||||
this.updateE2EStatus();
|
||||
},
|
||||
|
||||
onUserTrustStatusChanged: function(userId, trustStatus) {
|
||||
if (userId !== this.props.member.userId) return;
|
||||
this.updateE2EStatus();
|
||||
},
|
||||
|
||||
updateE2EStatus: async function() {
|
||||
const cli = MatrixClientPeg.get();
|
||||
const { userId } = this.props.member;
|
||||
const isMe = userId === cli.getUserId();
|
||||
const userVerified = cli.checkUserTrust(userId).isCrossSigningVerified();
|
||||
if (!userVerified) {
|
||||
this.setState({
|
||||
e2eStatus: "normal",
|
||||
});
|
||||
return;
|
||||
}
|
||||
user.removeListener(
|
||||
"User._unstable_statusMessage",
|
||||
this._onStatusMessageCommitted,
|
||||
);
|
||||
|
||||
const devices = await cli.getStoredDevicesForUser(userId);
|
||||
const anyDeviceUnverified = devices.some(device => {
|
||||
const { deviceId } = device;
|
||||
// For your own devices, we use the stricter check of cross-signing
|
||||
// verification to encourage everyone to trust their own devices via
|
||||
// cross-signing so that other users can then safely trust you.
|
||||
// For other people's devices, the more general verified check that
|
||||
// includes locally verified devices can be used.
|
||||
const deviceTrust = cli.checkDeviceTrust(userId, deviceId);
|
||||
return isMe ? !deviceTrust.isCrossSigningVerified() : !deviceTrust.isVerified();
|
||||
});
|
||||
this.setState({
|
||||
e2eStatus: anyDeviceUnverified ? "warning" : "verified",
|
||||
});
|
||||
},
|
||||
|
||||
getStatusMessage() {
|
||||
|
@ -94,6 +167,12 @@ export default createReactClass({
|
|||
) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
nextState.isRoomEncrypted !== this.state.isRoomEncrypted ||
|
||||
nextState.e2eStatus !== this.state.e2eStatus
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
|
@ -153,14 +232,26 @@ export default createReactClass({
|
|||
|
||||
const powerStatus = powerStatusMap.get(powerLevel);
|
||||
|
||||
let e2eStatus;
|
||||
if (this.state.isRoomEncrypted) {
|
||||
e2eStatus = this.state.e2eStatus;
|
||||
}
|
||||
|
||||
return (
|
||||
<EntityTile {...this.props} presenceState={presenceState}
|
||||
<EntityTile
|
||||
{...this.props}
|
||||
presenceState={presenceState}
|
||||
presenceLastActiveAgo={member.user ? member.user.lastActiveAgo : 0}
|
||||
presenceLastTs={member.user ? member.user.lastPresenceTs : 0}
|
||||
presenceCurrentlyActive={member.user ? member.user.currentlyActive : false}
|
||||
avatarJsx={av} title={this.getPowerLabel()} onClick={this.onClick}
|
||||
name={name} powerStatus={powerStatus} showPresence={this.props.showPresence}
|
||||
avatarJsx={av}
|
||||
title={this.getPowerLabel()}
|
||||
name={name}
|
||||
powerStatus={powerStatus}
|
||||
showPresence={this.props.showPresence}
|
||||
subtextLabel={statusMessage}
|
||||
e2eStatus={e2eStatus}
|
||||
onClick={this.onClick}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -124,7 +124,7 @@ export default class RoomRecoveryReminder extends React.PureComponent {
|
|||
|
||||
let setupCaption;
|
||||
if (this.state.backupInfo) {
|
||||
setupCaption = _t("Connect this device to Key Backup");
|
||||
setupCaption = _t("Connect this session to Key Backup");
|
||||
} else {
|
||||
setupCaption = _t("Start using Key Backup");
|
||||
}
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2019 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.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import createReactClass from 'create-react-class';
|
||||
import * as Avatar from '../../../Avatar';
|
||||
import * as sdk from "../../../index";
|
||||
|
||||
export default createReactClass({
|
||||
displayName: 'UserTile',
|
||||
|
||||
propTypes: {
|
||||
user: PropTypes.any.isRequired, // User
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const EntityTile = sdk.getComponent("rooms.EntityTile");
|
||||
const user = this.props.user;
|
||||
const name = user.displayName || user.userId;
|
||||
let active = -1;
|
||||
|
||||
// FIXME: make presence data update whenever User.presence changes...
|
||||
active = user.lastActiveAgo ?
|
||||
(Date.now() - (user.lastPresenceTs - user.lastActiveAgo)) : -1;
|
||||
|
||||
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
const avatarJsx = (
|
||||
<BaseAvatar width={36} height={36} name={name} idName={user.userId}
|
||||
url={Avatar.avatarUrlForUser(user, 36, 36, "crop")} />
|
||||
);
|
||||
|
||||
return (
|
||||
<EntityTile {...this.props} presenceState={user.presence} presenceActiveAgo={active}
|
||||
presenceCurrentlyActive={user.currentlyActive}
|
||||
name={name} title={user.userId} avatarJsx={avatarJsx} />
|
||||
);
|
||||
},
|
||||
});
|
|
@ -113,7 +113,7 @@ export default createReactClass({
|
|||
description:
|
||||
<div>
|
||||
{ _t(
|
||||
'Changing password will currently reset any end-to-end encryption keys on all devices, ' +
|
||||
'Changing password will currently reset any end-to-end encryption keys on all sessions, ' +
|
||||
'making encrypted chat history unreadable, unless you first export your room keys ' +
|
||||
'and re-import them afterwards. ' +
|
||||
'In future this will be improved.',
|
||||
|
|
|
@ -127,7 +127,7 @@ export default class CrossSigningPanel extends React.PureComponent {
|
|||
} else if (crossSigningPrivateKeysInStorage) {
|
||||
summarisedStatus = <p>{_t(
|
||||
"Your account has a cross-signing identity in secret storage, but it " +
|
||||
"is not yet trusted by this device.",
|
||||
"is not yet trusted by this session.",
|
||||
)}</p>;
|
||||
} else {
|
||||
summarisedStatus = <p>{_t(
|
||||
|
@ -152,7 +152,7 @@ export default class CrossSigningPanel extends React.PureComponent {
|
|||
<table className="mx_CrossSigningPanel_statusList"><tbody>
|
||||
<tr>
|
||||
<td>{_t("Cross-signing public keys:")}</td>
|
||||
<td>{crossSigningPublicKeysOnDevice ? _t("on device") : _t("not found")}</td>
|
||||
<td>{crossSigningPublicKeysOnDevice ? _t("in memory") : _t("not found")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{_t("Cross-signing private keys:")}</td>
|
||||
|
|
|
@ -62,10 +62,10 @@ export default class DevicesPanel extends React.Component {
|
|||
let errtxt;
|
||||
if (error.httpStatus == 404) {
|
||||
// 404 probably means the HS doesn't yet support the API.
|
||||
errtxt = _t("Your homeserver does not support device management.");
|
||||
errtxt = _t("Your homeserver does not support session management.");
|
||||
} else {
|
||||
console.error("Error loading devices:", error);
|
||||
errtxt = _t("Unable to load device list");
|
||||
console.error("Error loading sessions:", error);
|
||||
errtxt = _t("Unable to load session list");
|
||||
}
|
||||
this.setState({deviceLoadError: errtxt});
|
||||
},
|
||||
|
@ -130,7 +130,7 @@ export default class DevicesPanel extends React.Component {
|
|||
makeRequest: this._makeDeleteRequest.bind(this),
|
||||
});
|
||||
}).catch((e) => {
|
||||
console.error("Error deleting devices", e);
|
||||
console.error("Error deleting sessions", e);
|
||||
if (this._unmounted) { return; }
|
||||
}).finally(() => {
|
||||
this.setState({
|
||||
|
@ -188,7 +188,7 @@ export default class DevicesPanel extends React.Component {
|
|||
const deleteButton = this.state.deleting ?
|
||||
<Spinner w={22} h={22} /> :
|
||||
<AccessibleButton onClick={this._onDeleteClick} kind="danger_sm">
|
||||
{ _t("Delete %(count)s devices", {count: this.state.selectedDevices.length}) }
|
||||
{ _t("Delete %(count)s sessions", {count: this.state.selectedDevices.length}) }
|
||||
</AccessibleButton>;
|
||||
|
||||
const classes = classNames(this.props.className, "mx_DevicesPanel");
|
||||
|
|
|
@ -40,7 +40,7 @@ export default class DevicesPanelEntry extends React.Component {
|
|||
return MatrixClientPeg.get().setDeviceDetails(device.device_id, {
|
||||
display_name: value,
|
||||
}).catch((e) => {
|
||||
console.error("Error setting device display name", e);
|
||||
console.error("Error setting session display name", e);
|
||||
throw new Error(_t("Failed to set display name"));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -186,23 +186,23 @@ export default class KeyBackupPanel extends React.PureComponent {
|
|||
if (MatrixClientPeg.get().getKeyBackupEnabled()) {
|
||||
clientBackupStatus = <div>
|
||||
<p>{encryptedMessageAreEncrypted}</p>
|
||||
<p>✅ {_t("This device is backing up your keys. ")}</p>
|
||||
<p>✅ {_t("This session is backing up your keys. ")}</p>
|
||||
</div>;
|
||||
} else {
|
||||
clientBackupStatus = <div>
|
||||
<p>{encryptedMessageAreEncrypted}</p>
|
||||
<p>{_t(
|
||||
"This device is <b>not backing up your keys</b>, " +
|
||||
"This session is <b>not backing up your keys</b>, " +
|
||||
"but you do have an existing backup you can restore from " +
|
||||
"and add to going forward.", {},
|
||||
{b: sub => <b>{sub}</b>},
|
||||
)}</p>
|
||||
<p>{_t(
|
||||
"Connect this device to key backup before signing out to avoid " +
|
||||
"losing any keys that may only be on this device.",
|
||||
"Connect this session to key backup before signing out to avoid " +
|
||||
"losing any keys that may only be on this session.",
|
||||
)}</p>
|
||||
</div>;
|
||||
restoreButtonCaption = _t("Connect this device to Key Backup");
|
||||
restoreButtonCaption = _t("Connect this session to Key Backup");
|
||||
}
|
||||
|
||||
let keyStatus;
|
||||
|
@ -264,42 +264,42 @@ export default class KeyBackupPanel extends React.PureComponent {
|
|||
);
|
||||
} else if (!sig.device) {
|
||||
sigStatus = _t(
|
||||
"Backup has a signature from <verify>unknown</verify> device with ID %(deviceId)s",
|
||||
"Backup has a signature from <verify>unknown</verify> session with ID %(deviceId)s",
|
||||
{ deviceId: sig.deviceId }, { verify },
|
||||
);
|
||||
} else if (sig.valid && fromThisDevice) {
|
||||
sigStatus = _t(
|
||||
"Backup has a <validity>valid</validity> signature from this device",
|
||||
"Backup has a <validity>valid</validity> signature from this session",
|
||||
{}, { validity },
|
||||
);
|
||||
} else if (!sig.valid && fromThisDevice) {
|
||||
// it can happen...
|
||||
sigStatus = _t(
|
||||
"Backup has an <validity>invalid</validity> signature from this device",
|
||||
"Backup has an <validity>invalid</validity> signature from this session",
|
||||
{}, { validity },
|
||||
);
|
||||
} else if (sig.valid && sig.device.isVerified()) {
|
||||
sigStatus = _t(
|
||||
"Backup has a <validity>valid</validity> signature from " +
|
||||
"<verify>verified</verify> device <device></device>",
|
||||
"<verify>verified</verify> session <device></device>",
|
||||
{}, { validity, verify, device },
|
||||
);
|
||||
} else if (sig.valid && !sig.device.isVerified()) {
|
||||
sigStatus = _t(
|
||||
"Backup has a <validity>valid</validity> signature from " +
|
||||
"<verify>unverified</verify> device <device></device>",
|
||||
"<verify>unverified</verify> session <device></device>",
|
||||
{}, { validity, verify, device },
|
||||
);
|
||||
} else if (!sig.valid && sig.device.isVerified()) {
|
||||
sigStatus = _t(
|
||||
"Backup has an <validity>invalid</validity> signature from " +
|
||||
"<verify>verified</verify> device <device></device>",
|
||||
"<verify>verified</verify> session <device></device>",
|
||||
{}, { validity, verify, device },
|
||||
);
|
||||
} else if (!sig.valid && !sig.device.isVerified()) {
|
||||
sigStatus = _t(
|
||||
"Backup has an <validity>invalid</validity> signature from " +
|
||||
"<verify>unverified</verify> device <device></device>",
|
||||
"<verify>unverified</verify> session <device></device>",
|
||||
{}, { validity, verify, device },
|
||||
);
|
||||
}
|
||||
|
@ -309,12 +309,12 @@ export default class KeyBackupPanel extends React.PureComponent {
|
|||
</div>;
|
||||
});
|
||||
if (this.state.backupSigStatus.sigs.length === 0) {
|
||||
backupSigStatuses = _t("Backup is not signed by any of your devices");
|
||||
backupSigStatuses = _t("Backup is not signed by any of your sessions");
|
||||
}
|
||||
|
||||
let trustedLocally;
|
||||
if (this.state.backupSigStatus.trusted_locally) {
|
||||
trustedLocally = _t("This backup is trusted because it has been restored on this device");
|
||||
trustedLocally = _t("This backup is trusted because it has been restored on this session");
|
||||
}
|
||||
|
||||
let buttonRow = (
|
||||
|
@ -330,7 +330,7 @@ export default class KeyBackupPanel extends React.PureComponent {
|
|||
if (this.state.backupKeyStored && !SettingsStore.isFeatureEnabled("feature_cross_signing")) {
|
||||
buttonRow = <p>⚠️ {_t(
|
||||
"Backup key stored in secret storage, but this feature is not " +
|
||||
"enabled on this device. Please enable cross-signing in Labs to " +
|
||||
"enabled on this session. Please enable cross-signing in Labs to " +
|
||||
"modify key backup state.",
|
||||
)}</p>;
|
||||
}
|
||||
|
@ -352,7 +352,7 @@ export default class KeyBackupPanel extends React.PureComponent {
|
|||
return <div>
|
||||
<div>
|
||||
<p>{_t(
|
||||
"Your keys are <b>not being backed up from this device</b>.", {},
|
||||
"Your keys are <b>not being backed up from this session</b>.", {},
|
||||
{b: sub => <b>{sub}</b>},
|
||||
)}</p>
|
||||
<p>{encryptedMessageAreEncrypted}</p>
|
||||
|
|
|
@ -864,7 +864,7 @@ export default createReactClass({
|
|||
|
||||
<LabelledToggleSwitch value={SettingsStore.getValue("notificationsEnabled")}
|
||||
onChange={this.onEnableDesktopNotificationsChange}
|
||||
label={_t('Enable desktop notifications for this device')} />
|
||||
label={_t('Enable desktop notifications for this session')} />
|
||||
|
||||
<LabelledToggleSwitch value={SettingsStore.getValue("notificationBodyEnabled")}
|
||||
onChange={this.onEnableDesktopNotificationBodyChange}
|
||||
|
@ -872,7 +872,7 @@ export default createReactClass({
|
|||
|
||||
<LabelledToggleSwitch value={SettingsStore.getValue("audioNotificationsEnabled")}
|
||||
onChange={this.onEnableAudioNotificationsChange}
|
||||
label={_t('Enable audible notifications for this device')} />
|
||||
label={_t('Enable audible notifications for this session')} />
|
||||
|
||||
{ emailNotificationsRows }
|
||||
|
||||
|
|
|
@ -261,7 +261,7 @@ export default class GeneralUserSettingsTab extends React.Component {
|
|||
title: _t("Success"),
|
||||
description: _t(
|
||||
"Your password was successfully changed. You will not receive " +
|
||||
"push notifications on other devices until you log back in to them",
|
||||
"push notifications on other sessions until you log back in to them",
|
||||
) + ".",
|
||||
});
|
||||
};
|
||||
|
|
|
@ -66,6 +66,7 @@ export default class LabsUserSettingsTab extends React.Component {
|
|||
<SettingsFlag name={"showHiddenEventsInTimeline"} level={SettingLevel.DEVICE} />
|
||||
<SettingsFlag name={"lowBandwidth"} level={SettingLevel.DEVICE} />
|
||||
<SettingsFlag name={"sendReadReceipts"} level={SettingLevel.ACCOUNT} />
|
||||
<SettingsFlag name={"keepSecretStoragePassphraseForSession"} level={SettingLevel.DEVICE} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -185,11 +185,11 @@ export default class SecurityUserSettingsTab extends React.Component {
|
|||
<span className='mx_SettingsTab_subheading'>{_t("Cryptography")}</span>
|
||||
<ul className='mx_SettingsTab_subsectionText mx_SecurityUserSettingsTab_deviceInfo'>
|
||||
<li>
|
||||
<label>{_t("Device ID:")}</label>
|
||||
<label>{_t("Session ID:")}</label>
|
||||
<span><code>{deviceId}</code></span>
|
||||
</li>
|
||||
<li>
|
||||
<label>{_t("Device key:")}</label>
|
||||
<label>{_t("Session key:")}</label>
|
||||
<span><code><b>{identityKey}</b></code></span>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -285,9 +285,9 @@ export default class SecurityUserSettingsTab extends React.Component {
|
|||
<div className="mx_SettingsTab mx_SecurityUserSettingsTab">
|
||||
<div className="mx_SettingsTab_heading">{_t("Security & Privacy")}</div>
|
||||
<div className="mx_SettingsTab_section">
|
||||
<span className="mx_SettingsTab_subheading">{_t("Devices")}</span>
|
||||
<span className="mx_SettingsTab_subheading">{_t("Sessions")}</span>
|
||||
<div className='mx_SettingsTab_subsectionText'>
|
||||
{_t("A device's public name is visible to people you communicate with")}
|
||||
{_t("A session's public name is visible to people you communicate with")}
|
||||
<DevicesPanel />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -39,7 +39,7 @@ export default class SetupEncryptionToast extends React.PureComponent {
|
|||
switch (this.props.kind) {
|
||||
case 'set_up_encryption':
|
||||
case 'upgrade_encryption':
|
||||
return _t('Verify your other devices easier');
|
||||
return _t('Verify yourself & others to keep your chats safe');
|
||||
case 'verify_this_session':
|
||||
return _t('Other users may not trust it');
|
||||
}
|
||||
|
|
|
@ -24,21 +24,20 @@ import NewSessionReviewDialog from '../dialogs/NewSessionReviewDialog';
|
|||
import FormButton from '../elements/FormButton';
|
||||
import { replaceableComponent } from '../../../utils/replaceableComponent';
|
||||
|
||||
@replaceableComponent("views.toasts.VerifySessionToast")
|
||||
export default class VerifySessionToast extends React.PureComponent {
|
||||
@replaceableComponent("views.toasts.UnverifiedSessionToast")
|
||||
export default class UnverifiedSessionToast extends React.PureComponent {
|
||||
static propTypes = {
|
||||
toastKey: PropTypes.string.isRequired,
|
||||
deviceId: PropTypes.string,
|
||||
device: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
_onLaterClick = () => {
|
||||
DeviceListener.sharedInstance().dismissVerification(this.props.deviceId);
|
||||
const { device } = this.props;
|
||||
DeviceListener.sharedInstance().dismissVerification(device.deviceId);
|
||||
};
|
||||
|
||||
_onReviewClick = async () => {
|
||||
const cli = MatrixClientPeg.get();
|
||||
|
||||
const device = await cli.getStoredDevice(cli.getUserId(), this.props.deviceId);
|
||||
const { device } = this.props;
|
||||
|
||||
Modal.createTrackedDialog('New Session Review', 'Starting dialog', NewSessionReviewDialog, {
|
||||
userId: MatrixClientPeg.get().getUserId(),
|
||||
|
@ -47,8 +46,16 @@ export default class VerifySessionToast extends React.PureComponent {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { device } = this.props;
|
||||
|
||||
return (<div>
|
||||
<div className="mx_Toast_description">{_t("Review & verify your new session")}</div>
|
||||
<div className="mx_Toast_description">
|
||||
<span className="mx_Toast_deviceName">
|
||||
{device.getDisplayName()}
|
||||
</span> <span className="mx_Toast_deviceID">
|
||||
({device.deviceId})
|
||||
</span>
|
||||
</div>
|
||||
<div className="mx_Toast_buttons" aria-live="off">
|
||||
<FormButton label={_t("Later")} kind="danger" onClick={this._onLaterClick} />
|
||||
<FormButton label={_t("Review")} onClick={this._onReviewClick} />
|
|
@ -33,11 +33,13 @@ export default class VerificationRequestToast extends React.PureComponent {
|
|||
|
||||
componentDidMount() {
|
||||
const {request} = this.props;
|
||||
this._intervalHandle = setInterval(() => {
|
||||
let {counter} = this.state;
|
||||
counter = Math.max(0, counter - 1);
|
||||
this.setState({counter});
|
||||
}, 1000);
|
||||
if (request.timeout && request.timeout > 0) {
|
||||
this._intervalHandle = setInterval(() => {
|
||||
let {counter} = this.state;
|
||||
counter = Math.max(0, counter - 1);
|
||||
this.setState({counter});
|
||||
}, 1000);
|
||||
}
|
||||
request.on("change", this._checkRequestIsPending);
|
||||
// We should probably have a separate class managing the active verification toasts,
|
||||
// rather than monitoring this in the toast component itself, since we'll get problems
|
||||
|
@ -56,7 +58,10 @@ export default class VerificationRequestToast extends React.PureComponent {
|
|||
|
||||
_checkRequestIsPending = () => {
|
||||
const {request} = this.props;
|
||||
if (request.ready || request.started || request.done || request.cancelled || request.observeOnly) {
|
||||
const isPendingInRoomRequest = request.channel.roomId &&
|
||||
!(request.ready || request.started || request.done || request.cancelled || request.observeOnly);
|
||||
const isPendingDeviceRequest = request.channel.deviceId && request.started;
|
||||
if (!isPendingInRoomRequest && !isPendingDeviceRequest) {
|
||||
ToastStore.sharedInstance().dismissToast(this.props.toastKey);
|
||||
}
|
||||
};
|
||||
|
@ -82,10 +87,14 @@ export default class VerificationRequestToast extends React.PureComponent {
|
|||
should_peek: false,
|
||||
});
|
||||
await request.accept();
|
||||
const cli = MatrixClientPeg.get();
|
||||
dis.dispatch({
|
||||
action: "set_right_panel_phase",
|
||||
phase: RIGHT_PANEL_PHASES.EncryptionPanel,
|
||||
refireParams: {verificationRequest: request},
|
||||
refireParams: {
|
||||
verificationRequest: request,
|
||||
member: cli.getUser(request.otherUserId),
|
||||
},
|
||||
});
|
||||
} else if (request.channel.deviceId && request.verifier) {
|
||||
// show to_device verifications in dialog still
|
||||
|
@ -113,10 +122,13 @@ export default class VerificationRequestToast extends React.PureComponent {
|
|||
nameLabel = _t("%(name)s (%(userId)s)", {name: user.displayName, userId});
|
||||
}
|
||||
}
|
||||
const declineLabel = this.state.counter == 0 ?
|
||||
_t("Decline") :
|
||||
_t("Decline (%(counter)s)", {counter: this.state.counter});
|
||||
return (<div>
|
||||
<div className="mx_Toast_description">{nameLabel}</div>
|
||||
<div className="mx_Toast_buttons" aria-live="off">
|
||||
<FormButton label={_t("Decline (%(counter)s)", {counter: this.state.counter})} kind="danger" onClick={this.cancel} />
|
||||
<FormButton label={declineLabel} kind="danger" onClick={this.cancel} />
|
||||
<FormButton label={_t("Accept")} onClick={this.accept} />
|
||||
</div>
|
||||
</div>);
|
||||
|
|
|
@ -16,8 +16,10 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as sdk from '../../../index';
|
||||
import { _t, _td } from '../../../languageHandler';
|
||||
import {PendingActionSpinner} from "../right_panel/EncryptionInfo";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import DialogButtons from "../elements/DialogButtons";
|
||||
|
||||
function capFirst(s) {
|
||||
return s.charAt(0).toUpperCase() + s.slice(1);
|
||||
|
@ -25,18 +27,28 @@ function capFirst(s) {
|
|||
|
||||
export default class VerificationShowSas extends React.Component {
|
||||
static propTypes = {
|
||||
pending: PropTypes.bool,
|
||||
displayName: PropTypes.string, // required if pending is true
|
||||
onDone: PropTypes.func.isRequired,
|
||||
onCancel: PropTypes.func.isRequired,
|
||||
sas: PropTypes.object.isRequired,
|
||||
isSelf: PropTypes.bool,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
pending: false,
|
||||
};
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
onMatchClick = () => {
|
||||
this.setState({ pending: true });
|
||||
this.props.onDone();
|
||||
};
|
||||
|
||||
render() {
|
||||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||
|
||||
let sasDisplay;
|
||||
let sasCaption;
|
||||
if (this.props.sas.emoji) {
|
||||
|
@ -51,11 +63,17 @@ export default class VerificationShowSas extends React.Component {
|
|||
</div>,
|
||||
);
|
||||
sasDisplay = <div className="mx_VerificationShowSas_emojiSas">
|
||||
{emojiBlocks}
|
||||
{emojiBlocks.slice(0, 4)}
|
||||
<div className="mx_VerificationShowSas_emojiSas_break" />
|
||||
{emojiBlocks.slice(4)}
|
||||
</div>;
|
||||
sasCaption = _t(
|
||||
"Verify this user by confirming the following emoji appear on their screen.",
|
||||
);
|
||||
sasCaption = this.props.isSelf ?
|
||||
_t(
|
||||
"Confirm the emoji below are displayed on both devices, in the same order:",
|
||||
):
|
||||
_t(
|
||||
"Verify this user by confirming the following emoji appear on their screen.",
|
||||
);
|
||||
} else if (this.props.sas.decimal) {
|
||||
const numberBlocks = this.props.sas.decimal.map((num, i) => <span key={i}>
|
||||
{num}
|
||||
|
@ -63,32 +81,46 @@ export default class VerificationShowSas extends React.Component {
|
|||
sasDisplay = <div className="mx_VerificationShowSas_decimalSas">
|
||||
{numberBlocks}
|
||||
</div>;
|
||||
sasCaption = _t(
|
||||
"Verify this user by confirming the following number appears on their screen.",
|
||||
);
|
||||
sasCaption = this.props.isSelf ?
|
||||
_t(
|
||||
"Verify this device by confirming the following number appears on its screen.",
|
||||
):
|
||||
_t(
|
||||
"Verify this user by confirming the following number appears on their screen.",
|
||||
);
|
||||
} else {
|
||||
return <div>
|
||||
{_t("Unable to find a supported verification method.")}
|
||||
<DialogButtons
|
||||
primaryButton={_t('Cancel')}
|
||||
hasCancel={false}
|
||||
onPrimaryButtonClick={this.props.onCancel}
|
||||
/>
|
||||
<AccessibleButton kind="primary" onClick={this.props.onCancel} className="mx_UserInfo_wideButton">
|
||||
{_t('Cancel')}
|
||||
</AccessibleButton>
|
||||
</div>;
|
||||
}
|
||||
|
||||
let confirm;
|
||||
if (this.state.pending) {
|
||||
const {displayName} = this.props;
|
||||
const text = _t("Waiting for %(displayName)s to verify…", {displayName});
|
||||
confirm = <PendingActionSpinner text={text} />;
|
||||
} else {
|
||||
// FIXME: stop using DialogButtons here once this component is only used in the right panel verification
|
||||
confirm = <DialogButtons
|
||||
primaryButton={_t("They match")}
|
||||
onPrimaryButtonClick={this.onMatchClick}
|
||||
primaryButtonClass="mx_UserInfo_wideButton"
|
||||
cancelButton={_t("They don't match")}
|
||||
onCancel={this.props.onCancel}
|
||||
cancelButtonClass="mx_UserInfo_wideButton"
|
||||
/>;
|
||||
}
|
||||
|
||||
return <div className="mx_VerificationShowSas">
|
||||
<p>{sasCaption}</p>
|
||||
<p>{_t(
|
||||
"For maximum security, we recommend you do this in person or use another " +
|
||||
"trusted means of communication.",
|
||||
)}</p>
|
||||
{sasDisplay}
|
||||
<DialogButtons onPrimaryButtonClick={this.props.onDone}
|
||||
primaryButton={_t("Continue")}
|
||||
hasCancel={true}
|
||||
onCancel={this.props.onCancel}
|
||||
/>
|
||||
<p>{this.props.isSelf ?
|
||||
"":
|
||||
_t("To be secure, do this in person or use a trusted way to communicate.")}</p>
|
||||
{confirm}
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -426,7 +426,7 @@ export class PartCreator {
|
|||
let room;
|
||||
if (alias[0] === '#') {
|
||||
room = this._client.getRooms().find((r) => {
|
||||
return r.getAliases().includes(alias);
|
||||
return r.getCanonicalAlias() === alias || r.getAliases().includes(alias);
|
||||
});
|
||||
} else {
|
||||
room = this._client.getRoom(alias);
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
"Changelog": "سِجل التغييرات",
|
||||
"Send Account Data": "إرسال بيانات الحساب",
|
||||
"Waiting for response from server": "في انتظار الرد مِن الخادوم",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "سيسمح لك هذا بالعودة إلى حسابك بعد الخروج، وتسجيل الدخول على الأجهزة الأخرى.",
|
||||
"Send logs": "إرسال السِجلات",
|
||||
"Download this file": "تنزيل هذا الملف",
|
||||
"Thank you!": "شكرًا !",
|
||||
|
|
|
@ -74,9 +74,6 @@
|
|||
"Moderator": "Moderator",
|
||||
"Admin": "Administrator",
|
||||
"Start a chat": "Danışığa başlamaq",
|
||||
"Who would you like to communicate with?": "Kimlə siz əlaqə saxlamaq istəyirdiniz?",
|
||||
"Start Chat": "Danışığa başlamaq",
|
||||
"Invite new room members": "Yeni iştirakçıların otağına dəvət etmək",
|
||||
"You need to be logged in.": "Siz sistemə girməlisiniz.",
|
||||
"You need to be able to invite users to do that.": "Bunun üçün siz istifadəçiləri dəvət etmək imkanına malik olmalısınız.",
|
||||
"Failed to send request.": "Sorğunu göndərməyi bacarmadı.",
|
||||
|
@ -126,14 +123,11 @@
|
|||
"%(senderName)s made future room history visible to all room members.": "%(senderName)s iştirakçılar üçün danışıqların tarixini açdı.",
|
||||
"%(senderName)s made future room history visible to anyone.": "%(senderName)s hamı üçün danışıqların tarixini açdı.",
|
||||
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s naməlum rejimdə otağın tarixini açdı (%(visibility)s).",
|
||||
"%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s включил(а) в комнате сквозное шифрование (алгоритм %(algorithm)s).",
|
||||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s üçün %(fromPowerLevel)s-dan %(toPowerLevel)s-lə",
|
||||
"%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s hüquqların səviyyələrini dəyişdirdi %(powerLevelDiffText)s.",
|
||||
"Failed to join room": "Otağa girməyi bacarmadı",
|
||||
"Always show message timestamps": "Həmişə mesajların göndərilməsi vaxtını göstərmək",
|
||||
"Autoplay GIFs and videos": "GIF animasiyalarını və videolarını avtomatik olaraq oynayır",
|
||||
"Never send encrypted messages to unverified devices from this device": "Heç vaxt (bu qurğudan) yoxlanılmamış qurğulara şifrlənmiş mesajları göndərməmək",
|
||||
"Never send encrypted messages to unverified devices in this room from this device": "Heç vaxt (bu otaqda, bu qurğudan) yoxlanılmamış qurğulara şifrlənmiş mesajları göndərməmək",
|
||||
"Accept": "Qəbul etmək",
|
||||
"Error": "Səhv",
|
||||
"Incorrect verification code": "Təsdiq etmənin səhv kodu",
|
||||
|
@ -152,8 +146,6 @@
|
|||
"Failed to set display name": "Görünüş adını təyin etmək bacarmadı",
|
||||
"Notification targets": "Xəbərdarlıqlar üçün qurğular",
|
||||
"On": "Qoşmaq",
|
||||
"Invalid alias format": "Adının yolverilməz formatı",
|
||||
"'%(alias)s' is not a valid format for an alias": "Ad '%(alias)s' yolverilməz formata malikdir",
|
||||
"not specified": "qeyd edilmədi",
|
||||
"Local addresses for this room:": "Sizin serverinizdə bu otağın ünvanları:",
|
||||
"New address (e.g. #foo:%(localDomain)s)": "Yeni ünvan (məsələn, #nəsə:%(localDomain)s)",
|
||||
|
@ -168,8 +160,6 @@
|
|||
"Failed to toggle moderator status": "Moderatorun statusunu dəyişdirməyi bacarmadı",
|
||||
"Failed to change power level": "Hüquqların səviyyəsini dəyişdirməyi bacarmadı",
|
||||
"Are you sure?": "Siz əminsiniz?",
|
||||
"No devices with registered encryption keys": "Şifrləmənin qeyd edilmiş açarlarıyla qurğu yoxdur",
|
||||
"Devices": "Qurğular",
|
||||
"Unignore": "Blokdan çıxarmaq",
|
||||
"Ignore": "Bloklamaq",
|
||||
"User Options": "Hərəkətlər",
|
||||
|
@ -182,17 +172,13 @@
|
|||
"Video call": "Video çağırış",
|
||||
"Upload file": "Faylı göndərmək",
|
||||
"You do not have permission to post to this room": "Siz bu otağa yaza bilmirsiniz",
|
||||
"Hide Text Formatting Toolbar": "Mətnin formatlaşdırılmasının alətlərini gizlətmək",
|
||||
"Command error": "Komandanın səhvi",
|
||||
"Markdown is disabled": "Markdown kəsilmişdir",
|
||||
"Markdown is enabled": "Markdown qoşulmuşdur",
|
||||
"Join Room": "Otağa girmək",
|
||||
"Upload avatar": "Avatar-ı yükləmək",
|
||||
"Settings": "Qurmalar",
|
||||
"Forget room": "Otağı unutmaq",
|
||||
"Invites": "Dəvətlər",
|
||||
"Favourites": "Seçilmişlər",
|
||||
"People": "İnsanlar",
|
||||
"Low priority": "Əhəmiyyətsizlər",
|
||||
"Historical": "Arxiv",
|
||||
"Failed to unban": "Blokdan çıxarmağı bacarmadı",
|
||||
|
@ -267,7 +253,6 @@
|
|||
"Click to unmute audio": "Klikləyin, səsi qoşmaq üçün",
|
||||
"Click to mute audio": "Klikləyin, səsi söndürmək üçün",
|
||||
"Failed to load timeline position": "Xronologiyadan nişanı yükləməyi bacarmadı",
|
||||
"Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Şifrə uğurla dəyişdirildi. Təkrar avtorizasiyaya qədər siz başqa cihazlarda push-xəbərdarlıqları almayacaqsınız",
|
||||
"Unable to remove contact information": "Əlaqə məlumatlarının silməyi bacarmadı",
|
||||
"<not supported>": "<dəstəklənmir>",
|
||||
"Import E2E room keys": "Şifrləmənin açarlarının idxalı",
|
||||
|
@ -282,7 +267,6 @@
|
|||
"click to reveal": "açılış üçün basın",
|
||||
"Homeserver is": "Ev serveri bu",
|
||||
"Identity Server is": "Eyniləşdirmənin serveri bu",
|
||||
"matrix-react-sdk version:": "matrix-react-sdk versiyası:",
|
||||
"olm version:": "Olm versiyası:",
|
||||
"Failed to send email": "Email göndərilməsinin səhvi",
|
||||
"A new password must be entered.": "Yeni parolu daxil edin.",
|
||||
|
@ -317,7 +301,6 @@
|
|||
"Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "'Çörək parçaları' funksiyadan istifadə edmiirsiniz (otaqlar siyahısından yuxarıdakı avatarlar)",
|
||||
"Analytics": "Analitik",
|
||||
"Call Failed": "Uğursuz zəng",
|
||||
"There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Bu otaqda məlum olmayan cihazlar var: onları təsdiq etmədən davam etsəniz, kimsə zənginizə qulaq asmaq mümkün olacaq.",
|
||||
"Review Devices": "Cihazları nəzərdən keçirin",
|
||||
"Call Anyway": "Hər halda zəng edin",
|
||||
"Answer Anyway": "Hər halda cavab verin",
|
||||
|
@ -358,8 +341,6 @@
|
|||
"Registration Required": "Qeydiyyat tələb olunur",
|
||||
"You need to register to do this. Would you like to register now?": "Bunu etmək üçün qeydiyyatdan keçməlisiniz. İndi qeydiyyatdan keçmək istərdiniz?",
|
||||
"Restricted": "Məhduddur",
|
||||
"Email, name or Matrix ID": "E-poçt, ad və ya Matrix ID",
|
||||
"Send Invites": "Dəvət göndərin",
|
||||
"Failed to invite": "Dəvət alınmadı",
|
||||
"Failed to invite users to the room:": "İstifadəçiləri otağa dəvət etmək alınmadı:",
|
||||
"Unable to create widget.": "Widjet yaratmaq olmur.",
|
||||
|
@ -370,8 +351,6 @@
|
|||
"Prepends ¯\\_(ツ)_/¯ to a plain-text message": "¯ \\ _ (ツ) _ / ¯ işarəsini mesaja elavə edir.",
|
||||
"Searches DuckDuckGo for results": "Nəticələr üçün DuckDuckGo-da axtarır",
|
||||
"Upgrades a room to a new version": "Bir otağı yeni bir versiyaya yüksəldir",
|
||||
"Room upgrade confirmation": "Otaq yenilənməsi quraşdırılması",
|
||||
"Upgrading a room can be destructive and isn't always necessary.": "Bir otağı təkmilləşdirməsi dağıdıcı ola bilər və həmişə lazım deyil.",
|
||||
"Changes your display nickname in the current room only": "Yalnız cari otaqda ekran ləqəbinizi dəyişdirir",
|
||||
"Changes your avatar in this current room only": "Avatarınızı yalnız bu cari otaqda dəyişir",
|
||||
"Changes your avatar in all rooms": "Bütün otaqlarda avatarınızı dəyişdirir",
|
||||
|
@ -384,12 +363,9 @@
|
|||
"Opens the Developer Tools dialog": "Geliştirici Alətlər dialoqunu açır",
|
||||
"Adds a custom widget by URL to the room": "Otağa URL tərəfindən xüsusi bir widjet əlavə edir",
|
||||
"You cannot modify widgets in this room.": "Bu otaqda vidjetləri dəyişdirə bilməzsiniz.",
|
||||
"Verifies a user, device, and pubkey tuple": "Bir istifadəçini, cihazı və publik açarı yoxlayır",
|
||||
"Unknown (user, device) pair:": "Naməlum (istifadəçi, cihaz) qoşulma:",
|
||||
"Verified key": "Təsdiqlənmiş açar",
|
||||
"Sends the given message coloured as a rainbow": "Verilən mesajı göy qurşağı kimi rəngli göndərir",
|
||||
"Sends the given emote coloured as a rainbow": "Göndərilmiş emote rəngini göy qurşağı kimi göndərir",
|
||||
"Unrecognised command:": "Tanınmayan əmr:",
|
||||
"Add Email Address": "Emal ünvan əlavə etmək",
|
||||
"Add Phone Number": "Telefon nömrəsi əlavə etmək",
|
||||
"e.g. %(exampleValue)s": "e.g. %(exampleValue)s",
|
||||
|
@ -410,7 +386,6 @@
|
|||
"Only continue if you trust the owner of the server.": "Yalnız server sahibinə etibar etsəniz davam edin.",
|
||||
"Trust": "Etibar",
|
||||
"Custom (%(level)s)": "Xüsusi (%(level)s)",
|
||||
"Failed to start chat": "Söhbətə başlamaq olmur",
|
||||
"Failed to invite the following users to the %(roomName)s room:": "Aşağıdakı istifadəçiləri %(roomName)s otağına dəvət etmək alınmadı:",
|
||||
"Room %(roomId)s not visible": "Otaq %(roomId)s görünmür",
|
||||
"Messages": "Mesajlar",
|
||||
|
@ -425,10 +400,6 @@
|
|||
"Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "E-poçtla dəvət etmək üçün şəxsiyyət serverindən istifadə edin. Defolt şəxsiyyət serverini (%(defaultIdentityServerName)s) istifadə etməyə və ya Parametrlərdə idarə etməyə davam edin.",
|
||||
"Use an identity server to invite by email. Manage in Settings.": "E-poçtla dəvət etmək üçün şəxsiyyət serverindən istifadə edin. Parametrlərdə idarə edin.",
|
||||
"Please supply a https:// or http:// widget URL": "Zəhmət olmasa https:// və ya http:// widget URL təmin edin",
|
||||
"Device already verified!": "Cihaz artıq təsdiqləndi!",
|
||||
"WARNING: Device already verified, but keys do NOT MATCH!": "XƏBƏRDARLIQ: Cihaz artıq təsdiqləndi, lakin açarlar uyğun gəlmir!",
|
||||
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "XƏBƏRDARLIQ: ƏSAS VERIFİKASİYA VERİLİR! %(userId)s və cihaz %(deviceId)s üçün imza açarı \"%(fprint)s\" ilə təmin olunmayan \"%(fingerprint)s\". Bu, ünsiyyətlərinizin tutulduğunu ifadə edə bilər!",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Təqdim etdiyiniz imza açarı %(userId)s cihazının %(deviceId)s cihazından aldığınız imza açarına uyğundur. Cihaz təsdiqlənmiş kimi qeyd edildi.",
|
||||
"Forces the current outbound group session in an encrypted room to be discarded": "Şifrəli bir otaqda mövcud qrup sessiyasını ləğv etməyə məcbur edir",
|
||||
"Displays list of commands with usages and descriptions": "İstifadə qaydaları və təsvirləri ilə komanda siyahısını göstərir",
|
||||
"%(senderName)s requested a VoIP conference.": "%(senderName)s VoIP konfrans istədi.",
|
||||
|
|
|
@ -102,10 +102,6 @@
|
|||
"Moderator": "Модератор",
|
||||
"Admin": "Администратор",
|
||||
"Start a chat": "Започване на чат",
|
||||
"Who would you like to communicate with?": "С кой бихте желали да си комуникирате?",
|
||||
"Start Chat": "Започни чат",
|
||||
"Invite new room members": "Покана на нови членове в стаята",
|
||||
"Send Invites": "Изпрати покани",
|
||||
"Failed to invite": "Неуспешна покана",
|
||||
"Failed to invite the following users to the %(roomName)s room:": "Следните потребителите не успяха да бъдат добавени в %(roomName)s:",
|
||||
"You need to be logged in.": "Трябва да влезете в профила си.",
|
||||
|
@ -131,10 +127,7 @@
|
|||
"You are now ignoring %(userId)s": "Вече игнорирате %(userId)s",
|
||||
"Unignored user": "Неигнориран потребител",
|
||||
"You are no longer ignoring %(userId)s": "Вече не игнорирате %(userId)s",
|
||||
"Device already verified!": "Устройството е вече потвърдено!",
|
||||
"WARNING: Device already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: Устройстовото е потвърдено, но ключовете не съвпадат!",
|
||||
"Verified key": "Потвърден ключ",
|
||||
"Unrecognised command:": "Неразпозната команда:",
|
||||
"Reason": "Причина",
|
||||
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s прие поканата за %(displayName)s.",
|
||||
"%(targetName)s accepted an invitation.": "%(targetName)s прие поканата.",
|
||||
|
@ -171,7 +164,6 @@
|
|||
"%(senderName)s made future room history visible to all room members.": "%(senderName)s направи бъдещата история на стаята видима за всички членове в нея.",
|
||||
"%(senderName)s made future room history visible to anyone.": "%(senderName)s направи бъдещата история на стаята видима за всеки.",
|
||||
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s направи бъдещата история на стаята видима по непознат начин (%(visibility)s).",
|
||||
"%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s включи шифроване от край до край (алгоритъм %(algorithm)s).",
|
||||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s от %(fromPowerLevel)s на %(toPowerLevel)s",
|
||||
"%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s смени нивото на достъп на %(powerLevelDiffText)s.",
|
||||
"%(senderName)s changed the pinned messages for the room.": "%(senderName)s смени закачените съобщения за стаята.",
|
||||
|
@ -194,8 +186,6 @@
|
|||
"Enable automatic language detection for syntax highlighting": "Включване на автоматично разпознаване на език за подчертаване на синтаксиса",
|
||||
"Automatically replace plain text Emoji": "Автоматично откриване и заместване на емотикони в текста",
|
||||
"Mirror local video feed": "Показвай ми огледално моя видео образ",
|
||||
"Never send encrypted messages to unverified devices from this device": "Никога не изпращай шифровани съобщения от това устройство до непотвърдени устройства",
|
||||
"Never send encrypted messages to unverified devices in this room from this device": "Никога не изпращай шифровани съобщения от това устройство до непотвърдени устройства в тази стая",
|
||||
"Enable inline URL previews by default": "Включване по подразбиране на URL прегледи",
|
||||
"Enable URL previews for this room (only affects you)": "Включване на URL прегледи за тази стая (засяга само Вас)",
|
||||
"Enable URL previews by default for participants in this room": "Включване по подразбиране на URL прегледи за участници в тази стая",
|
||||
|
@ -223,10 +213,7 @@
|
|||
"New Password": "Нова парола",
|
||||
"Confirm password": "Потвърждаване на парола",
|
||||
"Change Password": "Смяна на парола",
|
||||
"Unable to load device list": "Неуспешно зареждане на списък с устройства",
|
||||
"Authentication": "Автентикация",
|
||||
"Delete %(count)s devices|other": "Изтрий %(count)s устройства",
|
||||
"Delete %(count)s devices|one": "Изтрий устройство",
|
||||
"Device ID": "Идентификатор на устройство",
|
||||
"Last seen": "Последно видян",
|
||||
"Failed to set display name": "Неуспешно задаване на име",
|
||||
|
@ -244,9 +231,6 @@
|
|||
"%(senderName)s sent a video": "%(senderName)s изпрати видео",
|
||||
"%(senderName)s uploaded a file": "%(senderName)s качи файл",
|
||||
"Options": "Настройки",
|
||||
"Undecryptable": "Невъзможно разшифроване",
|
||||
"Encrypted by an unverified device": "Шифровано от непотвърдено устройство",
|
||||
"Unencrypted message": "Нешифровано съобщение",
|
||||
"Please select the destination room for this message": "Моля, изберете стаята, в която искате да изпратите това съобщение",
|
||||
"Blacklisted": "В черния списък",
|
||||
"device id: ": "идентификатор на устройството: ",
|
||||
|
@ -266,8 +250,6 @@
|
|||
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "След като си намалите нивото на достъп, няма да можете да възвърнете тази промяна. Ако сте последния потребител с привилегии в тази стая, ще бъде невъзможно да възвърнете привилегии си.",
|
||||
"Are you sure?": "Сигурни ли сте?",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Няма да можете да възвърнете тази промяна, тъй като повишавате този потребител до същото ниво на достъп като Вашето.",
|
||||
"No devices with registered encryption keys": "Няма устройства с регистрирани ключове за шифроване",
|
||||
"Devices": "Устройства",
|
||||
"Unignore": "Премахни игнорирането",
|
||||
"Ignore": "Игнорирай",
|
||||
"Mention": "Спомени",
|
||||
|
@ -287,20 +269,14 @@
|
|||
"Voice call": "Гласово повикване",
|
||||
"Video call": "Видео повикване",
|
||||
"Upload file": "Качи файл",
|
||||
"Show Text Formatting Toolbar": "Показване на лентата с инструменти за форматиране на текст",
|
||||
"Send an encrypted reply…": "Изпрати шифрован отговор…",
|
||||
"Send a reply (unencrypted)…": "Отговори (нешифрованo)…",
|
||||
"Send an encrypted message…": "Изпрати шифровано съобщение…",
|
||||
"Send a message (unencrypted)…": "Изпрати съобщение (нешифровано)…",
|
||||
"You do not have permission to post to this room": "Нямате разрешение да публикувате в тази стая",
|
||||
"Hide Text Formatting Toolbar": "Скриване на лентата с инструменти за форматиране на текст",
|
||||
"Server error": "Сървърна грешка",
|
||||
"Server unavailable, overloaded, or something else went wrong.": "Сървърът е недостъпен, претоварен или нещо друго се обърка.",
|
||||
"Command error": "Грешка в командата",
|
||||
"bold": "удебелен",
|
||||
"italic": "курсивен",
|
||||
"Markdown is disabled": "Markdown е изключен",
|
||||
"Markdown is enabled": "Markdown е включен",
|
||||
"No pinned messages.": "Няма закачени съобщения.",
|
||||
"Loading...": "Зареждане...",
|
||||
"Pinned Messages": "Закачени съобщения",
|
||||
|
@ -328,7 +304,6 @@
|
|||
"Community Invites": "Покани за общност",
|
||||
"Invites": "Покани",
|
||||
"Favourites": "Любими",
|
||||
"People": "Хора",
|
||||
"Low priority": "Нисък приоритет",
|
||||
"Historical": "Архив",
|
||||
"This room": "В тази стая",
|
||||
|
@ -357,8 +332,6 @@
|
|||
"Advanced": "Разширени",
|
||||
"Add a topic": "Добавете тема",
|
||||
"Jump to first unread message.": "Отиди до първото непрочетено съобщение.",
|
||||
"Invalid alias format": "Невалиден формат на псевдонима",
|
||||
"'%(alias)s' is not a valid format for an alias": "%(alias)s не е валиден формат на псевдоним",
|
||||
"not specified": "неопределен",
|
||||
"Remote addresses for this room:": "Отдалечени адреси на тази стая:",
|
||||
"Local addresses for this room:": "Локалните адреси на тази стая са:",
|
||||
|
@ -408,8 +381,6 @@
|
|||
"Community %(groupId)s not found": "Общност %(groupId)s не е намерена",
|
||||
"Create a new community": "Създаване на нова общност",
|
||||
"Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Създайте общност, за да групирате потребители и стаи! Изградете персонализирана начална страница, за да маркирате своето пространство в Matrix Вселената.",
|
||||
"Unknown (user, device) pair:": "Непозната двойка (потребител, устройство):",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Подписващият ключ, който сте предоставили, съвпада с подписващия ключ, който сте получили от устройството %(deviceId)s на %(userId)s. Устройството е маркирано като потвърдено.",
|
||||
"Jump to message": "Отиди до съобщението",
|
||||
"Jump to read receipt": "Отиди до потвърждението за прочитане",
|
||||
"Revoke Moderator": "Премахване на правата на модератора",
|
||||
|
@ -457,7 +428,6 @@
|
|||
"Blacklist": "Добави в черен списък",
|
||||
"Unverify": "Махни потвърждението",
|
||||
"Verify...": "Потвърди...",
|
||||
"Your unverified device '%(displayName)s' is requesting encryption keys.": "Вашето непотвърдено устройство '%(displayName)s' изисква ключове за шифроване.",
|
||||
"I have verified my email address": "Потвърдих имейл адреса си",
|
||||
"NOT verified": "НЕ е потвърдено",
|
||||
"verified": "потвърдено",
|
||||
|
@ -543,18 +513,13 @@
|
|||
"Unknown error": "Неизвестна грешка",
|
||||
"Incorrect password": "Неправилна парола",
|
||||
"Deactivate Account": "Затвори акаунта",
|
||||
"Device name": "Име на устройство",
|
||||
"Device key": "Ключ на устройство",
|
||||
"Verify device": "Потвърждение на устройство",
|
||||
"Start verification": "Започни потвърждението",
|
||||
"Verification Pending": "Очакване на потвърждение",
|
||||
"Verification": "Потвърждение",
|
||||
"I verify that the keys match": "Потвърждавам, че ключовете съвпадат",
|
||||
"An error has occurred.": "Възникна грешка.",
|
||||
"You added a new device '%(displayName)s', which is requesting encryption keys.": "Добавихте ново устройство '%(displayName)s', което изисква ключове за шифроване.",
|
||||
"Share without verifying": "Сподели без потвърждение",
|
||||
"Ignore request": "Игнорирай поканата",
|
||||
"Loading device info...": "Зареждане на информация за устройството...",
|
||||
"Encryption key request": "Заявка за ключ за шифроване",
|
||||
"Unable to restore session": "Неуспешно възстановяване на сесията",
|
||||
"Invalid Email Address": "Невалиден имейл адрес",
|
||||
|
@ -574,10 +539,6 @@
|
|||
"Username available": "Потребителското име не е заето",
|
||||
"To get started, please pick a username!": "За да започнете, моля изберете потребителско име!",
|
||||
"If you already have a Matrix account you can <a>log in</a> instead.": "Ако вече имате Matrix профил, можете да <a>влезете</a> с него.",
|
||||
"You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "В момента Вие блокирате непотвърдени устройства; за да изпращате съобщения до тези устройства, трябва да ги потвърдите.",
|
||||
"Room contains unknown devices": "Стаята съдържа непознати устройства",
|
||||
"\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" съдържа устройства, който не сте виждали до сега.",
|
||||
"Unknown devices": "Непознати устройства",
|
||||
"Private Chat": "Личен чат",
|
||||
"Public Chat": "Публичен чат",
|
||||
"Alias (optional)": "Псевдоним (по избор)",
|
||||
|
@ -619,8 +580,6 @@
|
|||
"Error whilst fetching joined communities": "Грешка при извличането на общности, към които сте присъединени",
|
||||
"You have no visible notifications": "Нямате видими известия",
|
||||
"Scroll to bottom of page": "Отиди до края на страницата",
|
||||
"Message not sent due to unknown devices being present": "Съобщението не е изпратено поради наличието на непознати устройства",
|
||||
"<showDevicesText>Show devices</showDevicesText>, <sendAnywayText>send anyway</sendAnywayText> or <cancelText>cancel</cancelText>.": "<showDevicesText>Покажи устройствата</showDevicesText>, <sendAnywayText>изпрати въпреки това</sendAnywayText> или <cancelText>откажи</cancelText>.",
|
||||
"%(count)s of your messages have not been sent.|other": "Някои от Вашите съобщение не бяха изпратени.",
|
||||
"%(count)s of your messages have not been sent.|one": "Вашето съобщение не беше изпратено.",
|
||||
"%(count)s <resendText>Resend all</resendText> or <cancelText>cancel all</cancelText> now. You can also select individual messages to resend or cancel.|other": "<resendText>Изпрати всички отново</resendText> или <cancelText>откажи всички</cancelText> сега. Също така може да изберете индивидуални съобщения, които да изпратите отново или да откажете.",
|
||||
|
@ -652,12 +611,9 @@
|
|||
"Light theme": "Светла тема",
|
||||
"Dark theme": "Тъмна тема",
|
||||
"Success": "Успешно",
|
||||
"Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Вашата парола беше успешно сменена. Няма да получавате известия на други устройства, докато не влезете отново в профила си от тях",
|
||||
"<not supported>": "<не се поддържа>",
|
||||
"Import E2E room keys": "Импортирай E2E ключове",
|
||||
"Cryptography": "Криптография",
|
||||
"Device ID:": "Идентификатор на устройството:",
|
||||
"Device key:": "Ключ на устройството:",
|
||||
"Riot collects anonymous analytics to allow us to improve the application.": "Riot събира анонимни статистики, за да ни позволи да подобрим приложението.",
|
||||
"Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Поверителността е важна за нас, затова не събираме лични или идентифициращи Вас данни.",
|
||||
"Learn more about how we use analytics.": "Научете повече за това как използваме статистическите данни.",
|
||||
|
@ -678,7 +634,6 @@
|
|||
"click to reveal": "натиснете за показване",
|
||||
"Homeserver is": "Home сървър:",
|
||||
"Identity Server is": "Сървър за самоличност:",
|
||||
"matrix-react-sdk version:": "Версия на matrix-react-sdk:",
|
||||
"riot-web version:": "Версия на riot-web:",
|
||||
"olm version:": "Версия на olm:",
|
||||
"Failed to send email": "Неуспешно изпращане на имейл",
|
||||
|
@ -706,7 +661,6 @@
|
|||
"Kicks user with given id": "Изгонва потребителя с даден идентификатор",
|
||||
"Changes your display nickname": "Сменя Вашия псевдоним",
|
||||
"Searches DuckDuckGo for results": "Търси в DuckDuckGo за резултати",
|
||||
"Verifies a user, device, and pubkey tuple": "Потвърждава потребител, устройство или ключова двойка",
|
||||
"Ignores a user, hiding their messages from you": "Игнорира потребител, скривайки съобщенията му от Вас",
|
||||
"Stops ignoring a user, showing their messages going forward": "Спира игнорирането на потребител, показвайки съобщенията му занапред",
|
||||
"Commands": "Команди",
|
||||
|
@ -726,7 +680,6 @@
|
|||
"Claimed Ed25519 fingerprint key": "Заявен ключов отпечатък Ed25519",
|
||||
"End-to-end encryption information": "Информация за шифроването от край до край",
|
||||
"Event information": "Информация за събитието",
|
||||
"Sender device information": "Информация за устройството на подателя",
|
||||
"Passphrases must match": "Паролите трябва да съвпадат",
|
||||
"Passphrase must not be empty": "Паролата не трябва да е празна",
|
||||
"Export room keys": "Експортиране на ключове за стаята",
|
||||
|
@ -737,16 +690,10 @@
|
|||
"File to import": "Файл за импортиране",
|
||||
"Import": "Импортирай",
|
||||
"Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Когато тази страница съдържа информация идентифицираща Вас (като например стая, потребител или идентификатор на група), тези данни биват премахнати преди да бъдат изпратени до сървъра.",
|
||||
"There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Има непознати устройства в тази стая. Ако продължите без да ги потвърдите, ще бъде възможно за някого да подслушва Вашия разговор.",
|
||||
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ВНИМАНИЕ: НЕУСПЕШНО ПОТВЪРЖДАВАНЕ НА КЛЮЧА! Ключът за подписване за %(userId)s и устройството %(deviceId)s е \"%(fprint)s\", което не съвпада с предоставения ключ \"%(fingerprint)s\". Това може да означава, че Вашата комуникация е прихваната!",
|
||||
"Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Смяната на парола ще нулира всички ключове за шифроване от край до край на всички устройства, правейки историята на шифрования чат невъзможна за четене, освен ако първо не експортирате ключовете за стаята и ги импортирате отново след това. В бъдеще това ще бъде подобрено.",
|
||||
"You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "На път сте да бъдете отведени до друг сайт, където можете да удостоверите профила си за използване с %(integrationsUrl)s. Искате ли да продължите?",
|
||||
"Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Сигурни ли сте, че искате да премахнете (изтриете) това събитие? Забележете, че ако изтриете събитие за промяна на името на стая или тема, това може да обърне промяната.",
|
||||
"To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "За да потвърдите, че на това устройство може да се вярва, моля свържете се със собственика му по друг начин (напр. на живо или чрез телефонен разговор) и го попитайте дали ключът, който той вижда в неговите настройки на потребителя за това устройство, съвпада с ключа по-долу:",
|
||||
"If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Ако съвпада, моля натиснете бутона за потвърждение по-долу. Ако не, то тогава някой друг имитира това устройство и вероятно искате вместо това да натиснете бутона за черен списък.",
|
||||
"If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Ако преди сте използвали по-нова версия на Riot, Вашата сесия може да не бъде съвместима с текущата версия. Затворете този прозорец и се върнете в по-новата версия.",
|
||||
"This will be your account name on the <span></span> homeserver, or you can pick a <a>different server</a>.": "Това ще бъде името на профила Ви на <span></span> Home сървъра, или можете да изберете <a>друг сървър</a>.",
|
||||
"We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Препоръчваме Ви да минете през процеса за потвърждение за всяко устройство, за да потвърдите, че принадлежат на легитимен собственик. Ако предпочитате, можете да изпратите съобщение без потвърждение.",
|
||||
"Data from an older version of Riot has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Засечени са данни от по-стара версия на Riot. Това ще доведе до неправилна работа на криптографията от край до край в по-старата версия. Шифрованите от край до край съобщения, които са били обменени наскоро (при използването на по-стара версия), може да не успеят да бъдат разшифровани в тази версия. Това също може да доведе до неуспех в обмяната на съобщения в тази версия. Ако имате проблеми, излезте и влезте отново в профила си. За да запазите историята на съобщенията, експортирайте и импортирайте отново Вашите ключове.",
|
||||
"Can't connect to homeserver - please check your connectivity, ensure your <a>homeserver's SSL certificate</a> is trusted, and that a browser extension is not blocking requests.": "Няма връзка с Home сървъра. Моля, проверете Вашата връзка. Уверете се, че <a>SSL сертификатът на Home сървъра</a> е надежден и че някое разширение на браузъра не блокира заявките.",
|
||||
"none": "няма",
|
||||
|
@ -756,11 +703,7 @@
|
|||
"The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Експортираният файл може да бъде предпазен с парола. Трябва да въведете парола тук, за да разшифровате файла.",
|
||||
"Did you know: you can use communities to filter your Riot.im experience!": "Знаете ли, че: може да използвате общности, за да филтрирате Вашето Riot.im преживяване!",
|
||||
"To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "За да създадете филтър, дръпнете и пуснете аватара на общността върху панела за филтриране в най-лявата част на екрана. По всяко време може да натиснете върху аватар от панела, за да видите само стаите и хората от тази общност.",
|
||||
"Your key share request has been sent - please check your other devices for key share requests.": "Заявката за споделяне на ключ е изпратена. Моля, проверете заявките за споделяне на другите Ви устройства.",
|
||||
"Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Заявки за споделяне на ключове се изпращат автоматично към другите Ви устройства. Ако сте ги отхвърлили от другите устройства, натиснете тук, за да заявите нови за тази сесия.",
|
||||
"If your other devices do not have the key for this message you will not be able to decrypt them.": "Ако другите Ви устройства нямат ключа за това съобщение, няма да можете да го разшифровате.",
|
||||
"Key request sent.": "Заявката за ключ е изпратена.",
|
||||
"<requestLink>Re-request encryption keys</requestLink> from your other devices.": "<requestLink>Заявете отново ключове за шифроване</requestLink> от другите Ви устройства.",
|
||||
"Code": "Код",
|
||||
"If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Ако сте изпратили грешка чрез GitHub, логовете за дебъгване могат да ни помогнат да проследим проблема. Логовете за дебъгване съдържат данни за използване на приложението, включващи потребителското Ви име, идентификаторите или псевдонимите на стаите или групите, които сте посетили, и потребителските имена на други потребители. Те не съдържат съобщения.",
|
||||
"Submit debug logs": "Изпрати логове за дебъгване",
|
||||
|
@ -823,7 +766,6 @@
|
|||
"Noisy": "Шумно",
|
||||
"Collecting app version information": "Събиране на информация за версията на приложението",
|
||||
"Delete the room alias %(alias)s and remove %(name)s from the directory?": "Изтриване на псевдонима %(alias)s на стаята и премахване на %(name)s от директорията?",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "Това ще Ви позволи да се върнете в профила си след излизане от него, и да влезете от други устройства.",
|
||||
"Enable notifications for this account": "Включване на известия за този профил",
|
||||
"Invite to this community": "Покани в тази общност",
|
||||
"Search…": "Търсене…",
|
||||
|
@ -912,8 +854,6 @@
|
|||
"Your User Agent": "Вашият браузър",
|
||||
"Your device resolution": "Разделителната способност на устройството Ви",
|
||||
"Always show encryption icons": "Винаги показвай икони за шифроване",
|
||||
"Unable to reply": "Не може да се отговори",
|
||||
"At this time it is not possible to reply with an emote.": "В момента не може да се отговори с емотикона.",
|
||||
"Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Не може да се зареди събитието, на което е отговорено. Или не съществува или нямате достъп да го видите.",
|
||||
"Popout widget": "Изкарай в нов прозорец",
|
||||
"Clear Storage and Sign Out": "Изчисти запазените данни и излез",
|
||||
|
@ -965,12 +905,6 @@
|
|||
"Permission Required": "Необходимо е разрешение",
|
||||
"A call is currently being placed!": "В момента се осъществява разговор!",
|
||||
"You do not have permission to start a conference call in this room": "Нямате достъп да започнете конферентен разговор в тази стая",
|
||||
"deleted": "изтрито",
|
||||
"underlined": "подчертано",
|
||||
"inline-code": "код",
|
||||
"block-quote": "цитат",
|
||||
"bulleted-list": "списък (с тирета)",
|
||||
"numbered-list": "номериран списък",
|
||||
"Failed to remove widget": "Неуспешно премахване на приспособление",
|
||||
"An error ocurred whilst trying to remove the widget from the room": "Възникна грешка при премахването на приспособлението от стаята",
|
||||
"System Alerts": "Системни уведомления",
|
||||
|
@ -1059,11 +993,6 @@
|
|||
"Encrypted messages in group chats": "Шифровани съобщения в групови чатове",
|
||||
"Delete Backup": "Изтрий резервното копие",
|
||||
"Unable to load key backup status": "Неуспешно зареждане на състоянието на резервното копие на ключа",
|
||||
"Backup has a <validity>valid</validity> signature from this device": "Резервното копие има <validity>валиден</validity> подпис за това устройство",
|
||||
"Backup has a <validity>valid</validity> signature from <verify>unverified</verify> device <device></device>": "Резервното копие има <validity>валиден</validity> подпис от <verify>непотвърдено</verify> устройство <device></device>",
|
||||
"Backup has an <validity>invalid</validity> signature from <verify>verified</verify> device <device></device>": "Резервното копие има <validity>невалиден</validity> подпис от <verify>потвърдено</verify> устройство <device></device>",
|
||||
"Backup has an <validity>invalid</validity> signature from <verify>unverified</verify> device <device></device>": "Резервното копие има <validity>невалиден</validity> подпис от <verify>непотвърдено</verify> устройство <device></device>",
|
||||
"Backup is not signed by any of your devices": "Резервното копие не е подписано от нито едно Ваше устройство",
|
||||
"Backup version: ": "Версия на резервното копие: ",
|
||||
"Algorithm: ": "Алгоритъм: ",
|
||||
"Don't ask again": "Не питай пак",
|
||||
|
@ -1090,7 +1019,6 @@
|
|||
"This looks like a valid recovery key!": "Това изглежда като валиден ключ за възстановяване!",
|
||||
"Not a valid recovery key": "Не е валиден ключ за възстановяване",
|
||||
"Access your secure message history and set up secure messaging by entering your recovery key.": "Получете достъп до защитената история на съобщенията и настройте защитен чат, чрез въвеждане на ключа за възстановяване.",
|
||||
"If you've forgotten your recovery passphrase you can <button>set up new recovery options</button>": "Ако сте забравили паролата за възстановяване, може да <button>настройте нов вариант за възстановяване</button>",
|
||||
"Invalid homeserver discovery response": "Невалиден отговор по време на откриването на конфигурацията за сървъра",
|
||||
"Invalid identity server discovery response": "Невалиден отговор по време на откриването на конфигурацията за сървъра за самоличност",
|
||||
"General failure": "Обща грешка",
|
||||
|
@ -1107,12 +1035,9 @@
|
|||
"Your Recovery Key": "Вашия ключ за възстановяване",
|
||||
"Copy to clipboard": "Копирай в клипборд",
|
||||
"Download": "Свали",
|
||||
"Your Recovery Key has been <b>copied to your clipboard</b>, paste it to:": "Ключа Ви за възстановяване <b>беше копиран в клипборда</b>, поставете го в:",
|
||||
"Your Recovery Key is in your <b>Downloads</b> folder.": "Ключът Ви за възстановяване е в папка <b>Изтеглени</b>.",
|
||||
"<b>Print it</b> and store it somewhere safe": "<b>Принтирайте го</b> и го съхранявайте на безопасно място",
|
||||
"<b>Save it</b> on a USB key or backup drive": "<b>Запазете го</b> на USB или резервен диск",
|
||||
"<b>Copy it</b> to your personal cloud storage": "<b>Копирайте го</b> в персонално облачно пространство",
|
||||
"Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another device.": "Без настроено Възстановяване на Защитени Съобщения, няма да може да възстановите шифрованата история на съобщенията, в случай че излезете от профила си или използвате друго устройство.",
|
||||
"Set up Secure Message Recovery": "Настрой Възстановяване на Защитени Съобщения",
|
||||
"Keep it safe": "Пазете го в безопасност",
|
||||
"Create Key Backup": "Създай резервно копие на ключа",
|
||||
|
@ -1123,7 +1048,6 @@
|
|||
"Straight rows of keys are easy to guess": "Клавиши от прави редици са лесни за отгатване",
|
||||
"Short keyboard patterns are easy to guess": "Къси клавиатурни последователности са лесни за отгатване",
|
||||
"Custom user status messages": "Собствено статус съобщение",
|
||||
"Backup has a <validity>valid</validity> signature from <verify>verified</verify> device <device></device>": "Резервното копие има <validity>валиден</validity> подпис от <verify>потвърдено</verify> устройство <device></device>",
|
||||
"Unable to load commit detail: %(msg)s": "Неуспешно зареждане на информация за commit: %(msg)s",
|
||||
"Set a new status...": "Задаване на нов статус...",
|
||||
"Clear status": "Изчисти статуса",
|
||||
|
@ -1164,20 +1088,17 @@
|
|||
"Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Защитените съобщения с този потребител са шифровани от край-до-край и не могат да бъдат прочетени от други.",
|
||||
"Got It": "Разбрах",
|
||||
"Verify this user by confirming the following number appears on their screen.": "Потвърдете този потребител като се уверите, че следното число се вижда на екрана му.",
|
||||
"For maximum security, we recommend you do this in person or use another trusted means of communication.": "За максимална сигурност, препоръчваме да го направите на живо или да използвате друг надежден начин за комуникация.",
|
||||
"Yes": "Да",
|
||||
"No": "Не",
|
||||
"We've sent you an email to verify your address. Please follow the instructions there and then click the button below.": "Изпратихме Ви имейл за да потвърдим адреса Ви. Последвайте инструкциите в имейла и след това кликнете на бутона по-долу.",
|
||||
"Email Address": "Имейл адрес",
|
||||
"Backing up %(sessionsRemaining)s keys...": "Правене на резервно копие на %(sessionsRemaining)s ключа...",
|
||||
"All keys backed up": "Всички ключове са в резервното копие",
|
||||
"Backup has a signature from <verify>unknown</verify> device with ID %(deviceId)s.": "Резервното копие съдържа подпис от <verify>непознато</verify> устройство с идентификатор %(deviceId)s.",
|
||||
"Add an email address to configure email notifications": "Добавете имейл адрес за да конфигурирате уведомления по имейл",
|
||||
"Unable to verify phone number.": "Неуспешно потвърждение на телефонния номер.",
|
||||
"Verification code": "Код за потвърждение",
|
||||
"Phone Number": "Телефонен номер",
|
||||
"Profile picture": "Профилна снимка",
|
||||
"Upload profile picture": "Качи профилна снимка",
|
||||
"Display Name": "Име",
|
||||
"Room information": "Информация за стаята",
|
||||
"Internal room ID:": "Идентификатор на стаята:",
|
||||
|
@ -1220,8 +1141,6 @@
|
|||
"Voice & Video": "Глас и видео",
|
||||
"Main address": "Основен адрес",
|
||||
"Room avatar": "Снимка на стаята",
|
||||
"Upload room avatar": "Качи снимка на стаята",
|
||||
"No room avatar": "Няма снимка на стаята",
|
||||
"Room Name": "Име на стаята",
|
||||
"Room Topic": "Тема на стаята",
|
||||
"Join": "Присъедини се",
|
||||
|
@ -1231,7 +1150,6 @@
|
|||
"Waiting for partner to accept...": "Изчакване партньора да приеме...",
|
||||
"Use two-way text verification": "Използвай двустранно текстово потвърждение",
|
||||
"Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Потвърди потребителя и го маркирай като доверен. Доверяването на потребители Ви дава допълнително спокойствие при използване на съобщения шифровани от край-до-край.",
|
||||
"Verifying this user will mark their device as trusted, and also mark your device as trusted to them.": "Потвърждението на този потребител ще маркира устройството му като доверено, а Вашето ще бъде маркирано като доверено при него.",
|
||||
"Waiting for partner to confirm...": "Изчакване партньора да потвърди...",
|
||||
"Incoming Verification Request": "Входяща заявка за потвърждение",
|
||||
"To help avoid duplicate issues, please <existingIssuesLink>view existing issues</existingIssuesLink> first (and add a +1) or <newIssueLink>create a new issue</newIssueLink> if you can't find it.": "За да се избегнат дублиращи се проблеми, моля първо <existingIssuesLink>прегледайте съществуващите проблеми</existingIssuesLink> (и гласувайте с +1) или <newIssueLink>създайте нов проблем</newIssueLink>, ако не сте намерили съществуващ.",
|
||||
|
@ -1267,10 +1185,7 @@
|
|||
"Keep going...": "Продължавайте...",
|
||||
"Starting backup...": "Започване на резервното копие...",
|
||||
"A new recovery passphrase and key for Secure Messages have been detected.": "Беше открита нова парола и ключ за Защитени Съобщения.",
|
||||
"This device is encrypting history using the new recovery method.": "Устройството шифрова историята използвайки новия метод за възстановяване.",
|
||||
"Recovery Method Removed": "Методът за възстановяване беше премахнат",
|
||||
"This device has detected that your recovery passphrase and key for Secure Messages have been removed.": "Устройството откри, че паролата за възстановяване и ключът за Защитени Съобщения са били премахнати.",
|
||||
"If you did this accidentally, you can setup Secure Messages on this device which will re-encrypt this device's message history with a new recovery method.": "Ако сте извършили това по погрешка, може да настройте Защитени Съобщения за това устройство, което ще зашифрова наново историята на съобщенията за това устройство, използвайки новия метод за възстановяване.",
|
||||
"If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Ако не сте премахнали метода за възстановяване, е възможно нападател да се опитва да получи достъп до акаунта Ви. Променете паролата на акаунта и настройте нов метод за възстановяване веднага от Настройки.",
|
||||
"The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Файлът '%(fileName)s' надхвърля ограничението за размер на файлове за този сървър",
|
||||
"Gets or sets the room topic": "Взима или настройва темата на стаята",
|
||||
|
@ -1329,7 +1244,6 @@
|
|||
"Book": "Книга",
|
||||
"Pencil": "Молив",
|
||||
"Paperclip": "Кламер",
|
||||
"Padlock": "Катинар",
|
||||
"Key": "Ключ",
|
||||
"Hammer": "Чук",
|
||||
"Telephone": "Телефон",
|
||||
|
@ -1347,12 +1261,6 @@
|
|||
"Headphones": "Слушалки",
|
||||
"Folder": "Папка",
|
||||
"Pin": "Кабърче",
|
||||
"Your homeserver does not support device management.": "Вашият сървър не поддържа управление на устройствата.",
|
||||
"This backup is trusted because it has been restored on this device": "Това резервно копие е доверено, понеже е било възстановено на това устройство",
|
||||
"Some devices for this user are not trusted": "Някои устройства на този потребител не са доверени",
|
||||
"Some devices in this encrypted room are not trusted": "Някои устройства в тази шифрована стая не са доверени",
|
||||
"All devices for this user are trusted": "Всички устройства на този потребител са доверени",
|
||||
"All devices in this encrypted room are trusted": "Всички устройства в тази шифрована стая са доверени",
|
||||
"Recovery Key Mismatch": "Ключа за възстановяване не съвпада",
|
||||
"Incorrect Recovery Passphrase": "Неправилна парола за възстановяване",
|
||||
"Backup could not be decrypted with this passphrase: please verify that you entered the correct recovery passphrase.": "Резервното копие не можа да бъде разшифровано с тази парола: потвърдете, че сте въвели правилната парола.",
|
||||
|
@ -1362,16 +1270,13 @@
|
|||
"This homeserver does not support communities": "Този сървър не поддържа общности",
|
||||
"A verification email will be sent to your inbox to confirm setting your new password.": "Ще Ви бъде изпратен имейл за потвърждение на новата парола.",
|
||||
"Your password has been reset.": "Паролата беше анулирана.",
|
||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "Бяхте изхвърлени от профила на всички ваши устройства и вече няма да получавате известия на тях. За да включите известията отново, влезте пак от всяко едно устройство.",
|
||||
"This homeserver does not support login using email address.": "Този сървър не поддържа влизане в профил посредством имейл адрес.",
|
||||
"Registration has been disabled on this homeserver.": "Регистрацията е изключена на този сървър.",
|
||||
"Unable to query for supported registration methods.": "Неуспешно взимане на поддържаните методи за регистрация.",
|
||||
"Are you sure? You will lose your encrypted messages if your keys are not backed up properly.": "Сигурни ли сте? Ако нямате работещо резервно копие на ключовете, ще загубите достъп до шифрованите съобщения.",
|
||||
"Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Шифрованите съобщения са защитени с шифроване от край до край. Само Вие и получателят (получателите) имате ключове за четенето им.",
|
||||
"Restore from Backup": "Възстанови от резервно копие",
|
||||
"This device is backing up your keys. ": "Това устройство прави резервни копия на ключовете. ",
|
||||
"Back up your keys before signing out to avoid losing them.": "Направете резервно копие на ключовете преди изход от профила, за да не ги загубите.",
|
||||
"Your keys are <b>not being backed up from this device</b>.": "<b>Това устройство не прави резервно копие</b> на ключовете Ви.",
|
||||
"Start using Key Backup": "Включи резервни копия за ключовете",
|
||||
"Never lose encrypted messages": "Никога не губете шифровани съобщения",
|
||||
"Messages in this room are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Съобщенията в тази стая са защитени с шифроване от край до край. Само Вие и получателят (получателите) имате ключове за разчитането им.",
|
||||
|
@ -1390,7 +1295,6 @@
|
|||
"Set up with a Recovery Key": "Настрой с ключ за възстановяване",
|
||||
"Please enter your passphrase a second time to confirm.": "Въведете паролата отново за потвърждение.",
|
||||
"Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your passphrase.": "Ключът за възстановяване дава допълнителна сигурност - може да го използвате за да възстановите достъпа до шифрованите съобщения, в случай че забравите паролата.",
|
||||
"Keep your recovery key somewhere very secure, like a password manager (or a safe)": "Пазете ключът за възстановяване на много сигурно място, например в password manager програма или сейф",
|
||||
"Your keys are being backed up (the first backup could take a few minutes).": "Прави се резервно копие на ключовете Ви (първото копие може да отнеме няколко минути).",
|
||||
"Secure your backup with a passphrase": "Защитете резервното копие с парола",
|
||||
"Confirm your passphrase": "Потвърдете паролата",
|
||||
|
@ -1448,22 +1352,15 @@
|
|||
"Power level": "Ниво на достъп",
|
||||
"Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, or <safariLink>Safari</safariLink> for the best experience.": "Инсталирайте <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink> или <safariLink>Safari</safariLink> за най-добра работа.",
|
||||
"Want more than a community? <a>Get your own server</a>": "Искате повече от общност? <a>Сдобийте се със собствен сървър</a>",
|
||||
"Changing your password will reset any end-to-end encryption keys on all of your devices, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another device before resetting your password.": "Промяната на паролата Ви, ще анулира всички ключове за шифроване от-край-до-край по всички Ваши устройства, правейки историята на чата нечетима. Настройте резервно копие на ключовете или експортирайте ключовете от друго устройство преди да промените паролата си.",
|
||||
"Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Дали използвате 'breadcrumbs' функцията (аватари над списъка със стаи)",
|
||||
"Replying With Files": "Отговаряне с файлове",
|
||||
"At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "Все още не е възможно да отговорите с файл. Искате ли да качите файла без той да бъде отговор?",
|
||||
"The file '%(fileName)s' failed to upload.": "Файлът '%(fileName)s' не можа да бъде качен.",
|
||||
"Room upgrade confirmation": "Потвърждение на обновяването на стаята",
|
||||
"Upgrading a room can be destructive and isn't always necessary.": "Обновяването на стаята може да бъде деструктивно и не винаги е задължително.",
|
||||
"Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Обновяването на стаи обикновено се препоръчва за стаи с версии считащи се за <i>нестабилни</i>. Нестабилните версии може да имат бъгове, липсващи функции или проблеми със сигурността.",
|
||||
"Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.": "Обновяванията на стаи обикновено повлияват само <i>сървърната</i> обработка. Ако имате проблем с Riot, моля съобщете за него със <issueLink />.",
|
||||
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "<b>Внимание</b>: Обновяването на стаята <i>няма автоматично да прехвърли членовете в новата версия на стаята.</i> Ще изпратим съобщение в старата стая с връзка към новата - членовете на стаята ще трябва да кликнат на връзката за да влязат в новата стая.",
|
||||
"Adds a custom widget by URL to the room": "Добавя собствено приспособление от URL в стаята",
|
||||
"Please supply a https:// or http:// widget URL": "Моля, укажете https:// или http:// адрес на приспособление",
|
||||
"You cannot modify widgets in this room.": "Не можете да модифицирате приспособления в тази стая.",
|
||||
"%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s премахна покана към %(targetDisplayName)s за присъединяване в стаята.",
|
||||
"Enable desktop notifications for this device": "Включи известия на работния плот за това устройство",
|
||||
"Enable audible notifications for this device": "Включи звукови уведомления за това устройство",
|
||||
"Upgrade this room to the recommended room version": "Обнови тази стая до препоръчаната версия на стаята",
|
||||
"This room is running room version <roomVersion />, which this homeserver has marked as <i>unstable</i>.": "Тази стая използва версия на стая <roomVersion />, която сървърът счита за <i>нестабилна</i>.",
|
||||
"Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Обновяването на тази стая ще изключи текущата стая и ще създаде обновена стая със същото име.",
|
||||
|
@ -1504,8 +1401,6 @@
|
|||
"A conference call could not be started because the integrations server is not available": "Не може да бъде започнат конферентен разговор, защото сървърът за интеграции не е достъпен",
|
||||
"The server does not support the room version specified.": "Сървърът не поддържа указаната версия на стая.",
|
||||
"Name or Matrix ID": "Име или Matrix идентификатор",
|
||||
"Email, name or Matrix ID": "Имейл, име или Matrix идентификатор",
|
||||
"Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />.": "Потвърдете, че искате да обновите стаята от <oldVersion /> до <newVersion />.",
|
||||
"Changes your avatar in this current room only": "Променя снимката Ви само в тази стая",
|
||||
"Unbans user with given ID": "Премахва блокирането на потребител с даден идентификатор",
|
||||
"Sends the given message coloured as a rainbow": "Изпраща текущото съобщение оцветено като дъга",
|
||||
|
@ -1515,10 +1410,6 @@
|
|||
"Sends the given emote coloured as a rainbow": "Изпраща дадената емоция, оцветена като дъга",
|
||||
"Show hidden events in timeline": "Покажи скрити събития по времевата линия",
|
||||
"When rooms are upgraded": "Когато стаите се актуализират",
|
||||
"This device is <b>not backing up your keys</b>, but you do have an existing backup you can restore from and add to going forward.": "Това устройстовото <b>не архивира ключовете ви</b>, вие обаче имате съществуващ архив, от който можете да ги възстановите и към който да ги добавяте в бъдеще.",
|
||||
"Connect this device to key backup before signing out to avoid losing any keys that may only be on this device.": "Преди да се отпишете, свържете устройство си към архивирането, за да предотвратите загуба на ключове, който може да се намират само на него.",
|
||||
"Connect this device to Key Backup": "Свържете това устройство към Архивиране на ключове",
|
||||
"Backup has an <validity>invalid</validity> signature from this device": "Архивирането получи <validity>невалиден</validity> подпис от това устройство",
|
||||
"this room": "тази стая",
|
||||
"View older messages in %(roomName)s.": "Виж по-стари съобщения в %(roomName)s.",
|
||||
"Joining room …": "Влизане в стая …",
|
||||
|
@ -1612,8 +1503,6 @@
|
|||
"Changes your avatar in all rooms": "Променя снимката ви във всички стаи",
|
||||
"Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "Моля, кажете ни какво се обърка, или още по-добре - създайте проблем в GitHub обясняващ ситуацията.",
|
||||
"Removing…": "Премахване…",
|
||||
"Clear all data on this device?": "Изчистване на всички данни от това устройство?",
|
||||
"Clearing all data from this device is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Изчистването на всички данни от устройството е необратимо. Шифрованите съобщения ще бъдат загубени, освен ако не е било направено резервно копие на ключовете.",
|
||||
"Clear all data": "Изчисти всички данни",
|
||||
"Your homeserver doesn't seem to support this feature.": "Не изглежда сървърът ви да поддържа тази функция.",
|
||||
"Resend edit": "Изпрати наново корекцията",
|
||||
|
@ -1621,14 +1510,12 @@
|
|||
"Resend removal": "Изпрати наново премахването",
|
||||
"Failed to re-authenticate due to a homeserver problem": "Неуспешна повторна автентикация поради проблем със сървъра",
|
||||
"Failed to re-authenticate": "Неуспешна повторна автентикация",
|
||||
"Regain access to your account and recover encryption keys stored on this device. Without them, you won’t be able to read all of your secure messages on any device.": "Възвърнете си достъпа до профила и възстановете ключовете за шифроване съхранени на това устройство. Без тях няма да можете да четете защитени съобщения на кое да е устройство.",
|
||||
"Enter your password to sign in and regain access to your account.": "Въведете паролата си за да влезете и да възстановите достъп до профила.",
|
||||
"Forgotten your password?": "Забравили сте си паролата?",
|
||||
"Sign in and regain access to your account.": "Влез и възвърни достъп до профила.",
|
||||
"You cannot sign in to your account. Please contact your homeserver admin for more information.": "Не можете да влезете в профила си. Свържете се с администратора на сървъра за повече информация.",
|
||||
"You're signed out": "Излязохте от профила",
|
||||
"Clear personal data": "Изчисти личните данни",
|
||||
"Warning: Your personal data (including encryption keys) is still stored on this device. Clear it if you're finished using this device, or want to sign in to another account.": "Внимание: личните ви данни (включително ключове за шифроване) все още се съхраняват на това устройство. Изчистете, ако сте приключили с използването на това устройство или искате да влезете в друг профил.",
|
||||
"Identity Server": "Сървър за самоличност",
|
||||
"Find others by phone or email": "Открийте други по телефон или имейл",
|
||||
"Be found by phone or email": "Бъдете открит по телефон или имейл",
|
||||
|
@ -1641,7 +1528,6 @@
|
|||
"Please ask the administrator of your homeserver (<code>%(homeserverDomain)s</code>) to configure a TURN server in order for calls to work reliably.": "Попитайте администратора на сървъра ви (<code>%(homeserverDomain)s</code>) да конфигурира TURN сървър, за да може разговорите да работят надеждно.",
|
||||
"Alternatively, you can try to use the public server at <code>turn.matrix.org</code>, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "Като алтернатива, може да използвате публичния сървър <code>turn.matrix.org</code>, но той не е толкова надежден, а и IP адресът ви ще бъде споделен с него. Може да управлявате това в Настройки.",
|
||||
"Try using turn.matrix.org": "Опитай turn.matrix.org",
|
||||
"Failed to start chat": "Неуспешно започване на чат",
|
||||
"Messages": "Съобщения",
|
||||
"Actions": "Действия",
|
||||
"Displays list of commands with usages and descriptions": "Показва списък с команди, начин на използване и описания",
|
||||
|
@ -1667,7 +1553,6 @@
|
|||
"Discovery": "Откриване",
|
||||
"Deactivate account": "Деактивиране на акаунт",
|
||||
"Always show the window menu bar": "Винаги показвай менютата на прозореца",
|
||||
"A device's public name is visible to people you communicate with": "Публичното име на устройството е видимо от всички, с които комуникирате",
|
||||
"Unable to revoke sharing for email address": "Неуспешно оттегляне на споделянето на имейл адреса",
|
||||
"Unable to share email address": "Неуспешно споделяне на имейл адрес",
|
||||
"Revoke": "Оттегли",
|
||||
|
@ -1680,7 +1565,6 @@
|
|||
"Remove %(email)s?": "Премахни %(email)s?",
|
||||
"Remove %(phone)s?": "Премахни %(phone)s?",
|
||||
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "Беше изпратено SMS съобщение към +%(msisdn)s. Въведете съдържащият се код за потвърждение.",
|
||||
"To verify that this device can be trusted, please check that the key you see in User Settings on that device matches the key below:": "За да потвърдите, че устройството е доверено, проверете дали ключът в Потребителски Настройки на устройството съвпада с ключа по-долу:",
|
||||
"Command Help": "Помощ за команди",
|
||||
"No identity server is configured: add one in server settings to reset your password.": "Не е конфигуриран сървър за самоличност: добавете такъв в настройки за сървъри за да може да възстановите паролата си.",
|
||||
"You do not have the required permissions to use this command.": "Нямате необходимите привилегии за да използвате тази команда.",
|
||||
|
@ -1772,7 +1656,6 @@
|
|||
"Add Phone Number": "Добави телефонен номер",
|
||||
"This action requires accessing the default identity server <server /> to validate an email address or phone number, but the server does not have any terms of service.": "Това действие изисква връзка със сървъра за самоличност <server /> за валидиране на имейл адреса или телефонния номер, но сървърът не предоставя условия за ползване.",
|
||||
"Trust": "Довери се",
|
||||
"Use the new, faster, composer for writing messages": "Използвай новия, по-бърз редактор за писане на съобщения",
|
||||
"Show previews/thumbnails for images": "Показвай преглед (умален размер) на снимки",
|
||||
"You should <b>remove your personal data</b> from identity server <idserver /> before disconnecting. Unfortunately, identity server <idserver /> is currently offline or cannot be reached.": "Би било добре да <b>премахнете личните си данни</b> от сървъра за самоличност <idserver /> преди прекъсване на връзката. За съжаление, сървърът за самоличност <idserver /> в момента не е достъпен.",
|
||||
"You should:": "Ще е добре да:",
|
||||
|
@ -1841,8 +1724,6 @@
|
|||
"%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s започна гласово обаждане. (не се поддържа от този браузър)",
|
||||
"%(senderName)s placed a video call.": "%(senderName)s започна видео обаждане.",
|
||||
"%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s започна видео обаждане. (не се поддържа от този браузър)",
|
||||
"Send verification requests in direct message, including a new verification UX in the member panel.": "Изпращай заявки за потвърждение в директни съобщения, както и нов панел за верификация на членове.",
|
||||
"Enable cross-signing to verify per-user instead of per-device (in development)": "Включи кръстосано-подписване, за да се верифицира на ниво потребител, а не устройство (в процес на разработка)",
|
||||
"Enable local event indexing and E2EE search (requires restart)": "Включи локални индексиране на събития и E2EE търсене (изисква рестартиране)",
|
||||
"Match system theme": "Напасване със системната тема",
|
||||
"My Ban List": "Моя списък с блокирания",
|
||||
|
@ -1874,11 +1755,9 @@
|
|||
"%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s промени правило блокиращо достъпа до неща отговарящи на %(oldGlob)s към отговарящи на %(newGlob)s поради %(reason)s",
|
||||
"The message you are trying to send is too large.": "Съобщението, което се опитвате да изпратите е прекалено голямо.",
|
||||
"Cross-signing and secret storage are enabled.": "Кръстосано-подписване и секретно складиране са включени.",
|
||||
"Your account has a cross-signing identity in secret storage, but it is not yet trusted by this device.": "За вашия профил има самоличност за кръстосано-подписване в секретно складиране, но все още не е доверена от това устройство.",
|
||||
"Cross-signing and secret storage are not yet set up.": "Кръстосаното-подписване и секретно складиране все още не са настроени.",
|
||||
"Bootstrap cross-signing and secret storage": "Инициализирай кръстосано-подписване и секретно складиране",
|
||||
"Cross-signing public keys:": "Публични ключове за кръстосано-подписване:",
|
||||
"on device": "на устройството",
|
||||
"not found": "не са намерени",
|
||||
"Cross-signing private keys:": "Private ключове за кръстосано подписване:",
|
||||
"in secret storage": "в секретно складиране",
|
||||
|
@ -1888,10 +1767,7 @@
|
|||
"Backup has a <validity>valid</validity> signature from this user": "Резервното копие има <validity>валиден</validity> подпис за този потребител",
|
||||
"Backup has a <validity>invalid</validity> signature from this user": "Резервното копие има <validity>невалиден</validity> подпис за този потребител",
|
||||
"Backup has a signature from <verify>unknown</verify> user with ID %(deviceId)s": "Резервното копие има подпис от <verify>непознат</verify> потребител с идентификатор %(deviceId)s",
|
||||
"Backup has a signature from <verify>unknown</verify> device with ID %(deviceId)s": "Резервното копие има подпис от <verify>непознато</verify> устройство с идентификатор %(deviceId)s",
|
||||
"Backup key stored in secret storage, but this feature is not enabled on this device. Please enable cross-signing in Labs to modify key backup state.": "Резервния ключ е съхранен в секретно складиране, но тази функция не е включена на това устройство. Включете кръстосано-подписване от Labs за да промените състоянието на резервното копие на ключа.",
|
||||
"Backup key stored: ": "Резервният ключ е съхранен: ",
|
||||
"Start using Key Backup with Secure Secret Storage": "Започни използване на резервно копие на ключ в защитено секретно складиране",
|
||||
"Use an Integration Manager <b>(%(serverName)s)</b> to manage bots, widgets, and sticker packs.": "Използвай мениджър на интеграции <b>%(serverName)s</b> за управление на ботове, приспособления и стикери.",
|
||||
"Use an Integration Manager to manage bots, widgets, and sticker packs.": "Използвай мениджър на интеграции за управление на ботове, приспособления и стикери.",
|
||||
"Manage integrations": "Управление на интеграциите",
|
||||
|
@ -1928,11 +1804,6 @@
|
|||
"Room ID or alias of ban list": "Идентификатор или име на стая списък за блокиране",
|
||||
"Subscribe": "Абонирай ме",
|
||||
"Cross-signing": "Кръстосано-подписване",
|
||||
"This user has not verified all of their devices.": "Този потребител не е потвърдил всичките си устройства.",
|
||||
"You have not verified this user. This user has verified all of their devices.": "Не сте потвърдили този потребител. Потребителят е потвърдил всичките си устройства.",
|
||||
"You have verified this user. This user has verified all of their devices.": "Потвърдили сте този потребител. Потребителят е потвърдил всичките си устройства.",
|
||||
"Some users in this encrypted room are not verified by you or they have not verified their own devices.": "Някои потребители в тази стая не са потвърдени от вас или не са потвърдили собствените си устройства.",
|
||||
"All users in this encrypted room are verified by you and they have verified their own devices.": "Всички потребители в тази стая са потвърдени от вас и са потвърдили всичките си устройства.",
|
||||
"This message cannot be decrypted": "Съобщението не може да бъде дешифровано",
|
||||
"Unencrypted": "Нешифровано",
|
||||
"Close preview": "Затвори прегледа",
|
||||
|
@ -1945,7 +1816,6 @@
|
|||
"%(count)s verified sessions|other": "%(count)s потвърдени сесии",
|
||||
"%(count)s verified sessions|one": "1 потвърдена сесия",
|
||||
"Direct message": "Директно съобщение",
|
||||
"Unverify user": "Отпотвърди потребители",
|
||||
"<strong>%(role)s</strong> in %(roomName)s": "<strong>%(role)s</strong> в%(roomName)s",
|
||||
"Messages in this room are end-to-end encrypted.": "Съобщенията в тази стая са шифровани от край-до-край.",
|
||||
"Verify": "Потвърди",
|
||||
|
@ -1982,11 +1852,9 @@
|
|||
"Enter secret storage passphrase": "Въведете парола за секретно складиране",
|
||||
"Unable to access secret storage. Please verify that you entered the correct passphrase.": "Неуспешен достъп до секретно складиране. Уверете се, че сте въвели правилната парола.",
|
||||
"<b>Warning</b>: You should only access secret storage from a trusted computer.": "<b>Внимание</b>: Трябва да достъпвате секретно складиране само от доверен компютър.",
|
||||
"Access your secure message history and your cross-signing identity for verifying other devices by entering your passphrase.": "Въведете парола за да достъпите защитената история на съобщенията и самоличността за кръстосано-подписване и потвърждение на други устройства.",
|
||||
"If you've forgotten your passphrase you can <button1>use your recovery key</button1> or <button2>set up new recovery options</button2>.": "Ако сте забравили паролата си, може да <button1>използвате ключ за възстановяване</button1> или да <button2>настройте опции за възстановяване</button2>.",
|
||||
"Enter secret storage recovery key": "Въведете ключ за възстановяване на секретно складиране",
|
||||
"Unable to access secret storage. Please verify that you entered the correct recovery key.": "Неуспешен достъп до секретно складиране. Подсигурете се, че сте въвели правилния ключ за възстановяване.",
|
||||
"Access your secure message history and your cross-signing identity for verifying other devices by entering your recovery key.": "Въведете ключа за възстановяване за да достъпите защитената история на съобщенията и самоличността за кръстосано-подписване и потвърждение на други устройства.",
|
||||
"If you've forgotten your recovery key you can <button>set up new recovery options</button>.": "Ако сте забравили ключа си за възстановяване, може да <button>настройте нови опции за възстановяване</button>.",
|
||||
"<b>Warning</b>: You should only set up key backup from a trusted computer.": "<b>Внимание</b>: Трябва да настройвате резервно копие на ключове само от доверен компютър.",
|
||||
"If you've forgotten your recovery key you can <button>set up new recovery options</button>": "Ако сте забравили ключа за възстановяване, може да <button>настройте нови опции за възстановяване</button>",
|
||||
|
@ -2000,36 +1868,20 @@
|
|||
"Country Dropdown": "Падащо меню за избор на държава",
|
||||
"Verification Request": "Заявка за потвърждение",
|
||||
" (1/%(totalCount)s)": " (1/%(totalCount)s)",
|
||||
"Secret Storage will be set up using your existing key backup details.Your secret storage passphrase and recovery key will be the same as they were for your key backup": "Секретно Складиране ще бъде настроено със съществуващия ви резервен ключ. Паролата и ключа за секретно складиране ще бъдат същите каквито са за резервно складиране",
|
||||
"<b>Warning</b>: You should only set up secret storage from a trusted computer.": "<b>Внимание</b>: Желателно е да настройвате секретно складиране само от доверен компютър.",
|
||||
"We'll use secret storage to optionally store an encrypted copy of your cross-signing identity for verifying other devices and message keys on our server. Protect your access to encrypted messages with a passphrase to keep it secure.": "Ще използваме секретно складиране за да предоставим опцията да се съхрани шифровано копие на идентичността ви за кръстосано-подписване, за потвърждаване на други устройства и ключове. Защитете достъпа си до шифровани съобщения с парола за да е защитено.",
|
||||
"Set up with a recovery key": "Настрой с ключ за възстановяване",
|
||||
"As a safety net, you can use it to restore your access to encrypted messages if you forget your passphrase.": "Като предпазна мярка, ако забравите паролата, може да го използвате за да възстановите достъпа до шифрованите съобщения.",
|
||||
"As a safety net, you can use it to restore your access to encrypted messages.": "Като предпазна мярка, може да го използвате за да възстановите достъпа до шифрованите съобщения.",
|
||||
"Keep your recovery key somewhere very secure, like a password manager (or a safe).": "Съхранявайте ключа за възстановяване на сигурно място, като в password manager (или сейф).",
|
||||
"Your recovery key has been <b>copied to your clipboard</b>, paste it to:": "Ключа за възстановяване беше <b>копиран в клиборд</b>, поставете го в:",
|
||||
"Your recovery key is in your <b>Downloads</b> folder.": "Ключа за възстановяване е във вашата папка <b>Изтегляния</b>.",
|
||||
"Your access to encrypted messages is now protected.": "Достъпът ви до шифровани съобщения вече е защитен.",
|
||||
"Without setting up secret storage, you won't be able to restore your access to encrypted messages or your cross-signing identity for verifying other devices if you log out or use another device.": "Без настройка на секретно складиране, ако излезе от профила или използвате друго устройство, няма да можете да възстановите достъпа до шифровани съобщения или идентичността за кръстосано-подписване за потвърждаване на други устройства.",
|
||||
"Set up secret storage": "Настрой секретно складиране",
|
||||
"Migrate from Key Backup": "Мигрирай от резервно копие на ключове",
|
||||
"Secure your encrypted messages with a passphrase": "Защитете шифрованите съобщения с парола",
|
||||
"Storing secrets...": "Складиране на тайни...",
|
||||
"Unable to set up secret storage": "Неуспешна настройка на секретно складиране",
|
||||
"New DM invite dialog (under development)": "Нов процес за канене чрез директни съобщения (все още се разработва)",
|
||||
"Show info about bridges in room settings": "Показвай информация за връзки с други мрежи в настройките на стаята",
|
||||
"This bridge was provisioned by <user />": "Тази връзка с друга мрежа е била настроена от <user />",
|
||||
"This bridge is managed by <user />.": "Тази връзка с друга мрежа се управлява от <user />.",
|
||||
"Bridged into <channelLink /> <networkLink />, on <protocolName />": "Свързано с <channelLink /><networkLink />, посредством <protocolName />",
|
||||
"Connected to <channelIcon /> <channelName /> on <networkIcon /> <networkName />": "Свързано с <channelIcon /><channelName /> посредством <networkIcon /><networkName />",
|
||||
"Connected via %(protocolName)s": "Свързано посредством %(protocolName)s",
|
||||
"Bridge Info": "Информация за връзката с друга мрежа",
|
||||
"Below is a list of bridges connected to this room.": "По-долу е списък на връзки с други мрежи свързани с тази стая.",
|
||||
"Recent Conversations": "Скорошни разговори",
|
||||
"Suggestions": "Предложения",
|
||||
"Show more": "Покажи повече",
|
||||
"Direct Messages": "Директни съобщения",
|
||||
"If you can't find someone, ask them for their username, or share your username (%(userId)s) or <a>profile link</a>.": "Ако не можете да намерите някой, питайте за потребителското им име, или споделете своето (%(userId)s) или <a>връзка към профила</a>.",
|
||||
"Go": "Давай",
|
||||
"Failed to find the following users": "Неуспешно откриване на следните потребители",
|
||||
"The following users might not exist or are invalid, and cannot be invited: %(csvNames)s": "Следните потребители не съществуват или са невалидни и не могат да бъдат поканени: %(csvNames)s"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{
|
||||
"People": "Gent",
|
||||
"Add a widget": "Afegeix un giny",
|
||||
"Account": "Compte",
|
||||
"No Microphones detected": "No s'ha detectat cap micròfon",
|
||||
|
@ -42,7 +41,6 @@
|
|||
"This phone number is already in use": "Aquest número de telèfon ja està en ús",
|
||||
"Failed to verify email address: make sure you clicked the link in the email": "No s'ha pogut verificar l'adreça de correu electrònic. Assegureu-vos de fer clic a l'enllaç del correu electrònic de verificació",
|
||||
"Call Failed": "No s'ha pogut realitzar la trucada",
|
||||
"There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Hi ha dispositius desconeguts a aquesta sala: si continueu sense verificar-los, és possible que algú escolti la vostra trucada.",
|
||||
"Review Devices": "Revisió de dispositius",
|
||||
"Call Anyway": "Truca de totes maneres",
|
||||
"Answer Anyway": "Contesta de totes maneres",
|
||||
|
@ -105,10 +103,6 @@
|
|||
"Moderator": "Moderador",
|
||||
"Admin": "Administrador",
|
||||
"Start a chat": "Comença un xat",
|
||||
"Who would you like to communicate with?": "Amb qui us voleu comunicar?",
|
||||
"Start Chat": "Comença un xat",
|
||||
"Invite new room members": "Convida a nous membres a la sala",
|
||||
"Send Invites": "Envia invitacions",
|
||||
"Failed to invite": "No s'ha pogut tramitar la invitació",
|
||||
"Failed to invite the following users to the %(roomName)s room:": "No s'ha pogut convidar a la sala %(roomName)s els següents usuaris:",
|
||||
"You need to be logged in.": "És necessari estar autenticat.",
|
||||
|
@ -130,14 +124,8 @@
|
|||
"You are now ignoring %(userId)s": "Esteu ignorant l'usuari %(userId)s",
|
||||
"Unignored user": "Usuari no ignorat",
|
||||
"You are no longer ignoring %(userId)s": "Ja no esteu ignorant l'usuari %(userId)s",
|
||||
"Device already verified!": "El dispositiu ja estava verificat!",
|
||||
"WARNING: Device already verified, but keys do NOT MATCH!": "AVÍS: El dispositiu ja estava verificat, però les claus NO COINCIDEIXEN!",
|
||||
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "AVÍS: NO S'HA POGUT VERIFICAR! La clau de signatura de l'usuari %(userId)s i el dispositiu %(deviceId)s és \"%(fprint)s\", però no coincideix amb la clau \"%(fingerprint)s\". Això pot voler dir que les vostres comunicacions estan sent interceptades!",
|
||||
"Verified key": "Claus verificades",
|
||||
"Call Timeout": "Temps d'espera de les trucades",
|
||||
"Unknown (user, device) pair:": "Parell desconegut (usuari, dispositiu):",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "La clau de signatura que heu proporcionat coincideix amb la clau de signatura que heu rebut del dispositiu %(deviceId)s de l'usuari %(userId)s. S'ha marcat el dispositiu com a dispositiu verificat.",
|
||||
"Unrecognised command:": "Ordre no reconegut:",
|
||||
"Reason": "Raó",
|
||||
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s ha acceptat la invitació de %(displayName)s.",
|
||||
"%(targetName)s accepted an invitation.": "%(targetName)s ha acceptat una invitació.",
|
||||
|
@ -174,7 +162,6 @@
|
|||
"%(senderName)s made future room history visible to all room members.": "%(senderName)s ha fet visible l'històric futur de la sala a tots els membres de la sala.",
|
||||
"%(senderName)s made future room history visible to anyone.": "%(senderName)s ha fet visible el futur historial de la sala per a tothom.",
|
||||
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s ha fet visible el futur historial de la sala per a desconeguts (%(visibility)s).",
|
||||
"%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s ha activat el xifratge d'extrem a extrem (algoritme %(algorithm)s).",
|
||||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s a %(toPowerLevel)s",
|
||||
"%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s ha canviat el nivell de poders de %(powerLevelDiffText)s.",
|
||||
"%(senderName)s changed the pinned messages for the room.": "%(senderName)s ha canviat els missatges fixats de la sala.",
|
||||
|
@ -196,7 +183,6 @@
|
|||
"Autoplay GIFs and videos": "Reprodueix de forma automàtica els GIF i vídeos",
|
||||
"Enable automatic language detection for syntax highlighting": "Activa la detecció automàtica d'idiomes per al ressaltat de sintaxi",
|
||||
"Automatically replace plain text Emoji": "Substitueix automàticament Emoji de text pla",
|
||||
"Never send encrypted messages to unverified devices in this room from this device": "No enviïs mai missatges xifrats a dispositius no verificats en aquesta sala des d'aquest dispositiu",
|
||||
"Enable inline URL previews by default": "Activa per defecte la vista prèvia d'URL en línia",
|
||||
"Enable URL previews for this room (only affects you)": "Activa la vista prèvia d'URL d'aquesta sala (no afecta altres usuaris)",
|
||||
"Enable URL previews by default for participants in this room": "Activa per defecte la vista prèvia d'URL per als participants d'aquesta sala",
|
||||
|
@ -204,7 +190,6 @@
|
|||
"Active call (%(roomName)s)": "Trucada activa (%(roomName)s)",
|
||||
"unknown caller": "trucada d'un desconegut",
|
||||
"Incoming voice call from %(name)s": "Trucada de veu entrant de %(name)s",
|
||||
"Never send encrypted messages to unverified devices from this device": "No enviïs mai missatges xifrats a dispositius no verificats des d'aquest dispositiu",
|
||||
"Incoming video call from %(name)s": "Trucada de vídeo entrant de %(name)s",
|
||||
"Incoming call from %(name)s": "Trucada entrant de %(name)s",
|
||||
"Decline": "Declina",
|
||||
|
@ -218,7 +203,6 @@
|
|||
"No display name": "Sense nom visible",
|
||||
"New passwords don't match": "Les noves contrasenyes no coincideixen",
|
||||
"Passwords can't be empty": "Les contrasenyes no poden estar buides",
|
||||
"Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Si canvieu la contrasenya, es reiniciaran totes les actuals claus de xifratge d'extrem per a tots els dispositius, fent que l'historial xifrat no sigui llegible, tret que primer exporteu les claus de la vostra sala i les torneu a importar després. En un futur això serà millorat.",
|
||||
"Export E2E room keys": "Exporta les claus E2E de la sala",
|
||||
"Do you want to set an email address?": "Voleu establir una adreça de correu electrònic?",
|
||||
"Current password": "Contrasenya actual",
|
||||
|
@ -226,10 +210,7 @@
|
|||
"New Password": "Nova contrasenya",
|
||||
"Confirm password": "Confirma la contrasenya",
|
||||
"Change Password": "Canvia la contrasenya",
|
||||
"Unable to load device list": "No s'ha pogut carregar la llista de dispositius",
|
||||
"Authentication": "Autenticació",
|
||||
"Delete %(count)s devices|other": "Suprimeix %(count)s dispositius",
|
||||
"Delete %(count)s devices|one": "Suprimeix el dispositiu",
|
||||
"Device ID": "ID del dispositiu",
|
||||
"Last seen": "Vist per última vegada",
|
||||
"Failed to set display name": "No s'ha pogut establir el nom visible",
|
||||
|
@ -246,9 +227,6 @@
|
|||
"%(senderName)s sent a video": "%(senderName)s ha enviat un vídeo",
|
||||
"%(senderName)s uploaded a file": "%(senderName)s ha pujat un fitxer",
|
||||
"Options": "Opcions",
|
||||
"Undecryptable": "Indesxifrable",
|
||||
"Encrypted by an unverified device": "Xifrat per un dispositiu no verificat",
|
||||
"Unencrypted message": "Missatge no xifrat",
|
||||
"Please select the destination room for this message": "Si us plau, seleccioneu la sala destinatària per a aquest missatge",
|
||||
"Blacklisted": "Llista negre",
|
||||
"device id: ": "ID del dispositiu: ",
|
||||
|
@ -269,8 +247,6 @@
|
|||
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "No podreu desfer aquest canvi ja que estareu baixant de grau de privilegis. Només un altre usuari amb més privilegis podrà fer que els recupereu.",
|
||||
"Are you sure?": "Esteu segur?",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "No podreu desfer aquesta acció ja que esteu donant al usuari el mateix nivell de privilegi que el vostre.",
|
||||
"No devices with registered encryption keys": "No hi ha cap dispositiu amb les claus de xifratge registrades",
|
||||
"Devices": "Dispositius",
|
||||
"Unignore": "Deixa de ignorar",
|
||||
"Ignore": "Ignora",
|
||||
"Jump to read receipt": "Vés a l'últim missatge llegit",
|
||||
|
@ -292,21 +268,15 @@
|
|||
"Voice call": "Trucada de veu",
|
||||
"Video call": "Trucada de vídeo",
|
||||
"Upload file": "Puja un fitxer",
|
||||
"Show Text Formatting Toolbar": "Mostra la barra d'eines de format de text",
|
||||
"Send an encrypted reply…": "Envia una resposta xifrada…",
|
||||
"Send a reply (unencrypted)…": "Envia una resposta (sense xifrar)…",
|
||||
"Send an encrypted message…": "Envia un missatge xifrat…",
|
||||
"Send a message (unencrypted)…": "Envia un missatge (sense xifrar)…",
|
||||
"You do not have permission to post to this room": "No teniu el permís per escriure en aquesta sala",
|
||||
"Hide Text Formatting Toolbar": "Amaga la barra d'eines de format de text",
|
||||
"Server error": "S'ha produït un error al servidor",
|
||||
"Mirror local video feed": "Mostra el vídeo local com un mirall",
|
||||
"Server unavailable, overloaded, or something else went wrong.": "El servidor no està disponible, està sobrecarregat o alguna altra cosa no ha funcionat correctament.",
|
||||
"Command error": "S'ha produït un error en l'ordre",
|
||||
"bold": "negreta",
|
||||
"italic": "cursiva",
|
||||
"Markdown is disabled": "El Markdown està desactivat",
|
||||
"Markdown is enabled": "El Markdown està activat",
|
||||
"Jump to message": "Salta al missatge",
|
||||
"No pinned messages.": "No hi ha cap missatge fixat.",
|
||||
"Loading...": "S'està carregant...",
|
||||
|
@ -362,8 +332,6 @@
|
|||
"Permissions": "Permisos",
|
||||
"Add a topic": "Afegeix un tema",
|
||||
"Jump to first unread message.": "Salta al primer missatge no llegit.",
|
||||
"Invalid alias format": "El format de l'àlies no és vàlid",
|
||||
"'%(alias)s' is not a valid format for an alias": "'%(alias)s' no és un format d'àlies vàlid",
|
||||
"Anyone who knows the room's link, including guests": "Qualsevol que conegui l'enllaç de la sala, inclosos els usuaris d'altres xarxes",
|
||||
"not specified": "sense especificar",
|
||||
"Remote addresses for this room:": "Adreces remotes per a aquesta sala:",
|
||||
|
@ -521,19 +489,11 @@
|
|||
"Unknown error": "S'ha produït un error desconegut",
|
||||
"Incorrect password": "Contrasenya incorrecta",
|
||||
"Deactivate Account": "Desactivar el compte",
|
||||
"To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Per verificar que es pot confiar en aquest dispositiu, poseu-vos en contacte amb el propietari mitjançant altres mitjans (per exemple, en persona o amb una trucada telefònica) i pregunteu-li si la clau que veuen a la configuració del seu usuari, aquest dispositiu coincideix amb la següent clau:",
|
||||
"Device name": "Nom del dispositiu",
|
||||
"Device key": "Clau del dispositiu",
|
||||
"If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Si coincideix, premeu el botó de verificació de sota. Si no coincideix, algú més està interceptant aquest dispositiu i probablement voleu prémer el botó de llista negra.",
|
||||
"Verify device": "Verifica el dispositiu",
|
||||
"I verify that the keys match": "Verifico que les claus coincideixen",
|
||||
"An error has occurred.": "S'ha produït un error.",
|
||||
"You added a new device '%(displayName)s', which is requesting encryption keys.": "Heu afegit el nou dispositiu «%(displayName)s», que està demanant les claus de xifratge.",
|
||||
"Your unverified device '%(displayName)s' is requesting encryption keys.": "El dispositiu no verificat «%(displayName)s» està demanant les claus de xifratge.",
|
||||
"Start verification": "Inicia la verificació",
|
||||
"Share without verifying": "Comparteix sense verificar",
|
||||
"Ignore request": "Ignora la sol·licitud",
|
||||
"Loading device info...": "S'està carregant la informació del dispositiu...",
|
||||
"Encryption key request": "Sol·licitud de claus",
|
||||
"Unable to restore session": "No s'ha pogut restaurar la sessió",
|
||||
"Invalid Email Address": "El correu electrònic no és vàlid",
|
||||
|
@ -552,11 +512,6 @@
|
|||
"This will be your account name on the <span></span> homeserver, or you can pick a <a>different server</a>.": "Aquest serà el nom del seu compte al <span></span> servidor amfitrió, o bé trieu-ne un altre <a>different server</a>.",
|
||||
"If you already have a Matrix account you can <a>log in</a> instead.": "Si ja teniu un compte a Matrix, podeu <a>log in</a>.",
|
||||
"If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Si anteriorment heu utilitzat un versió de Riot més recent, la vostra sessió podría ser incompatible amb aquesta versió. Tanqueu aquesta finestra i torneu a la versió més recent.",
|
||||
"You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Actualment teniu a la llista negre els dispositius no verificats; per enviar missatges a aquests dispositius, els heu de verificar abans.",
|
||||
"We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Recomanem que dugueu a terme el procès de verificació per a cada dispositiu per tal de confirmar que són del legítim propietari, però podeu enviar el missatge sense verificar-ho si ho preferiu.",
|
||||
"Room contains unknown devices": "Hi ha dispositius desconeguts a la sala",
|
||||
"\"%(RoomName)s\" contains devices that you haven't seen before.": "A la sala «%(RoomName)s» hi ha dispositius que no havíeu vist abans.",
|
||||
"Unknown devices": "Dispositius desconeguts",
|
||||
"Private Chat": "Xat privat",
|
||||
"Public Chat": "Xat públic",
|
||||
"Custom": "Personalitzat",
|
||||
|
@ -613,7 +568,6 @@
|
|||
"Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Crea una comunitat per agrupar usuaris i sales! Creeu una pàgina d'inici personalitzada per definir el vostre espai a l'univers Matrix.",
|
||||
"You have no visible notifications": "No teniu cap notificació visible",
|
||||
"Scroll to bottom of page": "Desplaça't fins a la part inferior de la pàgina",
|
||||
"Message not sent due to unknown devices being present": "El missatge no s'ha enviat perquè hi ha dispositius desconeguts presents",
|
||||
"%(count)s of your messages have not been sent.|other": "Alguns dels vostres missatges no s'han enviat.",
|
||||
"%(count)s of your messages have not been sent.|one": "El vostre missatge no s'ha enviat.",
|
||||
"Warning": "Avís",
|
||||
|
@ -636,7 +590,6 @@
|
|||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "S'ha intentat carregar un punt específic dins la línia de temps d'aquesta sala, però no teniu permís per veure el missatge en qüestió.",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "S'ha intentat carregar un punt específic de la línia de temps d'aquesta sala, però no s'ha pogut trobar.",
|
||||
"Failed to load timeline position": "No s'ha pogut carregar aquesta posició de la línia de temps",
|
||||
"<showDevicesText>Show devices</showDevicesText>, <sendAnywayText>send anyway</sendAnywayText> or <cancelText>cancel</cancelText>.": "<showDevicesText>Mostra els dispositius</showDevicesText>, <sendAnywayText>envia de totes maneres</sendAnywayText> o <cancelText>cancel·la</cancelText>.",
|
||||
"Signed Out": "Sessió tancada",
|
||||
"%(count)s <resendText>Resend all</resendText> or <cancelText>cancel all</cancelText> now. You can also select individual messages to resend or cancel.|other": "<resendText>Reenviar tot</resendText> o <cancelText>cancel·lar tot</cancelText> ara. També pots seleccionar missatges individualment per reenviar o cancel·lar.",
|
||||
"%(count)s <resendText>Resend all</resendText> or <cancelText>cancel all</cancelText> now. You can also select individual messages to resend or cancel.|one": "<resendText>Reenviar missarge</resendText> o <cancelText>cancel·lar missatge</cancelText> ara.",
|
||||
|
@ -648,10 +601,7 @@
|
|||
"Sign out": "Tancar sessió",
|
||||
"Import E2E room keys": "Importar claus E2E de sala",
|
||||
"Cryptography": "Criptografia",
|
||||
"Device ID:": "ID del dispositiu:",
|
||||
"Device key:": "Clau del dispositiu:",
|
||||
"Labs": "Laboraroris",
|
||||
"matrix-react-sdk version:": "Versió de matrix-react-sdk:",
|
||||
"riot-web version:": "Versió de riot-web:",
|
||||
"olm version:": "Versió d'olm:",
|
||||
"Incorrect username and/or password.": "Usuari i/o contrasenya incorrectes.",
|
||||
|
@ -664,7 +614,6 @@
|
|||
"Event information": "Informació d'esdeveniment",
|
||||
"User ID": "ID de l'usuari",
|
||||
"Decryption error": "Error de desxifratge",
|
||||
"Sender device information": "Informació del dispositiu remitent",
|
||||
"Export room keys": "Exporta les claus de la sala",
|
||||
"Upload an avatar:": "Pujar un avatar:",
|
||||
"Confirm passphrase": "Introduïu una contrasenya",
|
||||
|
@ -736,7 +685,6 @@
|
|||
"Noisy": "Sorollós",
|
||||
"Collecting app version information": "S'està recollint la informació de la versió de l'aplicació",
|
||||
"Delete the room alias %(alias)s and remove %(name)s from the directory?": "Voleu esborrar de la sala l'alies %(alias)s i retirar %(name)s del directori?",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "Això farà possible que pugueu tronar al vostre compte des de qualsevol dispositiu.",
|
||||
"Enable notifications for this account": "Habilita les notificacions per aquest compte",
|
||||
"Invite to this community": "Convida a aquesta comunitat",
|
||||
"Search…": "Cerca…",
|
||||
|
@ -847,7 +795,6 @@
|
|||
"Define the power level of a user": "Defineix el nivell d'autoritat d'un usuari",
|
||||
"Deops user with given id": "Degrada l'usuari amb l'id donat",
|
||||
"Opens the Developer Tools dialog": "Obre el diàleg d'Eines del desenvolupador",
|
||||
"Verifies a user, device, and pubkey tuple": "Verifica un usuari, dispositiu i tupla de clau pública",
|
||||
"Displays action": "Mostra l'acció",
|
||||
"Whether or not you're logged in (we don't record your username)": "Si heu iniciat sessió o no (no desem el vostre usuari)",
|
||||
"The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "El fitxer %(fileName)s supera el límit de pujades del servidor",
|
||||
|
|
|
@ -8,11 +8,9 @@
|
|||
"Logout": "Odhlásit se",
|
||||
"Low priority": "Nízká priorita",
|
||||
"Notifications": "Upozornění",
|
||||
"People": "Lidé",
|
||||
"Rooms": "Místnosti",
|
||||
"Search": "Hledání",
|
||||
"Settings": "Nastavení",
|
||||
"Start Chat": "Začít chat",
|
||||
"This room": "Tato místnost",
|
||||
"Video call": "Videohovor",
|
||||
"Voice call": "Telefonát",
|
||||
|
@ -94,7 +92,6 @@
|
|||
"%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s odstranil/a název místnosti.",
|
||||
"%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s změnil/a téma na „%(topic)s“.",
|
||||
"Changes your display nickname": "Změní vaši zobrazovanou přezdívku",
|
||||
"Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "V současnosti změna hesla resetuje všechny šifrovací klíče na všech zařízeních, což vám znepřístupní historii zašifrovaných chatů, pokud si nejprve nevyexportujete klíče svých místností a pak je do nich znova nevložíte. Toto bude v budoucnu lépe ošetřeno.",
|
||||
"Command error": "Chyba příkazu",
|
||||
"Commands": "Příkazy",
|
||||
"Confirm password": "Potvrďte heslo",
|
||||
|
@ -111,12 +108,8 @@
|
|||
"Decryption error": "Chyba dešifrování",
|
||||
"Delete widget": "Vymazat widget",
|
||||
"Default": "Výchozí",
|
||||
"Device already verified!": "Zařízení již bylo ověřeno!",
|
||||
"Device ID": "ID zařízení",
|
||||
"Device ID:": "ID zařízení:",
|
||||
"device id: ": "id zařízení: ",
|
||||
"Device key:": "Klíč zařízení:",
|
||||
"Devices": "Zařízení",
|
||||
"Direct chats": "Přímé chaty",
|
||||
"Disable Notifications": "Vypnout upozornění",
|
||||
"Disinvite": "Odvolat pozvání",
|
||||
|
@ -128,7 +121,6 @@
|
|||
"Emoji": "Emodži",
|
||||
"Enable automatic language detection for syntax highlighting": "Zapnout kvůli zvýrazňování syntaxe automatické rozpoznávání jazyka",
|
||||
"Enable Notifications": "Zapnout upozornění",
|
||||
"Encrypted by an unverified device": "Zašifrováno neověřeným zařízením",
|
||||
"%(senderName)s ended the call.": "%(senderName)s ukončil/a hovor.",
|
||||
"End-to-end encryption information": "Informace o end-to-end šifrování",
|
||||
"Enter passphrase": "Zadejte heslo",
|
||||
|
@ -174,13 +166,10 @@
|
|||
"Incoming voice call from %(name)s": "Příchozí hlasový hovor od %(name)s",
|
||||
"Incorrect username and/or password.": "Nesprávné uživatelské jméno nebo heslo.",
|
||||
"Incorrect verification code": "Nesprávný ověřovací kód",
|
||||
"Invalid alias format": "Neplaný formát aliasu",
|
||||
"Invalid Email Address": "Neplatná e-mailová adresa",
|
||||
"%(senderName)s invited %(targetName)s.": "%(senderName)s pozval/a %(targetName)s.",
|
||||
"Invite new room members": "Pozvat do místnosti nové členy",
|
||||
"Invites": "Pozvánky",
|
||||
"Invites user with given id to current room": "Pozve do aktuální místnosti uživatele s daným id",
|
||||
"'%(alias)s' is not a valid format for an alias": "'%(alias)s' není platný formát aliasu",
|
||||
"Join Room": "Vstoupit do místnosti",
|
||||
"%(targetName)s joined the room.": "%(targetName)s vstoupil/a do místnosti.",
|
||||
"%(senderName)s kicked %(targetName)s.": "%(senderName)s vykopnul/a %(targetName)s.",
|
||||
|
@ -189,7 +178,6 @@
|
|||
"Last seen": "Naposledy viděn/a",
|
||||
"Leave room": "Odejít z místnosti",
|
||||
"Local addresses for this room:": "Místní adresy této místnosti:",
|
||||
"matrix-react-sdk version:": "Verze matrix-react-sdk:",
|
||||
"Moderator": "Moderátor",
|
||||
"Name": "Jméno",
|
||||
"New address (e.g. #foo:%(localDomain)s)": "Nová adresa (např. #neco:%(localDomain)s)",
|
||||
|
@ -224,13 +212,11 @@
|
|||
"riot-web version:": "verze riot-web:",
|
||||
"Room %(roomId)s not visible": "Místnost %(roomId)s není viditelná",
|
||||
"Room Colour": "Barva místnosti",
|
||||
"Room contains unknown devices": "V místnosti jsou neznámá zařízení",
|
||||
"%(roomName)s does not exist.": "%(roomName)s neexistuje.",
|
||||
"%(roomName)s is not accessible at this time.": "Místnost %(roomName)s není v tuto chvíli dostupná.",
|
||||
"Save": "Uložit",
|
||||
"Scroll to bottom of page": "Přejít na konec stránky",
|
||||
"Send anyway": "Přesto poslat",
|
||||
"Sender device information": "Informace o zařízení odesílatele",
|
||||
"Send Reset Email": "Poslat resetovací e-mail",
|
||||
"%(senderDisplayName)s sent an image.": "%(senderDisplayName)s poslal/a obrázek.",
|
||||
"%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s poslal/a %(targetDisplayName)s pozvánku ke vstupu do místnosti.",
|
||||
|
@ -251,7 +237,6 @@
|
|||
"Submit": "Odeslat",
|
||||
"Success": "Úspěch",
|
||||
"The phone number entered looks invalid": "Zadané telefonní číslo se zdá být neplatné",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Zadaný podepisovaný klíč se shoduje s klíčem obdrženým od uživatele %(userId)s ze zařízení %(deviceId)s. Zařízení je označeno jako ověřené.",
|
||||
"This email address is already in use": "Tato e-mailová adresa je již používaná",
|
||||
"This email address was not found": "Tato e-mailová adresa nebyla nalezena",
|
||||
"This room has no local addresses": "Tato místnost nemá žádné místní adresy",
|
||||
|
@ -260,7 +245,6 @@
|
|||
"Warning!": "Varování!",
|
||||
"Who can access this room?": "Kdo má přístup k této místnosti?",
|
||||
"Who can read history?": "Kdo může číst historii?",
|
||||
"Who would you like to communicate with?": "S kým byste chtěli komunikovat?",
|
||||
"You are not in this room.": "Nejste v této místnosti.",
|
||||
"You do not have permission to do that in this room.": "V této místnosti nemáte na toto právo.",
|
||||
"You cannot place a call with yourself.": "Nemůžete volat sami sobě.",
|
||||
|
@ -288,7 +272,6 @@
|
|||
"To use it, just wait for autocomplete results to load and tab through them.": "Použijte tak, že vyčkáte na načtení našeptávaných výsledků a ty pak projdete tabulátorem.",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Nemáte práva k zobrazení zprávy v daném časovém úseku.",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Zpráva v daném časovém úseku nenalezena.",
|
||||
"%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s zapnul/a end-to-end šifrování (algoritmus %(algorithm)s).",
|
||||
"Unable to add email address": "Nepodařilo se přidat e-mailovou adresu",
|
||||
"Unable to create widget.": "Nepodařilo se vytvořit widget.",
|
||||
"Unable to remove contact information": "Nepodařilo se smazat kontaktní údaje",
|
||||
|
@ -297,17 +280,12 @@
|
|||
"%(senderName)s unbanned %(targetName)s.": "%(senderName)s přijal/a zpět %(targetName)s.",
|
||||
"Unable to capture screen": "Nepodařilo se zachytit obrazovku",
|
||||
"Unable to enable Notifications": "Nepodařilo se povolit upozornění",
|
||||
"Unable to load device list": "Nepodařilo se načíst seznam zařízení",
|
||||
"Undecryptable": "Nerozšifrovatelné",
|
||||
"unencrypted": "nešifrované",
|
||||
"Unencrypted message": "Nešifrovaná zpráva",
|
||||
"unknown caller": "neznámý volající",
|
||||
"unknown device": "neznámé zařízení",
|
||||
"Unknown room %(roomId)s": "Neznámá místnost %(roomId)s",
|
||||
"Unknown (user, device) pair:": "Neznámý pár (uživatel, zařízení):",
|
||||
"Unmute": "Povolit",
|
||||
"Unnamed Room": "Nepojmenovaná místnost",
|
||||
"Unrecognised command:": "Nerozpoznaný příkaz:",
|
||||
"Unrecognised room alias:": "Nerozpoznaný alias místnosti:",
|
||||
"Uploading %(filename)s and %(count)s others|zero": "Nahrávám %(filename)s",
|
||||
"Uploading %(filename)s and %(count)s others|one": "Nahrávám %(filename)s a %(count)s další",
|
||||
|
@ -326,7 +304,6 @@
|
|||
"Verified key": "Ověřený klíč",
|
||||
"(no answer)": "(žádná odpověď)",
|
||||
"(unknown failure: %(reason)s)": "(neznámá chyba: %(reason)s)",
|
||||
"WARNING: Device already verified, but keys do NOT MATCH!": "VAROVÁNÍ: Zařízení byl již ověřeno, ale klíče se NESHODUJÍ!",
|
||||
"The remote side failed to pick up": "Vzdálené straně se nepodařilo hovor přijmout",
|
||||
"Who would you like to add to this community?": "Koho chcete přidat do této skupiny?",
|
||||
"Invite new community members": "Pozvěte nové členy skupiny",
|
||||
|
@ -344,7 +321,6 @@
|
|||
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s",
|
||||
"Failed to add the following rooms to %(groupId)s:": "Nepodařilo se přidat následující místnosti do %(groupId)s:",
|
||||
"Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Vaše e-mailová adresa zřejmě nepatří k žádnému Matrix ID na tomto domovském serveru.",
|
||||
"Send Invites": "Odeslat pozvánky",
|
||||
"Failed to invite": "Pozvání se nezdařilo",
|
||||
"Failed to invite the following users to the %(roomName)s room:": "Do místnosti %(roomName)s se nepodařilo pozvat následující uživatele:",
|
||||
"You need to be logged in.": "Musíte být přihlášen/a.",
|
||||
|
@ -354,7 +330,6 @@
|
|||
"Unpin Message": "Odepnout zprávu",
|
||||
"Ignored user": "Ignorovaný uživatel",
|
||||
"Unignored user": "Odignorovaný uživatel",
|
||||
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "VAROVÁNÍ: OVĚŘENÍ KLÍČE SELHALO! Podepisovací klíč uživatele %(userId)s a zařízení %(deviceId)s je „%(fprint)s“, což nesouhlasí s dodaným klíčem „%(fingerprint)s“. Toto může znamenat, že vaše komunikace je odposlouchávána!",
|
||||
"Reason": "Důvod",
|
||||
"VoIP conference started.": "VoIP konference započata.",
|
||||
"VoIP conference finished.": "VoIP konference ukončena.",
|
||||
|
@ -371,8 +346,6 @@
|
|||
"Unignore": "Odignorovat",
|
||||
"Ignore": "Ignorovat",
|
||||
"Admin Tools": "Nástroje pro správce",
|
||||
"bold": "tučně",
|
||||
"italic": "kurzíva",
|
||||
"No pinned messages.": "Žádné připíchnuté zprávy.",
|
||||
"Pinned Messages": "Připíchnuté zprávy",
|
||||
"%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s odstranil/a svoje zobrazované jméno (%(oldDisplayName)s).",
|
||||
|
@ -404,18 +377,14 @@
|
|||
"Create": "Vytvořit",
|
||||
"User Options": "Volby uživatele",
|
||||
"Please select the destination room for this message": "Vyberte prosím pro tuto zprávu cílovou místnost",
|
||||
"No devices with registered encryption keys": "Žádná zařízení se zaregistrovanými šifrovacími klíči",
|
||||
"Jump to read receipt": "Skočit na poslední potvrzení o přečtení",
|
||||
"Invite": "Pozvat",
|
||||
"Revoke Moderator": "Odebrat moderátorství",
|
||||
"Make Moderator": "Udělit moderátorství",
|
||||
"and %(count)s others...|one": "a někdo další...",
|
||||
"Hangup": "Zavěsit",
|
||||
"Show Text Formatting Toolbar": "Zobrazit nástroje formátování textu",
|
||||
"Hide Text Formatting Toolbar": "Skrýt nástroje formátování textu",
|
||||
"Jump to message": "Přeskočit na zprávu",
|
||||
"Loading...": "Načítání...",
|
||||
"Loading device info...": "Načítá se info o zařízení...",
|
||||
"You seem to be uploading files, are you sure you want to quit?": "Zřejmě právě nahráváte soubory. Chcete přesto odejít?",
|
||||
"You seem to be in a call, are you sure you want to quit?": "Zřejmě máte probíhající hovor. Chcete přesto odejít?",
|
||||
"Idle": "Nečinný/á",
|
||||
|
@ -431,8 +400,6 @@
|
|||
"Mention": "Zmínit",
|
||||
"Blacklisted": "Na černé listině",
|
||||
"Invited": "Pozvaní",
|
||||
"Markdown is disabled": "Markdown je vypnutý",
|
||||
"Markdown is enabled": "Markdown je zapnutý",
|
||||
"Joins room with given alias": "Vstoupí do místnosti s daným aliasem",
|
||||
"Leave Community": "Odejít ze skupiny",
|
||||
"Leave %(groupName)s?": "Odejít z %(groupName)s?",
|
||||
|
@ -446,7 +413,6 @@
|
|||
"Failed to fetch avatar URL": "Nepodařilo se získat adresu avataru",
|
||||
"Error decrypting audio": "Chyba při dešifrování zvuku",
|
||||
"Banned by %(displayName)s": "Vykázán/a uživatelem %(displayName)s",
|
||||
"Never send encrypted messages to unverified devices in this room from this device": "Nikdy z tohoto zařízení neposílat šifrované zprávy neověřeným zařízením v této místnosti",
|
||||
"Privileged Users": "Privilegovaní uživatelé",
|
||||
"No users have specific privileges in this room": "Žádní uživatelé v této místnosti nemají zvláštní privilegia",
|
||||
"Publish this room to the public in %(domain)s's room directory?": "Zapsat tuto místnost do veřejného adresáře místností na %(domain)s?",
|
||||
|
@ -490,12 +456,9 @@
|
|||
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s zpřístupnil budoucí historii místnosti neznámým (%(visibility)s).",
|
||||
"Not a valid Riot keyfile": "Neplatný soubor s klíčem Riot",
|
||||
"Mirror local video feed": "Zrcadlit lokání video",
|
||||
"Never send encrypted messages to unverified devices from this device": "Z tohoto zařízení nikdy neodesílat šifrované zprávy na neověřená zařízení",
|
||||
"Enable inline URL previews by default": "Nastavit povolení náhledů URL adres jako výchozí",
|
||||
"Enable URL previews for this room (only affects you)": "Povolit náhledy URL adres pro tuto místnost (ovlivňuje pouze vás)",
|
||||
"Enable URL previews by default for participants in this room": "Povolit náhledy URL adres pro členy této místnosti jako výchozí",
|
||||
"Delete %(count)s devices|one": "Smazat zařízení",
|
||||
"Delete %(count)s devices|other": "Smazat %(count)s zařízení",
|
||||
" (unsupported)": " (nepodporované)",
|
||||
"Join as <voiceText>voice</voiceText> or <videoText>video</videoText>.": "Připojte se prostřednictvím <voiceText>audio</voiceText> nebo <videoText>video</videoText>.",
|
||||
"Ongoing conference call%(supportedText)s.": "Probíhající konferenční hovor%(supportedText)s.",
|
||||
|
@ -608,14 +571,7 @@
|
|||
"Something went wrong whilst creating your community": "Něco se pokazilo během vytváření vaší skupiny",
|
||||
"Unknown error": "Neznámá chyba",
|
||||
"Incorrect password": "Nesprávné heslo",
|
||||
"To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Pokud si chcete ověřit, zda je zařízení skutečně důvěryhodné, kontaktujte vlastníka jiným způsobem (např. osobně anebo telefonicky) a zeptejte se ho na klíč, který má pro toto zařízení zobrazený v nastavení a zda se shoduje s klíčem zobrazeným níže:",
|
||||
"Device name": "Název zařízení",
|
||||
"Device key": "Klíč zařízení",
|
||||
"If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Pokud se klíče shodují, stlačte ověřovací tlačítko uvedené níže. Pokud se neshodují, někdo další odposlouchává toto zařízení a v takovém případě by jste měli místo toho vybrat tlačítko černé listiny.",
|
||||
"Verify device": "Ověřit zařízení",
|
||||
"I verify that the keys match": "Ověřil jsem, klíče se shodují",
|
||||
"You added a new device '%(displayName)s', which is requesting encryption keys.": "Přidali jste nové zařízení s názvem '%(displayName)s', vyžadující šifrovací klíč.",
|
||||
"Your unverified device '%(displayName)s' is requesting encryption keys.": "Vaše neověřené zařízení s názvem '%(displayName)s' vyžaduje šifrovací klíč.",
|
||||
"Start verification": "Zahájit ověřování",
|
||||
"Share without verifying": "Sdílet bez ověření",
|
||||
"Ignore request": "Ignorovat žádost",
|
||||
|
@ -632,10 +588,6 @@
|
|||
"This will be your account name on the <span></span> homeserver, or you can pick a <a>different server</a>.": "Toto bude název vašeho účtu na domácím serveru <span></span>, anebo si můžete zvolit <a>jiný server</a>.",
|
||||
"If you already have a Matrix account you can <a>log in</a> instead.": "Pokud již účet Matrix máte, můžete se ihned <a>Přihlásit</a>.",
|
||||
"%(oneUser)sjoined %(count)s times|other": "%(oneUser)s %(count)s krát vstoupil",
|
||||
"You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Neověřená zařízení jsou v této chvíli na černé listině; pokud chcete zasílat zprávy na tato zařízení, musíte je nejdříve ověřit.",
|
||||
"We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Doporučujeme vám projít procesem ověřování pro všechna zařízení, abyste si potvrdili, že patří jejich pravým vlastníkům, ale pokud si to přejete, můžete zprávu znovu odeslat bez ověřování.",
|
||||
"\"%(RoomName)s\" contains devices that you haven't seen before.": "V místnosti „%(RoomName)s“ jsou zařízení s kterými jste dosud nikdy nekomunikovali.",
|
||||
"Unknown devices": "Neznámá zařízení",
|
||||
"Private Chat": "Soukromý chat",
|
||||
"Public Chat": "Veřejný chat",
|
||||
"You must <a>register</a> to use this functionality": "Musíte být <a>zaregistrovaný</a> pokud chcete využívat této funkce",
|
||||
|
@ -678,12 +630,10 @@
|
|||
"Sent messages will be stored until your connection has returned.": "Odeslané zprávy zůstanou uložené, dokud se spojení znovu neobnoví.",
|
||||
"Active call": "Aktivní hovor",
|
||||
"There's no one else here! Would you like to <inviteText>invite others</inviteText> or <nowarnText>stop warning about the empty room</nowarnText>?": "Kromě vás není v této místnosti nikdo jiný! Přejete si <inviteText>Pozvat další</inviteText> anebo <nowarnText>Přestat upozorňovat na prázdnou místnost</nowarnText>?",
|
||||
"Message not sent due to unknown devices being present": "Zpráva nebyla odeslána vzhledem k nalezeným neznámým zařízením",
|
||||
"Room": "Místnost",
|
||||
"Failed to load timeline position": "Nepodařilo se načíst pozici na časové ose",
|
||||
"Light theme": "Světlý motiv",
|
||||
"Dark theme": "Tmavý motiv",
|
||||
"Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Vaše heslo bylo úspěšně změněno. Na ostatních zařízeních se vám již nebudou zobrazovat okamžitá oznámení do té chvíle než se na nich znovu přihlásíte",
|
||||
"Analytics": "Analytické údaje",
|
||||
"Riot collects anonymous analytics to allow us to improve the application.": "Riot sbírá anonymní analytické údaje, které nám umožňují aplikaci dále zlepšovat.",
|
||||
"Labs": "Experimentální funkce",
|
||||
|
@ -701,7 +651,6 @@
|
|||
"This server does not support authentication with a phone number.": "Tento server nepodporuje ověření telefonním číslem.",
|
||||
"Deops user with given id": "Zruší stav moderátor uživateli se zadaným ID",
|
||||
"Searches DuckDuckGo for results": "Vyhledá výsledky na DuckDuckGo",
|
||||
"Verifies a user, device, and pubkey tuple": "Ověří zadané údaje uživatele, zařízení a veřejný klíč",
|
||||
"Ignores a user, hiding their messages from you": "Ignoruje uživatele a skryje všechny jeho zprávy",
|
||||
"Stops ignoring a user, showing their messages going forward": "Přestane ignorovat uživatele a začne zobrazovat jeho zprávy",
|
||||
"Notify the whole room": "Oznámení pro celou místnost",
|
||||
|
@ -711,7 +660,6 @@
|
|||
"This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Tento proces vás provede importem šifrovacích klíčů, které jste si stáhli z jiného Matrix klienta. Po úspěšném naimportování budete v tomto klientovi moci dešifrovat všechny zprávy, které jste mohli dešifrovat v původním klientovi.",
|
||||
"The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Stažený soubor je chráněn heslem. Soubor můžete naimportovat pouze pokud zadáte odpovídající heslo.",
|
||||
"Call Failed": "Hovor selhal",
|
||||
"There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "V této místnosti jsou neznámá zařízení: Pokud budete pokračovat bez jejich ověření, někdo může Váš hovor odposlouchávat.",
|
||||
"Review Devices": "Ověřit zařízení",
|
||||
"Call Anyway": "Přesto zavolat",
|
||||
"Answer Anyway": "Přesto přijmout",
|
||||
|
@ -771,7 +719,6 @@
|
|||
"Resend": "Poslat znovu",
|
||||
"Collecting app version information": "Sbírání informací o verzi aplikace",
|
||||
"Delete the room alias %(alias)s and remove %(name)s from the directory?": "Smazat alias místnosti %(alias)s a odstranit %(name)s z adresáře?",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "Toto vám umožní vrátit se po odhlášení ke svému účtu a používat jej na ostatních zařízeních.",
|
||||
"Keywords": "Klíčová slova",
|
||||
"Enable notifications for this account": "Zapnout upozornění na tomto účtu",
|
||||
"Invite to this community": "Pozvat do této komunity",
|
||||
|
@ -878,27 +825,15 @@
|
|||
"Send analytics data": "Odesílat analytická data",
|
||||
"Enable widget screenshots on supported widgets": "Povolit screenshot widgetu pro podporované widgety",
|
||||
"This event could not be displayed": "Tato událost nemohla být zobrazena",
|
||||
"Your key share request has been sent - please check your other devices for key share requests.": "Žádost o sdílení klíče byla odeslána - prosím zkontrolujte si Vaše ostatí zařízení.",
|
||||
"Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Žádost o sdílení klíčů je automaticky odesílaná na Vaše ostatní zařízení. Jestli jste žádost odmítly nebo zrušili dialogové okno se žádostí na ostatních zařízeních, kliknutím sem ji můžete opakovaně pro tuto relaci vyžádat.",
|
||||
"If your other devices do not have the key for this message you will not be able to decrypt them.": "Pokud Vaše ostatní zařízení nemají klíč pro tyto zprávy, nebudete je moci dešifrovat.",
|
||||
"Key request sent.": "Žádost o klíč poslána.",
|
||||
"<requestLink>Re-request encryption keys</requestLink> from your other devices.": "<requestLink>Znovu vyžádat šifrovací klíče</requestLink> z vašich ostatních zařízení.",
|
||||
"Demote yourself?": "Snížit Vaši vlastní hodnost?",
|
||||
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Tuto změnu nebudete moci vzít zpět, protože snižujete svoji vlastní hodnost, jste-li poslední privilegovaný uživatel v místnosti, bude nemožné vaši současnou hodnost získat zpět.",
|
||||
"Demote": "Degradovat",
|
||||
"Share Link to User": "Sdílet odkaz na uživatele",
|
||||
"deleted": "smazáno",
|
||||
"underlined": "podtrženo",
|
||||
"inline-code": "vnořený kód",
|
||||
"block-quote": "citace",
|
||||
"bulleted-list": "odrážkový seznam",
|
||||
"numbered-list": "číselný seznam",
|
||||
"Send an encrypted reply…": "Odeslat šifrovanou odpověď …",
|
||||
"Send a reply (unencrypted)…": "Odeslat odpověď (nešifrovaně) …",
|
||||
"Send an encrypted message…": "Odeslat šifrovanou zprávu …",
|
||||
"Send a message (unencrypted)…": "Odeslat zprávu (nešifrovaně) …",
|
||||
"Unable to reply": "Není možné odpovědět",
|
||||
"At this time it is not possible to reply with an emote.": "V odpovědi zatím nejde vyjádřit pocit.",
|
||||
"Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "%(displayName)s (%(userName)s) viděl %(dateTime)s",
|
||||
"Replying": "Odpovídá",
|
||||
"Share room": "Sdílet místnost",
|
||||
|
@ -975,7 +910,6 @@
|
|||
"Review terms and conditions": "Přečíst smluvní podmínky",
|
||||
"Did you know: you can use communities to filter your Riot.im experience!": "Věděli jste, že: práci s Riot.im si můžete zpříjemnit s použitím komunit!",
|
||||
"To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Pro nastavení filtru přetáhněte avatar komunity na panel filtrování na levé straně obrazovky. Potom můžete kdykoliv kliknout na avatar komunity na tomto panelu a Riot Vám bude zobrazovat jen místnosti a lidi z dané komunity.",
|
||||
"<showDevicesText>Show devices</showDevicesText>, <sendAnywayText>send anyway</sendAnywayText> or <cancelText>cancel</cancelText>.": "<showDevicesText>Zobrazit zařízení</showDevicesText>, <sendAnywayText>i tak odeslat</sendAnywayText> a nebo <cancelText>zrušit</cancelText>.",
|
||||
"You can't send any messages until you review and agree to <consentLink>our terms and conditions</consentLink>.": "Dokud si nepřečtete a neodsouhlasíte <consentLink>naše smluvní podmínky</consentLink>, nebudete moci posílat žádné zprávy.",
|
||||
"Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please <a>contact your service administrator</a> to continue using the service.": "Vaše zpráva nebyla odeslána, protože tento domácí server dosáhl svého měsíčního limitu pro aktivní uživatele. Prosím <a>kontaktujte Vašeho administratora</a> pro další využívání služby.",
|
||||
"Your message wasn't sent because this homeserver has exceeded a resource limit. Please <a>contact your service administrator</a> to continue using the service.": "Vaše zpráva nebyla odeslána, protože tento domácí server dosáhl limitu. Prosím <a>kontaktujte Vašeho administratora</a> pro další využívání služby.",
|
||||
|
@ -1017,9 +951,7 @@
|
|||
"Set a new password": "Nastavit nové heslo",
|
||||
"Room Name": "Jméno místnosti",
|
||||
"Room Topic": "Téma místnosti",
|
||||
"No room avatar": "Žádný avatar místnosti",
|
||||
"Room avatar": "Avatar místnosti",
|
||||
"Upload room avatar": "Nahrát avatar místnosti",
|
||||
"Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.": "Změny toho kdo smí číst historické zprávy se aplikují jenom na další zprávy v této místosti. Viditelnost už poslaných zpráv zůstane jaká byla.",
|
||||
"To link to this room, please add an alias.": "K vytvoření odkazu je potřeba vyrobit místnosti alias.",
|
||||
"Roles & Permissions": "Funkce & Práva",
|
||||
|
@ -1052,7 +984,7 @@
|
|||
"Show a placeholder for removed messages": "Zobrazovat zamazání místo smazané zprávy",
|
||||
"Show display name changes": "Zobrazovat změny jména",
|
||||
"Messages containing my username": "Zprávy obsahující moje uživatelské jméno",
|
||||
"Messages containing @room": "Zprávy obsahující @místnost",
|
||||
"Messages containing @room": "Zprávy obsahující @room",
|
||||
"Encrypted messages in one-to-one chats": "Zašifrované zprávy v přímých chatech",
|
||||
"Email addresses": "Emailové adresy",
|
||||
"Set a new account password...": "Nastavit nové heslo...",
|
||||
|
@ -1065,7 +997,6 @@
|
|||
"Unable to verify phone number.": "Nepovedlo se ověřit telefonní číslo.",
|
||||
"Verification code": "Ověřovací kód",
|
||||
"Profile picture": "Profilový obrázek",
|
||||
"Upload profile picture": "Nahrát profilový obrázek",
|
||||
"Display Name": "Zobrazované jméno",
|
||||
"Room Addresses": "Adresy místnosti",
|
||||
"For help with using Riot, click <a>here</a>.": "Pro pomoc s používáním Riotu, klikněte <a>sem</a>.",
|
||||
|
@ -1074,10 +1005,6 @@
|
|||
"Ignored users": "Ignorovaní uživatelé",
|
||||
"Bulk options": "Hromadná možnost",
|
||||
"Key backup": "Záloha klíčů",
|
||||
"Some devices for this user are not trusted": "Některá zařízení nejsou důvěryhodné",
|
||||
"Some devices in this encrypted room are not trusted": "Některá zařízení v této šifrované místnosti nejsou důvěryhodné",
|
||||
"All devices for this user are trusted": "Všechna zařízení tohoto uživatele jsou důvěryhodná",
|
||||
"All devices in this encrypted room are trusted": "Všechna zařízení v této šifrované místnosti jsou důveryhodná",
|
||||
"This room has been replaced and is no longer active.": "Tato místnost byla nahrazena a už není používaná.",
|
||||
"The conversation continues here.": "Konverzace pokračuje zde.",
|
||||
"We've sent you an email to verify your address. Please follow the instructions there and then click the button below.": "Poslali jsme Vám ověřovací email. Následujte prosím instrukce a pak klikněte na následující tlačítko.",
|
||||
|
@ -1087,21 +1014,11 @@
|
|||
"Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Šifrované zprávy jsou zabezpečené end-to-end šifrováním. Jenom Vy a příjemci mají dešifrovací klíče.",
|
||||
"Unable to load key backup status": "Nepovedlo se načíst stav zálohy",
|
||||
"Restore from Backup": "Obnovit ze zálohy",
|
||||
"This device is backing up your keys. ": "Toto zařízení má zálohované klíče. ",
|
||||
"Back up your keys before signing out to avoid losing them.": "Před odhlášením si zazálohujte klíče abyste o ně nepřišli.",
|
||||
"Backing up %(sessionsRemaining)s keys...": "Zálohování %(sessionsRemaining)s klíčů...",
|
||||
"All keys backed up": "Všechny klíče jsou zazálohované",
|
||||
"Backup has a signature from <verify>unknown</verify> device with ID %(deviceId)s.": "Záloha je podepsaná <verify>neznámým</verify> zařízením s ID %(deviceId)s.",
|
||||
"Backup has a <validity>valid</validity> signature from this device": "Záloha má <validity>platný</validity> podpis tohoto zařízení",
|
||||
"Backup has a <validity>valid</validity> signature from <verify>verified</verify> device <device></device>": "Záloha má <validity>platný</validity> podpis <verify>ověřeného</verify> zařízení <device></device>",
|
||||
"Backup has a <validity>valid</validity> signature from <verify>unverified</verify> device <device></device>": "Záloha má <validity>platný</validity> podpis <verify>neověřeného</verify> zařízení <device></device>",
|
||||
"Backup has an <validity>invalid</validity> signature from <verify>verified</verify> device <device></device>": "Záloha má <validity>neplatný</validity> podpis <verify>ověřeného</verify> zařízení <device></device>",
|
||||
"Backup has an <validity>invalid</validity> signature from <verify>unverified</verify> device <device></device>": "Záloha má <validity>neplatný</validity> podpis <verify>neověřeného</verify> zařízení <device></device>",
|
||||
"Backup is not signed by any of your devices": "Záloha není podepsaná žádným Vaším zařízením",
|
||||
"This backup is trusted because it has been restored on this device": "Tato záloha je důvěryhodná, protože už z ní byly obnovené klíče",
|
||||
"Backup version: ": "Verze zálohy: ",
|
||||
"Algorithm: ": "Algoritmus: ",
|
||||
"Your keys are <b>not being backed up from this device</b>.": "Vaše klíče se z tohoto zařízení <b>nezálohují</b>.",
|
||||
"Start using Key Backup": "Začít používat zálohu klíčů",
|
||||
"Add an email address to configure email notifications": "Pro nastavení emailových upozornění je třeba přidat emailovou adresu",
|
||||
"Whether or not you're logged in (we don't record your username)": "Jestli jste přihlášený/á (nezaznamenáváme ale Vaše jméno)",
|
||||
|
@ -1175,7 +1092,6 @@
|
|||
"Verify this user by confirming the following emoji appear on their screen.": "Ověřte uživatele zkontrolováním, že se mu na obrazovce objevily stejné obrázky.",
|
||||
"Verify this user by confirming the following number appears on their screen.": "Ověřte uživatele zkontrolováním, že se na obrazovce objevila stejná čísla.",
|
||||
"Unable to find a supported verification method.": "Nepovedlo se nám najít podporovanou metodu ověření.",
|
||||
"For maximum security, we recommend you do this in person or use another trusted means of communication.": "Pro co nejlepší bezpečnost doporučujeme ověření dělat osobně nebo přes nějaký jiný důvěryhodný kanál.",
|
||||
"Dog": "Pes",
|
||||
"Cat": "Kočka",
|
||||
"Lion": "Lev",
|
||||
|
@ -1221,7 +1137,6 @@
|
|||
"Book": "Kniha",
|
||||
"Pencil": "Tužka",
|
||||
"Paperclip": "Sponka",
|
||||
"Padlock": "Zámek",
|
||||
"Key": "Klíč",
|
||||
"Hammer": "Kladivo",
|
||||
"Telephone": "Telefon",
|
||||
|
@ -1262,7 +1177,6 @@
|
|||
"Incompatible Database": "Nekompatibilní databáze",
|
||||
"Continue With Encryption Disabled": "Pokračovat bez šifrování",
|
||||
"Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Po ověření bude uživatel označen jako důvěryhodný. Ověřování uživatelů Vám dává jistotu, že je komunikace důvěrná.",
|
||||
"Verifying this user will mark their device as trusted, and also mark your device as trusted to them.": "Ověření uživatele označí jeho zařízení za důvěryhodná a Vaše zařízení budou důvěryhodná pro něj.",
|
||||
"Waiting for partner to confirm...": "Čekám až to partner potvrdí...",
|
||||
"Incoming Verification Request": "Přišla Vám žádost o ověření",
|
||||
"Incompatible local cache": "Nekompatibilní lokální vyrovnávací paměť",
|
||||
|
@ -1288,9 +1202,7 @@
|
|||
"This looks like a valid recovery key!": "To vypadá jako správný klíč!",
|
||||
"Not a valid recovery key": "To není správný klíč",
|
||||
"Access your secure message history and set up secure messaging by entering your recovery key.": "Zadejte obnovovací klíč pro přístupu k historii zpráv a zabezpečené komunikaci.",
|
||||
"If you've forgotten your recovery passphrase you can <button>set up new recovery options</button>": "Pokud si nepamatujete heslo k obnovení, můžete si <button>nastavit další možnosti obnovení klíčů</button>",
|
||||
"Recovery Method Removed": "Záloha klíčů byla odstraněna",
|
||||
"This device has detected that your recovery passphrase and key for Secure Messages have been removed.": "Na tomto zařízení došlo k odstranění hesla k zálohám a klíče k zabezpečné konverzaci.",
|
||||
"Go to Settings": "Přejít do nastavení",
|
||||
"Enter a passphrase...": "Zadejte silné heslo...",
|
||||
"For maximum security, this should be different from your account password.": "Z bezpečnostních důvodů by toto heslo mělo být jiné než přihlašovací heslo.",
|
||||
|
@ -1306,12 +1218,9 @@
|
|||
"As a safety net, you can use it to restore your encrypted message history if you forget your Recovery Passphrase.": "Tento klíč můžete použít jako záchranou síť k obnově zašifrované historie pokud byste zapomněl/a heslo k záloze.",
|
||||
"As a safety net, you can use it to restore your encrypted message history.": "Tento klíč můžete použít jako záchranou síť k obnově zašifrované historie.",
|
||||
"Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your passphrase.": "Obnovovací klíč je záchraná síť - lze použít k obnově zašifrovaných zpráv když zapomenete heslo.",
|
||||
"Keep your recovery key somewhere very secure, like a password manager (or a safe)": "Uchovejte tento klíč na velmi bezpečném místě, například ve správci hesel (password manageru) nebo v trezoru",
|
||||
"Your Recovery Key": "Váš klíč pro obnovu zálohy",
|
||||
"Copy to clipboard": "Zkopírovat do schránky",
|
||||
"Download": "Stáhnout",
|
||||
"Your Recovery Key has been <b>copied to your clipboard</b>, paste it to:": "Klíč byl <b>uložen do schránky</b>, vložte ho:",
|
||||
"Your Recovery Key is in your <b>Downloads</b> folder.": "Klíč byl uložen do <b>složky se staženými soubory</b>.",
|
||||
"<b>Print it</b> and store it somewhere safe": "<b>Vytiskněte</b> si ho a bezpečně ho uložte",
|
||||
"<b>Save it</b> on a USB key or backup drive": "<b>Uložte ho</b> na bezpečnou USB flash disk nebo zálohovací disk",
|
||||
"<b>Copy it</b> to your personal cloud storage": "<b>Zkopírujte si ho</b> na osobní cloudové úložiště",
|
||||
|
@ -1326,7 +1235,6 @@
|
|||
"Unable to create key backup": "Nepovedlo se vyrobit zálohů klíčů",
|
||||
"Retry": "Zkusit znovu",
|
||||
"Set up Secure Messages": "Nastavit bezpečné obnovení zpráv",
|
||||
"This device is encrypting history using the new recovery method.": "Toto zařízení šifruje historii pomocí nového způsobu zálohy a obnovy.",
|
||||
"If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Pokud jste způsob obnovy neodstranili Vy, útočníci se můžou pokoušet dostat k vašemu účtu. Změňte si raději ihned heslo a nastavte nový způsob obnovy v Nastavení.",
|
||||
"Set up": "Nastavit",
|
||||
"Don't ask again": "Už se neptat",
|
||||
|
@ -1334,9 +1242,7 @@
|
|||
"If you don't want to set this up now, you can later in Settings.": "Pokud nechcete nastavení dokončit teď, můžete se k tomu vrátit později v nastavení.",
|
||||
"A new recovery passphrase and key for Secure Messages have been detected.": "Detekovali jsme nové heslo a klíč pro bezpečné obnovení.",
|
||||
"If you didn't set the new recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Pokud jste nenastavili nový způsob obnovy Vy, útočníci se můžou pokoušet dostat k vašemu účtu. Změňte si raději ihned heslo a nastavte nový způsob obnovy v Nastavení.",
|
||||
"If you did this accidentally, you can setup Secure Messages on this device which will re-encrypt this device's message history with a new recovery method.": "Pokud jste to udělali omylem, můžete si na tomto zařízení nastavit bezpečné obnovení zpráv, což znovu zašifruje kompletní historii s novým způsobem obnovení.",
|
||||
"Set up Secure Message Recovery": "Nastavit bezpečné obnovení zpráv",
|
||||
"Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another device.": "Když si nenastavíte bezpečné obnovení zpráv, nebudete mít možnost po odhlášení nebo přihlášení se na jiném zařízení číst historii šifrovaných konverzací.",
|
||||
"Without setting up Secure Message Recovery, you'll lose your secure message history when you log out.": "Bez nastavení bezpečného obnovení zpráv přijdete po odhlášení o historii šifrované komunikace.",
|
||||
"Show a reminder to enable Secure Message Recovery in encrypted rooms": "V šifrovaných konverzacích zobrazovat upozornění na možnost aktivovat bezpečné obnovení zpráv",
|
||||
"Gets or sets the room topic": "Nastaví nebo zjistí téma místnosti",
|
||||
|
@ -1347,7 +1253,6 @@
|
|||
"Enable Community Filter Panel": "Povolit panel Filtr komunity",
|
||||
"Show developer tools": "Zobrazit nástoje pro vývojáře",
|
||||
"Encrypted messages in group chats": "Šifrované zprávy ve skupinových konverzacích",
|
||||
"Your homeserver does not support device management.": "Váš domovský server nepodporuje správu zařízení.",
|
||||
"Open Devtools": "Otevřít nástroje pro vývojáře",
|
||||
"Credits": "Poděkování",
|
||||
"You've previously used a newer version of Riot on %(host)s. To use this version again with end to end encryption, you will need to sign out and back in again. ": "Už jste na adrese %(host)s použili novější verzi Riotu. Jestli chcete znovu používat tuto verzi i s E2E šifrováním, je potřeba se odhlásit a znovu přihlásit. ",
|
||||
|
@ -1394,7 +1299,6 @@
|
|||
"A verification email will be sent to your inbox to confirm setting your new password.": "Nastavení nového hesla je potřeba potvrdit. Bude Vám odeslán ověřovací email.",
|
||||
"Sign in instead": "Přihlásit se",
|
||||
"Your password has been reset.": "Heslo bylo resetováno.",
|
||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "Na všech zařízení jsme Vás odhlásili, takže nedostáváte žádné upozornění. Můžete je znovu povolit tím, že se na každém zařízení přihlásíte.",
|
||||
"Sign in with single sign-on": "Přihlásit se přes jednotné přihlašování",
|
||||
"Create account": "Vytvořit účet",
|
||||
"Unable to query for supported registration methods.": "Nepovedlo se načíst podporované způsoby přihlášení.",
|
||||
|
@ -1444,13 +1348,7 @@
|
|||
"The file '%(fileName)s' failed to upload.": "Soubor '%(fileName)s' se nepodařilo nahrát.",
|
||||
"The server does not support the room version specified.": "Server nepodporuje určenou verzi místnosti.",
|
||||
"Name or Matrix ID": "Jméno nebo Matrix ID",
|
||||
"Email, name or Matrix ID": "Email, jméno nebo Matrix ID",
|
||||
"Room upgrade confirmation": "Potvrzení: Upgrade místnosti",
|
||||
"Upgrading a room can be destructive and isn't always necessary.": "Upgrade místnosti může mít destruktivní následky a možná není potřeba.",
|
||||
"Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Upgrade místnosti se většinou doporučuje pokud je původní verze <i>nestabilní</i>. V nestabilních verzích můžou být chyby, chybějící funkce nebo můžou mít bezpečnostní problémy.",
|
||||
"Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.": "Upgrade místnosti se většinou týká zpracování <i>serverovem</i>. Pokud máte problém s klientem Riot, nahlašte nám prosím chybu na GitHub: <issueLink />.",
|
||||
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "<b>Varování</b>: Upgrade místnosti <i>automaticky převede všechny členy na novou verzi místnosti.</i> Do staré místnosti pošleme odkaz na novou místnost - všichni členové na něj budou muset kliknout, aby se přidali do nové místnosti.",
|
||||
"Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />.": "Potvrďte prosím, že chcete pokračovat a opravdu provést upgrade z verze <oldVersion /> na verzi <newVersion />.",
|
||||
"Changes your avatar in this current room only": "Změní váš avatar jen v této místnosti",
|
||||
"Unbans user with given ID": "Přijmout zpět uživatele s daným identifikátorem",
|
||||
"Adds a custom widget by URL to the room": "Přidá do místnosti vlastní widget podle adresy URL",
|
||||
|
@ -1467,12 +1365,6 @@
|
|||
"The user's homeserver does not support the version of the room.": "Uživatelův domovský server nepodporuje verzi této místnosti.",
|
||||
"Show hidden events in timeline": "Zobrazovat skryté události",
|
||||
"When rooms are upgraded": "Když je proveden upgrade místnosti",
|
||||
"This device is <b>not backing up your keys</b>, but you do have an existing backup you can restore from and add to going forward.": "Toto zařízení <b>nezálohuje vaše klíče</b>, ale máte existující zálohu kterou lze obnovit.",
|
||||
"Connect this device to key backup before signing out to avoid losing any keys that may only be on this device.": "Před odhlášením připojte toto zařízení k záloze klíčů, ať o ně nepřijdete.",
|
||||
"Connect this device to Key Backup": "Připojit zařízení k zálohování klíčů",
|
||||
"Backup has an <validity>invalid</validity> signature from this device": "Záloha má <validity>neplatný</validity> podpis z tohoto zařízení",
|
||||
"Enable desktop notifications for this device": "Povolit na tomto zařízení notifikace",
|
||||
"Enable audible notifications for this device": "Povolit na tomto zařízení zvukové notifikace",
|
||||
"<a>Upgrade</a> to your own domain": "<a>Přejít</a> na vlastní doménu",
|
||||
"Upgrade this room to the recommended room version": "Provést upgrade místnosti na doporučenou verzi",
|
||||
"this room": "tato místnost",
|
||||
|
@ -1568,7 +1460,6 @@
|
|||
"You have %(count)s unread notifications in a prior version of this room.|other": "Máte %(count)s nepřečtených notifikací v předchozí verzi této místnosti.",
|
||||
"You have %(count)s unread notifications in a prior version of this room.|one": "Máte %(count)s nepřečtenou notifikaci v předchozí verzi této místnosti.",
|
||||
"Your profile": "Váš profil",
|
||||
"Changing your password will reset any end-to-end encryption keys on all of your devices, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another device before resetting your password.": "Změna hesla resetuje šifrovací klíče na všech vašich zařízeních a přijdete tak o přístup k historickým zprávám. Před změnou hesla si nastavte zálohu klíčů nebo si klíče pro místnosti exportujte.",
|
||||
"Your Matrix account on <underlinedServerName />": "Váš Matrix účet na serveru <underlinedServerName />",
|
||||
"Failed to get autodiscovery configuration from server": "Nepovedlo se automaticky načíst konfiguraci ze serveru",
|
||||
"Invalid base_url for m.homeserver": "Neplatná base_url pro m.homeserver",
|
||||
|
@ -1597,7 +1488,6 @@
|
|||
"Please ask the administrator of your homeserver (<code>%(homeserverDomain)s</code>) to configure a TURN server in order for calls to work reliably.": "Zeptejte se administrátora (<code>%(homeserverDomain)s</code>) jestli by nemohl nakonfigurovat server TURN, aby začalo fungoval volání.",
|
||||
"Alternatively, you can try to use the public server at <code>turn.matrix.org</code>, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "Případně můžete zkusit použít veřejný server <code>turn.matrix.org</code>, což nemusí fungovat tak spolehlivě a řekne to tomu cizímu serveru vaší IP adresu. Můžete to udělat v Nastavení.",
|
||||
"Try using turn.matrix.org": "Zkuste použít turn.matrix.org",
|
||||
"Failed to start chat": "Nepovedlo se začít chat",
|
||||
"Messages": "Zprávy",
|
||||
"Actions": "Akce",
|
||||
"Sends a message as plain text, without interpreting it as markdown": "Pošle zprávu jako prostý text, neinterpretuje jí jako Markdown",
|
||||
|
@ -1648,8 +1538,6 @@
|
|||
"Close dialog": "Zavřít dialog",
|
||||
"Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "Napište nám prosím co se pokazilo a nebo nám napište issue na GitHub, kde popíšete problém.",
|
||||
"Removing…": "Odstaňování…",
|
||||
"Clear all data on this device?": "Smazat všechna data na tomto zařízení?",
|
||||
"Clearing all data from this device is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Smazání všech dat na tomto zařízení je nevratné. Zašifrované zprávy nepůjde obnovit, pokud nejsou klíče zazálohované.",
|
||||
"Clear all data": "Smazat všechna data",
|
||||
"Please enter a name for the room": "Zadejte prosím jméno místnosti",
|
||||
"Set a room alias to easily share your room with other people.": "Nastavte alias místnosti, abyste mohli místnost snadno sdílet s ostatními.",
|
||||
|
@ -1661,7 +1549,6 @@
|
|||
"Hide advanced": "Skrýt pokročilé",
|
||||
"Show advanced": "Zobrazit pokročilé",
|
||||
"Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "Zamezit uživatelům jiných domovských serverů, aby se připojili do místnosti (Toto nelze později změnit!)",
|
||||
"To verify that this device can be trusted, please check that the key you see in User Settings on that device matches the key below:": "Abyste ověřili, že je toto zařízení důvěryhodné, zkontrolujte, že klíč v Nastavení na tom zařízení se shoduje s tímto klíčem:",
|
||||
"Your homeserver doesn't seem to support this feature.": "Váš domovský server asi tuto funkci nepodporuje.",
|
||||
"Message edits": "Editování zpráv",
|
||||
"Please fill why you're reporting.": "Vyplňte prosím co chcete nahlásit.",
|
||||
|
@ -1678,7 +1565,6 @@
|
|||
"Trust": "Důvěra",
|
||||
"%(name)s (%(userId)s)": "%(name)s (%(userId)s)",
|
||||
"Multiple integration managers": "Více správců integrací",
|
||||
"Use the new, faster, composer for writing messages": "Použít nový, rychlejší editor zpráv",
|
||||
"Show previews/thumbnails for images": "Zobrazovat náhledy obrázků",
|
||||
"You should <b>remove your personal data</b> from identity server <idserver /> before disconnecting. Unfortunately, identity server <idserver /> is currently offline or cannot be reached.": "Před odpojením byste měli <b>smazat osobní údaje</b> ze serveru identit <idserver />. Bohužel, server je offline nebo neodpovídá.",
|
||||
"You should:": "Měli byste:",
|
||||
|
@ -1690,7 +1576,6 @@
|
|||
"Show tray icon and minimize window to it on close": "Zobrazovat systémovou ikonu a minimalizovat při zavření",
|
||||
"Read Marker lifetime (ms)": "životnost značky přečteno (ms)",
|
||||
"Read Marker off-screen lifetime (ms)": "životnost značky přečteno mimo obrazovku (ms)",
|
||||
"A device's public name is visible to people you communicate with": "Veřejné jméno zařízení je viditelné pro lidi se kterými komunikujete",
|
||||
"Upgrade the room": "Upgradovat místnost",
|
||||
"Enable room encryption": "Povolit v místnosti šifrování",
|
||||
"Error changing power level requirement": "Chyba změny požadavku na úroveň oprávnění",
|
||||
|
@ -1820,14 +1705,12 @@
|
|||
"Registration Successful": "Úspěšná registrace",
|
||||
"Failed to re-authenticate due to a homeserver problem": "Kvůli problémům s domovským server se nepovedlo autentifikovat znovu",
|
||||
"Failed to re-authenticate": "Nepovedlo se autentifikovat",
|
||||
"Regain access to your account and recover encryption keys stored on this device. Without them, you won’t be able to read all of your secure messages on any device.": "Získejte znovu přístup k účtu a obnovte si šifrovací klíče uložené na tomto zařízení. Bez nich nebudete schopni číst zabezpečené zprávy na některých zařízeních.",
|
||||
"Enter your password to sign in and regain access to your account.": "Zadejte heslo pro přihlášení a obnovte si přístup k účtu.",
|
||||
"Forgotten your password?": "Zapomněli jste heslo?",
|
||||
"Sign in and regain access to your account.": "Přihlaste se a získejte přístup ke svému účtu.",
|
||||
"You cannot sign in to your account. Please contact your homeserver admin for more information.": "Nemůžete se přihlásit do svého účtu. Kontaktujte administrátora domovského serveru pro více informací.",
|
||||
"You're signed out": "Jste odhlášeni",
|
||||
"Clear personal data": "Smazat osobní data",
|
||||
"Warning: Your personal data (including encryption keys) is still stored on this device. Clear it if you're finished using this device, or want to sign in to another account.": "Varování: Vaše osobní data (včetně šifrovacích klíčů) jsou pořád uložena na tomto zařízení. Smažte je, pokud už toto zařízení nehodláte používat nebo se přihlašte pod jiný účet.",
|
||||
"Command Autocomplete": "Automatické doplňování příkazů",
|
||||
"Community Autocomplete": "Automatické doplňování komunit",
|
||||
"DuckDuckGo Results": "Výsledky hledání DuckDuckGo",
|
||||
|
@ -1860,13 +1743,11 @@
|
|||
"%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s změnil pravidlo blokující servery odpovídající %(oldGlob)s na servery odpovídající %(newGlob)s z důvodu %(reason)s",
|
||||
"%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s změnil blokovací pravidlo odpovídající %(oldGlob)s na odpovídající %(newGlob)s z důvodu %(reason)s",
|
||||
"Try out new ways to ignore people (experimental)": "Vyzkošejte nové metody ignorování lidí (experimentální)",
|
||||
"Send verification requests in direct message, including a new verification UX in the member panel.": "Poslat požadavek na ověření v přímé zprávě včetně nového verifikačního rozhraní v panelu.",
|
||||
"Enable local event indexing and E2EE search (requires restart)": "Povolit lokální indexování a vyhledávání v E2E šifrovaných zprávách (vyžaduje restart)",
|
||||
"Match system theme": "Přizpůsobit se systémovému vzhledu",
|
||||
"My Ban List": "Můj seznam zablokovaných",
|
||||
"This is your list of users/servers you have blocked - don't leave the room!": "Toto je váš seznam blokovaných uživatelů/serverů - neopouštějte tuto místnost!",
|
||||
"Decline (%(counter)s)": "Odmítnout (%(counter)s)",
|
||||
"on device": "na zařízení",
|
||||
"Connecting to integration manager...": "Připojuji se ke správci integrací...",
|
||||
"Cannot connect to integration manager": "Nepovedlo se připojení ke správci integrací",
|
||||
"The integration manager is offline or it cannot reach your homeserver.": "Správce integrací neběží nebo se nemůže připojit k vašemu domovskému serveru.",
|
||||
|
@ -1911,11 +1792,7 @@
|
|||
"Failed to connect to integration manager": "Nepovedlo se připojit ke správci integrací",
|
||||
"Trusted": "Důvěryhodné",
|
||||
"Not trusted": "Nedůvěryhodné",
|
||||
"Hide verified Sign-In's": "Skrýt důvěryhodná přihlášení",
|
||||
"%(count)s verified Sign-In's|other": "%(count)s důvěryhodných přihlášení",
|
||||
"%(count)s verified Sign-In's|one": "1 důvěryhodné přihlášení",
|
||||
"Direct message": "Přímá zpráva",
|
||||
"Unverify user": "Nedůvěřovat uživateli",
|
||||
"<strong>%(role)s</strong> in %(roomName)s": "<strong>%(role)s</strong> v %(roomName)s",
|
||||
"Messages in this room are end-to-end encrypted.": "V této místosti jsou zprávy E2E šifrované.",
|
||||
"Security": "Bezpečnost",
|
||||
|
@ -1965,16 +1842,12 @@
|
|||
"User Status": "Stav uživatele",
|
||||
"Verification Request": "Požadavek na ověření",
|
||||
" (1/%(totalCount)s)": " (1/%(totalCount)s)",
|
||||
"<b>Warning</b>: You should only set up secret storage from a trusted computer.": "<b>Varování</b>: Nastavujte bezpečné úložiště pouze z důvěryhodného počítače.",
|
||||
"Set up with a recovery key": "Nastavit obnovovací klíč",
|
||||
"As a safety net, you can use it to restore your access to encrypted messages if you forget your passphrase.": "Můžete jej použít jako záchranou síť na obnovení šifrovaných zpráv když zapomenete heslo.",
|
||||
"As a safety net, you can use it to restore your access to encrypted messages.": "Můžete jej použít jako záchranou síť na obnovení šifrovaných zpráv.",
|
||||
"Keep your recovery key somewhere very secure, like a password manager (or a safe).": "Uschovejte svůj klíč na velmi bezpečném místě, například ve správci hesel (nebo v trezoru).",
|
||||
"Your recovery key has been <b>copied to your clipboard</b>, paste it to:": "Váš obnovovací klíč byl <b>zkopírován do schránky</b>, vložte jej:",
|
||||
"Your recovery key is in your <b>Downloads</b> folder.": "Váš obnovací klíč je ve složce <b>Stažené</b>.",
|
||||
"Your access to encrypted messages is now protected.": "Přístup k šifrovaným zprávám je teď chráněn.",
|
||||
"Set up secret storage": "Nastavit bezpečné úložiště",
|
||||
"Secure your encrypted messages with a passphrase": "Zabezpečte vaše šifrované zprávy heslem",
|
||||
"Storing secrets...": "Ukládám tajná data...",
|
||||
"Unable to set up secret storage": "Nepovedlo se nastavit bezpečné úložiště",
|
||||
"The message you are trying to send is too large.": "Zpráva kterou se snažíte odeslat je příliš velká.",
|
||||
|
@ -1982,12 +1855,6 @@
|
|||
"Backup has a <validity>valid</validity> signature from this user": "Záloha má <validity>platný</validity> podpis od tohoto uživatele",
|
||||
"Backup has a <validity>invalid</validity> signature from this user": "Záloha má <validity>neplatný</validity> podpis od tohoto uživatele",
|
||||
"Backup has a signature from <verify>unknown</verify> user with ID %(deviceId)s": "Záloha je podepsaná <verify>neznámým</verify> uživatelem %(deviceId)s",
|
||||
"Backup has a signature from <verify>unknown</verify> device with ID %(deviceId)s": "Záloha je podepsaná <verify>neznámým</verify> zařízením %(deviceId)s",
|
||||
"This user has not verified all of their devices.": "Uživatel neověřil všechna svá zařízení.",
|
||||
"You have not verified this user. This user has verified all of their devices.": "Tohoto uživatele jste neověřili. Uživatel má ověřená všechna svá zařízení.",
|
||||
"You have verified this user. This user has verified all of their devices.": "Tohoto uživatele jste ověřili. Uživatel má ověřená všechna svá zařízení.",
|
||||
"Some users in this encrypted room are not verified by you or they have not verified their own devices.": "Někteřé uživatele v této šifrované místnosti jste neověřili nebo nemají ověřená některá svá zařízení.",
|
||||
"All users in this encrypted room are verified by you and they have verified their own devices.": "Všichni uživatelé v této šifrované místnosti jsou ověření a mají ověřená všechna svá zařízení.",
|
||||
"Close preview": "Zavřít náhled",
|
||||
"Hide verified sessions": "Schovat ověřené relace",
|
||||
"%(count)s verified sessions|other": "%(count)s ověřených relací",
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"You have no visible notifications": "Du har ingen synlige meddelelser",
|
||||
"Invites": "Invitationer",
|
||||
"Favourites": "Favoritter",
|
||||
"People": "Personilg chat",
|
||||
"Rooms": "Rum",
|
||||
"Low priority": "Lav prioritet",
|
||||
"Historical": "Historisk",
|
||||
|
@ -28,7 +27,6 @@
|
|||
"Session ID": "Sessions ID",
|
||||
"End-to-end encryption information": "End-to-end krypterings oplysninger",
|
||||
"Event information": "Hændelses information",
|
||||
"Sender device information": "Afsende enheds-oplysning",
|
||||
"Displays action": "Viser handling",
|
||||
"Bans user with given id": "Forbyder bruger med givet id",
|
||||
"Deops user with given id": "Fjerner OP af bruger med givet id",
|
||||
|
@ -146,10 +144,6 @@
|
|||
"Restricted": "Begrænset",
|
||||
"Moderator": "Moderator",
|
||||
"Start a chat": "Start en chat",
|
||||
"Who would you like to communicate with?": "Hvem vil du kommunikere med?",
|
||||
"Start Chat": "Start Chat",
|
||||
"Invite new room members": "Inviter nye rummedlemmer",
|
||||
"Send Invites": "Send invitationer",
|
||||
"Operation failed": "Operation mislykkedes",
|
||||
"Failed to invite": "Kunne ikke invitere",
|
||||
"Failed to invite the following users to the %(roomName)s room:": "Kunne ikke invitere de følgende brugere til %(roomName)s rummet:",
|
||||
|
@ -172,13 +166,7 @@
|
|||
"You are now ignoring %(userId)s": "Du ignorere nu %(userId)s",
|
||||
"Unignored user": "Holdt op med at ignorere bruger",
|
||||
"You are no longer ignoring %(userId)s": "Du ignorer ikke længere %(userId)s",
|
||||
"Unknown (user, device) pair:": "Ukendt (bruger, enhed) par:",
|
||||
"Device already verified!": "Enhed allerede verificeret!",
|
||||
"WARNING: Device already verified, but keys do NOT MATCH!": "ADVARSEL: Enhed allerede verificeret, men nøgler PASSER IKKE!",
|
||||
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ADVARSEL: NØGLE VERIFICERING FEJLEDE! Signaturnøglen for %(userId)s and enhed %(deviceId)s er \"%(fprint)s\" hvilket ikke passer med den oplyste nøgle \"%(fingerprint)s\". Dette kan betyde jeres kommunikation bliver opsnappet!",
|
||||
"Verified key": "Verificeret nøgle",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Signaturnøglen du oplste passer med nøglen fra %(userId)ss enhed %(deviceId)s. Enheden er markeret som verificeret.",
|
||||
"Unrecognised command:": "Ukendt kommando:",
|
||||
"Reason": "Årsag",
|
||||
"%(senderName)s requested a VoIP conference.": "%(senderName)s forespurgte en VoIP konference.",
|
||||
"%(senderName)s invited %(targetName)s.": "%(senderName)s inviterede %(targetName)s.",
|
||||
|
@ -259,7 +247,6 @@
|
|||
"Noisy": "Støjende",
|
||||
"Collecting app version information": "Indsamler app versionsoplysninger",
|
||||
"Delete the room alias %(alias)s and remove %(name)s from the directory?": "Slet rumaliaset %(alias)s og fjern %(name)s fra kataloget?",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "Dette vil tillade dig at vende tilbage til din konto efter at have logget ud og at logge ind på andre enheder.",
|
||||
"Keywords": "Søgeord",
|
||||
"Enable notifications for this account": "Aktivér underretninger for dette brugernavn",
|
||||
"Invite to this community": "Inviter til dette fællesskab",
|
||||
|
@ -361,7 +348,6 @@
|
|||
"The information being sent to us to help make Riot.im better includes:": "Information som sendes til os for at kunne forbedre Riot.im inkluderer:",
|
||||
"Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Hvis denne side indeholder identificerbar information, så som rum, bruger eller gruppe ID, bliver disse fjernet før dataene sendes til serveren.",
|
||||
"Call Failed": "Opkald mislykkedes",
|
||||
"There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Der er ukendte enheder i dette rum: hvis du fortsætter uden at bekræfte dem, kan det være muligt at nogen aflytter dit opkald.",
|
||||
"Review Devices": "Gennemse enheder",
|
||||
"Call Anyway": "Ring op alligevel",
|
||||
"Answer Anyway": "Tag imod alligevel",
|
||||
|
@ -391,8 +377,6 @@
|
|||
"Unable to load! Check your network connectivity and try again.": "Kunne ikke hente! Tjek din netværksforbindelse og prøv igen.",
|
||||
"Registration Required": "Registrering påkrævet",
|
||||
"You need to register to do this. Would you like to register now?": "Du behøver registrere dig for at gøre dette. Vil du registrere nu?",
|
||||
"Email, name or Matrix ID": "E-mail, navn eller Matrix-ID",
|
||||
"Failed to start chat": "Kunne ikke starte chatten",
|
||||
"Failed to invite users to the room:": "Kunne ikke invitere brugere til rummet:",
|
||||
"Missing roomId.": "roomId mangler.",
|
||||
"Messages": "Beskeder",
|
||||
|
@ -402,12 +386,7 @@
|
|||
"Sends a message as plain text, without interpreting it as markdown": "Sender en besked som ren tekst, uden at fortolke den som Markdown",
|
||||
"Upgrades a room to a new version": "Opgraderer et rum til en ny version",
|
||||
"You do not have the required permissions to use this command.": "Du har ikke de nødvendige rettigheder for at udføre denne kommando.",
|
||||
"Room upgrade confirmation": "Rum opgraderings information",
|
||||
"Upgrading a room can be destructive and isn't always necessary.": "At opgradere et rum kan være skadelig og er ikke altid nødvendigt.",
|
||||
"Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Rumopgraderinger anbefales typisk når en rumversion betragtes som <i>ustabil</i>. Ustabile rumversioner kan have fejl, manglende funktioner eller sikkerhedsbrister.",
|
||||
"Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.": "Rumopgraderinger påvirker normalt kun <i>servernes</i> behandling af rum. Hvis du har problemer med din Riot-klient bedes du oprette en sag på <issueLink />.",
|
||||
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "<b>Advarsel:</b> Opgradering af et rum <i>flytter ikke automatisk rummets medlemmer til den nye version af rummet.</i> Vi sender et link til den nye version i den gamle version af rummet - rummets medlemmer må klikke på dette link for at tilgå det nye rum.",
|
||||
"Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />.": "Bekræft venligst at du vil fortsætte med at opgradere rummet fra <oldVersion /> til <newVersion />.",
|
||||
"Changes your display nickname in the current room only": "Ændrer dit viste navn kun for det nuværende rum",
|
||||
"Changes the avatar of the current room": "Ændrer avataren af det nuværende rum",
|
||||
"Changes your avatar in this current room only": "Ændrer din avatar kun for det nuværende rum",
|
||||
|
@ -427,7 +406,6 @@
|
|||
"Adds a custom widget by URL to the room": "Tilføjer en widget til rummet vha. URL",
|
||||
"Please supply a https:// or http:// widget URL": "Oplys en https:// eller http:// widget URL",
|
||||
"You cannot modify widgets in this room.": "Du kan ikke ændre widgets i dette rum.",
|
||||
"Verifies a user, device, and pubkey tuple": "Bekræfter en tupel (kombination) af bruger, enhed og offentlig nøgle",
|
||||
"Forces the current outbound group session in an encrypted room to be discarded": "Tvinger den nuværende udgående gruppe-session i et krypteret rum til at blive kasseret",
|
||||
"Sends the given message coloured as a rainbow": "Sender beskeden med regnbuefarver",
|
||||
"Sends the given emote coloured as a rainbow": "Sender emoji'en med regnbuefarver",
|
||||
|
@ -457,7 +435,6 @@
|
|||
"%(senderName)s made future room history visible to all room members.": "%(senderName)s gjorde fremtidig rumhistorik synligt for alle rummedlemmer.",
|
||||
"%(senderName)s made future room history visible to anyone.": "%(senderName)s gjorde fremtidig rumhistorik synligt for alle.",
|
||||
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s gjorde fremtidig rumhistorik synligt for ukendt (%(visibility)s).",
|
||||
"%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s aktiverede end-to-end kryptering (algoritme %(algorithm)s).",
|
||||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s fra %(fromPowerLevel)s til %(toPowerLevel)s",
|
||||
"%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s ændrede rettighedsniveau af %(powerLevelDiffText)s.",
|
||||
"%(senderName)s changed the pinned messages for the room.": "%(senderName)s ændrede de fastgjorte beskeder for rummet.",
|
||||
|
@ -537,7 +514,6 @@
|
|||
"Group & filter rooms by custom tags (refresh to apply changes)": "Gruppér og filtrér rum efter egne tags (opdater for at anvende ændringerne)",
|
||||
"Render simple counters in room header": "Vis simple tællere i rumhovedet",
|
||||
"Multiple integration managers": "Flere integrationsmanagere",
|
||||
"Use the new, faster, composer for writing messages": "Brug den nye, hurtigere editor for at forfatte beskeder",
|
||||
"Enable Emoji suggestions while typing": "Aktiver emoji forslag under indtastning",
|
||||
"Use compact timeline layout": "Brug kompakt tidslinje",
|
||||
"Show a placeholder for removed messages": "Vis en pladsholder for fjernede beskeder"
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"You have no visible notifications": "Du hast keine sichtbaren Benachrichtigungen",
|
||||
"Invites": "Einladungen",
|
||||
"Favourites": "Favoriten",
|
||||
"People": "Personen",
|
||||
"Rooms": "Räume",
|
||||
"Low priority": "Niedrige Priorität",
|
||||
"Historical": "Archiv",
|
||||
|
@ -28,7 +27,6 @@
|
|||
"Session ID": "Sitzungs-ID",
|
||||
"End-to-end encryption information": "Informationen zur Ende-zu-Ende-Verschlüsselung",
|
||||
"Event information": "Ereignis-Information",
|
||||
"Sender device information": "Geräte-Informationen des Absenders",
|
||||
"Displays action": "Zeigt Aktionen an",
|
||||
"Bans user with given id": "Verbannt den Benutzer mit der angegebenen ID",
|
||||
"Deops user with given id": "Setzt das Berechtigungslevel beim Benutzer mit der angegebenen ID zurück",
|
||||
|
@ -54,7 +52,6 @@
|
|||
"Deactivate Account": "Benutzerkonto schließen",
|
||||
"Failed to send email": "Fehler beim Senden der E-Mail",
|
||||
"Account": "Benutzerkonto",
|
||||
"Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Dein Passwort wurde erfolgreich geändert. Du wirst erst Benachrichtigungen auf anderen Geräten empfangen können, wenn du dich dort erneut anmeldest",
|
||||
"Click here to fix": "Zum reparieren hier klicken",
|
||||
"Default": "Standard",
|
||||
"Export E2E room keys": "E2E-Raum-Schlüssel exportieren",
|
||||
|
@ -72,14 +69,11 @@
|
|||
"I have verified my email address": "Ich habe meine E-Mail-Adresse verifiziert",
|
||||
"Import E2E room keys": "E2E-Raum-Schlüssel importieren",
|
||||
"Invalid Email Address": "Ungültige E-Mail-Adresse",
|
||||
"Invite new room members": "Neue Raum-Mitglieder einladen",
|
||||
"Sign in with": "Anmelden mit",
|
||||
"Leave room": "Raum verlassen",
|
||||
"Logout": "Abmelden",
|
||||
"Manage Integrations": "Integrationen verwalten",
|
||||
"Moderator": "Moderator",
|
||||
"Never send encrypted messages to unverified devices from this device": "Niemals verschlüsselte Nachrichten an unverifizierte Geräte von diesem Gerät aus versenden",
|
||||
"Never send encrypted messages to unverified devices in this room from this device": "Niemals verschlüsselte Nachrichten an unverifizierte Geräte in diesem Raum von diesem Gerät aus senden",
|
||||
"Notifications": "Benachrichtigungen",
|
||||
"<not supported>": "<nicht unterstützt>",
|
||||
"No users have specific privileges in this room": "Kein Benutzer hat in diesem Raum besondere Berechtigungen",
|
||||
|
@ -94,14 +88,12 @@
|
|||
"Remove": "Entfernen",
|
||||
"Return to login screen": "Zur Anmeldemaske zurückkehren",
|
||||
"Room Colour": "Raumfarbe",
|
||||
"Send Invites": "Einladungen senden",
|
||||
"Send Reset Email": "E-Mail zum Zurücksetzen senden",
|
||||
"Settings": "Einstellungen",
|
||||
"Signed Out": "Abgemeldet",
|
||||
"Sign out": "Abmelden",
|
||||
"Someone": "Jemand",
|
||||
"Start a chat": "Chat starten",
|
||||
"Start Chat": "Chat beginnen",
|
||||
"Success": "Erfolg",
|
||||
"This doesn't appear to be a valid email address": "Dies scheint keine gültige E-Mail-Adresse zu sein",
|
||||
"This room is not accessible by remote Matrix servers": "Remote-Matrix-Server können auf diesen Raum nicht zugreifen",
|
||||
|
@ -124,7 +116,6 @@
|
|||
"VoIP conference started.": "VoIP-Konferenz gestartet.",
|
||||
"Who can access this room?": "Wer hat Zugang zu diesem Raum?",
|
||||
"Who can read history?": "Wer kann den bisherigen Chatverlauf lesen?",
|
||||
"Who would you like to communicate with?": "Mit wem möchtest du kommunizieren?",
|
||||
"You do not have permission to post to this room": "Du hast keine Berechtigung, in diesem Raum etwas zu senden",
|
||||
"Call Timeout": "Anruf-Timeout",
|
||||
"Existing Call": "Bereits bestehender Anruf",
|
||||
|
@ -206,7 +197,6 @@
|
|||
"%(senderName)s set their display name to %(displayName)s.": "%(senderName)s hat den Anzeigenamen geändert in %(displayName)s.",
|
||||
"This room is not recognised.": "Dieser Raum wurde nicht erkannt.",
|
||||
"To use it, just wait for autocomplete results to load and tab through them.": "Um diese Funktion zu nutzen, warte einfach auf die Autovervollständigungsergebnisse und benutze dann die TAB-Taste zum durchblättern.",
|
||||
"%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s hat die Ende-zu-Ende-Verschlüsselung aktiviert (Algorithmus: %(algorithm)s).",
|
||||
"%(senderName)s unbanned %(targetName)s.": "%(senderName)s hat die Verbannung von %(targetName)s aufgehoben.",
|
||||
"Usage": "Verwendung",
|
||||
"%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s hat die Einladung für %(targetName)s zurückgezogen.",
|
||||
|
@ -228,7 +218,6 @@
|
|||
"Click to mute video": "Klicken, um das Video stummzuschalten",
|
||||
"Command error": "Befehlsfehler",
|
||||
"Decrypt %(text)s": "%(text)s entschlüsseln",
|
||||
"Devices": "Geräte",
|
||||
"Direct chats": "Direkt-Chats",
|
||||
"Disinvite": "Einladung zurückziehen",
|
||||
"Download %(text)s": "%(text)s herunterladen",
|
||||
|
@ -240,19 +229,12 @@
|
|||
"Failed to reject invite": "Ablehnen der Einladung ist fehlgeschlagen",
|
||||
"Failed to set display name": "Anzeigename konnte nicht gesetzt werden",
|
||||
"Fill screen": "Fülle Bildschirm",
|
||||
"Hide Text Formatting Toolbar": "Text-Formatierungs-Werkzeugleiste verbergen",
|
||||
"Incorrect verification code": "Falscher Verifizierungscode",
|
||||
"Invalid alias format": "Ungültiges Alias-Format",
|
||||
"'%(alias)s' is not a valid format for an alias": "'%(alias)s' ist kein gültiges Alias-Format",
|
||||
"Join Room": "Dem Raum beitreten",
|
||||
"Kick": "Kicken",
|
||||
"Local addresses for this room:": "Lokale Adressen dieses Raumes:",
|
||||
"Markdown is disabled": "Markdown ist deaktiviert",
|
||||
"Markdown is enabled": "Markdown ist aktiviert",
|
||||
"Message not sent due to unknown devices being present": "Nachrichten wurden nicht gesendet, da unbekannte Geräte anwesend sind",
|
||||
"New address (e.g. #foo:%(localDomain)s)": "Neue Adresse (z. B. #foo:%(localDomain)s)",
|
||||
"not specified": "nicht spezifiziert",
|
||||
"No devices with registered encryption keys": "Keine Geräte mit registrierten Verschlüsselungs-Schlüsseln",
|
||||
"No more results": "Keine weiteren Ergebnisse",
|
||||
"No results": "Keine Ergebnisse",
|
||||
"OK": "OK",
|
||||
|
@ -267,7 +249,6 @@
|
|||
"This room has no local addresses": "Dieser Raum hat keine lokale Adresse",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Es wurde versucht, einen bestimmten Punkt im Chatverlauf dieses Raumes zu laden. Dir fehlt jedoch die Berechtigung, die betreffende Nachricht zu sehen.",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Es wurde versucht, einen bestimmten Punkt im Chatverlauf dieses Raumes zu laden, der Punkt konnte jedoch nicht gefunden werden.",
|
||||
"Unable to load device list": "Geräteliste konnte nicht geladen werden",
|
||||
"Unknown room %(roomId)s": "Unbekannter Raum %(roomId)s",
|
||||
"You seem to be in a call, are you sure you want to quit?": "Du scheinst in einem Anruf zu sein. Bist du sicher schließen zu wollen?",
|
||||
"You seem to be uploading files, are you sure you want to quit?": "Du scheinst Dateien hochzuladen. Bist du sicher schließen zu wollen?",
|
||||
|
@ -275,8 +256,6 @@
|
|||
"Make Moderator": "Zum Moderator ernennen",
|
||||
"Room": "Raum",
|
||||
"Cancel": "Abbrechen",
|
||||
"bold": "Fett",
|
||||
"italic": "Kursiv",
|
||||
"Click to unmute video": "Klicken, um die Video-Stummschaltung zu deaktivieren",
|
||||
"Click to unmute audio": "Klicken, um den Ton wieder einzuschalten",
|
||||
"Failed to load timeline position": "Laden der Chat-Position fehlgeschlagen",
|
||||
|
@ -291,7 +270,6 @@
|
|||
"Confirm password": "Passwort bestätigen",
|
||||
"Current password": "Aktuelles Passwort",
|
||||
"Email": "E-Mail",
|
||||
"matrix-react-sdk version:": "Version von matrix-react-sdk:",
|
||||
"New passwords don't match": "Die neuen Passwörter stimmen nicht überein",
|
||||
"olm version:": "Version von olm:",
|
||||
"Passwords can't be empty": "Passwortfelder dürfen nicht leer sein",
|
||||
|
@ -302,7 +280,6 @@
|
|||
"Error decrypting attachment": "Fehler beim Entschlüsseln des Anhangs",
|
||||
"Mute": "Stummschalten",
|
||||
"Operation failed": "Aktion fehlgeschlagen",
|
||||
"Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Eine Änderung des Passworts setzt derzeit alle Schlüssel für die E2E-Verschlüsselung auf allen verwendeten Geräten zurück. Bereits verschlüsselte Chat-Inhalte sind somit nur noch lesbar, wenn du zunächst alle Schlüssel exportierst und später wieder importierst. Wir arbeiten an einer Verbesserung dieser momentan noch notwendigen Vorgehensweise.",
|
||||
"Unmute": "Stummschalten aufheben",
|
||||
"Invalid file%(extra)s": "Ungültige Datei%(extra)s",
|
||||
"Please select the destination room for this message": "Bitte den Raum auswählen, an den diese Nachricht gesendet werden soll",
|
||||
|
@ -320,14 +297,8 @@
|
|||
"Unknown error": "Unbekannter Fehler",
|
||||
"Incorrect password": "Ungültiges Passwort",
|
||||
"To continue, please enter your password.": "Zum fortfahren bitte Passwort eingeben.",
|
||||
"Device name": "Geräte-Name",
|
||||
"Device key": "Geräte-Schlüssel",
|
||||
"Verify device": "Gerät verifizieren",
|
||||
"I verify that the keys match": "Ich bestätige, dass die Schlüssel identisch sind",
|
||||
"Unable to restore session": "Sitzungswiederherstellung fehlgeschlagen",
|
||||
"You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Nicht verifizierte Geräte werden aktuell blockiert und auf die Sperrliste gesetzt. Um Nachrichten an diese Geräte senden zu können, müssen diese zunächst verifiziert werden.",
|
||||
"\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" enthält Geräte, die du bislang noch nicht gesehen hast.",
|
||||
"Unknown devices": "Unbekannte Geräte",
|
||||
"Unknown Address": "Unbekannte Adresse",
|
||||
"Verify...": "Verifizieren...",
|
||||
"ex. @bob:example.com": "z. B. @bob:example.com",
|
||||
|
@ -357,15 +328,12 @@
|
|||
"Online": "Online",
|
||||
" (unsupported)": " (nicht unterstützt)",
|
||||
"This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Dieser Prozess erlaubt es dir, die zuvor von einem anderen Matrix-Client exportierten Verschlüsselungs-Schlüssel zu importieren. Danach kannst du alle Nachrichten entschlüsseln, die auch bereits auf dem anderen Client entschlüsselt werden konnten.",
|
||||
"To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Um sicherzustellen, dass diesem Gerät vertraut werden kann, kontaktiere bitte den Eigentümer des Geräts über ein anderes Kommunikationsmittel (z.B. im persönlichen Gespräch oder durch einen Telefonanruf) und vergewissere dich, dass der Schlüssel, den der Eigentümer in den Benutzer-Einstellungen für dieses Gerät sieht, mit dem folgenden Schlüssel identisch ist:",
|
||||
"If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Wenn er identisch ist, bitte den Bestätigen-Button unten verwenden. Falls er nicht identisch sein sollte, hat eine Fremdperson Kontrolle über dieses Gerät und es sollte gesperrt werden.",
|
||||
"If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Wenn du zuvor eine aktuellere Version von Riot verwendet hast, ist deine Sitzung eventuell inkompatibel mit dieser Version. Bitte schließe dieses Fenster und kehre zur aktuelleren Version zurück.",
|
||||
"Blacklist": "Blockieren",
|
||||
"Unblacklist": "Entblockieren",
|
||||
"Unverify": "Verifizierung widerrufen",
|
||||
"Drop file here to upload": "Datei hier loslassen zum hochladen",
|
||||
"Idle": "Untätig",
|
||||
"We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Wir empfehlen dir, für jedes Gerät den Verifizierungsprozess durchzuführen, um sicherzustellen, dass sie tatsächlich ihrem rechtmäßigem Eigentümer gehören. Alternativ kannst du die Nachrichten auch ohne Verifizierung erneut senden.",
|
||||
"Ongoing conference call%(supportedText)s.": "Laufendes Konferenzgespräch%(supportedText)s.",
|
||||
"You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Du wirst jetzt auf die Website eines Drittanbieters weitergeleitet, damit du dein Benutzerkonto für die Verwendung von %(integrationsUrl)s authentifizieren kannst. Möchtest du fortfahren?",
|
||||
"Start automatically after system login": "Nach System-Login automatisch starten",
|
||||
|
@ -380,30 +348,22 @@
|
|||
"Default Device": "Standard-Gerät",
|
||||
"Microphone": "Mikrofon",
|
||||
"Camera": "Kamera",
|
||||
"Device already verified!": "Gerät bereits verifiziert!",
|
||||
"Export": "Export",
|
||||
"Import": "Importieren",
|
||||
"Incorrect username and/or password.": "Inkorrekter Nutzername und/oder Passwort.",
|
||||
"Results from DuckDuckGo": "Ergebnisse von DuckDuckGo",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Den Signaturschlüssel den du bereitstellst stimmt mit dem Schlüssel den du von %(userId)s's Gerät %(deviceId)s empfangen hast überein. Gerät als verifiziert markiert.",
|
||||
"Add a topic": "Thema hinzufügen",
|
||||
"Anyone": "Jeder",
|
||||
"Are you sure you want to leave the room '%(roomName)s'?": "Bist du sicher, dass du den Raum '%(roomName)s' verlassen möchtest?",
|
||||
"Custom level": "Benutzerdefiniertes Berechtigungslevel",
|
||||
"Device ID:": "Geräte-Kennung:",
|
||||
"device id: ": "Geräte-ID: ",
|
||||
"Device key:": "Geräte-Schlüssel:",
|
||||
"Publish this room to the public in %(domain)s's room directory?": "Diesen Raum im Raum-Verzeichnis von %(domain)s veröffentlichen?",
|
||||
"Register": "Registrieren",
|
||||
"Save": "Speichern",
|
||||
"Unknown (user, device) pair:": "Unbekanntes (Benutzer-/Gerät-)Paar:",
|
||||
"Remote addresses for this room:": "Remote-Adressen für diesen Raum:",
|
||||
"Unrecognised command:": "Unbekannter Befehl:",
|
||||
"Unrecognised room alias:": "Unbekannter Raum-Alias:",
|
||||
"Use compact timeline layout": "Kompaktes Chatverlauf-Layout verwenden",
|
||||
"Verified key": "Verifizierter Schlüssel",
|
||||
"WARNING: Device already verified, but keys do NOT MATCH!": "WARNUNG: Gerät bereits verifiziert, aber Schlüssel sind NICHT GLEICH!",
|
||||
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "WARNUNG: SCHLÜSSEL-VERIFIZIERUNG FEHLGESCHLAGEN! Der Signatur-Schlüssel für %(userId)s und das Gerät %(deviceId)s ist \"%(fprint)s\", welcher nicht mit dem bereitgestellten Schlüssel \"%(fingerprint)s\" übereinstimmt. Dies kann bedeuten, dass deine Kommunikation abgehört wird!",
|
||||
"You have <a>disabled</a> URL previews by default.": "Du hast die URL-Vorschau standardmäßig <a>deaktiviert</a>.",
|
||||
"You have <a>enabled</a> URL previews by default.": "Du hast die URL-Vorschau standardmäßig <a>aktiviert</a>.",
|
||||
"%(senderDisplayName)s changed the room avatar to <img/>": "%(senderDisplayName)s hat das Raum-Bild geändert zu <img/>",
|
||||
|
@ -438,7 +398,6 @@
|
|||
"Disable Notifications": "Benachrichtigungen deaktivieren",
|
||||
"Drop File Here": "Lasse Datei hier los",
|
||||
"Enable Notifications": "Benachrichtigungen aktivieren",
|
||||
"Encrypted by an unverified device": "Von einem nicht verifizierten Gerät verschlüsselt",
|
||||
"Failed to upload profile picture!": "Hochladen des Profilbild's fehlgeschlagen!",
|
||||
"Incoming call from %(name)s": "Eingehender Anruf von %(name)s",
|
||||
"Incoming video call from %(name)s": "Eingehender Video-Anruf von %(name)s",
|
||||
|
@ -448,16 +407,12 @@
|
|||
"No display name": "Kein Anzeigename",
|
||||
"Private Chat": "Privater Chat",
|
||||
"Public Chat": "Öffentlicher Chat",
|
||||
"Room contains unknown devices": "Raum enthält unbekannte Geräte",
|
||||
"%(roomName)s does not exist.": "%(roomName)s existert nicht.",
|
||||
"%(roomName)s is not accessible at this time.": "%(roomName)s ist aktuell nicht zugreifbar.",
|
||||
"Seen by %(userName)s at %(dateTime)s": "Gesehen von %(userName)s um %(dateTime)s",
|
||||
"Send anyway": "Trotzdem senden",
|
||||
"Start authentication": "Authentifizierung beginnen",
|
||||
"Show Text Formatting Toolbar": "Text-Formatierungs-Werkzeugleiste anzeigen",
|
||||
"This room": "In diesem Raum",
|
||||
"Undecryptable": "Nicht entschlüsselbar",
|
||||
"Unencrypted message": "Nicht verschlüsselbare Nachricht",
|
||||
"unknown caller": "Unbekannter Anrufer",
|
||||
"Unnamed Room": "Unbenannter Raum",
|
||||
"Upload new:": "Neue(s) hochladen:",
|
||||
|
@ -476,9 +431,7 @@
|
|||
"Start verification": "Verifizierung starten",
|
||||
"Share without verifying": "Ohne Verifizierung verwenden",
|
||||
"Ignore request": "Anforderung ignorieren",
|
||||
"You added a new device '%(displayName)s', which is requesting encryption keys.": "Du hast das neue Gerät '%(displayName)s' hinzugefügt, welches nun Verschlüsselungs-Schlüssel anfordert.",
|
||||
"Encryption key request": "Anforderung von Verschlüsselungs-Schlüsseln",
|
||||
"Your unverified device '%(displayName)s' is requesting encryption keys.": "Dein nicht verifiziertes Gerät '%(displayName)s' fordert Verschlüsselungs-Schlüssel an.",
|
||||
"Check for update": "Suche nach Updates",
|
||||
"Add a widget": "Widget hinzufügen",
|
||||
"Allow": "Erlauben",
|
||||
|
@ -490,8 +443,6 @@
|
|||
"Unable to create widget.": "Widget kann nicht erstellt werden.",
|
||||
"You are not in this room.": "Du bist nicht in diesem Raum.",
|
||||
"You do not have permission to do that in this room.": "Du hast dafür keine Berechtigung in diesem Raum.",
|
||||
"Verifies a user, device, and pubkey tuple": "Verifiziert ein Tupel aus Benutzer, Gerät und öffentlichem Schlüssel",
|
||||
"Loading device info...": "Lädt Geräte-Info...",
|
||||
"Example": "Beispiel",
|
||||
"Create": "Erstellen",
|
||||
"Featured Rooms:": "Hervorgehobene Räume:",
|
||||
|
@ -705,13 +656,10 @@
|
|||
"Flair": "Abzeichen",
|
||||
"Showing flair for these communities:": "Abzeichen für diese Communities zeigen:",
|
||||
"This room is not showing flair for any communities": "Dieser Raum zeigt für keine Communities die Abzeichen an",
|
||||
"Delete %(count)s devices|other": "Lösche %(count)s Geräte",
|
||||
"Delete %(count)s devices|one": "Lösche Gerät",
|
||||
"Something went wrong when trying to get your communities.": "Beim Laden deiner Communites ist etwas schief gelaufen.",
|
||||
"Display your community flair in rooms configured to show it.": "Zeige deinen Community-Flair in den Räumen, die es erlauben.",
|
||||
"This homeserver doesn't offer any login flows which are supported by this client.": "Dieser Heimserver verfügt über keinen, von diesem Client unterstütztes Anmeldeverfahren.",
|
||||
"Call Failed": "Anruf fehlgeschlagen",
|
||||
"There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "In diesem Raum befinden sich nicht-verifizierte Geräte. Wenn du fortfährst ohne sie zu verifizieren, könnten Angreifer den Anruf mithören.",
|
||||
"Review Devices": "Geräte ansehen",
|
||||
"Call Anyway": "Trotzdem anrufen",
|
||||
"Answer Anyway": "Trotzdem annehmen",
|
||||
|
@ -743,7 +691,6 @@
|
|||
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s",
|
||||
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Du wirst nicht in der Lage sein, die Änderung zurückzusetzen, da du dich degradierst. Wenn du der letze Nutzer mit Berechtigungen bist, wird es unmöglich sein die Privilegien zurückzubekommen.",
|
||||
"Community IDs cannot be empty.": "Community-IDs können nicht leer sein.",
|
||||
"<showDevicesText>Show devices</showDevicesText>, <sendAnywayText>send anyway</sendAnywayText> or <cancelText>cancel</cancelText>.": "<showDevicesText>Geräte anzeigen</showDevicesText>, <sendAnywayText>trotzdem senden</sendAnywayText> oder <cancelText>abbrechen</cancelText>.",
|
||||
"Learn more about how we use analytics.": "Lerne mehr darüber, wie wir die Analysedaten nutzen.",
|
||||
"Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Wenn diese Seite identifizierbare Informationen wie Raum, Nutzer oder Gruppen-ID enthalten, werden diese Daten entfernt bevor sie an den Server gesendet werden.",
|
||||
"Which officially provided instance you are using, if any": "Welche offiziell angebotene Instanz du nutzt, wenn es der Fall ist",
|
||||
|
@ -756,11 +703,7 @@
|
|||
"Did you know: you can use communities to filter your Riot.im experience!": "Wusstest du: Du kannst Communities nutzen um deine Riot.im-Erfahrung zu filtern!",
|
||||
"To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Um einen Filter zu setzen, siehe einen Community-Bild auf das Filter-Panel ganz links. Du kannst jederzeit auf einen Avatar im Filter-Panel klicken um nur die Räume und Personen aus der Community zu sehen.",
|
||||
"Clear filter": "Filter zurücksetzen",
|
||||
"Your key share request has been sent - please check your other devices for key share requests.": "Die Anfrage den Schlüssel zu teilen wurden gesendet. Bitte sieh auf deinen anderen Geräte nach der Anfrage.",
|
||||
"Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Schlüssel-Anfragen wurden automatisch zu den anderen Geräten gesendet. Wenn du diese Anfragen auf deinen anderen Geräten abgelehnt oder verpasst hast, klicke hier um die Schlüssel für diese Sitzung erneut anzufragen.",
|
||||
"If your other devices do not have the key for this message you will not be able to decrypt them.": "Wenn deine anderen Geräte keine Schlüssel für diese Nachricht haben, wirst du diese nicht entschlüsseln können.",
|
||||
"Key request sent.": "Schlüssel-Anfragen gesendet.",
|
||||
"<requestLink>Re-request encryption keys</requestLink> from your other devices.": "Verschlüsselungs-Schlüssel von deinen anderen Geräten <requestLink>erneut anfragen</requestLink>.",
|
||||
"If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Wenn du einen Fehler via GitHub gemeldet hast, können Fehlerberichte uns helfen um das Problem zu finden. Sie enthalten Anwendungsdaten wie deinen Nutzernamen, Raum- und Gruppen-ID's und Aliase die du besucht hast und Nutzernamen anderer Nutzer. Sie enthalten keine Nachrichten.",
|
||||
"Submit debug logs": "Fehlerberichte einreichen",
|
||||
"Code": "Code",
|
||||
|
@ -823,7 +766,6 @@
|
|||
"Noisy": "Laut",
|
||||
"Collecting app version information": "App-Versionsinformationen werden abgerufen",
|
||||
"Delete the room alias %(alias)s and remove %(name)s from the directory?": "Soll der Raum-Alias %(alias)s gelöscht und der %(name)s aus dem Verzeichnis entfernt werden?",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "Dies erlaubt dir, dich wieder an deinem Konto anzumelden, nachdem du dich abgemeldet hast.",
|
||||
"Keywords": "Schlüsselwörter",
|
||||
"Enable notifications for this account": "Benachrichtigungen für dieses Benutzerkonto aktivieren",
|
||||
"Invite to this community": "In diese Community einladen",
|
||||
|
@ -913,7 +855,6 @@
|
|||
"Your device resolution": "Deine Bildschirmauflösung",
|
||||
"Popout widget": "Widget ausklinken",
|
||||
"Always show encryption icons": "Immer Verschlüsselungssymbole zeigen",
|
||||
"Unable to reply": "Antworten nicht möglich",
|
||||
"Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Das Ereignis, auf das geantwortet wurde, konnte nicht geladen werden. Entweder es existiert nicht oder du hast keine Berechtigung, dieses anzusehen.",
|
||||
"Send Logs": "Sende Protokoll",
|
||||
"Clear Storage and Sign Out": "Speicher leeren und abmelden",
|
||||
|
@ -921,7 +862,6 @@
|
|||
"We encountered an error trying to restore your previous session.": "Wir haben ein Problem beim Wiederherstellen deiner vorherigen Sitzung festgestellt.",
|
||||
"Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Den Browser-Speicher zu löschen kann das Problem lösen, wird dich aber abmelden und verschlüsselte Chats unlesbar machen.",
|
||||
"Collapse Reply Thread": "Antwort-Thread zusammenklappen",
|
||||
"At this time it is not possible to reply with an emote.": "An dieser Stelle ist es nicht möglich mit einer Umschreibung zu antworten.",
|
||||
"Enable widget screenshots on supported widgets": "Widget-Screenshots bei unterstützten Widgets aktivieren",
|
||||
"Send analytics data": "Analysedaten senden",
|
||||
"e.g. %(exampleValue)s": "z.B. %(exampleValue)s",
|
||||
|
@ -965,14 +905,8 @@
|
|||
"A call is currently being placed!": "Ein Anruf wurde schon gestartet!",
|
||||
"Permission Required": "Berechtigung benötigt",
|
||||
"You do not have permission to start a conference call in this room": "Du hast keine Berechtigung um ein Konferenzgespräch in diesem Raum zu starten",
|
||||
"deleted": "gelöscht",
|
||||
"underlined": "unterstrichen",
|
||||
"bulleted-list": "Liste mit Punkten",
|
||||
"numbered-list": "Liste mit Nummern",
|
||||
"Failed to remove widget": "Widget konnte nicht entfernt werden",
|
||||
"An error ocurred whilst trying to remove the widget from the room": "Ein Fehler trat auf, während versucht wurde das Widget aus diesem Raum zu entfernen",
|
||||
"inline-code": "Quellcode",
|
||||
"block-quote": "Zitat",
|
||||
"System Alerts": "System-Benachrichtigung",
|
||||
"Only room administrators will see this warning": "Nur Raum-Administratoren werden diese Nachricht sehen",
|
||||
"Please <a>contact your service administrator</a> to continue using the service.": "Bitte <a>kontaktiere deinen Systemadministrator</a> um diesen Dienst weiter zu nutzen.",
|
||||
|
@ -1024,11 +958,6 @@
|
|||
"Show developer tools": "Zeige Entwickler-Werkzeuge",
|
||||
"Unable to load! Check your network connectivity and try again.": "Konnte nicht geladen werden! Überprüfe die Netzwerkverbindung und versuche es erneut.",
|
||||
"Delete Backup": "Sicherung löschen",
|
||||
"Backup has a <validity>valid</validity> signature from this device": "Sicherung hat eine <validity>valide</validity> Signatur von diesem Gerät",
|
||||
"Backup has an <validity>invalid</validity> signature from <verify>verified</verify> device <device></device>": "Sicherung hat eine <validity>invalide</validity> Signatur vom <verify>verifiziertem</verify> Gerät <device></device>",
|
||||
"Backup has an <validity>invalid</validity> signature from <verify>unverified</verify> device <device></device>": "Sicherung hat eine <validity>invalide</validity> Signatur vom <verify>unverifiziertem</verify> Gerät <device></device>",
|
||||
"Backup has a <validity>valid</validity> signature from <verify>unverified</verify> device <device></device>": "Sicherung hat eine <validity>valide</validity> Signatur vom <verify>unverifiziertem</verify> Gerät <device></device>",
|
||||
"Backup is not signed by any of your devices": "Sicherung wurde von keinem deiner Geräte signiert",
|
||||
"Backup version: ": "Sicherungsversion: ",
|
||||
"Algorithm: ": "Algorithmus: ",
|
||||
"To avoid losing your chat history, you must export your room keys before logging out. You will need to go back to the newer version of Riot to do this": "Um deinen Chatverlauf nicht zu verlieren, musst du deine Raum-Schlüssel exportieren, bevor du dich abmeldest. Du musst zurück zu einer neueren Riot-Version gehen, um dies zu tun",
|
||||
|
@ -1095,7 +1024,6 @@
|
|||
"Straight rows of keys are easy to guess": "Gerade Reihen von Tasten sind einfach zu erraten",
|
||||
"Custom user status messages": "Angepasste Nutzerstatus-Nachrichten",
|
||||
"Unable to load key backup status": "Konnte Status des Schlüsselbackups nicht laden",
|
||||
"Backup has a <validity>valid</validity> signature from <verify>verified</verify> device <device></device>": "Sicherung hat eine <validity>valide</validity> Signatur von einem <verify>verifiziertem</verify> Gerät <device></device>",
|
||||
"Don't ask again": "Nicht erneut fragen",
|
||||
"Set up": "Einrichten",
|
||||
"Please review and accept all of the homeserver's policies": "Bitte sieh dir die Heimserver-Regularien an und akzeptiere sie",
|
||||
|
@ -1110,7 +1038,6 @@
|
|||
"If you've forgotten your recovery passphrase you can <button1>use your recovery key</button1> or <button2>set up new recovery options</button2>": "Wenn du deinen Wiederherstellungspassphrase vergessen hast, kannst du <button1>deinen Wiederherstellungsschlüssel benutzen</button1> oder <button2>neue Wiederherstellungsoptionen einrichten</button2>",
|
||||
"You've previously used a newer version of Riot on %(host)s. To use this version again with end to end encryption, you will need to sign out and back in again. ": "Du hast kürzlich eine neuere Version von Riot auf %(host)s verwendet. Um diese Version erneut mit Ende-zu-Ende-Verschlüsselung zu nutzen, musst du dich ab- und wieder anmelden. ",
|
||||
"Access your secure message history and set up secure messaging by entering your recovery key.": "Auf sichere Nachrichtenhistorie zugreifen und sicheren Nachrichtenversand einrichten indem du deinen Wiederherstellungsschlüssel eingibst.",
|
||||
"If you've forgotten your recovery passphrase you can <button>set up new recovery options</button>": "Wenn du deine Wiederherstellungspassphrase vergessen hast, kannst du <button>neue Wiederherstellungsoptionen einrichten</button>",
|
||||
"Set a new status...": "Setze einen neuen Status...",
|
||||
"Clear status": "Status löschen",
|
||||
"Invalid homeserver discovery response": "Ungültige Antwort beim Aufspüren des Heimservers",
|
||||
|
@ -1120,8 +1047,6 @@
|
|||
"Great! This passphrase looks strong enough.": "Gut! Diese Passphrase sieht stark genug aus.",
|
||||
"As a safety net, you can use it to restore your encrypted message history if you forget your Recovery Passphrase.": "Als Sicherheitsnetz kannst du ihn benutzen um deine verschlüsselte Nachrichtenhistorie wiederherzustellen, falls du deine Wiederherstellungspassphrase vergessen hast.",
|
||||
"As a safety net, you can use it to restore your encrypted message history.": "Als Sicherheitsnetz kannst du ihn benutzen um deine verschlüsselte Nachrichtenhistorie wiederherzustellen.",
|
||||
"Your Recovery Key has been <b>copied to your clipboard</b>, paste it to:": "Dein Wiederherstellungsschlüssel wurde <b>in deine Zwischenablage kopiert</b>. Füge ihn hier ein:",
|
||||
"Your Recovery Key is in your <b>Downloads</b> folder.": "Dein Wiederherstellungsschlüssel ist in deinem <b>Downloads</b>-Ordner.",
|
||||
"Set up Secure Message Recovery": "Richte Sichere Nachrichten-Wiederherstellung ein",
|
||||
"Without setting up Secure Message Recovery, you'll lose your secure message history when you log out.": "Ohne Sichere Nachrichten-Wiederherstellung einzurichten, wirst du deine sichere Nachrichtenhistorie verlieren, wenn du dich abmeldest.",
|
||||
"If you don't want to set this up now, you can later in Settings.": "Wenn du dies jetzt nicht einrichten willst, kannst du dies später in den Einstellungen tun.",
|
||||
|
@ -1130,7 +1055,6 @@
|
|||
"Set up Secure Messages": "Richte sichere Nachrichten ein",
|
||||
"Go to Settings": "Gehe zu Einstellungen",
|
||||
"Sign in with single sign-on": "Mit Single Sign-On anmelden",
|
||||
"Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another device.": "Wenn du die Sichere Nachrichten-Wiederherstellung nicht einrichtest, wirst du nicht in der Lage sein deine verschlüsselte Nachrichtenhistorie wiederherzustellen, wenn du dich abmeldest oder ein weiteres Gerät benutzt.",
|
||||
"Waiting for %(userId)s to confirm...": "Warte auf Bestätigung für %(userId)s ...",
|
||||
"Unrecognised address": "Nicht erkannte Adresse",
|
||||
"User %(user_id)s may or may not exist": "Existenz der Benutzer %(user_id)s unsicher",
|
||||
|
@ -1164,20 +1088,17 @@
|
|||
"Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Sichere Nachrichten mit diesem Benutzer sind Ende-zu-Ende-verschlüsselt und können nicht von Dritten gelesen werden.",
|
||||
"Got It": "Verstanden",
|
||||
"Verify this user by confirming the following number appears on their screen.": "Verifizieren Sie diesen Benutzer, indem Sie bestätigen, dass die folgende Nummer auf dessen Bildschirm erscheint.",
|
||||
"For maximum security, we recommend you do this in person or use another trusted means of communication.": "Für maximale Sicherheit empfehlen wir, dies persönlich zu tun oder ein anderes vertrauenswürdiges Kommunikationsmittel zu verwenden.",
|
||||
"Yes": "Ja",
|
||||
"No": "Nein",
|
||||
"We've sent you an email to verify your address. Please follow the instructions there and then click the button below.": "Wir haben dir eine E-Mail geschickt, um deine Adresse zu überprüfen. Bitte folge den Anweisungen dort und klicke dann auf die Schaltfläche unten.",
|
||||
"Email Address": "E-Mail-Adresse",
|
||||
"Backing up %(sessionsRemaining)s keys...": "Sichere %(sessionsRemaining)s Schlüssel...",
|
||||
"All keys backed up": "Alle Schlüssel gesichert",
|
||||
"Backup has a signature from <verify>unknown</verify> device with ID %(deviceId)s.": "Sicherung hat eine Signatur von einem <verify>unbekannten</verify> Gerät mit der ID %(deviceId)s.",
|
||||
"Add an email address to configure email notifications": "Füge eine E-Mail-Adresse hinzu, um E-Mail-Benachrichtigungen zu konfigurieren",
|
||||
"Unable to verify phone number.": "Die Telefonnummer kann nicht überprüft werden.",
|
||||
"Verification code": "Bestätigungscode",
|
||||
"Phone Number": "Telefonnummer",
|
||||
"Profile picture": "Profilbild",
|
||||
"Upload profile picture": "Profilbild hochladen",
|
||||
"Display Name": "Anzeigename",
|
||||
"Room information": "Rauminformationen",
|
||||
"Internal room ID:": "Interne Raum ID:",
|
||||
|
@ -1257,7 +1178,6 @@
|
|||
"Book": "Buch",
|
||||
"Pencil": "Stift",
|
||||
"Paperclip": "Büroklammer",
|
||||
"Padlock": "Vorhängeschloss",
|
||||
"Key": "Schlüssel",
|
||||
"Hammer": "Hammer",
|
||||
"Telephone": "Telefon",
|
||||
|
@ -1275,8 +1195,6 @@
|
|||
"Headphones": "Kopfhörer",
|
||||
"Folder": "Ordner",
|
||||
"Pin": "Stecknadel",
|
||||
"Your homeserver does not support device management.": "Dein Heimserver unterstützt Geräte-Management nicht.",
|
||||
"This backup is trusted because it has been restored on this device": "Dieser Sicherung wird vertraut, weil es auf diesem Gerät wiederhergestellt wurde",
|
||||
"Timeline": "Chatverlauf",
|
||||
"Autocomplete delay (ms)": "Verzögerung zur Autovervollständigung (ms)",
|
||||
"Roles & Permissions": "Rollen & Berechtigungen",
|
||||
|
@ -1292,14 +1210,8 @@
|
|||
"Verify this user by confirming the following emoji appear on their screen.": "Verifizieren Sie diesen Benutzer, indem Sie bestätigen, dass folgendes Emoji auf dessen Bildschirm erscheint.",
|
||||
"Missing media permissions, click the button below to request.": "Fehlende Medienberechtigungen. Drücke auf den Knopf unten, um sie anzufordern.",
|
||||
"Request media permissions": "Medienberechtigungen anfordern",
|
||||
"Some devices for this user are not trusted": "Nicht allen Geräte dieses Benutzers wird vertraut",
|
||||
"Some devices in this encrypted room are not trusted": "Nicht allen Geräten in diesem Verschlüsselten Raum wird vertraut",
|
||||
"All devices for this user are trusted": "Allen Geräten dieses Benutzers wird vertraut",
|
||||
"All devices in this encrypted room are trusted": "Allen Geräten in diesem Raum wird vertraut",
|
||||
"Main address": "Primäre Adresse",
|
||||
"Room avatar": "Raum-Bild",
|
||||
"Upload room avatar": "Raum-Bild hochladen",
|
||||
"No room avatar": "Kein Raum-Bild",
|
||||
"Room Name": "Raum-Name",
|
||||
"Room Topic": "Raum-Thema",
|
||||
"Join": "Beitreten",
|
||||
|
@ -1314,9 +1226,7 @@
|
|||
"Are you sure? You will lose your encrypted messages if your keys are not backed up properly.": "Bist du sicher? Du wirst deine verschlüsselten Nachrichten verlieren, wenn deine Schlüssel nicht gesichert sind.",
|
||||
"Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Verschlüsselte Nachrichten sind mit Ende-zu-Ende-Verschlüsselung gesichert. Nur du und der/die Empfänger haben die Schlüssel um diese Nachrichten zu lesen.",
|
||||
"Restore from Backup": "Von Sicherung wiederherstellen",
|
||||
"This device is backing up your keys. ": "Dieses Gerät sichert deine Schlüssel. ",
|
||||
"Back up your keys before signing out to avoid losing them.": "Sichere deine Schlüssel bevor du dich abmeldest, damit du sie nicht verlierst.",
|
||||
"Your keys are <b>not being backed up from this device</b>.": "Deine Schlüssel werden <b>nicht von diesem Gerät gesichert</b>.",
|
||||
"Start using Key Backup": "Beginne Schlüsselsicherung zu nutzen",
|
||||
"Credits": "Danksagungen",
|
||||
"Starting backup...": "Starte Backup...",
|
||||
|
@ -1337,7 +1247,6 @@
|
|||
"Composer": "Nachrichteneingabefeld",
|
||||
"Nothing appearing? Not all clients support interactive verification yet. <button>Use legacy verification</button>.": "Es ist nichts aufgetaucht? Noch nicht alle Clients unterstützen die interaktive Verifikation. <button>Nutze alte Verifikation</button>.",
|
||||
"Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Verifiziere diesen Benutzer und markiere ihn als \"vertraut\". Dies gibt dir bei Ende-zu-Ende-verschlüsselten Nachrichten extra Seelenfrieden.",
|
||||
"Verifying this user will mark their device as trusted, and also mark your device as trusted to them.": "Das Verifizieren dieses Benutzers wird seine Geräte als \"vertraut\" markieren und dein Gerät bei ihnen als \"vertraut\" markieren.",
|
||||
"I don't want my encrypted messages": "Ich möchte meine verschlüsselten Nachrichten nicht",
|
||||
"You'll lose access to your encrypted messages": "Du wirst den Zugang zu deinen verschlüsselten Nachrichten verlieren",
|
||||
"If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.": "Wenn du Fehler bemerkst oder eine Rückmeldung geben möchtest, teile dies uns auf GitHub mit.",
|
||||
|
@ -1372,7 +1281,6 @@
|
|||
"A verification email will be sent to your inbox to confirm setting your new password.": "Eine Verifizierungs-E-Mail wird an dich gesendet um dein neues Passwort zu bestätigen.",
|
||||
"Sign in instead": "Stattdessen anmelden",
|
||||
"Your password has been reset.": "Dein Passwort wurde zurückgesetzt.",
|
||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "Du wurdest auf allen Geräten abgemeldet und wirst keine Push-Benachrichtigungen bekommen. Um Benachrichtigungen wieder zu aktivieren, melde dich auf jedem Gerät erneut an.",
|
||||
"Set a new password": "Setze ein neues Passwort",
|
||||
"This homeserver does not support login using email address.": "Dieser Heimserver unterstützt eine Anmeldung über E-Mail-Adresse nicht.",
|
||||
"Create account": "Konto anlegen",
|
||||
|
@ -1383,12 +1291,8 @@
|
|||
"Set up with a Recovery Key": "Wiederherstellungsschlüssel einrichten",
|
||||
"Please enter your passphrase a second time to confirm.": "Bitte gebe deine Passphrase ein weiteres mal zur Bestätigung ein.",
|
||||
"Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your passphrase.": "Dein Wiederherstellungsschlüssel ist ein Sicherungsnetz - Du kannst ihn benutzen um Zugang zu deinen verschlüsselten Nachrichten zu bekommen, wenn du deine Passphrase vergisst.",
|
||||
"Keep your recovery key somewhere very secure, like a password manager (or a safe)": "Speichere deinen Wiederherstellungsschlüssel irgendwo, wo er sicher ist. Das kann ein Passwort-Manager oder Safe sein",
|
||||
"A new recovery passphrase and key for Secure Messages have been detected.": "Eine neue Wiederherstellungspassphrase und -Schlüssel für sichere Nachrichten wurde festgestellt.",
|
||||
"This device is encrypting history using the new recovery method.": "Dieses Gerät verschlüsselt die Historie mit einer neuen Wiederherstellungsmethode.",
|
||||
"Recovery Method Removed": "Wiederherstellungsmethode gelöscht",
|
||||
"This device has detected that your recovery passphrase and key for Secure Messages have been removed.": "Dieses Gerät hat bemerkt, dass deine Wiederherstellungspassphrase und -Schlüssel für Sichere Nachrichten gelöscht wurde.",
|
||||
"If you did this accidentally, you can setup Secure Messages on this device which will re-encrypt this device's message history with a new recovery method.": "Wenn du dies aus Versehen getan hast, kannst du Sichere Nachrichten auf diesem Gerät einrichten, wodurch die Nachrichtenhistorie von diesem Gerät mit einer neuen Wiederherstellungsmethode erneut verschlüsselt wird.",
|
||||
"If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Wenn du die Wiederherstellungsmethode nicht gelöscht hast, kann ein Angreifer versuchen Zugang zu deinem Konto zu bekommen. Ändere dein Passwort und richte sofort eine neue Wiederherstellungsmethode in den Einstellungen ein.",
|
||||
"Backup could not be decrypted with this key: please verify that you entered the correct recovery key.": "Sicherung konnte mit diesem Schlüssel nicht entschlüsselt werden: Bitte stelle sicher, dass du den richtigen Wiederherstellungsschlüssel eingegeben hast.",
|
||||
"Incorrect Recovery Passphrase": "Falsche Wiederherstellungspassphrase",
|
||||
|
@ -1448,22 +1352,16 @@
|
|||
"Want more than a community? <a>Get your own server</a>": "Du möchtest mehr als eine Community? <a>Hol dir deinen eigenen Server</a>",
|
||||
"Could not load user profile": "Konnte Nutzerprofil nicht laden",
|
||||
"Your Matrix account on %(serverName)s": "Dein Matrixkonto auf %(serverName)s",
|
||||
"Email, name or Matrix ID": "E-Mail, Name oder Matrix-ID",
|
||||
"Name or Matrix ID": "Name oder Matrix ID",
|
||||
"Your Riot is misconfigured": "Dein Riot ist falsch konfiguriert",
|
||||
"You cannot modify widgets in this room.": "Du kannst in diesem Raum keine Widgets verändern.",
|
||||
"Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Ob du die \"Breadcrumbs\"-Funktion nutzt oder nicht (Avatare oberhalb der Raumliste)",
|
||||
"A conference call could not be started because the integrations server is not available": "Ein Konferenzanruf konnte nicht gestartet werden, da der Integrationsserver nicht verfügbar ist",
|
||||
"The server does not support the room version specified.": "Der Server unterstützt die angegebene Raumversion nicht.",
|
||||
"Room upgrade confirmation": "Raum-Upgradebestätigung",
|
||||
"Upgrading a room can be destructive and isn't always necessary.": "Ein Raum-Upgrade kann destruktiv sein und ist nicht immer notwendig.",
|
||||
"Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Raum-Upgrades werden üblicherweise empfohlen, wenn eine Raum-Version <i>instabil</i> ist. Instabile Raum-Versionen können Bugs, fehlende Features oder Sicherheitslücken enthalten.",
|
||||
"Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.": "Raum-Upgrades betreffen überlicherweise nur <i>serverseitige</i> Datenverarbeitung des Raumes. Wenn du ein Problem mit deinem Riot-Client hast, dann erstelle bitte ein Issue mit <issueLink />.",
|
||||
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "<b>Achtung</b>: Ein Raum-Upgrade wird <i>die Mitglieder des Raumes nicht automatisch auf die neue Version migrieren.</i> Wir werden in der alten Raumversion einen Link zum neuen Raum posten - Raum-Mitglieder müssen dann auf diesen Link klicken um dem neuen Raum beizutreten.",
|
||||
"Replying With Files": "Mit Dateien antworten",
|
||||
"At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "Momentan ist es nicht möglich mit einer Datei zu antworten. Möchtest Du die Datei hochladen ohne zu antworten?",
|
||||
"The file '%(fileName)s' failed to upload.": "Die Datei \"%(fileName)s\" konnte nicht hochgeladen werden.",
|
||||
"Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />.": "Bitte bestätige, dass du mit dem Raum-Upgrade von <oldVersion /> auf <newVersion /> fortfahren möchtest.",
|
||||
"Changes your avatar in this current room only": "Ändert deinen Avatar für diesen Raum",
|
||||
"Unbans user with given ID": "Entbannt den Benutzer mit der angegebenen ID",
|
||||
"Sends the given message coloured as a rainbow": "Sendet die Nachricht in Regenbogenfarben",
|
||||
|
@ -1486,7 +1384,6 @@
|
|||
"Show recently visited rooms above the room list": "Zeige kürzlich besuchte Räume oberhalb der Raumliste",
|
||||
"Show hidden events in timeline": "Zeige versteckte Ereignisse in der Chronik",
|
||||
"Low bandwidth mode": "Modus für niedrige Bandbreite",
|
||||
"Enable desktop notifications for this device": "Desktop-Benachrichtigungen für dieses Gerät aktivieren",
|
||||
"Reset": "Zurücksetzen",
|
||||
"Joining room …": "Raum beitreten…",
|
||||
"Rejecting invite …": "Einladung ablehnen…",
|
||||
|
@ -1516,19 +1413,14 @@
|
|||
"Revoke invite": "Einladung zurückziehen",
|
||||
"Invited by %(sender)s": "Eingeladen von %(sender)s",
|
||||
"Changes your avatar in all rooms": "Verändert dein Profilbild in allen Räumen",
|
||||
"This device is <b>not backing up your keys</b>, but you do have an existing backup you can restore from and add to going forward.": "Dieses Gerät <b>speichert deine Schlüssel nicht</b>, aber du hast ein bestehendes Backup, welches du wiederherstellen kannst um fortzufahren.",
|
||||
"Backup has an <validity>invalid</validity> signature from this device": "Das Backup besitzt eine <validity>ungültige</validity> Signatur von diesem Gerät",
|
||||
"Failed to start chat": "Chat konnte nicht gestartet werden",
|
||||
"Messages": "Nachrichten",
|
||||
"Actions": "Aktionen",
|
||||
"Displays list of commands with usages and descriptions": "Zeigt eine Liste von Befehlen mit Verwendungen und Beschreibungen an",
|
||||
"Connect this device to Key Backup": "Schließen Sie dieses Gerät an Key Backup an",
|
||||
"Call failed due to misconfigured server": "Anruf aufgrund eines falsch konfigurierten Servers fehlgeschlagen",
|
||||
"Try using turn.matrix.org": "Versuchen Sie es mit turn.matrix.org",
|
||||
"You do not have the required permissions to use this command.": "Sie haben nicht die erforderlichen Berechtigungen, um diesen Befehl zu verwenden.",
|
||||
"Multiple integration managers": "Mehrere Integrationsmanager",
|
||||
"Public Name": "Öffentlicher Name",
|
||||
"Enable audible notifications for this device": "Aktivieren Sie die akustischen Benachrichtigungen für dieses Gerät",
|
||||
"Identity Server URL must be HTTPS": "Die Identity Server-URL muss HTTPS sein",
|
||||
"Could not connect to Identity Server": "Verbindung zum Identity Server konnte nicht hergestellt werden",
|
||||
"Checking server": "Server wird überprüft",
|
||||
|
@ -1545,7 +1437,6 @@
|
|||
"Do not use an identity server": "Keinen Identitätsserver verwenden",
|
||||
"Enter a new identity server": "Gib einen neuen Identitätsserver ein",
|
||||
"Clear personal data": "Persönliche Daten löschen",
|
||||
"Warning: Your personal data (including encryption keys) is still stored on this device. Clear it if you're finished using this device, or want to sign in to another account.": "Warnung: Deine persönlichen Daten (inkl. Verschlüsselungsschlüssel) sind noch auf diesem Gerät gespeichert. Lösche diese Daten, wenn du mit der Nutzung auf diesem Gerät fertig bist oder dich in einen anderen Account einloggen möchtest.",
|
||||
"Disconnecting from your identity server will mean you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Wenn du die Verbindung zu deinem Identitätsserver trennst, heißt das, dass du nicht mehr von anderen Benutzern gefunden werden und auch andere nicht mehr per E-Mail oder Telefonnummer einladen kannst.",
|
||||
"Please ask the administrator of your homeserver (<code>%(homeserverDomain)s</code>) to configure a TURN server in order for calls to work reliably.": "Bitte frage den Administrator deines Heimservers (<code>%(homeserverDomain)s</code>) darum, einen TURN-Server einzurichten, damit Anrufe zuverlässig funktionieren.",
|
||||
"Disconnect from the identity server <idserver />?": "Verbindung zum Identitätsserver <idserver /> trennen?",
|
||||
|
@ -1554,8 +1445,6 @@
|
|||
"Changes the avatar of the current room": "Ändert den Avatar für diesen Raum",
|
||||
"Deactivate account": "Benutzerkonto schließen",
|
||||
"Show previews/thumbnails for images": "Zeige eine Vorschau für Bilder",
|
||||
"A device's public name is visible to people you communicate with": "Der Gerätename ist sichtbar für die Personen mit denen du kommunizierst",
|
||||
"Clear all data on this device?": "Alle Daten auf diesem Gerät löschen?",
|
||||
"View": "Vorschau",
|
||||
"Find a room…": "Suche einen Raum…",
|
||||
"Find a room… (e.g. %(exampleRoom)s)": "Suche einen Raum… (z.B. %(exampleRoom)s)",
|
||||
|
@ -1569,9 +1458,6 @@
|
|||
"Use an identity server to invite by email. Manage in Settings.": "Nutze einen Identitätsserver, um über E-Mail Einladungen zu verschicken. Verwalte es in den Einstellungen.",
|
||||
"%(name)s (%(userId)s)": "%(name)s (%(userId)s)",
|
||||
"Try out new ways to ignore people (experimental)": "Versuche neue Möglichkeiten, um Menschen zu ignorieren (experimentell)",
|
||||
"Send verification requests in direct message, including a new verification UX in the member panel.": "Verschicke Bestätigungsanfragen via Direktnachricht, inklusive einer neuen Verifikationsnutzer*innenoberfläche im Mitglieds-Panel",
|
||||
"Enable cross-signing to verify per-user instead of per-device (in development)": "Schalte cross-signing ein, um Verifizierung per Benutzer*in statt per Gerät zu ermöglichen (in Entwicklung)",
|
||||
"Use the new, faster, composer for writing messages": "Nutze die neue, schnellere Schreiboberfläche um Nachrichten zu verfassen.",
|
||||
"Send read receipts for messages (requires compatible homeserver to disable)": "Schicke Lesebestätigungen für Nachrichten (erfordert einen kompatiblen Heimserver zum Deaktivieren)",
|
||||
"My Ban List": "Meine Bannliste",
|
||||
"This is your list of users/servers you have blocked - don't leave the room!": "Dies ist die Liste von Benutzer*innen/Servern, die du blockiert hast - verlasse den Raum nicht!",
|
||||
|
@ -1585,5 +1471,76 @@
|
|||
"%(senderName)s placed a voice call.": "%(senderName)s tätigte einen Sprachanruf.",
|
||||
"%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s tätigte einen Sprachanruf (Nicht von diesem Browser unterstützt)",
|
||||
"%(senderName)s placed a video call.": "%(senderName)s tätigte einen Videoanruf.",
|
||||
"%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s tätigte einen Videoanruf (Nicht von diesem Browser unterstützt)"
|
||||
"%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s tätigte einen Videoanruf (Nicht von diesem Browser unterstützt)",
|
||||
"Verify this session": "Sitzung verifizieren",
|
||||
"Set up encryption": "Verschlüsselung einrichten",
|
||||
"%(senderName)s added %(addedAddresses)s and %(count)s other addresses to this room|other": "%(senderName)s hat %(addedAddresses)s und %(count)s Adressen zu diesem Raum hinzugefügt",
|
||||
"%(senderName)s removed %(removedAddresses)s and %(count)s other addresses from this room|other": "%(senderName)s hat %(removedAddresses)s und %(count)s andere Adressen aus diesem Raum entfernt",
|
||||
"%(senderName)s removed %(countRemoved)s and added %(countAdded)s addresses to this room": "%(senderName)s hat %(countRemoved)s entfernt und %(countAdded)s Adressen zu diesem Raum hinzugefügt",
|
||||
"%(senderName)s turned on end-to-end encryption.": "%(senderName)s hat die Ende-zu-Ende Verschlüsselung aktiviert.",
|
||||
"%(senderName)s turned on end-to-end encryption (unrecognised algorithm %(algorithm)s).": "%(senderName)s hat die Ende-zu-Ende Verschlüsselung aktiviert (unbekannter Algorithmus %(algorithm)s).",
|
||||
"%(senderName)s updated an invalid ban rule": "%(senderName)s hat eine ungültige Bannregel aktualisiert",
|
||||
"The message you are trying to send is too large.": "Die Nachricht, die du versuchst zu senden, ist zu lang.",
|
||||
"a few seconds ago": "vor ein paar Sekunden",
|
||||
"about a minute ago": "vor etwa einer Minute",
|
||||
"%(num)s minutes ago": "vor %(num)s Minuten",
|
||||
"about an hour ago": "vor etwa einer Stunde",
|
||||
"%(num)s hours ago": "vor %(num)s Stunden",
|
||||
"about a day ago": "vor etwa einem Tag",
|
||||
"%(num)s days ago": "vor %(num)s Tagen",
|
||||
"about a minute from now": "in etwa einer Minute",
|
||||
"%(num)s minutes from now": "In etwa %(num)s Minuten",
|
||||
"about an hour from now": "in etwa einer Stunde",
|
||||
"%(num)s hours from now": "in %(num)s Stunden",
|
||||
"about a day from now": "in etwa einem Tag",
|
||||
"%(num)s days from now": "in %(num)s Tagen",
|
||||
"Show info about bridges in room settings": "Information über Bridges in den Raumeinstellungen anzeigen",
|
||||
"Enable message search in encrypted rooms": "Nachrichtensuche in verschlüsselten Räumen aktivieren",
|
||||
"Lock": "Sperren",
|
||||
"Later": "Später",
|
||||
"Review": "Überprüfen",
|
||||
"Verify": "Verifizieren",
|
||||
"Decline (%(counter)s)": "Zurückweisen (%(counter)s)",
|
||||
"not found": "nicht gefunden",
|
||||
"rooms.": "Räume.",
|
||||
"Manage": "Verwalten",
|
||||
"Securely cache encrypted messages locally for them to appear in search results.": "Speichere verschlüsselte Nachrichten sicher lokal zwischen, sodass sie in Suchergebnissen erscheinen können.",
|
||||
"Enable": "Aktivieren",
|
||||
"Connecting to integration manager...": "Verbinden zum Integrationsmanager...",
|
||||
"Cannot connect to integration manager": "Verbindung zum Integrationsmanager fehlgeschlagen",
|
||||
"The integration manager is offline or it cannot reach your homeserver.": "Der Integrationsmanager ist offline oder er kann den Heimserver nicht erreichen.",
|
||||
"not stored": "nicht gespeichert",
|
||||
"Backup has a signature from <verify>unknown</verify> user with ID %(deviceId)s": "Backup hat eine Signatur von <verify>Unbekanntem</verify> Nutzer mit ID %(deviceId)s",
|
||||
"Backup key stored: ": "Backup Schlüssel gespeichert: ",
|
||||
"Clear notifications": "Benachrichtigungen löschen",
|
||||
"Disconnect from the identity server <current /> and connect to <new /> instead?": "Verbindung vom Identitätsserver <current /> trennen und stattdessen zu <new /> verbinden?",
|
||||
"The identity server you have chosen does not have any terms of service.": "Der Identitätsserver, den du gewählt hast, hat keine Nutzungsbedingungen.",
|
||||
"Disconnect identity server": "Verbindung zum Identitätsserver trennen",
|
||||
"contact the administrators of identity server <idserver />": "Administrator des Identitätsservers <idserver /> kontaktieren",
|
||||
"wait and try again later": "warte und versuche es später erneut",
|
||||
"Disconnect anyway": "Verbindung trotzdem trennen",
|
||||
"You are still <b>sharing your personal data</b> on the identity server <idserver />.": "Du <b>teilst deine persönlichen Daten</b> immer noch auf dem Identitätsserver <idserver />.",
|
||||
"We recommend that you remove your email addresses and phone numbers from the identity server before disconnecting.": "Wir empfehlen, dass du deine Email Adressen und Telefonnummern vom Identitätsserver löschst, bevor du die Verbindung trennst.",
|
||||
"You are not currently using an identity server. To discover and be discoverable by existing contacts you know, add one below.": "Du nutzt momentan keinen Identitätsserver. Um von bestehenden Kontakten die du kennst gefunden zu werden und diese zu finden, füge unten einen hinzu.",
|
||||
"Use an Integration Manager <b>(%(serverName)s)</b> to manage bots, widgets, and sticker packs.": "Nutze einen Integrationsmanager <b>(%(serverName)s)</b> um Bots, Widgets und Sticker Packs zu verwalten.",
|
||||
"Use an Integration Manager to manage bots, widgets, and sticker packs.": "Verwende einen Integrationsmanager um Bots, Widgets und Sticker Packs zu verwalten.",
|
||||
"Manage integrations": "Integrationen verwalten",
|
||||
"Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Stimme den Nutzungsbedingungen des Identitätsservers %(serverName)s zu, um dich per Email Adresse und Telefonnummer auffindbar zu machen.",
|
||||
"Clear cache and reload": "Cache löschen und neu laden",
|
||||
"Customise your experience with experimental labs features. <a>Learn more</a>.": "Passe deine Erfahrung mit experimentellen Lab Funktionen an. <a>Mehr erfahren</a>.",
|
||||
"Ignored/Blocked": "Ignoriert/Blockiert",
|
||||
"Something went wrong. Please try again or view your console for hints.": "Etwas ist schief gelaufen. Bitte versuche es erneut oder sieh für weitere Hinweise in deiner Konsole nach.",
|
||||
"Error subscribing to list": "Fehler beim Abonnieren der Liste",
|
||||
"Please verify the room ID or alias and try again.": "Bitte überprüfe die Raum ID oder den Alias und versuche es erneut.",
|
||||
"Error removing ignored user/server": "Fehler beim Entfernen eines ignorierten Benutzers/Servers",
|
||||
"Error unsubscribing from list": "Fehler beim Deabonnieren der Liste",
|
||||
"Please try again or view your console for hints.": "Bitte versuche es erneut oder sieh für weitere Hinweise in deine Konsole.",
|
||||
"Server rules": "Serverregeln",
|
||||
"User rules": "Nutzerregeln",
|
||||
"You have not ignored anyone.": "Du hast niemanden ignoriert.",
|
||||
"You are currently ignoring:": "Du ignorierst momentan:",
|
||||
"Unsubscribe": "Deabonnieren",
|
||||
"View rules": "Regeln betrachten",
|
||||
"You are currently subscribed to:": "Du abonnierst momentan:",
|
||||
"⚠ These settings are meant for advanced users.": "⚠ Diese Einstellungen sind für fortgeschrittene Nutzer gedacht."
|
||||
}
|
||||
|
|
|
@ -59,12 +59,8 @@
|
|||
"Decrypt %(text)s": "Αποκρυπτογράφηση %(text)s",
|
||||
"Decryption error": "Σφάλμα αποκρυπτογράφησης",
|
||||
"Default": "Προεπιλογή",
|
||||
"Device already verified!": "Η συσκευή έχει ήδη επαληθευτεί!",
|
||||
"Device ID": "Αναγνωριστικό συσκευής",
|
||||
"Device ID:": "Αναγνωριστικό συσκευής:",
|
||||
"device id: ": "αναγνωριστικό συσκευής: ",
|
||||
"Device key:": "Κλειδί συσκευής:",
|
||||
"Devices": "Συσκευές",
|
||||
"Direct chats": "Απευθείας συνομιλίες",
|
||||
"Disinvite": "Ανάκληση πρόσκλησης",
|
||||
"Download %(text)s": "Λήψη %(text)s",
|
||||
|
@ -103,7 +99,6 @@
|
|||
"Incorrect username and/or password.": "Λανθασμένο όνομα χρήστη και/ή κωδικός.",
|
||||
"Incorrect verification code": "Λανθασμένος κωδικός επαλήθευσης",
|
||||
"Invalid Email Address": "Μη έγκυρη διεύθυνση ηλεκτρονικής αλληλογραφίας",
|
||||
"Invite new room members": "Προσκαλέστε νέα μέλη",
|
||||
"Invited": "Προσκλήθηκε",
|
||||
"Invites": "Προσκλήσεις",
|
||||
"Sign in with": "Συνδεθείτε με",
|
||||
|
@ -118,8 +113,6 @@
|
|||
"Local addresses for this room:": "Τοπική διεύθυνση για το δωμάτιο:",
|
||||
"Logout": "Αποσύνδεση",
|
||||
"Low priority": "Χαμηλής προτεραιότητας",
|
||||
"matrix-react-sdk version:": "Έκδοση matrix-react-sdk:",
|
||||
"Message not sent due to unknown devices being present": "Το μήνυμα δεν στάλθηκε γιατί υπάρχουν άγνωστες συσκευές",
|
||||
"Click here to fix": "Κάνε κλικ εδώ για διόρθωση",
|
||||
"Command error": "Σφάλμα εντολής",
|
||||
"Commands": "Εντολές",
|
||||
|
@ -140,7 +133,6 @@
|
|||
"olm version:": "Έκδοση olm:",
|
||||
"Password": "Κωδικός πρόσβασης",
|
||||
"Passwords can't be empty": "Οι κωδικοί πρόσβασης δεν γίνετε να είναι κενοί",
|
||||
"People": "Άτομα",
|
||||
"Phone": "Τηλέφωνο",
|
||||
"Register": "Εγγραφή",
|
||||
"riot-web version:": "Έκδοση riot-web:",
|
||||
|
@ -157,12 +149,9 @@
|
|||
"This email address is already in use": "Η διεύθυνση ηλ. αλληλογραφίας χρησιμοποιείται ήδη",
|
||||
"This email address was not found": "Δεν βρέθηκε η διεύθυνση ηλ. αλληλογραφίας",
|
||||
"Success": "Επιτυχία",
|
||||
"Start Chat": "Συνομιλία",
|
||||
"Cancel": "Ακύρωση",
|
||||
"Custom Server Options": "Προσαρμοσμένες ρυθμίσεις διακομιστή",
|
||||
"Dismiss": "Απόρριψη",
|
||||
"bold": "έντονα",
|
||||
"italic": "πλάγια",
|
||||
"Close": "Κλείσιμο",
|
||||
"Create new room": "Δημιουργία νέου δωματίου",
|
||||
"Room directory": "Ευρετήριο",
|
||||
|
@ -193,8 +182,6 @@
|
|||
"Home": "Αρχική",
|
||||
"Last seen": "Τελευταία εμφάνιση",
|
||||
"Manage Integrations": "Διαχείριση ενσωματώσεων",
|
||||
"Markdown is disabled": "Το Markdown είναι απενεργοποιημένο",
|
||||
"Markdown is enabled": "Το Markdown είναι ενεργοποιημένο",
|
||||
"Missing room_id in request": "Λείπει το room_id στο αίτημα",
|
||||
"Permissions": "Δικαιώματα",
|
||||
"Power level must be positive integer.": "Το επίπεδο δύναμης πρέπει να είναι ένας θετικός ακέραιος.",
|
||||
|
@ -214,7 +201,6 @@
|
|||
"Searches DuckDuckGo for results": "Γίνεται αναζήτηση στο DuckDuckGo για αποτελέσματα",
|
||||
"Seen by %(userName)s at %(dateTime)s": "Διαβάστηκε από τον/την %(userName)s στις %(dateTime)s",
|
||||
"Send anyway": "Αποστολή ούτως ή άλλως",
|
||||
"Send Invites": "Αποστολή προσκλήσεων",
|
||||
"Send Reset Email": "Αποστολή μηνύματος επαναφοράς",
|
||||
"%(senderDisplayName)s sent an image.": "Ο %(senderDisplayName)s έστειλε μια φωτογραφία.",
|
||||
"Session ID": "Αναγνωριστικό συνεδρίας",
|
||||
|
@ -231,15 +217,12 @@
|
|||
"Unban": "Άρση αποκλεισμού",
|
||||
"%(senderName)s unbanned %(targetName)s.": "Ο χρήστης %(senderName)s έδιωξε τον χρήστη %(targetName)s.",
|
||||
"Unable to enable Notifications": "Αδυναμία ενεργοποίησης των ειδοποιήσεων",
|
||||
"Unable to load device list": "Αδυναμία φόρτωσης της λίστας συσκευών",
|
||||
"unencrypted": "μη κρυπτογραφημένο",
|
||||
"Unencrypted message": "Μη κρυπτογραφημένο μήνυμα",
|
||||
"unknown caller": "άγνωστος καλών",
|
||||
"unknown device": "άγνωστη συσκευή",
|
||||
"Unknown room %(roomId)s": "Άγνωστο δωμάτιο %(roomId)s",
|
||||
"Unmute": "Άρση σίγασης",
|
||||
"Unnamed Room": "Ανώνυμο δωμάτιο",
|
||||
"Unrecognised command:": "Μη αναγνωρίσιμη εντολή:",
|
||||
"Unrecognised room alias:": "Μη αναγνωρίσιμο ψευδώνυμο:",
|
||||
"Upload avatar": "Αποστολή προσωπικής εικόνας",
|
||||
"Upload Failed": "Απέτυχε η αποστολή",
|
||||
|
@ -252,7 +235,6 @@
|
|||
"Video call": "Βιντεοκλήση",
|
||||
"Voice call": "Φωνητική κλήση",
|
||||
"Warning!": "Προειδοποίηση!",
|
||||
"Who would you like to communicate with?": "Με ποιον θα θέλατε να επικοινωνήσετε;",
|
||||
"You are already in a call.": "Είστε ήδη σε μια κλήση.",
|
||||
"You have no visible notifications": "Δεν έχετε ορατές ειδοποιήσεις",
|
||||
"You must <a>register</a> to use this functionality": "Πρέπει να <a>εγγραφείτε</a> για να χρησιμοποιήσετε αυτή την λειτουργία",
|
||||
|
@ -300,11 +282,7 @@
|
|||
"Unknown error": "Άγνωστο σφάλμα",
|
||||
"Incorrect password": "Λανθασμένος κωδικός πρόσβασης",
|
||||
"To continue, please enter your password.": "Για να συνεχίσετε, παρακαλούμε πληκτρολογήστε τον κωδικό πρόσβασής σας.",
|
||||
"Device name": "Όνομα συσκευής",
|
||||
"Device key": "Κλειδί συσκευής",
|
||||
"Verify device": "Επιβεβαίωση συσκευής",
|
||||
"Unable to restore session": "Αδυναμία επαναφοράς συνεδρίας",
|
||||
"Unknown devices": "Άγνωστες συσκευές",
|
||||
"Unknown Address": "Άγνωστη διεύθυνση",
|
||||
"Blacklist": "Μαύρη λίστα",
|
||||
"Verify...": "Επιβεβαίωση...",
|
||||
|
@ -327,7 +305,6 @@
|
|||
"Username not available": "Μη διαθέσιμο όνομα χρήστη",
|
||||
"Something went wrong!": "Κάτι πήγε στραβά!",
|
||||
"Could not connect to the integration server": "Αδυναμία σύνδεσης στον διακομιστή ενσωμάτωσης",
|
||||
"Encrypted by an unverified device": "Κρυπτογραφημένο από μια ανεπιβεβαίωτη συσκευή",
|
||||
"Error: Problem communicating with the given homeserver.": "Σφάλμα: πρόβλημα κατά την επικοινωνία με τον ορισμένο διακομιστή.",
|
||||
"Failed to ban user": "Δεν ήταν δυνατό ο αποκλεισμός του χρήστη",
|
||||
"Failed to change power level": "Δεν ήταν δυνατή η αλλαγή του επιπέδου δύναμης",
|
||||
|
@ -335,26 +312,20 @@
|
|||
"Failed to unban": "Δεν ήταν δυνατή η άρση του αποκλεισμού",
|
||||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s από %(fromPowerLevel)s σε %(toPowerLevel)s",
|
||||
"Guests cannot join this room even if explicitly invited.": "Οι επισκέπτες δεν μπορούν να συνδεθούν στο δωμάτιο ακόμη και αν έχουν καλεστεί.",
|
||||
"Hide Text Formatting Toolbar": "Απόκρυψη εργαλειοθήκης μορφοποίησης κειμένου",
|
||||
"Incoming call from %(name)s": "Εισερχόμενη κλήση από %(name)s",
|
||||
"Incoming video call from %(name)s": "Εισερχόμενη βιντεοκλήση από %(name)s",
|
||||
"Incoming voice call from %(name)s": "Εισερχόμενη φωνητική κλήση από %(name)s",
|
||||
"Invalid alias format": "Μη έγκυρη μορφή ψευδώνυμου",
|
||||
"Invalid file%(extra)s": "Μη έγκυρο αρχείο %(extra)s",
|
||||
"%(senderName)s invited %(targetName)s.": "Ο %(senderName)s προσκάλεσε τον %(targetName)s.",
|
||||
"Invites user with given id to current room": "Προσκαλεί τον χρήστη με το δοσμένο αναγνωριστικό στο τρέχον δωμάτιο",
|
||||
"'%(alias)s' is not a valid format for an alias": "Το '%(alias)s' δεν είναι μια έγκυρη μορφή ψευδώνυμου",
|
||||
"%(senderName)s made future room history visible to all room members, from the point they are invited.": "Ο %(senderName)s έκανε το μελλοντικό ιστορικό του δωματίου δημόσιο όλα τα μέλη, από τη στιγμή που προσκλήθηκαν.",
|
||||
"%(senderName)s made future room history visible to all room members, from the point they joined.": "Ο %(senderName)s έκανε το μελλοντικό ιστορικό του δωματίου δημόσιο όλα τα μέλη, από τη στιγμή που συνδέθηκαν.",
|
||||
"%(senderName)s made future room history visible to all room members.": "Ο %(senderName)s έκανε το μελλοντικό ιστορικό του δωματίου δημόσιο όλα τα μέλη.",
|
||||
"%(senderName)s made future room history visible to anyone.": "Ο %(senderName)s έκανε το μελλοντικό ιστορικό του δωματίου δημόσιο οποιοσδήποτε.",
|
||||
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "Ο %(senderName)s έκανε το μελλοντικό ιστορικό του δωματίου δημόσιο άγνωστο (%(visibility)s).",
|
||||
"Missing user_id in request": "Λείπει το user_id στο αίτημα",
|
||||
"Never send encrypted messages to unverified devices from this device": "Να μη γίνει ποτέ αποστολή κρυπτογραφημένων μηνυμάτων σε ανεπιβεβαίωτες συσκευές από αυτή τη συσκευή",
|
||||
"Never send encrypted messages to unverified devices in this room from this device": "Να μη γίνει ποτέ αποστολή κρυπτογραφημένων μηνυμάτων σε ανεπιβεβαίωτες συσκευές, σε αυτό το δωμάτιο, από αυτή τη συσκευή",
|
||||
"not specified": "μη καθορισμένο",
|
||||
"NOT verified": "ΧΩΡΙΣ επαλήθευση",
|
||||
"No devices with registered encryption keys": "Καθόλου συσκευές με εγγεγραμένα κλειδιά κρυπτογράφησης",
|
||||
"No display name": "Χωρίς όνομα",
|
||||
"No users have specific privileges in this room": "Κανένας χρήστης δεν έχει συγκεκριμένα δικαιώματα σε αυτό το δωμάτιο",
|
||||
"Only people who have been invited": "Μόνο άτομα που έχουν προσκληθεί",
|
||||
|
@ -363,18 +334,14 @@
|
|||
"%(senderName)s requested a VoIP conference.": "Ο %(senderName)s αιτήθηκε μια συνδιάσκεψη VoIP.",
|
||||
"Riot does not have permission to send you notifications - please check your browser settings": "Το Riot δεν έχει δικαιώματα για αποστολή ειδοποιήσεων - παρακαλούμε ελέγξτε τις ρυθμίσεις του περιηγητή σας",
|
||||
"Riot was not given permission to send notifications - please try again": "Δεν δόθηκαν δικαιώματα αποστολής ειδοποιήσεων στο Riot - παρακαλούμε προσπαθήστε ξανά",
|
||||
"Room contains unknown devices": "Το δωμάτιο περιέχει άγνωστες συσκευές",
|
||||
"%(roomName)s is not accessible at this time.": "Το %(roomName)s δεν είναι προσβάσιμο αυτή τη στιγμή.",
|
||||
"Scroll to bottom of page": "Μετάβαση στο τέλος της σελίδας",
|
||||
"Sender device information": "Πληροφορίες συσκευής αποστολέα",
|
||||
"Server may be unavailable, overloaded, or search timed out :(": "Ο διακομιστής μπορεί να είναι μη διαθέσιμος, υπερφορτωμένος, ή να έχει λήξει η αναζήτηση :(",
|
||||
"Server may be unavailable, overloaded, or you hit a bug.": "Ο διακομιστής μπορεί να είναι μη διαθέσιμος, υπερφορτωμένος, ή να πέσατε σε ένα σφάλμα.",
|
||||
"Server unavailable, overloaded, or something else went wrong.": "Ο διακομιστής μπορεί να είναι μη διαθέσιμος, υπερφορτωμένος, ή κάτι άλλο να πήγε στραβά.",
|
||||
"Show Text Formatting Toolbar": "Εμφάνιση της εργαλειοθήκης μορφοποίησης κειμένου",
|
||||
"%(count)s of your messages have not been sent.|other": "Μερικά από τα μηνύματα σας δεν έχουν αποσταλεί.",
|
||||
"This room is not recognised.": "Αυτό το δωμάτιο δεν αναγνωρίζεται.",
|
||||
"Unable to capture screen": "Αδυναμία σύλληψης οθόνης",
|
||||
"Unknown (user, device) pair:": "Άγνωστο ζεύγος (χρήστη, συσκευής):",
|
||||
"Uploading %(filename)s and %(count)s others|zero": "Γίνεται αποστολή του %(filename)s",
|
||||
"Uploading %(filename)s and %(count)s others|other": "Γίνεται αποστολή του %(filename)s και %(count)s υπολοίπων",
|
||||
"%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (δύναμη %(powerLevelNumber)s)",
|
||||
|
@ -385,7 +352,6 @@
|
|||
"VoIP conference finished.": "Ολοκληρώθηκε η συνδιάσκεψη VoIP.",
|
||||
"VoIP conference started.": "Ξεκίνησησε η συνδιάσκεψη VoIP.",
|
||||
"VoIP is unsupported": "Δεν υποστηρίζεται το VoIP",
|
||||
"WARNING: Device already verified, but keys do NOT MATCH!": "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Η συσκευή έχει επαληθευτεί, αλλά τα κλειδιά ΔΕΝ ΤΑΙΡΙΑΖΟΥΝ!",
|
||||
"Who can access this room?": "Ποιος μπορεί να προσπελάσει αυτό το δωμάτιο;",
|
||||
"Who can read history?": "Ποιος μπορεί να διαβάσει το ιστορικό;",
|
||||
"%(senderName)s withdrew %(targetName)s's invitation.": "Ο %(senderName)s ανακάλεσε την πρόσκληση του %(targetName)s.",
|
||||
|
@ -401,7 +367,6 @@
|
|||
"Riot collects anonymous analytics to allow us to improve the application.": "Το Riot συλλέγει ανώνυμα δεδομένα επιτρέποντας μας να βελτιώσουμε την εφαρμογή.",
|
||||
"Failed to invite": "Δεν ήταν δυνατή η πρόσκληση",
|
||||
"I verify that the keys match": "Επιβεβαιώνω πως ταιριάζουν τα κλειδιά",
|
||||
"\"%(RoomName)s\" contains devices that you haven't seen before.": "Το \"%(RoomName)s\" περιέχει συσκευές που δεν έχετε ξαναδεί.",
|
||||
"Please check your email to continue registration.": "Παρακαλούμε ελέγξτε την ηλεκτρονική σας αλληλογραφία για να συνεχίσετε με την εγγραφή.",
|
||||
"If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Αν δεν ορίσετε μια διεύθυνση ηλεκτρονικής αλληλογραφίας, δεν θα θα μπορείτε να επαναφέρετε τον κωδικό πρόσβασης σας. Είστε σίγουροι;",
|
||||
"Removed or unknown message type": "Αφαιρέθηκε ή άγνωστος τύπος μηνύματος",
|
||||
|
@ -418,8 +383,6 @@
|
|||
"The email address linked to your account must be entered.": "Πρέπει να εισηχθεί η διεύθυνση ηλ. αλληλογραφίας που είναι συνδεδεμένη με τον λογαριασμό σας.",
|
||||
"The remote side failed to pick up": "Η απομακρυσμένη πλευρά απέτυχε να συλλέξει",
|
||||
"This room is not accessible by remote Matrix servers": "Αυτό το δωμάτιο δεν είναι προσβάσιμο από απομακρυσμένους διακομιστές Matrix",
|
||||
"%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "Ο %(senderName)s ενεργοποίησε την από άκρο σε άκρο κρυπτογράφηση (algorithm %(algorithm)s).",
|
||||
"Undecryptable": "Μη αποκρυπτογραφημένο",
|
||||
"Uploading %(filename)s and %(count)s others|one": "Γίνεται αποστολή του %(filename)s και %(count)s υπολοίπα",
|
||||
"You have <a>disabled</a> URL previews by default.": "Έχετε <a>απενεργοποιημένη</a> από προεπιλογή την προεπισκόπηση συνδέσμων.",
|
||||
"You have <a>enabled</a> URL previews by default.": "Έχετε <a>ενεργοποιημένη</a> από προεπιλογή την προεπισκόπηση συνδέσμων.",
|
||||
|
@ -432,9 +395,7 @@
|
|||
"Join as <voiceText>voice</voiceText> or <videoText>video</videoText>.": "Συμμετάσχετε με <voiceText>φωνή</voiceText> ή <videoText>βίντεο</videoText>.",
|
||||
"Joins room with given alias": "Συνδέεστε στο δωμάτιο με δοσμένο ψευδώνυμο",
|
||||
"Show timestamps in 12 hour format (e.g. 2:30pm)": "Εμφάνιση χρονικών σημάνσεων σε 12ωρη μορφή ώρας (π.χ. 2:30 μ.μ.)",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "Το κλειδί υπογραφής που δώσατε αντιστοιχεί στο κλειδί υπογραφής που λάβατε από τη συσκευή %(userId)s %(deviceId)s. Η συσκευή έχει επισημανθεί ως επιβεβαιωμένη.",
|
||||
"Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Η διεύθυνση της ηλ. αλληλογραφίας σας δεν φαίνεται να συσχετίζεται με μια ταυτότητα Matrix σε αυτόν τον Διακομιστή Φιλοξενίας.",
|
||||
"Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Ο κωδικός πρόσβασής σας άλλαξε επιτυχώς. Δεν θα λάβετε ειδοποιήσεις push σε άλλες συσκευές μέχρι να συνδεθείτε ξανά σε αυτές",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Δεν θα μπορέσετε να αναιρέσετε αυτήν την αλλαγή καθώς προωθείτε τον χρήστη να έχει το ίδιο επίπεδο δύναμης με τον εαυτό σας.",
|
||||
"Sent messages will be stored until your connection has returned.": "Τα απεσταλμένα μηνύματα θα αποθηκευτούν μέχρι να αακτηθεί η σύνδεσή σας.",
|
||||
"Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Είστε βέβαιοι ότι θέλετε να καταργήσετε (διαγράψετε) αυτό το συμβάν; Σημειώστε ότι αν διαγράψετε το όνομα δωματίου ή αλλάξετε το θέμα, θα μπορούσε να αναιρέσει την αλλαγή.",
|
||||
|
@ -452,22 +413,16 @@
|
|||
"Your browser does not support the required cryptography extensions": "Ο περιηγητής σας δεν υποστηρίζει τα απαιτούμενα πρόσθετα κρυπτογράφησης",
|
||||
"Not a valid Riot keyfile": "Μη έγκυρο αρχείο κλειδιού Riot",
|
||||
"Authentication check failed: incorrect password?": "Αποτυχία ελέγχου πιστοποίησης: λανθασμένος κωδικός πρόσβασης;",
|
||||
"Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Η αλλαγή του κωδικού πρόσβασης θα επαναφέρει τα κλειδιά κρυπτογράφησης από άκρο σε άκρο σε όλες τις συσκευές, καθιστώντας το κρυπτογραφημένο ιστορικό συζητήσεων μη αναγνώσιμο, εκτός και αν εξάγετε πρώτα τα κλειδιά και τα εισαγάγετε ξανά στο δωμάτιο. Στο μέλλον αυτή η διαδικασία θα βελτιωθεί.",
|
||||
"Claimed Ed25519 fingerprint key": "Απαιτήθηκε κλειδί αποτυπώματος Ed25519",
|
||||
"Displays action": "Εμφανίζει την ενέργεια",
|
||||
"To use it, just wait for autocomplete results to load and tab through them.": "Για να το χρησιμοποιήσετε, απλά περιμένετε μέχρι να φορτωθούν τα αποτέλεσμα αυτόματης συμπλήρωσης. Έπειτα επιλέξτε ένα από αυτά χρησιμοποιώντας τον στηλοθέτη.",
|
||||
"Use compact timeline layout": "Χρήση συμπαγούς διάταξης χρονολογίου",
|
||||
"(could not connect media)": "(αδυναμία σύνδεσης με το πολυμέσο)",
|
||||
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: ΑΠΕΤΥΧΕ Η ΕΠΙΒΕΒΑΙΩΣΗ ΤΟΥ ΚΛΕΙΔΙΟΥ! Το κλειδί υπογραφής για τον χρήστη %(userId)s και συσκευή %(deviceId)s είναι \"%(fprint)s\" και δεν ταιριάζει με το δοσμένο κλειδί \"%(fingerprint)s\". Αυτό σημαίνει ότι η επικοινωνία σας μπορεί να έχει υποκλαπεί!",
|
||||
"This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Αυτή η διαδικασία σας επιτρέπει να εξαγάγετε τα κλειδιά για τα μηνύματα που έχετε λάβει σε κρυπτογραφημένα δωμάτια σε ένα τοπικό αρχείο. Στη συνέχεια, θα μπορέσετε να εισάγετε το αρχείο σε άλλο πρόγραμμα του Matrix, έτσι ώστε το πρόγραμμα να είναι σε θέση να αποκρυπτογραφήσει αυτά τα μηνύματα.",
|
||||
"The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Το αρχείο εξαγωγής θα επιτρέψει σε οποιονδήποτε που μπορεί να το διαβάσει να αποκρυπτογραφήσει κρυπτογραφημένα μηνύματα που εσείς μπορείτε να δείτε, οπότε θα πρέπει να είστε προσεκτικοί για να το κρατήσετε ασφαλές. Για να βοηθήσετε με αυτό, θα πρέπει να εισαγάγετε ένα συνθηματικό, το οποία θα χρησιμοποιηθεί για την κρυπτογράφηση των εξαγόμενων δεδομένων. Η εισαγωγή δεδομένων θα είναι δυνατή χρησιμοποιώντας μόνο το ίδιο συνθηματικό.",
|
||||
"This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Αυτή η διαδικασία σας επιτρέπει να εισαγάγετε κλειδιά κρυπτογράφησης που έχετε προηγουμένως εξάγει από άλλο πρόγραμμα του Matrix. Στη συνέχεια, θα μπορέσετε να αποκρυπτογραφήσετε τυχόν μηνύματα που το άλλο πρόγραμμα θα μπορούσε να αποκρυπτογραφήσει.",
|
||||
"The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Το αρχείο εξαγωγής θα είναι προστατευμένο με συνθηματικό. Θα χρειαστεί να πληκτρολογήσετε το συνθηματικό εδώ για να αποκρυπτογραφήσετε το αρχείο.",
|
||||
"To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Για να βεβαιωθείτε ότι είναι αξιόπιστη αυτή η συσκευή, επικοινωνήστε με τον κάτοχο της χρησιμοποιώντας άλλα μέσα (π.χ. προσωπικά ή μέσω τηλεφώνου) και ρωτήστε εάν το κλειδί που βλέπετε στις ρυθμίσεις χρήστη για αυτήν τη συσκευή ταιριάζει με το παρακάτω κλειδί:",
|
||||
"If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Εάν ταιριάζει, πατήστε το κουμπί επιβεβαίωσης παρακάτω. Εάν όχι, τότε κάποιος άλλος παρακολουθεί αυτή τη συσκευή και ίσως θέλετε να πατήσετε το κουμπί της μαύρης λίστας.",
|
||||
"If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Αν χρησιμοποιούσατε προηγουμένως μια πιο πρόσφατη έκδοση του Riot, η συνεδρία σας ίσως είναι μη συμβατή με αυτήν την έκδοση. Κλείστε αυτό το παράθυρο και επιστρέψτε στην πιο πρόσφατη έκδοση.",
|
||||
"You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Αυτήν τη στιγμή βάζετε σε μαύρη λίστα μη επιβαιωμένες συσκευές. Για να στείλετε μηνύματα σε αυτές τις συσκευές, πρέπει να τις επιβεβαιώσετε.",
|
||||
"We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Σας συνιστούμε να ολοκληρώσετε τη διαδικασία επαλήθευσης για κάθε συσκευή και να επιβεβαιώσετε ότι ανήκουν στον νόμιμο κάτοχό της, αλλά εάν προτιμάτε μπορείτε να στείλετε ξανά το μήνυμα χωρίς επαλήθευση.",
|
||||
"You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Θα μεταφερθείτε σε έναν ιστότοπου τρίτου για να πραγματοποιηθεί η πιστοποίηση του λογαριασμού σας με το %(integrationsUrl)s. Θα θέλατε να συνεχίσετε;",
|
||||
"Do you want to set an email address?": "Θέλετε να ορίσετε μια διεύθυνση ηλεκτρονικής αλληλογραφίας;",
|
||||
"This will allow you to reset your password and receive notifications.": "Αυτό θα σας επιτρέψει να επαναφέρετε τον κωδικό πρόσβαση σας και θα μπορείτε να λαμβάνετε ειδοποιήσεις.",
|
||||
|
@ -475,8 +430,6 @@
|
|||
"Start verification": "Έναρξη επιβεβαίωσης",
|
||||
"Share without verifying": "Κοινή χρήση χωρίς επιβεβαίωση",
|
||||
"Ignore request": "Παράβλεψη αιτήματος",
|
||||
"You added a new device '%(displayName)s', which is requesting encryption keys.": "Έχετε προσθέσει μια νέα συσκευή '%(displayName)s', η οποία ζητά κλειδιά κρυπτογράφησης.",
|
||||
"Your unverified device '%(displayName)s' is requesting encryption keys.": "Η ανεπιβεβαίωτη συσκευή σας '%(displayName)s' ζητά κλειδιά κρυπτογράφησης.",
|
||||
"Encryption key request": "Αίτημα κλειδιού κρυπτογράφησης",
|
||||
"Check for update": "Έλεγχος για ενημέρωση",
|
||||
"Fetching third party location failed": "Η λήψη τοποθεσίας απέτυχε",
|
||||
|
@ -527,7 +480,6 @@
|
|||
"Noisy": "Δυνατά",
|
||||
"Collecting app version information": "Συγκέντρωση πληροφοριών σχετικά με την έκδοση της εφαρμογής",
|
||||
"Delete the room alias %(alias)s and remove %(name)s from the directory?": "Διαγραφή του ψευδώνυμου %(alias)s και αφαίρεση του %(name)s από το ευρετήριο;",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "Αυτό θα σας επιτρέψει να επιστρέψετε στον λογαριασμό σας αφού αποσυνδεθείτε και συνδεθείτε από άλλες συσκευές.",
|
||||
"Keywords": "Λέξεις κλειδιά",
|
||||
"Enable notifications for this account": "Ενεργοποίηση ειδοποιήσεων για τον λογαριασμό",
|
||||
"Messages containing <span>keywords</span>": "Μηνύματα που περιέχουν <span>λέξεις κλειδιά</span>",
|
||||
|
@ -624,7 +576,6 @@
|
|||
"Failed to invite users to community": "Αποτυχία πρόσκλησης χρηστών στην κοινότητα",
|
||||
"Failed to invite users to %(groupId)s": "Αποτυχία πρόσκλησης χρηστών στο %(groupId)s",
|
||||
"Failed to add the following rooms to %(groupId)s:": "Αποτυχία προσθήκης στο %(groupId)s των δωματίων:",
|
||||
"There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "Υπάρχουν άγνωστες συσκευές στο δωμάτιο: εάν συνεχίσετε χωρίς να τις επιβεβαιώσετε, θα μπορούσε κάποιος να κρυφακούει την κλήση σας.",
|
||||
"Show these rooms to non-members on the community page and room list?": "Εμφάνιση αυτών των δωματίων σε μη-μέλη στην σελίδα της κοινότητας και στη λίστα δωματίων;",
|
||||
"Room name or alias": "Όνομα η ψευδώνυμο δωματίου",
|
||||
"Restricted": "Περιορισμένο/η",
|
||||
|
@ -640,15 +591,12 @@
|
|||
"%(widgetName)s widget removed by %(senderName)s": "Το widget %(widgetName)s αφαιρέθηκε από τον/την %(senderName)s",
|
||||
"Message Pinning": "Καρφίτσωμα Μηνυμάτων",
|
||||
"Enable URL previews for this room (only affects you)": "Ενεργοποίηση προεπισκόπισης URL για αυτό το δωμάτιο (επηρεάζει μόνο εσάς)",
|
||||
"Delete %(count)s devices|other": "Διαγραφή %(count)s συσκευών",
|
||||
"Delete %(count)s devices|one": "Διαγραφή συσκευής",
|
||||
"Cannot add any more widgets": "Δεν είναι δυνατή η προσθήκη άλλων γραφικών στοιχείων",
|
||||
"The maximum permitted number of widgets have already been added to this room.": "Ο μέγιστος επιτρεπτός αριθμός γραφικών στοιχείων έχει ήδη προστεθεί σε αυτό το δωμάτιο.",
|
||||
"Add a widget": "Προσθέστε ένα γραφικό στοιχείο",
|
||||
"%(senderName)s sent an image": "Ο/Η %(senderName)s έστειλε μία εικόνα",
|
||||
"%(senderName)s sent a video": "Ο/Η %(senderName)s έστειλε ένα βίντεο",
|
||||
"%(senderName)s uploaded a file": "Ο/Η %(senderName)s αναφόρτωσε ένα αρχείο",
|
||||
"If your other devices do not have the key for this message you will not be able to decrypt them.": "Εάν οι άλλες συσκευές σας δεν έχουν το κλειδί για αυτό το μήνυμα, τότε δεν θα μπορείτε να το αποκρυπτογραφήσετε.",
|
||||
"Disinvite this user?": "Απόσυρση της πρόσκλησης αυτού του χρήστη;",
|
||||
"Mention": "Αναφορά",
|
||||
"Invite": "Πρόσκληση",
|
||||
|
@ -657,7 +605,6 @@
|
|||
"Send a reply (unencrypted)…": "Αποστολή απάντησης (μη κρυπτογραφημένης)…",
|
||||
"Send an encrypted message…": "Αποστολή κρυπτογραφημένου μηνύματος…",
|
||||
"Send a message (unencrypted)…": "Αποστολή μηνύματος (μη κρυπτογραφημένου)…",
|
||||
"Unable to reply": "Αδυναμία απάντησης",
|
||||
"Unpin Message": "Ξεκαρφίτσωμα μηνύματος",
|
||||
"Jump to message": "Πηγαίντε στο μήνυμα",
|
||||
"No pinned messages.": "Κανένα καρφιτσωμένο μήνυμα.",
|
||||
|
@ -704,8 +651,6 @@
|
|||
"Unable to load! Check your network connectivity and try again.": "Αδυναμία φόρτωσης! Ελέγξτε την σύνδεση του δικτύου και προσπαθήστε ξανά.",
|
||||
"Registration Required": "Απαιτείτε Εγγραφή",
|
||||
"You need to register to do this. Would you like to register now?": "Χρειάζεται να γίνει εγγραφή για αυτό. Θα θέλατε να κάνετε εγγραφή τώρα;",
|
||||
"Email, name or Matrix ID": "Ηλ. ταχυδρομείο, όνομα ή ταυτότητα Matrix",
|
||||
"Failed to start chat": "Αποτυχία αρχικοποίησης συνομιλίας",
|
||||
"Failed to invite users to the room:": "Αποτυχία πρόσκλησης χρηστών στο δωμάτιο:",
|
||||
"Missing roomId.": "Λείπει η ταυτότητα δωματίου.",
|
||||
"Messages": "Μηνύματα",
|
||||
|
@ -715,12 +660,7 @@
|
|||
"Sends a message as plain text, without interpreting it as markdown": "Αποστέλλει ένα μήνυμα ως απλό κείμενο, χωρίς να το ερμηνεύει ως \"markdown\"",
|
||||
"Upgrades a room to a new version": "Αναβαθμίζει το δωμάτιο σε μια καινούργια έκδοση",
|
||||
"You do not have the required permissions to use this command.": "Δεν διαθέτετε τις απαιτούμενες άδειες για να χρησιμοποιήσετε αυτήν την εντολή.",
|
||||
"Room upgrade confirmation": "Επιβεβαίωση αναβάθμισης δωματίου",
|
||||
"Upgrading a room can be destructive and isn't always necessary.": "Η αναβάθμιση ενός δωματίου μπορεί να είναι καταστροφική και δεν είναι πάντα απαραίτητη.",
|
||||
"Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Οι αναβαθμίσεις δωματίου είναι συνήθως προτεινόμενες όταν μια έκδοση δωματίου θεωρείτε <i>ασταθής</i>. Ασταθείς εκδόσεις δωματίων μπορεί να έχουν σφάλματα, ελλειπή χαρακτηριστικά, ή αδυναμίες ασφαλείας.",
|
||||
"Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.": "Οι αναβαθμίσεις δωματίων συνήθως επηρεάζουν μόνο την επεξεργασία του δωματίου <i>από την πλευρά του διακομιστή</i>. Εάν έχετε προβλήματα με το πρόγραμμα-πελάτη Riot, παρακαλώ αρχειοθετήστε ένα πρόβλημα μέσω <issueLink />.",
|
||||
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "<b>Προσοχή</b>: Αναβαθμίζοντας ένα δωμάτιο <i>δεν θα μεταφέρει αυτόματα τα μέλη του δωματίου στη νέα έκδοση του δωματίου.</i> Θα αναρτήσουμε ένα σύνδεσμο προς το νέο δωμάτιο στη παλιά έκδοση του δωματίου - τα μέλη του δωματίου θα πρέπει να πατήσουν στον σύνδεσμο για να μπουν στο νέο δωμάτιο.",
|
||||
"Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />.": "Παρακαλώ επιβεβαιώστε ότι θα θέλατε να προχωρήσετε με την αναβάθμιση του δωματίου από <oldVersion /> σε <newVersion />.",
|
||||
"Changes your display nickname in the current room only": "Αλλάζει το εμφανιζόμενο ψευδώνυμο μόνο στο παρόν δωμάτιο",
|
||||
"Changes the avatar of the current room": "Αλλάζει το άβαταρ αυτού του δωματίου",
|
||||
"Changes your avatar in this current room only": "Αλλάζει το άβαταρ σας μόνο στο παρόν δωμάτιο",
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
"Unable to load! Check your network connectivity and try again.": "Unable to load! Check your network connectivity and try again.",
|
||||
"Dismiss": "Dismiss",
|
||||
"Call Failed": "Call Failed",
|
||||
"There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.",
|
||||
"There are unknown sessions in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "There are unknown sessions in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.",
|
||||
"Review Devices": "Review Devices",
|
||||
"Call Anyway": "Call Anyway",
|
||||
"Answer Anyway": "Answer Anyway",
|
||||
|
@ -60,7 +60,7 @@
|
|||
"Server may be unavailable, overloaded, or you hit a bug.": "Server may be unavailable, overloaded, or you hit a bug.",
|
||||
"The server does not support the room version specified.": "The server does not support the room version specified.",
|
||||
"Failure to create room": "Failure to create room",
|
||||
"Send cross-signing keys to homeserver": "Send cross-signing keys to homeserver",
|
||||
"Setting up keys": "Setting up keys",
|
||||
"Send anyway": "Send anyway",
|
||||
"Send": "Send",
|
||||
"Sun": "Sun",
|
||||
|
@ -91,7 +91,7 @@
|
|||
"Verify this session": "Verify this session",
|
||||
"Encryption upgrade available": "Encryption upgrade available",
|
||||
"Set up encryption": "Set up encryption",
|
||||
"New Session": "New Session",
|
||||
"Unverified session": "Unverified session",
|
||||
"Who would you like to add to this community?": "Who would you like to add to this community?",
|
||||
"Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID",
|
||||
"Invite new community members": "Invite new community members",
|
||||
|
@ -184,13 +184,13 @@
|
|||
"Adds a custom widget by URL to the room": "Adds a custom widget by URL to the room",
|
||||
"Please supply a https:// or http:// widget URL": "Please supply a https:// or http:// widget URL",
|
||||
"You cannot modify widgets in this room.": "You cannot modify widgets in this room.",
|
||||
"Verifies a user, device, and pubkey tuple": "Verifies a user, device, and pubkey tuple",
|
||||
"Unknown (user, device) pair:": "Unknown (user, device) pair:",
|
||||
"Device already verified!": "Device already verified!",
|
||||
"WARNING: Device already verified, but keys do NOT MATCH!": "WARNING: Device already verified, but keys do NOT MATCH!",
|
||||
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!",
|
||||
"Verifies a user, session, and pubkey tuple": "Verifies a user, session, and pubkey tuple",
|
||||
"Unknown (user, session) pair:": "Unknown (user, session) pair:",
|
||||
"Session already verified!": "Session already verified!",
|
||||
"WARNING: Session already verified, but keys do NOT MATCH!": "WARNING: Session already verified, but keys do NOT MATCH!",
|
||||
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!",
|
||||
"Verified key": "Verified key",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.",
|
||||
"Displays action": "Displays action",
|
||||
"Forces the current outbound group session in an encrypted room to be discarded": "Forces the current outbound group session in an encrypted room to be discarded",
|
||||
"Sends the given message coloured as a rainbow": "Sends the given message coloured as a rainbow",
|
||||
|
@ -259,8 +259,6 @@
|
|||
"%(senderName)s made future room history visible to all room members.": "%(senderName)s made future room history visible to all room members.",
|
||||
"%(senderName)s made future room history visible to anyone.": "%(senderName)s made future room history visible to anyone.",
|
||||
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s made future room history visible to unknown (%(visibility)s).",
|
||||
"%(senderName)s turned on end-to-end encryption.": "%(senderName)s turned on end-to-end encryption.",
|
||||
"%(senderName)s turned on end-to-end encryption (unrecognised algorithm %(algorithm)s).": "%(senderName)s turned on end-to-end encryption (unrecognised algorithm %(algorithm)s).",
|
||||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s",
|
||||
"%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s changed the power level of %(powerLevelDiffText)s.",
|
||||
"%(senderName)s changed the pinned messages for the room.": "%(senderName)s changed the pinned messages for the room.",
|
||||
|
@ -373,9 +371,10 @@
|
|||
"Multiple integration managers": "Multiple integration managers",
|
||||
"Try out new ways to ignore people (experimental)": "Try out new ways to ignore people (experimental)",
|
||||
"Show a presence dot next to DMs in the room list": "Show a presence dot next to DMs in the room list",
|
||||
"Enable cross-signing to verify per-user instead of per-device (in development)": "Enable cross-signing to verify per-user instead of per-device (in development)",
|
||||
"Enable cross-signing to verify per-user instead of per-session (in development)": "Enable cross-signing to verify per-user instead of per-session (in development)",
|
||||
"Enable local event indexing and E2EE search (requires restart)": "Enable local event indexing and E2EE search (requires restart)",
|
||||
"Show info about bridges in room settings": "Show info about bridges in room settings",
|
||||
"Show padlocks on invite only rooms": "Show padlocks on invite only rooms",
|
||||
"Enable Emoji suggestions while typing": "Enable Emoji suggestions while typing",
|
||||
"Use compact timeline layout": "Use compact timeline layout",
|
||||
"Show a placeholder for removed messages": "Show a placeholder for removed messages",
|
||||
|
@ -398,8 +397,8 @@
|
|||
"Match system theme": "Match system theme",
|
||||
"Allow Peer-to-Peer for 1:1 calls": "Allow Peer-to-Peer for 1:1 calls",
|
||||
"Send analytics data": "Send analytics data",
|
||||
"Never send encrypted messages to unverified devices from this device": "Never send encrypted messages to unverified devices from this device",
|
||||
"Never send encrypted messages to unverified devices in this room from this device": "Never send encrypted messages to unverified devices in this room from this device",
|
||||
"Never send encrypted messages to unverified sessions from this session": "Never send encrypted messages to unverified sessions from this session",
|
||||
"Never send encrypted messages to unverified sessions in this room from this session": "Never send encrypted messages to unverified sessions in this room from this session",
|
||||
"Enable inline URL previews by default": "Enable inline URL previews by default",
|
||||
"Enable URL previews for this room (only affects you)": "Enable URL previews for this room (only affects you)",
|
||||
"Enable URL previews by default for participants in this room": "Enable URL previews by default for participants in this room",
|
||||
|
@ -415,6 +414,8 @@
|
|||
"Send read receipts for messages (requires compatible homeserver to disable)": "Send read receipts for messages (requires compatible homeserver to disable)",
|
||||
"Show previews/thumbnails for images": "Show previews/thumbnails for images",
|
||||
"Enable message search in encrypted rooms": "Enable message search in encrypted rooms",
|
||||
"Keep secret storage passphrase in memory for this session": "Keep secret storage passphrase in memory for this session",
|
||||
"How fast should messages be downloaded.": "How fast should messages be downloaded.",
|
||||
"Collecting app version information": "Collecting app version information",
|
||||
"Collecting logs": "Collecting logs",
|
||||
"Uploading report": "Uploading report",
|
||||
|
@ -444,11 +445,16 @@
|
|||
"You've successfully verified this user.": "You've successfully verified this user.",
|
||||
"Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.",
|
||||
"Got It": "Got It",
|
||||
"Confirm the emoji below are displayed on both devices, in the same order:": "Confirm the emoji below are displayed on both devices, in the same order:",
|
||||
"Verify this user by confirming the following emoji appear on their screen.": "Verify this user by confirming the following emoji appear on their screen.",
|
||||
"Verify this device by confirming the following number appears on its screen.": "Verify this device by confirming the following number appears on its screen.",
|
||||
"Verify this user by confirming the following number appears on their screen.": "Verify this user by confirming the following number appears on their screen.",
|
||||
"Unable to find a supported verification method.": "Unable to find a supported verification method.",
|
||||
"Cancel": "Cancel",
|
||||
"For maximum security, we recommend you do this in person or use another trusted means of communication.": "For maximum security, we recommend you do this in person or use another trusted means of communication.",
|
||||
"Waiting for %(displayName)s to verify…": "Waiting for %(displayName)s to verify…",
|
||||
"They match": "They match",
|
||||
"They don't match": "They don't match",
|
||||
"To be secure, do this in person or use a trusted way to communicate.": "To be secure, do this in person or use a trusted way to communicate.",
|
||||
"Dog": "Dog",
|
||||
"Cat": "Cat",
|
||||
"Lion": "Lion",
|
||||
|
@ -513,13 +519,12 @@
|
|||
"Headphones": "Headphones",
|
||||
"Folder": "Folder",
|
||||
"Pin": "Pin",
|
||||
"Review & verify your new session": "Review & verify your new session",
|
||||
"Later": "Later",
|
||||
"Review": "Review",
|
||||
"Verify your other devices easier": "Verify your other devices easier",
|
||||
"Verify yourself & others to keep your chats safe": "Verify yourself & others to keep your chats safe",
|
||||
"Other users may not trust it": "Other users may not trust it",
|
||||
"Upgrade": "Upgrade",
|
||||
"Verify": "Verify",
|
||||
"Later": "Later",
|
||||
"Review": "Review",
|
||||
"Decline (%(counter)s)": "Decline (%(counter)s)",
|
||||
"Accept <policyLink /> to continue:": "Accept <policyLink /> to continue:",
|
||||
"Upload": "Upload",
|
||||
|
@ -536,7 +541,7 @@
|
|||
"New passwords don't match": "New passwords don't match",
|
||||
"Passwords can't be empty": "Passwords can't be empty",
|
||||
"Warning!": "Warning!",
|
||||
"Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.",
|
||||
"Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.",
|
||||
"Export E2E room keys": "Export E2E room keys",
|
||||
"Do you want to set an email address?": "Do you want to set an email address?",
|
||||
"Current password": "Current password",
|
||||
|
@ -545,21 +550,21 @@
|
|||
"Confirm password": "Confirm password",
|
||||
"Change Password": "Change Password",
|
||||
"Cross-signing and secret storage are enabled.": "Cross-signing and secret storage are enabled.",
|
||||
"Your account has a cross-signing identity in secret storage, but it is not yet trusted by this device.": "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this device.",
|
||||
"Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.",
|
||||
"Cross-signing and secret storage are not yet set up.": "Cross-signing and secret storage are not yet set up.",
|
||||
"Bootstrap cross-signing and secret storage": "Bootstrap cross-signing and secret storage",
|
||||
"Cross-signing public keys:": "Cross-signing public keys:",
|
||||
"on device": "on device",
|
||||
"in memory": "in memory",
|
||||
"not found": "not found",
|
||||
"Cross-signing private keys:": "Cross-signing private keys:",
|
||||
"in secret storage": "in secret storage",
|
||||
"Secret storage public key:": "Secret storage public key:",
|
||||
"in account data": "in account data",
|
||||
"Your homeserver does not support device management.": "Your homeserver does not support device management.",
|
||||
"Unable to load device list": "Unable to load device list",
|
||||
"Your homeserver does not support session management.": "Your homeserver does not support session management.",
|
||||
"Unable to load session list": "Unable to load session list",
|
||||
"Authentication": "Authentication",
|
||||
"Delete %(count)s devices|other": "Delete %(count)s devices",
|
||||
"Delete %(count)s devices|one": "Delete device",
|
||||
"Delete %(count)s sessions|other": "Delete %(count)s sessions",
|
||||
"Delete %(count)s sessions|one": "Delete %(count)s session",
|
||||
"ID": "ID",
|
||||
"Public Name": "Public Name",
|
||||
"Last seen": "Last seen",
|
||||
|
@ -582,30 +587,30 @@
|
|||
"Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.",
|
||||
"Unable to load key backup status": "Unable to load key backup status",
|
||||
"Restore from Backup": "Restore from Backup",
|
||||
"This device is backing up your keys. ": "This device is backing up your keys. ",
|
||||
"This device is <b>not backing up your keys</b>, but you do have an existing backup you can restore from and add to going forward.": "This device is <b>not backing up your keys</b>, but you do have an existing backup you can restore from and add to going forward.",
|
||||
"Connect this device to key backup before signing out to avoid losing any keys that may only be on this device.": "Connect this device to key backup before signing out to avoid losing any keys that may only be on this device.",
|
||||
"Connect this device to Key Backup": "Connect this device to Key Backup",
|
||||
"This session is backing up your keys. ": "This session is backing up your keys. ",
|
||||
"This session is <b>not backing up your keys</b>, but you do have an existing backup you can restore from and add to going forward.": "This session is <b>not backing up your keys</b>, but you do have an existing backup you can restore from and add to going forward.",
|
||||
"Connect this session to key backup before signing out to avoid losing any keys that may only be on this session.": "Connect this session to key backup before signing out to avoid losing any keys that may only be on this session.",
|
||||
"Connect this session to Key Backup": "Connect this session to Key Backup",
|
||||
"not stored": "not stored",
|
||||
"Backing up %(sessionsRemaining)s keys...": "Backing up %(sessionsRemaining)s keys...",
|
||||
"All keys backed up": "All keys backed up",
|
||||
"Backup has a <validity>valid</validity> signature from this user": "Backup has a <validity>valid</validity> signature from this user",
|
||||
"Backup has a <validity>invalid</validity> signature from this user": "Backup has a <validity>invalid</validity> signature from this user",
|
||||
"Backup has a signature from <verify>unknown</verify> user with ID %(deviceId)s": "Backup has a signature from <verify>unknown</verify> user with ID %(deviceId)s",
|
||||
"Backup has a signature from <verify>unknown</verify> device with ID %(deviceId)s": "Backup has a signature from <verify>unknown</verify> device with ID %(deviceId)s",
|
||||
"Backup has a <validity>valid</validity> signature from this device": "Backup has a <validity>valid</validity> signature from this device",
|
||||
"Backup has an <validity>invalid</validity> signature from this device": "Backup has an <validity>invalid</validity> signature from this device",
|
||||
"Backup has a <validity>valid</validity> signature from <verify>verified</verify> device <device></device>": "Backup has a <validity>valid</validity> signature from <verify>verified</verify> device <device></device>",
|
||||
"Backup has a <validity>valid</validity> signature from <verify>unverified</verify> device <device></device>": "Backup has a <validity>valid</validity> signature from <verify>unverified</verify> device <device></device>",
|
||||
"Backup has an <validity>invalid</validity> signature from <verify>verified</verify> device <device></device>": "Backup has an <validity>invalid</validity> signature from <verify>verified</verify> device <device></device>",
|
||||
"Backup has an <validity>invalid</validity> signature from <verify>unverified</verify> device <device></device>": "Backup has an <validity>invalid</validity> signature from <verify>unverified</verify> device <device></device>",
|
||||
"Backup is not signed by any of your devices": "Backup is not signed by any of your devices",
|
||||
"This backup is trusted because it has been restored on this device": "This backup is trusted because it has been restored on this device",
|
||||
"Backup key stored in secret storage, but this feature is not enabled on this device. Please enable cross-signing in Labs to modify key backup state.": "Backup key stored in secret storage, but this feature is not enabled on this device. Please enable cross-signing in Labs to modify key backup state.",
|
||||
"Backup has a signature from <verify>unknown</verify> session with ID %(deviceId)s": "Backup has a signature from <verify>unknown</verify> session with ID %(deviceId)s",
|
||||
"Backup has a <validity>valid</validity> signature from this session": "Backup has a <validity>valid</validity> signature from this session",
|
||||
"Backup has an <validity>invalid</validity> signature from this session": "Backup has an <validity>invalid</validity> signature from this session",
|
||||
"Backup has a <validity>valid</validity> signature from <verify>verified</verify> session <device></device>": "Backup has a <validity>valid</validity> signature from <verify>verified</verify> session <device></device>",
|
||||
"Backup has a <validity>valid</validity> signature from <verify>unverified</verify> session <device></device>": "Backup has a <validity>valid</validity> signature from <verify>unverified</verify> session <device></device>",
|
||||
"Backup has an <validity>invalid</validity> signature from <verify>verified</verify> session <device></device>": "Backup has an <validity>invalid</validity> signature from <verify>verified</verify> session <device></device>",
|
||||
"Backup has an <validity>invalid</validity> signature from <verify>unverified</verify> session <device></device>": "Backup has an <validity>invalid</validity> signature from <verify>unverified</verify> session <device></device>",
|
||||
"Backup is not signed by any of your sessions": "Backup is not signed by any of your sessions",
|
||||
"This backup is trusted because it has been restored on this session": "This backup is trusted because it has been restored on this session",
|
||||
"Backup key stored in secret storage, but this feature is not enabled on this session. Please enable cross-signing in Labs to modify key backup state.": "Backup key stored in secret storage, but this feature is not enabled on this session. Please enable cross-signing in Labs to modify key backup state.",
|
||||
"Backup version: ": "Backup version: ",
|
||||
"Algorithm: ": "Algorithm: ",
|
||||
"Backup key stored: ": "Backup key stored: ",
|
||||
"Your keys are <b>not being backed up from this device</b>.": "Your keys are <b>not being backed up from this device</b>.",
|
||||
"Your keys are <b>not being backed up from this session</b>.": "Your keys are <b>not being backed up from this session</b>.",
|
||||
"Back up your keys before signing out to avoid losing them.": "Back up your keys before signing out to avoid losing them.",
|
||||
"Start using Key Backup": "Start using Key Backup",
|
||||
"Error saving email notification preferences": "Error saving email notification preferences",
|
||||
|
@ -629,9 +634,9 @@
|
|||
"Advanced notification settings": "Advanced notification settings",
|
||||
"There are advanced notifications which are not shown here": "There are advanced notifications which are not shown here",
|
||||
"You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply": "You might have configured them in a client other than Riot. You cannot tune them in Riot but they still apply",
|
||||
"Enable desktop notifications for this device": "Enable desktop notifications for this device",
|
||||
"Enable desktop notifications for this session": "Enable desktop notifications for this session",
|
||||
"Show message in desktop notification": "Show message in desktop notification",
|
||||
"Enable audible notifications for this device": "Enable audible notifications for this device",
|
||||
"Enable audible notifications for this session": "Enable audible notifications for this session",
|
||||
"Off": "Off",
|
||||
"On": "On",
|
||||
"Noisy": "Noisy",
|
||||
|
@ -676,7 +681,7 @@
|
|||
"Flair": "Flair",
|
||||
"Failed to change password. Is your password correct?": "Failed to change password. Is your password correct?",
|
||||
"Success": "Success",
|
||||
"Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them",
|
||||
"Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them",
|
||||
"Profile": "Profile",
|
||||
"Email addresses": "Email addresses",
|
||||
"Phone numbers": "Phone numbers",
|
||||
|
@ -761,8 +766,8 @@
|
|||
"<not supported>": "<not supported>",
|
||||
"Import E2E room keys": "Import E2E room keys",
|
||||
"Cryptography": "Cryptography",
|
||||
"Device ID:": "Device ID:",
|
||||
"Device key:": "Device key:",
|
||||
"Session ID:": "Session ID:",
|
||||
"Session key:": "Session key:",
|
||||
"Bulk options": "Bulk options",
|
||||
"Accept all %(invitedRooms)s invites": "Accept all %(invitedRooms)s invites",
|
||||
"Reject all %(invitedRooms)s invites": "Reject all %(invitedRooms)s invites",
|
||||
|
@ -770,8 +775,8 @@
|
|||
"Message search": "Message search",
|
||||
"Cross-signing": "Cross-signing",
|
||||
"Security & Privacy": "Security & Privacy",
|
||||
"Devices": "Devices",
|
||||
"A device's public name is visible to people you communicate with": "A device's public name is visible to people you communicate with",
|
||||
"Sessions": "Sessions",
|
||||
"A session's public name is visible to people you communicate with": "A session's public name is visible to people you communicate with",
|
||||
"Riot collects anonymous analytics to allow us to improve the application.": "Riot collects anonymous analytics to allow us to improve the application.",
|
||||
"Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.",
|
||||
"Learn more about how we use analytics.": "Learn more about how we use analytics.",
|
||||
|
@ -896,30 +901,31 @@
|
|||
" (unsupported)": " (unsupported)",
|
||||
"Join as <voiceText>voice</voiceText> or <videoText>video</videoText>.": "Join as <voiceText>voice</voiceText> or <videoText>video</videoText>.",
|
||||
"Ongoing conference call%(supportedText)s.": "Ongoing conference call%(supportedText)s.",
|
||||
"This user has not verified all of their devices.": "This user has not verified all of their devices.",
|
||||
"You have not verified this user. This user has verified all of their devices.": "You have not verified this user. This user has verified all of their devices.",
|
||||
"You have verified this user. This user has verified all of their devices.": "You have verified this user. This user has verified all of their devices.",
|
||||
"Someone is using an unknown device": "Someone is using an unknown device",
|
||||
"This user has not verified all of their sessions.": "This user has not verified all of their sessions.",
|
||||
"You have not verified this user.": "You have not verified this user.",
|
||||
"You have verified this user. This user has verified all of their sessions.": "You have verified this user. This user has verified all of their sessions.",
|
||||
"Someone is using an unknown session": "Someone is using an unknown session",
|
||||
"This room is end-to-end encrypted": "This room is end-to-end encrypted",
|
||||
"Everyone in this room is verified": "Everyone in this room is verified",
|
||||
"Some devices for this user are not trusted": "Some devices for this user are not trusted",
|
||||
"All devices for this user are trusted": "All devices for this user are trusted",
|
||||
"Some devices in this encrypted room are not trusted": "Some devices in this encrypted room are not trusted",
|
||||
"All devices in this encrypted room are trusted": "All devices in this encrypted room are trusted",
|
||||
"Some sessions for this user are not trusted": "Some sessions for this user are not trusted",
|
||||
"All sessions for this user are trusted": "All sessions for this user are trusted",
|
||||
"Some sessions in this encrypted room are not trusted": "Some sessions in this encrypted room are not trusted",
|
||||
"All sessions in this encrypted room are trusted": "All sessions in this encrypted room are trusted",
|
||||
"Edit message": "Edit message",
|
||||
"Mod": "Mod",
|
||||
"This event could not be displayed": "This event could not be displayed",
|
||||
"%(senderName)s sent an image": "%(senderName)s sent an image",
|
||||
"%(senderName)s sent a video": "%(senderName)s sent a video",
|
||||
"%(senderName)s uploaded a file": "%(senderName)s uploaded a file",
|
||||
"Your key share request has been sent - please check your other devices for key share requests.": "Your key share request has been sent - please check your other devices for key share requests.",
|
||||
"Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.",
|
||||
"If your other devices do not have the key for this message you will not be able to decrypt them.": "If your other devices do not have the key for this message you will not be able to decrypt them.",
|
||||
"Your key share request has been sent - please check your other sessions for key share requests.": "Your key share request has been sent - please check your other sessions for key share requests.",
|
||||
"Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.",
|
||||
"If your other sessions do not have the key for this message you will not be able to decrypt them.": "If your other sessions do not have the key for this message you will not be able to decrypt them.",
|
||||
"Key request sent.": "Key request sent.",
|
||||
"<requestLink>Re-request encryption keys</requestLink> from your other devices.": "<requestLink>Re-request encryption keys</requestLink> from your other devices.",
|
||||
"<requestLink>Re-request encryption keys</requestLink> from your other sessions.": "<requestLink>Re-request encryption keys</requestLink> from your other sessions.",
|
||||
"This message cannot be decrypted": "This message cannot be decrypted",
|
||||
"Encrypted by an unverified device": "Encrypted by an unverified device",
|
||||
"Encrypted by an unverified session": "Encrypted by an unverified session",
|
||||
"Unencrypted": "Unencrypted",
|
||||
"Encrypted by a deleted device": "Encrypted by a deleted device",
|
||||
"Encrypted by a deleted session": "Encrypted by a deleted session",
|
||||
"Please select the destination room for this message": "Please select the destination room for this message",
|
||||
"Invite only": "Invite only",
|
||||
"Scroll to bottom of page": "Scroll to bottom of page",
|
||||
|
@ -954,7 +960,7 @@
|
|||
"Failed to change power level": "Failed to change power level",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.",
|
||||
"Are you sure?": "Are you sure?",
|
||||
"No devices with registered encryption keys": "No devices with registered encryption keys",
|
||||
"No sessions with registered encryption keys": "No sessions with registered encryption keys",
|
||||
"Jump to read receipt": "Jump to read receipt",
|
||||
"Mention": "Mention",
|
||||
"Invite": "Invite",
|
||||
|
@ -1141,17 +1147,28 @@
|
|||
"URL previews are disabled by default for participants in this room.": "URL previews are disabled by default for participants in this room.",
|
||||
"In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.",
|
||||
"When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.",
|
||||
"Waiting for %(displayName)s to accept…": "Waiting for %(displayName)s to accept…",
|
||||
"Start Verification": "Start Verification",
|
||||
"Messages in this room are end-to-end encrypted.": "Messages in this room are end-to-end encrypted.",
|
||||
"Your messages are secured and only you and the recipient have the unique keys to unlock them.": "Your messages are secured and only you and the recipient have the unique keys to unlock them.",
|
||||
"Verify User": "Verify User",
|
||||
"For extra security, verify this user by checking a one-time code on both of your devices.": "For extra security, verify this user by checking a one-time code on both of your devices.",
|
||||
"For maximum security, do this in person.": "For maximum security, do this in person.",
|
||||
"Start Verification": "Start Verification",
|
||||
"Your messages are not secure": "Your messages are not secure",
|
||||
"One of the following may be compromised:": "One of the following may be compromised:",
|
||||
"Your homeserver": "Your homeserver",
|
||||
"The homeserver the user you’re verifying is connected to": "The homeserver the user you’re verifying is connected to",
|
||||
"Yours, or the other users’ internet connection": "Yours, or the other users’ internet connection",
|
||||
"Yours, or the other users’ session": "Yours, or the other users’ session",
|
||||
"Members": "Members",
|
||||
"Files": "Files",
|
||||
"Trusted": "Trusted",
|
||||
"Not trusted": "Not trusted",
|
||||
"Hide verified sessions": "Hide verified sessions",
|
||||
"%(count)s verified sessions|other": "%(count)s verified sessions",
|
||||
"%(count)s verified sessions|one": "1 verified session",
|
||||
"Hide verified sessions": "Hide verified sessions",
|
||||
"%(count)s sessions|other": "%(count)s sessions",
|
||||
"%(count)s sessions|one": "%(count)s session",
|
||||
"Hide sessions": "Hide sessions",
|
||||
"Direct message": "Direct message",
|
||||
"Remove from community": "Remove from community",
|
||||
"Disinvite this user from community?": "Disinvite this user from community?",
|
||||
|
@ -1161,8 +1178,16 @@
|
|||
"<strong>%(role)s</strong> in %(roomName)s": "<strong>%(role)s</strong> in %(roomName)s",
|
||||
"This client does not support end-to-end encryption.": "This client does not support end-to-end encryption.",
|
||||
"Messages in this room are not end-to-end encrypted.": "Messages in this room are not end-to-end encrypted.",
|
||||
"Messages in this room are end-to-end encrypted.": "Messages in this room are end-to-end encrypted.",
|
||||
"Security": "Security",
|
||||
"Verify by emoji": "Verify by emoji",
|
||||
"Verify by comparing unique emoji.": "Verify by comparing unique emoji.",
|
||||
"Ask %(displayName)s to scan your code:": "Ask %(displayName)s to scan your code:",
|
||||
"If you can't scan the code above, verify by comparing unique emoji.": "If you can't scan the code above, verify by comparing unique emoji.",
|
||||
"You've successfully verified %(displayName)s!": "You've successfully verified %(displayName)s!",
|
||||
"Got it": "Got it",
|
||||
"Verification timed out. Start verification again from their profile.": "Verification timed out. Start verification again from their profile.",
|
||||
"%(displayName)s cancelled verification. Start verification again from their profile.": "%(displayName)s cancelled verification. Start verification again from their profile.",
|
||||
"You cancelled verification. Start verification again from their profile.": "You cancelled verification. Start verification again from their profile.",
|
||||
"Sunday": "Sunday",
|
||||
"Monday": "Monday",
|
||||
"Tuesday": "Tuesday",
|
||||
|
@ -1173,6 +1198,10 @@
|
|||
"Today": "Today",
|
||||
"Yesterday": "Yesterday",
|
||||
"View Source": "View Source",
|
||||
"Encryption enabled": "Encryption enabled",
|
||||
"Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.",
|
||||
"Encryption not enabled": "Encryption not enabled",
|
||||
"The encryption used by this room isn't supported.": "The encryption used by this room isn't supported.",
|
||||
"Error decrypting audio": "Error decrypting audio",
|
||||
"React": "React",
|
||||
"Reply": "Reply",
|
||||
|
@ -1403,8 +1432,8 @@
|
|||
"Removing…": "Removing…",
|
||||
"Confirm Removal": "Confirm Removal",
|
||||
"Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.",
|
||||
"Clear all data on this device?": "Clear all data on this device?",
|
||||
"Clearing all data from this device is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Clearing all data from this device is permanent. Encrypted messages will be lost unless their keys have been backed up.",
|
||||
"Clear all data in this session?": "Clear all data in this session?",
|
||||
"Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.",
|
||||
"Clear all data": "Clear all data",
|
||||
"Community IDs cannot be empty.": "Community IDs cannot be empty.",
|
||||
"Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Community IDs may only contain characters a-z, 0-9, or '=_-./'",
|
||||
|
@ -1439,20 +1468,20 @@
|
|||
"Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not be shared with any new or unregistered users, but registered users who already have access to these messages will still have access to their copy.": "Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not be shared with any new or unregistered users, but registered users who already have access to these messages will still have access to their copy.",
|
||||
"Please forget all messages I have sent when my account is deactivated (<b>Warning:</b> this will cause future users to see an incomplete view of conversations)": "Please forget all messages I have sent when my account is deactivated (<b>Warning:</b> this will cause future users to see an incomplete view of conversations)",
|
||||
"To continue, please enter your password:": "To continue, please enter your password:",
|
||||
"Verify device": "Verify device",
|
||||
"Verify session": "Verify session",
|
||||
"Use Legacy Verification (for older clients)": "Use Legacy Verification (for older clients)",
|
||||
"Verify by comparing a short text string.": "Verify by comparing a short text string.",
|
||||
"Begin Verifying": "Begin Verifying",
|
||||
"Waiting for partner to accept...": "Waiting for partner to accept...",
|
||||
"Nothing appearing? Not all clients support interactive verification yet. <button>Use legacy verification</button>.": "Nothing appearing? Not all clients support interactive verification yet. <button>Use legacy verification</button>.",
|
||||
"Waiting for %(userId)s to confirm...": "Waiting for %(userId)s to confirm...",
|
||||
"To verify that this device can be trusted, please check that the key you see in User Settings on that device matches the key below:": "To verify that this device can be trusted, please check that the key you see in User Settings on that device matches the key below:",
|
||||
"To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:",
|
||||
"To verify that this session can be trusted, please check that the key you see in User Settings on that device matches the key below:": "To verify that this session can be trusted, please check that the key you see in User Settings on that device matches the key below:",
|
||||
"To verify that this session can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this session matches the key below:": "To verify that this session can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this session matches the key below:",
|
||||
"Use two-way text verification": "Use two-way text verification",
|
||||
"Device name": "Device name",
|
||||
"Device ID": "Device ID",
|
||||
"Device key": "Device key",
|
||||
"If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.",
|
||||
"Session name": "Session name",
|
||||
"Session ID": "Session ID",
|
||||
"Session key": "Session key",
|
||||
"If it matches, press the verify button below. If it doesn't, then someone else is intercepting this session and you probably want to press the blacklist button instead.": "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this session and you probably want to press the blacklist button instead.",
|
||||
"I verify that the keys match": "I verify that the keys match",
|
||||
"Back": "Back",
|
||||
"Send Custom Event": "Send Custom Event",
|
||||
|
@ -1471,7 +1500,9 @@
|
|||
"Developer Tools": "Developer Tools",
|
||||
"An error has occurred.": "An error has occurred.",
|
||||
"Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.",
|
||||
"Verifying this user will mark their device as trusted, and also mark your device as trusted to them.": "Verifying this user will mark their device as trusted, and also mark your device as trusted to them.",
|
||||
"Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.",
|
||||
"Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.",
|
||||
"Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "Verifying this device will mark it as trusted, and users who have verified with you will trust this device.",
|
||||
"Waiting for partner to confirm...": "Waiting for partner to confirm...",
|
||||
"Incoming Verification Request": "Incoming Verification Request",
|
||||
"Integrations are disabled": "Integrations are disabled",
|
||||
|
@ -1490,12 +1521,12 @@
|
|||
"If you can't find someone, ask them for their username, share your username (%(userId)s) or <a>profile link</a>.": "If you can't find someone, ask them for their username, share your username (%(userId)s) or <a>profile link</a>.",
|
||||
"Go": "Go",
|
||||
"If you can't find someone, ask them for their username (e.g. @user:server.com) or <a>share this room</a>.": "If you can't find someone, ask them for their username (e.g. @user:server.com) or <a>share this room</a>.",
|
||||
"You added a new device '%(displayName)s', which is requesting encryption keys.": "You added a new device '%(displayName)s', which is requesting encryption keys.",
|
||||
"Your unverified device '%(displayName)s' is requesting encryption keys.": "Your unverified device '%(displayName)s' is requesting encryption keys.",
|
||||
"You added a new session '%(displayName)s', which is requesting encryption keys.": "You added a new session '%(displayName)s', which is requesting encryption keys.",
|
||||
"Your unverified session '%(displayName)s' is requesting encryption keys.": "Your unverified session '%(displayName)s' is requesting encryption keys.",
|
||||
"Start verification": "Start verification",
|
||||
"Share without verifying": "Share without verifying",
|
||||
"Ignore request": "Ignore request",
|
||||
"Loading device info...": "Loading device info...",
|
||||
"Loading session info...": "Loading session info...",
|
||||
"Encryption key request": "Encryption key request",
|
||||
"You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.": "You've previously used Riot on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, Riot needs to resync your account.",
|
||||
"If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "If the other version of Riot is still open in another tab, please close it as using Riot on the same host with both lazy loading enabled and disabled simultaneously will cause issues.",
|
||||
|
@ -1564,7 +1595,7 @@
|
|||
"Remember, you can always set an email address in user settings if you change your mind.": "Remember, you can always set an email address in user settings if you change your mind.",
|
||||
"(HTTP status %(httpStatus)s)": "(HTTP status %(httpStatus)s)",
|
||||
"Please set a password!": "Please set a password!",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "This will allow you to return to your account after signing out, and sign in on other devices.",
|
||||
"This will allow you to return to your account after signing out, and sign in on other sessions.": "This will allow you to return to your account after signing out, and sign in on other sessions.",
|
||||
"Share Room": "Share Room",
|
||||
"Link to most recent message": "Link to most recent message",
|
||||
"Share User": "Share User",
|
||||
|
@ -1587,11 +1618,11 @@
|
|||
"Summary": "Summary",
|
||||
"Document": "Document",
|
||||
"Next": "Next",
|
||||
"You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.",
|
||||
"We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.",
|
||||
"Room contains unknown devices": "Room contains unknown devices",
|
||||
"\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" contains devices that you haven't seen before.",
|
||||
"Unknown devices": "Unknown devices",
|
||||
"You are currently blacklisting unverified sessions; to send messages to these sessions you must verify them.": "You are currently blacklisting unverified sessions; to send messages to these sessions you must verify them.",
|
||||
"We recommend you go through the verification process for each session to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "We recommend you go through the verification process for each session to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.",
|
||||
"Room contains unknown sessions": "Room contains unknown sessions",
|
||||
"\"%(RoomName)s\" contains sessions that you haven't seen before.": "\"%(RoomName)s\" contains sessions that you haven't seen before.",
|
||||
"Unknown sessions": "Unknown sessions",
|
||||
"Upload files (%(current)s of %(total)s)": "Upload files (%(current)s of %(total)s)",
|
||||
"Upload files": "Upload files",
|
||||
"Upload all": "Upload all",
|
||||
|
@ -1610,29 +1641,29 @@
|
|||
"Enter secret storage passphrase": "Enter secret storage passphrase",
|
||||
"Unable to access secret storage. Please verify that you entered the correct passphrase.": "Unable to access secret storage. Please verify that you entered the correct passphrase.",
|
||||
"<b>Warning</b>: You should only access secret storage from a trusted computer.": "<b>Warning</b>: You should only access secret storage from a trusted computer.",
|
||||
"Access your secure message history and your cross-signing identity for verifying other devices by entering your passphrase.": "Access your secure message history and your cross-signing identity for verifying other devices by entering your passphrase.",
|
||||
"Access your secure message history and your cross-signing identity for verifying other sessions by entering your passphrase.": "Access your secure message history and your cross-signing identity for verifying other sessions by entering your passphrase.",
|
||||
"If you've forgotten your passphrase you can <button1>use your recovery key</button1> or <button2>set up new recovery options</button2>.": "If you've forgotten your passphrase you can <button1>use your recovery key</button1> or <button2>set up new recovery options</button2>.",
|
||||
"Enter secret storage recovery key": "Enter secret storage recovery key",
|
||||
"This looks like a valid recovery key!": "This looks like a valid recovery key!",
|
||||
"Unable to access secret storage. Please verify that you entered the correct recovery key.": "Unable to access secret storage. Please verify that you entered the correct recovery key.",
|
||||
"Not a valid recovery key": "Not a valid recovery key",
|
||||
"Access your secure message history and your cross-signing identity for verifying other devices by entering your recovery key.": "Access your secure message history and your cross-signing identity for verifying other devices by entering your recovery key.",
|
||||
"Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery key.": "Access your secure message history and your cross-signing identity for verifying other sessions by entering your recovery key.",
|
||||
"If you've forgotten your recovery key you can <button>set up new recovery options</button>.": "If you've forgotten your recovery key you can <button>set up new recovery options</button>.",
|
||||
"Unable to load backup status": "Unable to load backup status",
|
||||
"Recovery Key Mismatch": "Recovery Key Mismatch",
|
||||
"Recovery key mismatch": "Recovery key mismatch",
|
||||
"Backup could not be decrypted with this key: please verify that you entered the correct recovery key.": "Backup could not be decrypted with this key: please verify that you entered the correct recovery key.",
|
||||
"Incorrect Recovery Passphrase": "Incorrect Recovery Passphrase",
|
||||
"Incorrect recovery passphrase": "Incorrect recovery passphrase",
|
||||
"Backup could not be decrypted with this passphrase: please verify that you entered the correct recovery passphrase.": "Backup could not be decrypted with this passphrase: please verify that you entered the correct recovery passphrase.",
|
||||
"Unable to restore backup": "Unable to restore backup",
|
||||
"No backup found!": "No backup found!",
|
||||
"Backup Restored": "Backup Restored",
|
||||
"Backup restored": "Backup restored",
|
||||
"Failed to decrypt %(failedCount)s sessions!": "Failed to decrypt %(failedCount)s sessions!",
|
||||
"Restored %(sessionCount)s session keys": "Restored %(sessionCount)s session keys",
|
||||
"Enter Recovery Passphrase": "Enter Recovery Passphrase",
|
||||
"Enter recovery passphrase": "Enter recovery passphrase",
|
||||
"<b>Warning</b>: you should only set up key backup from a trusted computer.": "<b>Warning</b>: you should only set up key backup from a trusted computer.",
|
||||
"Access your secure message history and set up secure messaging by entering your recovery passphrase.": "Access your secure message history and set up secure messaging by entering your recovery passphrase.",
|
||||
"If you've forgotten your recovery passphrase you can <button1>use your recovery key</button1> or <button2>set up new recovery options</button2>": "If you've forgotten your recovery passphrase you can <button1>use your recovery key</button1> or <button2>set up new recovery options</button2>",
|
||||
"Enter Recovery Key": "Enter Recovery Key",
|
||||
"Enter recovery key": "Enter recovery key",
|
||||
"<b>Warning</b>: You should only set up key backup from a trusted computer.": "<b>Warning</b>: You should only set up key backup from a trusted computer.",
|
||||
"Access your secure message history and set up secure messaging by entering your recovery key.": "Access your secure message history and set up secure messaging by entering your recovery key.",
|
||||
"If you've forgotten your recovery key you can <button>set up new recovery options</button>": "If you've forgotten your recovery key you can <button>set up new recovery options</button>",
|
||||
|
@ -1687,7 +1718,7 @@
|
|||
"Country Dropdown": "Country Dropdown",
|
||||
"Custom Server Options": "Custom Server Options",
|
||||
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use this app with an existing Matrix account on a different homeserver.": "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use this app with an existing Matrix account on a different homeserver.",
|
||||
"To continue, please enter your password.": "To continue, please enter your password.",
|
||||
"Confirm your identity by entering your account password below.": "Confirm your identity by entering your account password below.",
|
||||
"Missing captcha public key in homeserver configuration. Please report this to your homeserver administrator.": "Missing captcha public key in homeserver configuration. Please report this to your homeserver administrator.",
|
||||
"Please review and accept all of the homeserver's policies": "Please review and accept all of the homeserver's policies",
|
||||
"Please review and accept the policies of this homeserver:": "Please review and accept the policies of this homeserver:",
|
||||
|
@ -1844,8 +1875,8 @@
|
|||
"Find a room… (e.g. %(exampleRoom)s)": "Find a room… (e.g. %(exampleRoom)s)",
|
||||
"If you can't find the room you're looking for, ask for an invite or <a>Create a new room</a>.": "If you can't find the room you're looking for, ask for an invite or <a>Create a new room</a>.",
|
||||
"Explore rooms": "Explore rooms",
|
||||
"Message not sent due to unknown devices being present": "Message not sent due to unknown devices being present",
|
||||
"<showDevicesText>Show devices</showDevicesText>, <sendAnywayText>send anyway</sendAnywayText> or <cancelText>cancel</cancelText>.": "<showDevicesText>Show devices</showDevicesText>, <sendAnywayText>send anyway</sendAnywayText> or <cancelText>cancel</cancelText>.",
|
||||
"Message not sent due to unknown sessions being present": "Message not sent due to unknown sessions being present",
|
||||
"<showSessionsText>Show sessions</showSessionsText>, <sendAnywayText>send anyway</sendAnywayText> or <cancelText>cancel</cancelText>.": "<showSessionsText>Show sessions</showSessionsText>, <sendAnywayText>send anyway</sendAnywayText> or <cancelText>cancel</cancelText>.",
|
||||
"You can't send any messages until you review and agree to <consentLink>our terms and conditions</consentLink>.": "You can't send any messages until you review and agree to <consentLink>our terms and conditions</consentLink>.",
|
||||
"Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please <a>contact your service administrator</a> to continue using the service.": "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please <a>contact your service administrator</a> to continue using the service.",
|
||||
"Your message wasn't sent because this homeserver has exceeded a resource limit. Please <a>contact your service administrator</a> to continue using the service.": "Your message wasn't sent because this homeserver has exceeded a resource limit. Please <a>contact your service administrator</a> to continue using the service.",
|
||||
|
@ -1891,14 +1922,15 @@
|
|||
"Start": "Start",
|
||||
"Session verified": "Session verified",
|
||||
"Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.",
|
||||
"Your new session is now verified. Other users will see it as trusted.": "Your new session is now verified. Other users will see it as trusted.",
|
||||
"Done": "Done",
|
||||
"Without completing security on this device, it won’t have access to encrypted messages.": "Without completing security on this device, it won’t have access to encrypted messages.",
|
||||
"Without completing security on this session, it won’t have access to encrypted messages.": "Without completing security on this session, it won’t have access to encrypted messages.",
|
||||
"Go Back": "Go Back",
|
||||
"Failed to send email": "Failed to send email",
|
||||
"The email address linked to your account must be entered.": "The email address linked to your account must be entered.",
|
||||
"A new password must be entered.": "A new password must be entered.",
|
||||
"New passwords must match each other.": "New passwords must match each other.",
|
||||
"Changing your password will reset any end-to-end encryption keys on all of your devices, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another device before resetting your password.": "Changing your password will reset any end-to-end encryption keys on all of your devices, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another device before resetting your password.",
|
||||
"Changing your password will reset any end-to-end encryption keys on all of your sessions, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another session before resetting your password.": "Changing your password will reset any end-to-end encryption keys on all of your sessions, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another session before resetting your password.",
|
||||
"Your Matrix account on %(serverName)s": "Your Matrix account on %(serverName)s",
|
||||
"Your Matrix account on <underlinedServerName />": "Your Matrix account on <underlinedServerName />",
|
||||
"No identity server is configured: add one in server settings to reset your password.": "No identity server is configured: add one in server settings to reset your password.",
|
||||
|
@ -1908,7 +1940,7 @@
|
|||
"An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.",
|
||||
"I have verified my email address": "I have verified my email address",
|
||||
"Your password has been reset.": "Your password has been reset.",
|
||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device.",
|
||||
"You have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "You have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, sign in again on each device.",
|
||||
"Return to login screen": "Return to login screen",
|
||||
"Set a new password": "Set a new password",
|
||||
"Invalid homeserver discovery response": "Invalid homeserver discovery response",
|
||||
|
@ -1946,14 +1978,14 @@
|
|||
"Create your account": "Create your account",
|
||||
"Failed to re-authenticate due to a homeserver problem": "Failed to re-authenticate due to a homeserver problem",
|
||||
"Failed to re-authenticate": "Failed to re-authenticate",
|
||||
"Regain access to your account and recover encryption keys stored on this device. Without them, you won’t be able to read all of your secure messages on any device.": "Regain access to your account and recover encryption keys stored on this device. Without them, you won’t be able to read all of your secure messages on any device.",
|
||||
"Regain access to your account and recover encryption keys stored in this session. Without them, you won’t be able to read all of your secure messages in any session.": "Regain access to your account and recover encryption keys stored in this session. Without them, you won’t be able to read all of your secure messages in any session.",
|
||||
"Enter your password to sign in and regain access to your account.": "Enter your password to sign in and regain access to your account.",
|
||||
"Forgotten your password?": "Forgotten your password?",
|
||||
"Sign in and regain access to your account.": "Sign in and regain access to your account.",
|
||||
"You cannot sign in to your account. Please contact your homeserver admin for more information.": "You cannot sign in to your account. Please contact your homeserver admin for more information.",
|
||||
"You're signed out": "You're signed out",
|
||||
"Clear personal data": "Clear personal data",
|
||||
"Warning: Your personal data (including encryption keys) is still stored on this device. Clear it if you're finished using this device, or want to sign in to another account.": "Warning: Your personal data (including encryption keys) is still stored on this device. Clear it if you're finished using this device, or want to sign in to another account.",
|
||||
"Warning: Your personal data (including encryption keys) is still stored in this session. Clear it if you're finished using this session, or want to sign in to another account.": "Warning: Your personal data (including encryption keys) is still stored in this session. Clear it if you're finished using this session, or want to sign in to another account.",
|
||||
"Commands": "Commands",
|
||||
"Command Autocomplete": "Command Autocomplete",
|
||||
"Community Autocomplete": "Community Autocomplete",
|
||||
|
@ -1971,6 +2003,7 @@
|
|||
"NOT verified": "NOT verified",
|
||||
"Blacklisted": "Blacklisted",
|
||||
"verified": "verified",
|
||||
"Device ID": "Device ID",
|
||||
"Verification": "Verification",
|
||||
"Ed25519 fingerprint": "Ed25519 fingerprint",
|
||||
"User ID": "User ID",
|
||||
|
@ -1980,9 +2013,8 @@
|
|||
"Algorithm": "Algorithm",
|
||||
"unencrypted": "unencrypted",
|
||||
"Decryption error": "Decryption error",
|
||||
"Session ID": "Session ID",
|
||||
"Event information": "Event information",
|
||||
"Sender device information": "Sender device information",
|
||||
"Sender session information": "Sender session information",
|
||||
"Passphrases must match": "Passphrases must match",
|
||||
"Passphrase must not be empty": "Passphrase must not be empty",
|
||||
"Export room keys": "Export room keys",
|
||||
|
@ -2000,54 +2032,46 @@
|
|||
"Restore": "Restore",
|
||||
"Enter your account password to confirm the upgrade:": "Enter your account password to confirm the upgrade:",
|
||||
"You'll need to authenticate with the server to confirm the upgrade.": "You'll need to authenticate with the server to confirm the upgrade.",
|
||||
"Upgrade this device to allow it to verify other devices, granting them access to encrypted messages and marking them as trusted for other users.": "Upgrade this device to allow it to verify other devices, granting them access to encrypted messages and marking them as trusted for other users.",
|
||||
"Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.",
|
||||
"Great! This passphrase looks strong enough.": "Great! This passphrase looks strong enough.",
|
||||
"Set up encryption on this device to allow it to verify other devices, granting them access to encrypted messages and marking them as trusted for other users.": "Set up encryption on this device to allow it to verify other devices, granting them access to encrypted messages and marking them as trusted for other users.",
|
||||
"Set up encryption on this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Set up encryption on this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.",
|
||||
"Secure your encryption keys with a passphrase. For maximum security this should be different to your account password:": "Secure your encryption keys with a passphrase. For maximum security this should be different to your account password:",
|
||||
"Enter a passphrase": "Enter a passphrase",
|
||||
"Back up my encryption keys, securing them with the same passphrase": "Back up my encryption keys, securing them with the same passphrase",
|
||||
"Set up with a recovery key": "Set up with a recovery key",
|
||||
"That matches!": "That matches!",
|
||||
"That doesn't match.": "That doesn't match.",
|
||||
"Go back to set it again.": "Go back to set it again.",
|
||||
"Enter your passphrase a second time to confirm it.": "Enter your passphrase a second time to confirm it.",
|
||||
"Confirm your passphrase": "Confirm your passphrase",
|
||||
"As a safety net, you can use it to restore your access to encrypted messages if you forget your passphrase.": "As a safety net, you can use it to restore your access to encrypted messages if you forget your passphrase.",
|
||||
"As a safety net, you can use it to restore your access to encrypted messages.": "As a safety net, you can use it to restore your access to encrypted messages.",
|
||||
"Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your passphrase.": "Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your passphrase.",
|
||||
"Keep your recovery key somewhere very secure, like a password manager (or a safe).": "Keep your recovery key somewhere very secure, like a password manager (or a safe).",
|
||||
"Your Recovery Key": "Your Recovery Key",
|
||||
"Copy to clipboard": "Copy to clipboard",
|
||||
"Keep a copy of it somewhere secure, like a password manager or even a safe.": "Keep a copy of it somewhere secure, like a password manager or even a safe.",
|
||||
"Your recovery key": "Your recovery key",
|
||||
"Copy": "Copy",
|
||||
"Download": "Download",
|
||||
"Your recovery key has been <b>copied to your clipboard</b>, paste it to:": "Your recovery key has been <b>copied to your clipboard</b>, paste it to:",
|
||||
"Your recovery key is in your <b>Downloads</b> folder.": "Your recovery key is in your <b>Downloads</b> folder.",
|
||||
"<b>Print it</b> and store it somewhere safe": "<b>Print it</b> and store it somewhere safe",
|
||||
"<b>Save it</b> on a USB key or backup drive": "<b>Save it</b> on a USB key or backup drive",
|
||||
"<b>Copy it</b> to your personal cloud storage": "<b>Copy it</b> to your personal cloud storage",
|
||||
"This device can now verify other devices, granting them access to encrypted messages and marking them as trusted for other users.": "This device can now verify other devices, granting them access to encrypted messages and marking them as trusted for other users.",
|
||||
"Verify other users in their profile.": "Verify other users in their profile.",
|
||||
"You can now verify your other devices, and other users to keep your chats safe.": "You can now verify your other devices, and other users to keep your chats safe.",
|
||||
"Upgrade your encryption": "Upgrade your encryption",
|
||||
"Recovery key": "Recovery key",
|
||||
"Keep it safe": "Keep it safe",
|
||||
"Storing secrets...": "Storing secrets...",
|
||||
"Encryption upgraded": "Encryption upgraded",
|
||||
"Encryption setup complete": "Encryption setup complete",
|
||||
"Make a copy of your recovery key": "Make a copy of your recovery key",
|
||||
"You're done!": "You're done!",
|
||||
"Unable to set up secret storage": "Unable to set up secret storage",
|
||||
"Retry": "Retry",
|
||||
"We'll store an encrypted copy of your keys on our server. Protect your backup with a passphrase to keep it secure.": "We'll store an encrypted copy of your keys on our server. Protect your backup with a passphrase to keep it secure.",
|
||||
"For maximum security, this should be different from your account password.": "For maximum security, this should be different from your account password.",
|
||||
"Enter a passphrase...": "Enter a passphrase...",
|
||||
"Set up with a Recovery Key": "Set up with a Recovery Key",
|
||||
"Please enter your passphrase a second time to confirm.": "Please enter your passphrase a second time to confirm.",
|
||||
"Repeat your passphrase...": "Repeat your passphrase...",
|
||||
"As a safety net, you can use it to restore your encrypted message history if you forget your Recovery Passphrase.": "As a safety net, you can use it to restore your encrypted message history if you forget your Recovery Passphrase.",
|
||||
"As a safety net, you can use it to restore your encrypted message history.": "As a safety net, you can use it to restore your encrypted message history.",
|
||||
"Your keys are being backed up (the first backup could take a few minutes).": "Your keys are being backed up (the first backup could take a few minutes).",
|
||||
"Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another device.": "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another device.",
|
||||
"Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.",
|
||||
"Set up Secure Message Recovery": "Set up Secure Message Recovery",
|
||||
"Secure your backup with a passphrase": "Secure your backup with a passphrase",
|
||||
"Starting backup...": "Starting backup...",
|
||||
"Success!": "Success!",
|
||||
"Create Key Backup": "Create Key Backup",
|
||||
"Create key backup": "Create key backup",
|
||||
"Unable to create key backup": "Unable to create key backup",
|
||||
"Without setting up Secure Message Recovery, you'll lose your secure message history when you log out.": "Without setting up Secure Message Recovery, you'll lose your secure message history when you log out.",
|
||||
"If you don't want to set this up now, you can later in Settings.": "If you don't want to set this up now, you can later in Settings.",
|
||||
|
@ -2056,12 +2080,12 @@
|
|||
"New Recovery Method": "New Recovery Method",
|
||||
"A new recovery passphrase and key for Secure Messages have been detected.": "A new recovery passphrase and key for Secure Messages have been detected.",
|
||||
"If you didn't set the new recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "If you didn't set the new recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.",
|
||||
"This device is encrypting history using the new recovery method.": "This device is encrypting history using the new recovery method.",
|
||||
"This session is encrypting history using the new recovery method.": "This session is encrypting history using the new recovery method.",
|
||||
"Go to Settings": "Go to Settings",
|
||||
"Set up Secure Messages": "Set up Secure Messages",
|
||||
"Recovery Method Removed": "Recovery Method Removed",
|
||||
"This device has detected that your recovery passphrase and key for Secure Messages have been removed.": "This device has detected that your recovery passphrase and key for Secure Messages have been removed.",
|
||||
"If you did this accidentally, you can setup Secure Messages on this device which will re-encrypt this device's message history with a new recovery method.": "If you did this accidentally, you can setup Secure Messages on this device which will re-encrypt this device's message history with a new recovery method.",
|
||||
"This session has detected that your recovery passphrase and key for Secure Messages have been removed.": "This session has detected that your recovery passphrase and key for Secure Messages have been removed.",
|
||||
"If you did this accidentally, you can setup Secure Messages on this session which will re-encrypt this session's message history with a new recovery method.": "If you did this accidentally, you can setup Secure Messages on this session which will re-encrypt this session's message history with a new recovery method.",
|
||||
"If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.",
|
||||
"If disabled, messages from encrypted rooms won't appear in search results.": "If disabled, messages from encrypted rooms won't appear in search results.",
|
||||
"Disable": "Disable",
|
||||
|
@ -2071,6 +2095,8 @@
|
|||
"Space used:": "Space used:",
|
||||
"Indexed messages:": "Indexed messages:",
|
||||
"Number of rooms:": "Number of rooms:",
|
||||
"of ": "of ",
|
||||
"Message downloading sleep time(ms)": "Message downloading sleep time(ms)",
|
||||
"Failed to set direct chat tag": "Failed to set direct chat tag",
|
||||
"Failed to remove tag %(tagName)s from room": "Failed to remove tag %(tagName)s from room",
|
||||
"Failed to add tag %(tagName)s to room": "Failed to add tag %(tagName)s to room"
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
"%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s removed the room name.",
|
||||
"%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s changed the topic to \"%(topic)s\".",
|
||||
"Changes your display nickname": "Changes your display nickname",
|
||||
"Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.",
|
||||
"Claimed Ed25519 fingerprint key": "Claimed Ed25519 fingerprint key",
|
||||
"Click here to fix": "Click here to fix",
|
||||
"Click to mute audio": "Click to mute audio",
|
||||
|
@ -72,12 +71,8 @@
|
|||
"Deops user with given id": "Deops user with given id",
|
||||
"Default": "Default",
|
||||
"Delete widget": "Delete widget",
|
||||
"Device already verified!": "Device already verified!",
|
||||
"Device ID": "Device ID",
|
||||
"Device ID:": "Device ID:",
|
||||
"device id: ": "device id: ",
|
||||
"Device key:": "Device key:",
|
||||
"Devices": "Devices",
|
||||
"Direct chats": "Direct chats",
|
||||
"Disinvite": "Disinvite",
|
||||
"Displays action": "Displays action",
|
||||
|
@ -124,7 +119,6 @@
|
|||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s",
|
||||
"Guests cannot join this room even if explicitly invited.": "Guests cannot join this room even if explicitly invited.",
|
||||
"Hangup": "Hangup",
|
||||
"Hide Text Formatting Toolbar": "Hide Text Formatting Toolbar",
|
||||
"Historical": "Historical",
|
||||
"Homeserver is": "Homeserver is",
|
||||
"Identity Server is": "Identity Server is",
|
||||
|
@ -133,15 +127,12 @@
|
|||
"Import E2E room keys": "Import E2E room keys",
|
||||
"Incorrect username and/or password.": "Incorrect username and/or password.",
|
||||
"Incorrect verification code": "Incorrect verification code",
|
||||
"Invalid alias format": "Invalid alias format",
|
||||
"Invalid Email Address": "Invalid Email Address",
|
||||
"Invalid file%(extra)s": "Invalid file%(extra)s",
|
||||
"%(senderName)s invited %(targetName)s.": "%(senderName)s invited %(targetName)s.",
|
||||
"Invite new room members": "Invite new room members",
|
||||
"Invited": "Invited",
|
||||
"Invites": "Invites",
|
||||
"Invites user with given id to current room": "Invites user with given id to current room",
|
||||
"'%(alias)s' is not a valid format for an alias": "'%(alias)s' is not a valid format for an alias",
|
||||
"Sign in with": "Sign in with",
|
||||
"Join Room": "Join Room",
|
||||
"%(targetName)s joined the room.": "%(targetName)s joined the room.",
|
||||
|
@ -172,17 +163,11 @@
|
|||
"%(senderName)s made future room history visible to anyone.": "%(senderName)s made future room history visible to anyone.",
|
||||
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s made future room history visible to unknown (%(visibility)s).",
|
||||
"Manage Integrations": "Manage Integrations",
|
||||
"Markdown is disabled": "Markdown is disabled",
|
||||
"Markdown is enabled": "Markdown is enabled",
|
||||
"matrix-react-sdk version:": "matrix-react-sdk version:",
|
||||
"Message not sent due to unknown devices being present": "Message not sent due to unknown devices being present",
|
||||
"Missing room_id in request": "Missing room_id in request",
|
||||
"Missing user_id in request": "Missing user_id in request",
|
||||
"Moderator": "Moderator",
|
||||
"Mute": "Mute",
|
||||
"Name": "Name",
|
||||
"Never send encrypted messages to unverified devices from this device": "Never send encrypted messages to unverified devices from this device",
|
||||
"Never send encrypted messages to unverified devices in this room from this device": "Never send encrypted messages to unverified devices in this room from this device",
|
||||
"New address (e.g. #foo:%(localDomain)s)": "New address (e.g. #foo:%(localDomain)s)",
|
||||
"New passwords don't match": "New passwords don't match",
|
||||
"New passwords must match each other.": "New passwords must match each other.",
|
||||
|
@ -192,7 +177,6 @@
|
|||
"(not supported by this browser)": "(not supported by this browser)",
|
||||
"<not supported>": "<not supported>",
|
||||
"NOT verified": "NOT verified",
|
||||
"No devices with registered encryption keys": "No devices with registered encryption keys",
|
||||
"No more results": "No more results",
|
||||
"No results": "No results",
|
||||
"No users have specific privileges in this room": "No users have specific privileges in this room",
|
||||
|
@ -202,7 +186,6 @@
|
|||
"Operation failed": "Operation failed",
|
||||
"Password": "Password",
|
||||
"Passwords can't be empty": "Passwords can't be empty",
|
||||
"People": "People",
|
||||
"Permissions": "Permissions",
|
||||
"Phone": "Phone",
|
||||
"Please check your email and click on the link it contains. Once this is done, click continue.": "Please check your email and click on the link it contains. Once this is done, click continue.",
|
||||
|
@ -233,8 +216,6 @@
|
|||
"Search": "Search",
|
||||
"Search failed": "Search failed",
|
||||
"Searches DuckDuckGo for results": "Searches DuckDuckGo for results",
|
||||
"Sender device information": "Sender device information",
|
||||
"Send Invites": "Send Invites",
|
||||
"Send Reset Email": "Send Reset Email",
|
||||
"%(senderDisplayName)s sent an image.": "%(senderDisplayName)s sent an image.",
|
||||
"%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.",
|
||||
|
@ -253,10 +234,8 @@
|
|||
"%(count)s of your messages have not been sent.|other": "Some of your messages have not been sent.",
|
||||
"Someone": "Someone",
|
||||
"Start a chat": "Start a chat",
|
||||
"Start Chat": "Start Chat",
|
||||
"Submit": "Submit",
|
||||
"Success": "Success",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.",
|
||||
"This email address is already in use": "This email address is already in use",
|
||||
"This email address was not found": "This email address was not found",
|
||||
"The email address linked to your account must be entered.": "The email address linked to your account must be entered.",
|
||||
|
@ -269,7 +248,6 @@
|
|||
"To use it, just wait for autocomplete results to load and tab through them.": "To use it, just wait for autocomplete results to load and tab through them.",
|
||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.",
|
||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.",
|
||||
"%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).",
|
||||
"Unable to add email address": "Unable to add email address",
|
||||
"Unable to remove contact information": "Unable to remove contact information",
|
||||
"Unable to verify email address.": "Unable to verify email address.",
|
||||
|
@ -277,14 +255,11 @@
|
|||
"%(senderName)s unbanned %(targetName)s.": "%(senderName)s unbanned %(targetName)s.",
|
||||
"Unable to capture screen": "Unable to capture screen",
|
||||
"Unable to enable Notifications": "Unable to enable Notifications",
|
||||
"Unable to load device list": "Unable to load device list",
|
||||
"unencrypted": "unencrypted",
|
||||
"unknown device": "unknown device",
|
||||
"unknown error code": "unknown error code",
|
||||
"Unknown room %(roomId)s": "Unknown room %(roomId)s",
|
||||
"Unknown (user, device) pair:": "Unknown (user, device) pair:",
|
||||
"Unmute": "Unmute",
|
||||
"Unrecognised command:": "Unrecognized command:",
|
||||
"Unrecognised room alias:": "Unrecognized room alias:",
|
||||
"Upload avatar": "Upload avatar",
|
||||
"Upload Failed": "Upload Failed",
|
||||
|
@ -306,11 +281,8 @@
|
|||
"(no answer)": "(no answer)",
|
||||
"(unknown failure: %(reason)s)": "(unknown failure: %(reason)s)",
|
||||
"Warning!": "Warning!",
|
||||
"WARNING: Device already verified, but keys do NOT MATCH!": "WARNING: Device already verified, but keys do NOT MATCH!",
|
||||
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!",
|
||||
"Who can access this room?": "Who can access this room?",
|
||||
"Who can read history?": "Who can read history?",
|
||||
"Who would you like to communicate with?": "Who would you like to communicate with?",
|
||||
"%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s withdrew %(targetName)s's invitation.",
|
||||
"You are already in a call.": "You are already in a call.",
|
||||
"You cannot place a call with yourself.": "You cannot place a call with yourself.",
|
||||
|
@ -322,7 +294,6 @@
|
|||
"You need to be able to invite users to do that.": "You need to be able to invite users to do that.",
|
||||
"You need to be logged in.": "You need to be logged in.",
|
||||
"Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Your email address does not appear to be associated with a Matrix ID on this Homeserver.",
|
||||
"Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them",
|
||||
"You seem to be in a call, are you sure you want to quit?": "You seem to be in a call, are you sure you want to quit?",
|
||||
"You seem to be uploading files, are you sure you want to quit?": "You seem to be uploading files, are you sure you want to quit?",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.",
|
||||
|
@ -359,8 +330,6 @@
|
|||
"Sent messages will be stored until your connection has returned.": "Sent messages will be stored until your connection has returned.",
|
||||
"Cancel": "Cancel",
|
||||
"Active call": "Active call",
|
||||
"bold": "bold",
|
||||
"italic": "italic",
|
||||
"Please select the destination room for this message": "Please select the destination room for this message",
|
||||
"Start automatically after system login": "Start automatically after system login",
|
||||
"Analytics": "Analytics",
|
||||
|
@ -387,18 +356,9 @@
|
|||
"Unknown error": "Unknown error",
|
||||
"Incorrect password": "Incorrect password",
|
||||
"To continue, please enter your password.": "To continue, please enter your password.",
|
||||
"To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:",
|
||||
"Device name": "Device name",
|
||||
"Device key": "Device key",
|
||||
"If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.",
|
||||
"Verify device": "Verify device",
|
||||
"I verify that the keys match": "I verify that the keys match",
|
||||
"Unable to restore session": "Unable to restore session",
|
||||
"If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.",
|
||||
"You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "You are currently blacklisting unverified devices; to send messages to these devices you must verify them.",
|
||||
"We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.",
|
||||
"\"%(RoomName)s\" contains devices that you haven't seen before.": "\"%(RoomName)s\" contains devices that you haven't seen before.",
|
||||
"Unknown devices": "Unknown devices",
|
||||
"Unknown Address": "Unknown Address",
|
||||
"Unblacklist": "Unblacklist",
|
||||
"Blacklist": "Blacklist",
|
||||
|
@ -444,7 +404,6 @@
|
|||
"Room directory": "Room directory",
|
||||
"Start chat": "Start chat",
|
||||
"Drop File Here": "Drop File Here",
|
||||
"Encrypted by an unverified device": "Encrypted by an unverified device",
|
||||
"Error: Problem communicating with the given homeserver.": "Error: Problem communicating with the given homeserver.",
|
||||
"Failed to fetch avatar URL": "Failed to fetch avatar URL",
|
||||
"Failed to upload profile picture!": "Failed to upload profile picture!",
|
||||
|
@ -457,17 +416,13 @@
|
|||
"No display name": "No display name",
|
||||
"Private Chat": "Private Chat",
|
||||
"Public Chat": "Public Chat",
|
||||
"Room contains unknown devices": "Room contains unknown devices",
|
||||
"%(roomName)s does not exist.": "%(roomName)s does not exist.",
|
||||
"%(roomName)s is not accessible at this time.": "%(roomName)s is not accessible at this time.",
|
||||
"Seen by %(userName)s at %(dateTime)s": "Seen by %(userName)s at %(dateTime)s",
|
||||
"Send anyway": "Send anyway",
|
||||
"Show Text Formatting Toolbar": "Show Text Formatting Toolbar",
|
||||
"Start authentication": "Start authentication",
|
||||
"The phone number entered looks invalid": "The phone number entered looks invalid",
|
||||
"This room": "This room",
|
||||
"Undecryptable": "Undecryptable",
|
||||
"Unencrypted message": "Unencrypted message",
|
||||
"unknown caller": "unknown caller",
|
||||
"Unnamed Room": "Unnamed Room",
|
||||
"Uploading %(filename)s and %(count)s others|zero": "Uploading %(filename)s",
|
||||
|
@ -494,8 +449,6 @@
|
|||
"Start verification": "Start verification",
|
||||
"Share without verifying": "Share without verifying",
|
||||
"Ignore request": "Ignore request",
|
||||
"You added a new device '%(displayName)s', which is requesting encryption keys.": "You added a new device '%(displayName)s', which is requesting encryption keys.",
|
||||
"Your unverified device '%(displayName)s' is requesting encryption keys.": "Your unverified device '%(displayName)s' is requesting encryption keys.",
|
||||
"Encryption key request": "Encryption key request",
|
||||
"Check for update": "Check for update",
|
||||
"Allow": "Allow",
|
||||
|
@ -508,7 +461,6 @@
|
|||
"Unable to create widget.": "Unable to create widget.",
|
||||
"You are not in this room.": "You are not in this room.",
|
||||
"You do not have permission to do that in this room.": "You do not have permission to do that in this room.",
|
||||
"Loading device info...": "Loading device info...",
|
||||
"Message removed by %(userId)s": "Message removed by %(userId)s",
|
||||
"Example": "Example",
|
||||
"Create": "Create",
|
||||
|
@ -519,7 +471,6 @@
|
|||
"Failed to upload image": "Failed to upload image",
|
||||
"%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s",
|
||||
"%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s",
|
||||
"Verifies a user, device, and pubkey tuple": "Verifies a user, device, and pubkey tuple",
|
||||
"%(senderName)s changed the pinned messages for the room.": "%(senderName)s changed the pinned messages for the room.",
|
||||
"Fetching third party location failed": "Fetching third party location failed",
|
||||
"A new version of Riot is available.": "A new version of Riot is available.",
|
||||
|
@ -568,7 +519,6 @@
|
|||
"Files": "Files",
|
||||
"Collecting app version information": "Collecting app version information",
|
||||
"Delete the room alias %(alias)s and remove %(name)s from the directory?": "Delete the room alias %(alias)s and remove %(name)s from the directory?",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "This will allow you to return to your account after signing out, and sign in on other devices.",
|
||||
"Keywords": "Keywords",
|
||||
"Unpin Message": "Unpin Message",
|
||||
"Enable notifications for this account": "Enable notifications for this account",
|
||||
|
@ -653,7 +603,6 @@
|
|||
"The information being sent to us to help make Riot.im better includes:": "The information being sent to us to help make Riot.im better includes:",
|
||||
"Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.",
|
||||
"Call Failed": "Call Failed",
|
||||
"There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.",
|
||||
"Review Devices": "Review Devices",
|
||||
"Call Anyway": "Call Anyway",
|
||||
"Answer Anyway": "Answer Anyway",
|
||||
|
@ -701,15 +650,9 @@
|
|||
"The server does not support the room version specified.": "The server does not support the room version specified.",
|
||||
"Name or Matrix ID": "Name or Matrix ID",
|
||||
"Unable to load! Check your network connectivity and try again.": "Unable to load! Check your network connectivity and try again.",
|
||||
"Email, name or Matrix ID": "Email, name or Matrix ID",
|
||||
"Failed to invite users to the room:": "Failed to invite users to the room:",
|
||||
"Upgrades a room to a new version": "Upgrades a room to a new version",
|
||||
"Room upgrade confirmation": "Room upgrade confirmation",
|
||||
"Upgrading a room can be destructive and isn't always necessary.": "Upgrading a room can be destructive and isn't always necessary.",
|
||||
"Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.",
|
||||
"Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.": "Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.",
|
||||
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.",
|
||||
"Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />.": "Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />.",
|
||||
"Changes your display nickname in the current room only": "Changes your display nickname in the current room only",
|
||||
"Changes your avatar in this current room only": "Changes your avatar in this current room only",
|
||||
"Gets or sets the room topic": "Gets or sets the room topic",
|
||||
|
@ -743,7 +686,6 @@
|
|||
"Call failed due to misconfigured server": "Call failed due to misconfigured server",
|
||||
"Please ask the administrator of your homeserver (<code>%(homeserverDomain)s</code>) to configure a TURN server in order for calls to work reliably.": "Please ask the administrator of your homeserver (<code>%(homeserverDomain)s</code>) to configure a TURN server in order for calls to work reliably.",
|
||||
"Try using turn.matrix.org": "Try using turn.matrix.org",
|
||||
"Failed to start chat": "Failed to start chat",
|
||||
"Messages": "Messages",
|
||||
"Actions": "Actions",
|
||||
"Other": "Other"
|
||||
|
|
|
@ -62,10 +62,6 @@
|
|||
"Moderator": "Ĉambrestro",
|
||||
"Admin": "Administranto",
|
||||
"Start a chat": "Komenci babilon",
|
||||
"Who would you like to communicate with?": "Kun kiu vi volas komuniki?",
|
||||
"Start Chat": "Komenci babilon",
|
||||
"Invite new room members": "Inviti novajn ĉambranojn",
|
||||
"Send Invites": "Sendi invitojn",
|
||||
"Operation failed": "Ago malsukcesis",
|
||||
"Failed to invite": "Invito malsukcesis",
|
||||
"Failed to invite the following users to the %(roomName)s room:": "Malsukcesis inviti la jenajn uzantojn al la ĉambro %(roomName)s:",
|
||||
|
@ -88,13 +84,7 @@
|
|||
"You are now ignoring %(userId)s": "Vi nun malatentas uzanton %(userId)s",
|
||||
"Unignored user": "Reatentata uzanto",
|
||||
"You are no longer ignoring %(userId)s": "Vi nun reatentas uzanton %(userId)s",
|
||||
"Unknown (user, device) pair:": "Nekonata duopo (uzanto, aparato):",
|
||||
"Device already verified!": "Aparato jam kontroliĝis!",
|
||||
"WARNING: Device already verified, but keys do NOT MATCH!": "AVERTO: Aparato jam kontroliĝis, sed la ŝlosiloj NE KONGRUAS!",
|
||||
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "AVERTO: KONTROLO DE ŜLOSILO MALSUKCESIS! Subskriba ŝlosilo por %(userId)s kaj aparato%(deviceId)s estas « %(fprint)s », kiu ne kongruas kun la donita ŝlosilo « %(fingerprint)s ». Eble do via komuniko estas subaŭskultata!",
|
||||
"Verified key": "Kontrolita ŝlosilo",
|
||||
"The signing key you provided matches the signing key you received from %(userId)s's device %(deviceId)s. Device marked as verified.": "La donita subskriba ŝlosilo kongruas kun la ŝlosilo ricevita de %(userId)s por ĝia aparato %(deviceId)s. Aparato markita kiel kontrolita.",
|
||||
"Unrecognised command:": "Nerekonita komando:",
|
||||
"Reason": "Kialo",
|
||||
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s akceptis la inviton por %(displayName)s.",
|
||||
"%(targetName)s accepted an invitation.": "%(targetName)s akceptis inviton.",
|
||||
|
@ -131,7 +121,6 @@
|
|||
"%(senderName)s made future room history visible to all room members.": "%(senderName)s videbligis estontan historion de la ĉambro al ĉiuj ĉambranoj.",
|
||||
"%(senderName)s made future room history visible to anyone.": "%(senderName)s videbligis estontan historion de la ĉambro al ĉiuj.",
|
||||
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s videbligis estontan historion de la ĉambro al nekonata (%(visibility)s).",
|
||||
"%(senderName)s turned on end-to-end encryption (algorithm %(algorithm)s).": "%(senderName)s ŝaltis ĝiscelan ĉifradon (algoritmo: %(algorithm)s).",
|
||||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s al %(toPowerLevel)s",
|
||||
"%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s ŝanĝis la potencan nivelon de %(powerLevelDiffText)s.",
|
||||
"%(senderName)s changed the pinned messages for the room.": "%(senderName)s ŝanĝis la fiksitajn mesaĝojn de la ĉambro.",
|
||||
|
@ -151,7 +140,6 @@
|
|||
"Always show message timestamps": "Ĉiam montri mesaĝajn tempindikojn",
|
||||
"Autoplay GIFs and videos": "Memfare ludi GIF-bildojn kaj filmojn",
|
||||
"Call Failed": "Voko malsukcesis",
|
||||
"There are unknown devices in this room: if you proceed without verifying them, it will be possible for someone to eavesdrop on your call.": "En la ĉambro estas nekonataj aparatoj: se vi daŭrigos ne kontrolante ilin, iu povos subaŭskulti vian vokon.",
|
||||
"Review Devices": "Kontroli aparatojn",
|
||||
"Call Anyway": "Tamen voki",
|
||||
"Answer Anyway": "Tamen respondi",
|
||||
|
@ -162,8 +150,6 @@
|
|||
"Enable automatic language detection for syntax highlighting": "Ŝalti memagan rekonon de lingvo por sintaksa markado",
|
||||
"Automatically replace plain text Emoji": "Memfare anstataŭigi tekstajn mienetojn",
|
||||
"Mirror local video feed": "Speguli lokan filmon",
|
||||
"Never send encrypted messages to unverified devices from this device": "Neniam sendi neĉifritajn mesaĝojn al nekontrolitaj aparatoj de tiu ĉi aparato",
|
||||
"Never send encrypted messages to unverified devices in this room from this device": "Neniam sendi ĉifritajn mesaĝojn al nekontrolitaj aparatoj en tiu ĉi ĉambro el tiu ĉi aparato",
|
||||
"Enable inline URL previews by default": "Ŝalti entekstan antaŭrigardon al retadresoj",
|
||||
"Enable URL previews for this room (only affects you)": "Ŝalti URL-antaŭrigardon en ĉi tiu ĉambro (nur por vi)",
|
||||
"Enable URL previews by default for participants in this room": "Ŝalti URL-antaŭrigardon por anoj de ĉi tiu ĉambro",
|
||||
|
@ -193,10 +179,7 @@
|
|||
"New Password": "Nova pasvorto",
|
||||
"Confirm password": "Konfirmi pasvorton",
|
||||
"Change Password": "Ŝanĝi pasvorton",
|
||||
"Unable to load device list": "Listo de aparatoj ne legeblas",
|
||||
"Authentication": "Aŭtentigo",
|
||||
"Delete %(count)s devices|other": "Forigi %(count)s aparatojn",
|
||||
"Delete %(count)s devices|one": "Forigi aparaton",
|
||||
"Device ID": "Aparata identigilo",
|
||||
"Last seen": "Laste vidita",
|
||||
"Failed to set display name": "Malsukcesis agordi vidigan nomon",
|
||||
|
@ -214,9 +197,6 @@
|
|||
"%(senderName)s sent a video": "%(senderName)s sendis filmon",
|
||||
"%(senderName)s uploaded a file": "%(senderName)s alŝutis dosieron",
|
||||
"Options": "Agordoj",
|
||||
"Undecryptable": "Nemalĉifrebla",
|
||||
"Encrypted by an unverified device": "Ĉifrita de nekontrolita aparato",
|
||||
"Unencrypted message": "Neĉifrita mesaĝo",
|
||||
"Please select the destination room for this message": "Bonvolu elekti celan ĉambron por tiu mesaĝo",
|
||||
"Blacklisted": "Senpova legi ĉifritajn mesaĝojn",
|
||||
"device id: ": "aparata identigilo: ",
|
||||
|
@ -235,11 +215,8 @@
|
|||
"Failed to change power level": "Malsukcesis ŝanĝi nivelon de potenco",
|
||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Tiun ĉi ŝanĝon vi ne povos fareblos, ĉar vi donas al la uzanto la saman nivelon de potenco, kiun havas vi mem.",
|
||||
"Are you sure?": "Ĉu vi certas?",
|
||||
"No devices with registered encryption keys": "Neniuj aparatoj kun registritaj ĉifraj ŝlosiloj",
|
||||
"Devices": "Aparatoj",
|
||||
"Unignore": "Reatenti",
|
||||
"Ignore": "Malatenti",
|
||||
"Changing password will currently reset any end-to-end encryption keys on all devices, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Ŝanĝo de pasvorto nuntempe nuligos ĉiujn ĝiscele ĉifrajn ŝlosilojn sur ĉiuj viaj aparatoj. Tio igos ĉifritajn babilajn historiojn nelegeblaj, krom se vi unue elportos viajn ĉambrajn ŝlosilojn kaj reenportos ilin poste. Estonte tio pliboniĝos.",
|
||||
"%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s ŝanĝis la profilbildon de %(roomName)s",
|
||||
"You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Vi estas direktota al ekstera retejo por aŭtentigi vian konton por uzo kun %(integrationsUrl)s. Ĉu vi volas daŭrigi tion?",
|
||||
"Jump to read receipt": "Salti al legokonfirmo",
|
||||
|
@ -262,16 +239,10 @@
|
|||
"Voice call": "Voĉvoko",
|
||||
"Video call": "Vidvoko",
|
||||
"Upload file": "Alŝuti dosieron",
|
||||
"Show Text Formatting Toolbar": "Montri tekstaranĝan breton",
|
||||
"You do not have permission to post to this room": "Mankas al vi permeso afiŝi en tiu ĉambro",
|
||||
"Hide Text Formatting Toolbar": "Kaŝi tekstaranĝan breton",
|
||||
"Server error": "Servila eraro",
|
||||
"Server unavailable, overloaded, or something else went wrong.": "Servilo estas neatingebla, troŝarĝita, aŭ io alia misokazis.",
|
||||
"Command error": "Komanda eraro",
|
||||
"bold": "grasa",
|
||||
"italic": "kursiva",
|
||||
"Markdown is disabled": "Marksubo estas malŝaltita",
|
||||
"Markdown is enabled": "Marksubo estas ŝaltita",
|
||||
"Unpin Message": "Malfiksi mesaĝon",
|
||||
"Jump to message": "Salti al mesaĝo",
|
||||
"No pinned messages.": "Neniuj fiksitaj mesaĝoj.",
|
||||
|
@ -305,7 +276,6 @@
|
|||
"Community Invites": "Komunumaj invitoj",
|
||||
"Invites": "Invitoj",
|
||||
"Favourites": "Ŝatataj",
|
||||
"People": "Homoj",
|
||||
"Rooms": "Ĉambroj",
|
||||
"Low priority": "Malpli gravaj",
|
||||
"Historical": "Estintaj",
|
||||
|
@ -340,8 +310,6 @@
|
|||
"Cancel": "Nuligi",
|
||||
"Jump to first unread message.": "Salti al unua nelegita mesaĝo.",
|
||||
"Close": "Fermi",
|
||||
"Invalid alias format": "Malvalida formo de kromnomo",
|
||||
"'%(alias)s' is not a valid format for an alias": "'%(alias)s' ne estas valida formo de kromnomo",
|
||||
"not specified": "nespecifita",
|
||||
"Remote addresses for this room:": "Foraj adresoj de ĉi tiu ĉambro:",
|
||||
"Local addresses for this room:": "Lokaj adresoj por ĉi tiu ĉambro:",
|
||||
|
@ -502,20 +470,12 @@
|
|||
"Unknown error": "Nekonata eraro",
|
||||
"Incorrect password": "Malĝusta pasvorto",
|
||||
"Deactivate Account": "Malaktivigi konton",
|
||||
"To verify that this device can be trusted, please contact its owner using some other means (e.g. in person or a phone call) and ask them whether the key they see in their User Settings for this device matches the key below:": "Por kontroli ke tiu ĉi aparato estas fidinda, bonvolu kontakti ties posedanton per alia maniero (ekz-e persone aŭ telefone) kaj demandi ĝin ĉu la ŝlosilo, kiun ĝi vidas en agordoj de uzanto ĉe si, kongruas kun la ĉi-suba ŝlosilo:",
|
||||
"Device name": "Aparata nomo",
|
||||
"Device key": "Aparata ŝlosilo",
|
||||
"If it matches, press the verify button below. If it doesn't, then someone else is intercepting this device and you probably want to press the blacklist button instead.": "Se ĝi kongruas, premu la kontrolan butonon sube. Se ne, tiuokaze iu alia interkaptas ĉi tiun aparaton, kaj eble vi premu la malpermesan butonon anstataŭe.",
|
||||
"Verify device": "Kontroli aparaton",
|
||||
"I verify that the keys match": "Mi kontrolas, ke la ŝlosiloj kongruas",
|
||||
"An error has occurred.": "Okazis eraro.",
|
||||
"OK": "Bone",
|
||||
"You added a new device '%(displayName)s', which is requesting encryption keys.": "Vi aldonis novan aparaton “%(displayName)s”, kiu petas ĉifrajn ŝlosilojn.",
|
||||
"Your unverified device '%(displayName)s' is requesting encryption keys.": "Via nekontrolita aparato '%(displayName)s' petas ĉifrajn ŝlosilojn.",
|
||||
"Start verification": "Komenci kontrolon",
|
||||
"Share without verifying": "Kunhavigi sen kontrolo",
|
||||
"Ignore request": "Malatenti peton",
|
||||
"Loading device info...": "Enleganta informojn pri aparato…",
|
||||
"Encryption key request": "Peto por ĉifra ŝlosilo",
|
||||
"Unable to restore session": "Seanco ne restaŭreblas",
|
||||
"If you have previously used a more recent version of Riot, your session may be incompatible with this version. Close this window and return to the more recent version.": "Se vi antaŭe uzis pli novan version de Riot, via seanco eble ne kongruos kun ĉi tiu versio. Fermu ĉi tiun fenestron kaj revenu al la pli nova versio.",
|
||||
|
@ -532,11 +492,6 @@
|
|||
"Blacklist": "Malpermesi legadon de ĉifritaj mesaĝoj",
|
||||
"Unverify": "Malkontroli",
|
||||
"If you already have a Matrix account you can <a>log in</a> instead.": "Se vi jam havas Matrix-konton, vi povas <a>saluti</a> anstataŭe.",
|
||||
"You are currently blacklisting unverified devices; to send messages to these devices you must verify them.": "Vi nun malpermesas legadon de ĉifritaj mesaĝoj al nekontrolitaj aparatoj; por sendi mesaĝojn al tiuj, vi devas ilin kontroli.",
|
||||
"We recommend you go through the verification process for each device to confirm they belong to their legitimate owner, but you can resend the message without verifying if you prefer.": "Ni rekomendas al vi bone kontroli ĉiun aparaton por certigi, ke ĝi apartenas al la verŝajna posedanto, sed vi povas resendi la mesaĝon sen kontrolo, laŭprefere.",
|
||||
"Room contains unknown devices": "Ĉambro enhavas nekonatajn aparatojn",
|
||||
"\"%(RoomName)s\" contains devices that you haven't seen before.": "« %(RoomName)s » enhavas aparatojn, kiujn vi neniam vidis antaŭe.",
|
||||
"Unknown devices": "Nekonataj aparatoj",
|
||||
"Private Chat": "Privata babilo",
|
||||
"Public Chat": "Publika babilo",
|
||||
"Custom": "Propra",
|
||||
|
@ -592,7 +547,6 @@
|
|||
"Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Kreu komunumon por kunigi uzantojn kaj ĉambrojn! Fari propran hejmpaĝon por montri vian spacon en la universo de Matrix.",
|
||||
"You have no visible notifications": "Neniuj videblaj sciigoj",
|
||||
"Scroll to bottom of page": "Rulumi al susbo de la paĝo",
|
||||
"Message not sent due to unknown devices being present": "Mesaĝo ne sendita pro ĉeesto de nekonataj aparatoj",
|
||||
"Connectivity to the server has been lost.": "Konekto al la servilo perdiĝis.",
|
||||
"Sent messages will be stored until your connection has returned.": "Senditaj mesaĝoj konserviĝos ĝis via konekto refunkcios.",
|
||||
"Active call": "Aktiva voko",
|
||||
|
@ -620,13 +574,10 @@
|
|||
"Dark theme": "Malhela haŭto",
|
||||
"Sign out": "Adiaŭi",
|
||||
"Success": "Sukceso",
|
||||
"Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Via pasvorto sukcese ŝanĝiĝis. Vi ne ricevos puŝatentigojn je aliaj aparatoj ĝis tiam, kiam vi resalutos per ili",
|
||||
"Unable to remove contact information": "Kontaktaj informoj ne forigeblas",
|
||||
"<not supported>": "<nesubtenata>",
|
||||
"Import E2E room keys": "Enporti ĝiscele ĉifrajn ĉambrajn ŝlosilojn",
|
||||
"Cryptography": "Kriptografio",
|
||||
"Device ID:": "Aparata identigilo:",
|
||||
"Device key:": "Aparata ŝlosilo:",
|
||||
"Analytics": "Analizo",
|
||||
"Riot collects anonymous analytics to allow us to improve the application.": "Riot kolektas sennomaj analizajn datumojn por helpi plibonigadon de la programo.",
|
||||
"Labs": "Eksperimentaj funkcioj",
|
||||
|
@ -648,7 +599,6 @@
|
|||
"click to reveal": "klaku por malkovri",
|
||||
"Homeserver is": "Hejmservilo estas",
|
||||
"Identity Server is": "Identiga servilo estas",
|
||||
"matrix-react-sdk version:": "versio de matrix-react-sdk:",
|
||||
"riot-web version:": "versio de riot-web:",
|
||||
"olm version:": "versio de olm:",
|
||||
"Failed to send email": "Malsukcesis sendi retleteron",
|
||||
|
@ -678,7 +628,6 @@
|
|||
"Kicks user with given id": "Forpelas uzanton kun la donita identigilo",
|
||||
"Changes your display nickname": "Ŝanĝas vian vidigan nomon",
|
||||
"Searches DuckDuckGo for results": "Serĉas rezultojn per DuckDuckGo",
|
||||
"Verifies a user, device, and pubkey tuple": "Kontrolas opon de uzanto, aparato, kaj publika ŝlosilo",
|
||||
"Ignores a user, hiding their messages from you": "Malatentas uzanton, kaŝante ĝiajn mesaĝojn de vi",
|
||||
"Stops ignoring a user, showing their messages going forward": "Ĉesas malatenti uzanton, montronte ĝiajn pluajn mesaĝojn",
|
||||
"Commands": "Komandoj",
|
||||
|
@ -701,7 +650,6 @@
|
|||
"Session ID": "Seanca identigilo",
|
||||
"End-to-end encryption information": "Informoj pri tutvoja ĉifrado",
|
||||
"Event information": "Informoj pri okazaĵo",
|
||||
"Sender device information": "Informoj pri aparato de sendinto",
|
||||
"Passphrases must match": "Pasfrazoj devas kongrui",
|
||||
"Passphrase must not be empty": "Pasfrazoj maldevas esti malplenaj",
|
||||
"Export room keys": "Elporti ĉambrajn ŝlosilojn",
|
||||
|
@ -785,7 +733,6 @@
|
|||
"Resend": "Resendi",
|
||||
"Collecting app version information": "Kolektanta informon pri versio de la aplikaĵo",
|
||||
"Delete the room alias %(alias)s and remove %(name)s from the directory?": "Ĉu forigi la ĉambran kromnomon %(alias)s kaj forigi %(name)s de la ujo?",
|
||||
"This will allow you to return to your account after signing out, and sign in on other devices.": "Ĉi tio permesos al vi reveni al via konto post adiaŭo, kaj saluti kun aliaj aparatoj.",
|
||||
"Enable notifications for this account": "Ŝalti sciigojn por tiu ĉi konto",
|
||||
"Invite to this community": "Inviti al tiu ĉi komunumo",
|
||||
"Messages containing <span>keywords</span>": "Mesaĝoj enhavantaj <span>ŝlosilovortojn</span>",
|
||||
|
@ -879,8 +826,6 @@
|
|||
"Always show encryption icons": "Ĉiam montri bildetojn de ĉifrado",
|
||||
"Send analytics data": "Sendi statistikajn datumojn",
|
||||
"Key request sent.": "Demando de ŝlosilo sendita.",
|
||||
"<requestLink>Re-request encryption keys</requestLink> from your other devices.": "<requestLink>Redemandi ĉifroŝlosilojn</requestLink> el viaj aliaj aparatoj.",
|
||||
"If your other devices do not have the key for this message you will not be able to decrypt them.": "Se viaj aliaj aparatoj ne havas la ŝlosilon por ĉi tiu mesaĝo, vi ne povos malĉifri ĝin.",
|
||||
"Permission Required": "Necesas permeso",
|
||||
"Registration Required": "Necesas registriĝo",
|
||||
"You need to register to do this. Would you like to register now?": "Por fari ĉi tion, vi bezonas registriĝi. Ĉu vi volas registriĝi nun?",
|
||||
|
@ -938,10 +883,8 @@
|
|||
"Language and region": "Lingvo kaj regiono",
|
||||
"Theme": "Haŭto",
|
||||
"General": "Ĝenerala",
|
||||
"Unable to reply": "Ne eblas respondi",
|
||||
"<a>In reply to</a> <pill>": "<a>Respondanta al</a> <pill>",
|
||||
"Share Message": "Diskonigi",
|
||||
"<showDevicesText>Show devices</showDevicesText>, <sendAnywayText>send anyway</sendAnywayText> or <cancelText>cancel</cancelText>.": "<showDevicesText>Montri aparatojn</showDevicesText>, <sendAnywayText>tamen sendi</sendAnywayText> aŭ <cancelText>nuligi</cancelText>.",
|
||||
"Whether or not you're logged in (we don't record your username)": "Ĉu vi salutis aŭ ne (ni ne registras vian uzantonomon)",
|
||||
"You do not have permission to start a conference call in this room": "Vi ne havas permeson komenci grupvokon en ĉi tiu ĉambro",
|
||||
"The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "La dosiero '%(fileName)s' superas la grandecan limon de ĉi tiu hejmservilo",
|
||||
|
@ -991,7 +934,6 @@
|
|||
"Book": "Libro",
|
||||
"Pencil": "Grifelo",
|
||||
"Scissors": "Tondilo",
|
||||
"Padlock": "Penda seruro",
|
||||
"Key": "Ŝlosilo",
|
||||
"Hammer": "Martelo",
|
||||
"Telephone": "Telefono",
|
||||
|
@ -1013,7 +955,6 @@
|
|||
"Email Address": "Retpoŝtadreso",
|
||||
"Phone Number": "Telefonnumero",
|
||||
"Profile picture": "Profilbildo",
|
||||
"Upload profile picture": "Alŝuti profilbildon",
|
||||
"<a>Upgrade</a> to your own domain": "<a>Ĝisdatigi</a> al via propra domajno",
|
||||
"Display Name": "Vidiga nomo",
|
||||
"Set a new account password...": "Agordi novan kontan pasvorton...",
|
||||
|
@ -1060,12 +1001,6 @@
|
|||
"Roles & Permissions": "Roloj & Permesoj",
|
||||
"Enable encryption?": "Ĉu ŝalti ĉifradon?",
|
||||
"Share Link to User": "Kunhavigi ligilon al uzanto",
|
||||
"deleted": "forigita",
|
||||
"underlined": "substrekita",
|
||||
"inline-code": "enteksta-kodo",
|
||||
"block-quote": "blokcito",
|
||||
"bulleted-list": "bula-listo",
|
||||
"numbered-list": "numerita-listo",
|
||||
"Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Vidita de %(displayName)s (%(userName)s) je %(dateTime)s",
|
||||
"Share room": "Kunhavigi ĉambron",
|
||||
"System Alerts": "Sistemaj avertoj",
|
||||
|
@ -1073,8 +1008,6 @@
|
|||
"Don't ask me again": "Ne demandu min denove",
|
||||
"Main address": "Ĉefa adreso",
|
||||
"Room avatar": "Profilbildo de ĉambro",
|
||||
"Upload room avatar": "Alŝuti profilbildon de ĉambro",
|
||||
"No room avatar": "Neniu profilbildo de ĉambro",
|
||||
"Room Name": "Nomo de ĉambro",
|
||||
"Room Topic": "Temo de ĉambro",
|
||||
"Yes, I want to help!": "Jes. Mi volas helpi!",
|
||||
|
@ -1150,14 +1083,8 @@
|
|||
"The file '%(fileName)s' failed to upload.": "Malsukcesis alŝuti dosieron « %(fileName)s ».",
|
||||
"The server does not support the room version specified.": "La servilo ne subtenas la donitan ĉambran version.",
|
||||
"Name or Matrix ID": "Nomo aŭ Matrix-identigilo",
|
||||
"Email, name or Matrix ID": "Retpoŝtadreso, nomo, aŭ Matrix-identigilo",
|
||||
"Upgrades a room to a new version": "Gradaltigas ĉambron al nova versio",
|
||||
"Room upgrade confirmation": "Konfirmo de ĉambra gradaltigo",
|
||||
"Upgrading a room can be destructive and isn't always necessary.": "Gradaltigo de ĉambro povas esti detrua kaj ne estas ĉiam necesa.",
|
||||
"Room upgrades are usually recommended when a room version is considered <i>unstable</i>. Unstable room versions might have bugs, missing features, or security vulnerabilities.": "Gradaltigoj de ĉambroj estas kutime rekomendataj kiam ĉambra versio estas opiniata <i>malstabila</i>. Malstabilaj ĉambraj versioj povas kunhavi erarojn, mankojn de funkcioj, aŭ malsekuraĵojn.",
|
||||
"Room upgrades usually only affect <i>server-side</i> processing of the room. If you're having problems with your Riot client, please file an issue with <issueLink />.": "Ĉambraj gradaltigoj efikas nur sur <i>servil-flanka</i> funkciado de la ĉambro. Se vi havas problemon kun via kliento (Riot), bonvolu raparti problemon per <issueLink />.",
|
||||
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members to the new version of the room.</i> We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "<b>Averto</b>: Gradaltigo de ĉambro <i>ne transmetos ĉiujn ĉambranojn al la nova versio de la ĉambro.</i> Ni afiŝos ligilon al la nova ĉambro en la malnova versio de la ĉambro – ĉambranoj devos tien klaki por aliĝi al la nova ĉambro.",
|
||||
"Please confirm that you'd like to go forward with upgrading this room from <oldVersion /> to <newVersion />.": "Bonvolu konfirmi, ke vi certe volas gradaltigi ĉi tiun ĉambron de <oldVersion /> al <newVersion />.",
|
||||
"Changes your display nickname in the current room only": "Ŝanĝas vian vidigan nomon nur en la nuna ĉambro",
|
||||
"Changes your avatar in this current room only": "Ŝanĝas vian profilbildon nur en la nuna ĉambro",
|
||||
"Gets or sets the room topic": "Ekhavas aŭ agordas la temon de la ĉambro",
|
||||
|
@ -1205,38 +1132,22 @@
|
|||
"Verify this user by confirming the following emoji appear on their screen.": "Kontrolu ĉi tiun uzanton per konfirmo, ke la jenaj bildsignoj aperis sur ĝia ekrano.",
|
||||
"Verify this user by confirming the following number appears on their screen.": "Kontrolu ĉu tiun uzanton per konfirmo, ke la jena numero aperis sur ĝia ekrano.",
|
||||
"Unable to find a supported verification method.": "Ne povas trovi subtenatan metodon de kontrolo.",
|
||||
"For maximum security, we recommend you do this in person or use another trusted means of communication.": "Por la plej bona sekureco, ni rekomendas fari ĉi tion persone, aŭ per alia, fidata komunikilo.",
|
||||
"Santa": "Kristnaska viro",
|
||||
"Thumbs up": "Dikfingro supren",
|
||||
"Paperclip": "Paperkuntenilo",
|
||||
"Pin": "Pinglo",
|
||||
"Your homeserver does not support device management.": "Via hejmservilo ne subtenas administradon de aparatoj.",
|
||||
"We've sent you an email to verify your address. Please follow the instructions there and then click the button below.": "Ni sendis al vi retleteron por konfirmi vian adreson. Bonvolu sekvi la tieajn intrukciojn kaj poste klaki al la butono sube.",
|
||||
"Are you sure? You will lose your encrypted messages if your keys are not backed up properly.": "Ĉu vi certas? Vi perdos ĉiujn viajn ĉifritajn mesaĝojn, se viaj ŝlosiloj ne estas savkopiitaj.",
|
||||
"Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Ĉifritaj mesaĝoj estas sekurigitaj per tutvoja ĉifrado. Nur vi kaj la ricevonto(j) havas la ŝlosilojn necesajn por legado.",
|
||||
"This device is backing up your keys. ": "Ĉi tiu aparato savkopias viajn ŝlosilojn. ",
|
||||
"Custom user status messages": "Propraj uzantoaj statmesaĝoj",
|
||||
"Group & filter rooms by custom tags (refresh to apply changes)": "Grupigi kaj filtri ĉambrojn per propraj etikedoj (aktualigu por ŝanĝojn apliki)",
|
||||
"Restore from Backup": "Rehavi el savkopio",
|
||||
"This device is <b>not backing up your keys</b>, but you do have an existing backup you can restore from and add to going forward.": "Tiu ĉi aparato ne <b>ne savkopias viajn ŝlosilojn</b>, sed vi jam havas savkopion, kiun vi povas restarigi, kaj aldonadi al ĝi de nun.",
|
||||
"Backing up %(sessionsRemaining)s keys...": "Savkopianta %(sessionsRemaining)s ŝlosilojn…",
|
||||
"All keys backed up": "Ĉiuj ŝlosiloj estas savkopiitaj",
|
||||
"Backup has a signature from <verify>unknown</verify> device with ID %(deviceId)s.": "Savkopio havas subskribon de <verify>nekonata</verify> aparato kun la identigilo %(deviceId)s.",
|
||||
"Backup has a <validity>valid</validity> signature from this device": "Savkopio havas <validity>validan</validity> subskribon de ĉi tiu aparato",
|
||||
"Backup has an <validity>invalid</validity> signature from this device": "Savkopio havas <validity>nevalidan</validity> subskribon de tiu ĉi aparato",
|
||||
"Backup has a <validity>valid</validity> signature from <verify>verified</verify> device <device></device>": "Savkopio havas <validity>validan</validity> subskribon de <verify>kontrolita</verify> aparato <device></device>",
|
||||
"Backup has a <validity>valid</validity> signature from <verify>unverified</verify> device <device></device>": "Savkopio havas <validity>validan</validity> subskribon de <verify>nekontrolita</verify> aparato <device></device>",
|
||||
"Backup has an <validity>invalid</validity> signature from <verify>verified</verify> device <device></device>": "Savkopio havas <validity>nevalidan</validity> subskribon de <verify>kontrolita</verify> aparato <device></device>",
|
||||
"Backup has an <validity>invalid</validity> signature from <verify>unverified</verify> device <device></device>": "Savkopio havas <validity>nevalidan</validity> subskribon de <verify>nekontrolita</verify> aparato <device></device>",
|
||||
"Backup is not signed by any of your devices": "Savkopio estas subskribita de neniu el viaj aparatoj",
|
||||
"This backup is trusted because it has been restored on this device": "Ĉi tiu savkopio estas fidata ĉar ĝi estis restarigita por ĉi tiu aparato",
|
||||
"Backup version: ": "Versio de savkopio: ",
|
||||
"Algorithm: ": "Algoritmo: ",
|
||||
"Your keys are <b>not being backed up from this device</b>.": "Viaj ŝlosiloj <b>ne estas savkopiataj de ĉi tiu aparato</b>.",
|
||||
"Back up your keys before signing out to avoid losing them.": "Savkopiu viajn ŝlosilojn antaŭ adiaŭo, por ilin ne perdi.",
|
||||
"Add an email address to configure email notifications": "Aldonu retpoŝtadreson por agordi retpoŝtajn sciigojn",
|
||||
"Enable desktop notifications for this device": "Ŝalti labortablajn sciigojn por ĉi tiu aparato",
|
||||
"Enable audible notifications for this device": "Ŝalti sonajn sciigojn por ĉi tiu aparato",
|
||||
"Unable to verify phone number.": "Ne povas kontroli telefonnumeron.",
|
||||
"Verification code": "Kontrola kodo",
|
||||
"Deactivating your account is a permanent action - be careful!": "Malaktivigo de via konto estas nemalfarebla – atentu!",
|
||||
|
@ -1287,10 +1198,6 @@
|
|||
"This room has already been upgraded.": "Ĉi tiu ĉambro jam gradaltiĝis.",
|
||||
"This room is running room version <roomVersion />, which this homeserver has marked as <i>unstable</i>.": "Ĉi tiu ĉambro uzas ĉambran version <roomVersion />, kiun la hejmservilo markis kiel <i>nestabilan</i>.",
|
||||
"Your Riot is misconfigured": "Via kliento Riot estas misagordita",
|
||||
"All devices for this user are trusted": "Ĉiuj aparatoj de tiu ĉi uzanto estas fidataj",
|
||||
"All devices in this encrypted room are trusted": "Ĉiuj aparatoj en ĉi tiu ĉifrita ĉambro estas fidataj",
|
||||
"Your key share request has been sent - please check your other devices for key share requests.": "Via peto por havigo de ŝlosilo sendiĝis – bonvolu kontroli viajn aliajn aparatojn pro petoj.",
|
||||
"At this time it is not possible to reply with an emote.": "Ankoraŭ ne eblas respondi per mieno.",
|
||||
"Joining room …": "Aliĝanta al ĉambro …",
|
||||
"Loading …": "Enleganta …",
|
||||
"Rejecting invite …": "Rifuzanta inviton …",
|
||||
|
@ -1338,7 +1245,6 @@
|
|||
"Nothing appearing? Not all clients support interactive verification yet. <button>Use legacy verification</button>.": "Ĉu neniu aperas? Ankoraŭ ne ĉiuj klientoj subtenas interagan kontrolon. <button>Uzi malnovecan kontrolon</button>.",
|
||||
"Waiting for %(userId)s to confirm...": "Atendanta konfirmon de %(userId)s…",
|
||||
"Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Kontrolu ĉi tiun uzanton por marki ĝin fidata. Fidado devas vin trankviligi dum uzado de tutvoja ĉifrado.",
|
||||
"Verifying this user will mark their device as trusted, and also mark your device as trusted to them.": "Kontrolo de ĉi tiu uzanto markos ĝian aparaton fidata, kaj ankaŭ la vian por ĝi.",
|
||||
"Waiting for partner to confirm...": "Atendas konfirmon de kunulo…",
|
||||
"Incoming Verification Request": "Venas kontrolpeto",
|
||||
"Manually export keys": "Mane elporti ŝlosilojn",
|
||||
|
@ -1398,7 +1304,6 @@
|
|||
"You have %(count)s unread notifications in a prior version of this room.|other": "Vi havas %(count)s nelegitajn sciigojn en antaŭa versio de ĉi tiu ĉambro.",
|
||||
"You have %(count)s unread notifications in a prior version of this room.|one": "Vi havas %(count)s nelegitan sciigon en antaŭa versio de ĉi tiu ĉambro.",
|
||||
"Your profile": "Via profilo",
|
||||
"Changing your password will reset any end-to-end encryption keys on all of your devices, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another device before resetting your password.": "Ŝanĝo de pasvorto renovigos tutvoje ĉifrajn ŝlosilojn de ĉiuj viaj aparatoj, igante la historion de ĉifrita babilo nelegebla. Agordu savkopiadon de ŝlosiloj, aŭ elportu ŝlosilojn de viaj ĉambroj el alia aparato, antaŭ ol vi ŝanĝos la pasvorton.",
|
||||
"Your Matrix account on <underlinedServerName />": "Via Matrix-konto sur <underlinedServerName />",
|
||||
"This homeserver does not support login using email address.": "Ĉi tiu hejmservilo ne subtenas saluton per retpoŝtadreso.",
|
||||
"Registration has been disabled on this homeserver.": "Registriĝoj malŝaltiĝis sur ĉi tiu hejmservilo.",
|
||||
|
@ -1440,7 +1345,6 @@
|
|||
"Show recently visited rooms above the room list": "Montri freŝe vizititajn ĉambrojn super la listo de ĉambroj",
|
||||
"Show hidden events in timeline": "Montri kaŝitajn okazojn en historio",
|
||||
"Low bandwidth mode": "Reĝimo de malmulta kapacito",
|
||||
"Connect this device to Key Backup": "Konekti ĉi tiun aparaton al Savkopiado de ŝlosiloj",
|
||||
"Start using Key Backup": "Ekuzi Savkopiadon de ŝlosiloj",
|
||||
"Timeline": "Historio",
|
||||
"Autocomplete delay (ms)": "Prokrasto de memaga kompletigo",
|
||||
|
@ -1451,7 +1355,6 @@
|
|||
"Notification sound": "Sono de sciigo",
|
||||
"Set a new custom sound": "Agordi novan propran sonon",
|
||||
"Browse": "Foliumi",
|
||||
"Some devices for this user are not trusted": "Iuj aparatoj de tiu ĉi uzanto ne estas fidataj",
|
||||
"Show all": "Montri ĉiujn",
|
||||
"Edited at %(date)s. Click to view edits.": "Redaktita je %(date)s. Klaku por vidi redaktojn.",
|
||||
"That doesn't look like a valid email address": "Tio ne ŝajnas esti valida retpoŝtadreso",
|
||||
|
@ -1480,8 +1383,6 @@
|
|||
"Encryption": "Ĉifrado",
|
||||
"Once enabled, encryption cannot be disabled.": "Post ŝalto, ne plu eblas malŝalti ĉifradon.",
|
||||
"Encrypted": "Ĉifrata",
|
||||
"Some devices in this encrypted room are not trusted": "Iuj aparatoj en ĉi tiu ĉifrata ĉambro ne estas fidataj",
|
||||
"Key share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, click here to request the keys for this session again.": "Petoj pri kunhavigo de ŝlosiloj sendiĝas al viaj aliaj aparatoj memage. Se vi rifuzis aŭ forlasis la peton en viaj aliaj aparatoj, klaku ĉi tien por repeti la ŝlosilojn por tiu ĉi kunsido.",
|
||||
"The conversation continues here.": "La interparolo pluas ĉi tie.",
|
||||
"This room has been replaced and is no longer active.": "Ĉi tiu ĉambro estas anstataŭita, kaj ne plu aktivas.",
|
||||
"Loading room preview": "Preparas antaŭrigardon al la ĉambro",
|
||||
|
@ -1496,8 +1397,6 @@
|
|||
"%(oneUser)smade no changes %(count)s times|other": "%(oneUser)snenion ŝanĝis je %(count)s fojoj",
|
||||
"%(oneUser)smade no changes %(count)s times|one": "%(oneUser)snenion ŝanĝis",
|
||||
"Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Ne povas enlegi la responditan okazon; aŭ ĝi ne ekzistas, aŭ vi ne rajtas vidi ĝin.",
|
||||
"Clear all data on this device?": "Ĉu vakigi ĉiujn datumojn en tiu ĉi aparato?",
|
||||
"Clearing all data from this device is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Vakigo de ĉiuj datumoj de tiu ĉi aparato estas porĉiama. Ĉifritaj mesaĝoj perdiĝos, malse vi savkopiis iliajn ŝlosilojn.",
|
||||
"Clear all data": "Vakigi ĉiujn datumojn",
|
||||
"Community IDs cannot be empty.": "Identigilo de komunumo ne estu malplena.",
|
||||
"To avoid losing your chat history, you must export your room keys before logging out. You will need to go back to the newer version of Riot to do this": "Por eviti perdon de via babila historio, vi devas elporti la ŝlosilojn de viaj ĉambroj antaŭ adiaŭo. Por tio vi bezonos reveni al la pli nova versio de Riot",
|
||||
|
@ -1537,7 +1436,6 @@
|
|||
"This looks like a valid recovery key!": "Ŝajnas esti valida rehava ŝlosilo!",
|
||||
"Not a valid recovery key": "Ne estas valida rehava ŝlosilo",
|
||||
"Access your secure message history and set up secure messaging by entering your recovery key.": "Aliru vian sekuran mesaĝan historion kaj agordu sekuran mesaĝadon per enigo de via rehava ŝlosilo.",
|
||||
"If you've forgotten your recovery passphrase you can <button>set up new recovery options</button>": "Se vi forgesis vian rehavan pasfrazon, vi povas <button>agordi novajn rehavajn elektojn</button>",
|
||||
"Resend %(unsentCount)s reaction(s)": "Resendi %(unsentCount)s reago(j)n",
|
||||
"Resend removal": "Resendi forigon",
|
||||
"Share Permalink": "Kunhavi daŭran ligilon",
|
||||
|
@ -1570,15 +1468,11 @@
|
|||
"New Recovery Method": "Nova rehava metodo",
|
||||
"A new recovery passphrase and key for Secure Messages have been detected.": "Novaj rehava pasfrazo kaj ŝlosilo por sekuraj mesaĝoj troviĝis.",
|
||||
"If you didn't set the new recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Se vi ne agordis la novan rehavan metodon, eble atakanto provas aliri vian konton. Vi tuj ŝanĝu la pasvorton de via konto, kaj agordu novan rehavan metodon en la agordoj.",
|
||||
"This device is encrypting history using the new recovery method.": "Ĉi tiu aparato ĉifras historion kun la nova rehava metodo.",
|
||||
"Set up Secure Messages": "Agordi sekurajn mesaĝojn",
|
||||
"Recovery Method Removed": "Rehava metodo foriĝis",
|
||||
"This device has detected that your recovery passphrase and key for Secure Messages have been removed.": "Ĉi tiu aparato trovis, ke viaj rehava pasfrazo kaj ŝlosilo por sekuraj mesaĝoj foriĝis.",
|
||||
"If you did this accidentally, you can setup Secure Messages on this device which will re-encrypt this device's message history with a new recovery method.": "Se vi faris tion akcidente, vi povas agordi sekurajn mesaĝojn per ĉi tiu aparato, reĉifrante la mesaĝan historion de la aparato kun nova rehava metodo.",
|
||||
"If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Se vi ne forigis la rehavan metodon, eble atakanto provas aliri vian konton. Vi tuj ŝanĝu la pasvorton de via konto, kaj agordu novan rehavan metodon en la agordoj.",
|
||||
"Use a longer keyboard pattern with more turns": "Uzu pli longan tekston kun plia varieco",
|
||||
"Unable to load key backup status": "Ne povas enlegi staton de ŝlosila savkopio",
|
||||
"Connect this device to key backup before signing out to avoid losing any keys that may only be on this device.": "Konektu ĉi tiun aparaton al ŝlosila savkopiado antaŭ adiaŭo, por eviti perdon de ŝlosiloj de tiu ĉi aparato.",
|
||||
"Reset": "Reagordi",
|
||||
"Demote yourself?": "Ĉu malrangaltigi vin mem?",
|
||||
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Vi ne povos malfari tiun ŝanĝon, ĉar vi malrangaltigas vin mem; se vi estas la lasta povohava uzanto en la ĉambro, estos neeble vian povon rehavi.",
|
||||
|
@ -1586,7 +1480,6 @@
|
|||
"Power level": "Povonivelo",
|
||||
"Use two-way text verification": "Uzi duflankan tekstan kontrolon",
|
||||
"Upgrading this room requires closing down the current instance of the room and creating a new room in its place. To give room members the best possible experience, we will:": "Gradaltigo de ĉi tiu ĉambro bezonas fermi ĝin, kaj krei novan por anstataŭi ĝin. Por plejbonigi sperton de la ĉambranoj, ni:",
|
||||
"You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "Vi adiaŭis ĉiujn aparatojn kaj ne plu ricevados sciigojn. Por reŝalti ilin, resalutu per ĉiu el la aparatoj.",
|
||||
"Invalid homeserver discovery response": "Nevalida eltrova respondo de hejmservilo",
|
||||
"Failed to get autodiscovery configuration from server": "Malsukcesis akiri agordojn de memaga eltrovado de la servilo",
|
||||
"Homeserver URL does not appear to be a valid Matrix homeserver": "URL por hejmservilo ŝajne ne ligas al valida hejmservilo de Matrix",
|
||||
|
@ -1595,26 +1488,20 @@
|
|||
"Sign in with single sign-on": "Salutu per ununura saluto",
|
||||
"Failed to re-authenticate due to a homeserver problem": "Malsukcesis reaŭtentigi pro hejmservila problemo",
|
||||
"Failed to re-authenticate": "Malsukcesis reaŭtentigi",
|
||||
"Regain access to your account and recover encryption keys stored on this device. Without them, you won’t be able to read all of your secure messages on any device.": "Rehavu aliron al via konto kaj ĉifrajn ŝlosilojn memoratajn de tiu ĉi aparato. Sen ili, vi ne povos legi ĉiujn viajn sekurajn mesaĝojn per iu ajn aparato.",
|
||||
"Enter your password to sign in and regain access to your account.": "Enigu vian pasvorton por saluti kaj rehavi aliron al via konto.",
|
||||
"Sign in and regain access to your account.": "Saluti kaj rehavi aliron al via konto.",
|
||||
"You cannot sign in to your account. Please contact your homeserver admin for more information.": "Vi ne povas saluti per via konto. Bonvolu kontakti administranton de via hejmservilo por akiri pliajn informojn.",
|
||||
"Warning: Your personal data (including encryption keys) is still stored on this device. Clear it if you're finished using this device, or want to sign in to another account.": "Averto: Tiu ĉi aparato ankoraŭ memoras viajn personajn datumojn (inkluzive ĉifrajn ŝlosilojn). Vakigu ilin, se vi ĉesas uzi ĉi tiun aparaton, aŭ volas saluti per alia konto.",
|
||||
"Set up with a Recovery Key": "Agordi per rehava ŝlosilo",
|
||||
"Go back to set it again.": "Reiru por reagordi ĝin.",
|
||||
"As a safety net, you can use it to restore your encrypted message history if you forget your Recovery Passphrase.": "Asekure vi povas uzi ĝin por rehavi vian historion de ĉifritaj mesaĝoj se vi forgesos vian rehavan pasfrazon.",
|
||||
"As a safety net, you can use it to restore your encrypted message history.": "Asekure vi povas uzi ĝin por rehavi vian historion de ĉifritaj mesaĝoj.",
|
||||
"Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your passphrase.": "Via rehava ŝlosilo estas asekuro – vi povos uzi ĝin por rehavi aliron al viaj ĉifritaj mesaĝoj, se vi forgesos vian pasfrazon.",
|
||||
"Keep your recovery key somewhere very secure, like a password manager (or a safe)": "Konservu vian rehavan ŝlosilon en tre sekura loko, kiel en administrilo de pasvortoj (aŭ sekurŝranko)",
|
||||
"Your Recovery Key": "Via rehava ŝlosilo",
|
||||
"Copy to clipboard": "Kopii al tondujo",
|
||||
"Your Recovery Key has been <b>copied to your clipboard</b>, paste it to:": "Via rehava ŝlosilo <b>kopiiĝis al via tondujo</b>, algluu ĝin al:",
|
||||
"Your Recovery Key is in your <b>Downloads</b> folder.": "Via rehava ŝlosilo estas en via <b>elŝuta</b> dosierujo.",
|
||||
"<b>Print it</b> and store it somewhere safe": "<b>Presu ĝin</b> kaj konservu ĝin en sekura loko",
|
||||
"<b>Save it</b> on a USB key or backup drive": "<b>Konservu ĝin</b> en poŝmemorilo aŭ savkopia disko",
|
||||
"<b>Copy it</b> to your personal cloud storage": "<b>Kopiu ĝin</b> al via persona enreta konservejo",
|
||||
"Your keys are being backed up (the first backup could take a few minutes).": "Viaj ŝlosiloj estas savkopiataj (la unua savkopio povas daŭri kelkajn minutojn).",
|
||||
"Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another device.": "Sen agordo de sekura rehavo de mesaĝoj, vi ne povos rehavi vian historion de ĉifritaj mesaĝoj se vi adiaŭos aŭ uzos alian aparaton.",
|
||||
"Set up Secure Message Recovery": "Agordi sekuran rehavon de mesaĝoj",
|
||||
"Secure your backup with a passphrase": "Sekurigi vian savkopion per pasfrazo",
|
||||
"Confirm your passphrase": "Konfirmu vian pasfrazon",
|
||||
|
@ -1650,7 +1537,6 @@
|
|||
"Public Name": "Publika nomo",
|
||||
"Do not use an identity server": "Ne uzi identigan servilon",
|
||||
"Enter a new identity server": "Enigi novan identigan servilon",
|
||||
"Failed to start chat": "Malsukcesis komenci babilon",
|
||||
"Messages": "Mesaĝoj",
|
||||
"Actions": "Agoj",
|
||||
"Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Uzu identigan servilon por inviti retpoŝte. Klaku al « daŭrigi » por uzi la norman identigan servilon (%(defaultIdentityServerName)s) aŭ administru tion en Agordoj.",
|
||||
|
@ -1683,7 +1569,6 @@
|
|||
"Discovery": "Trovado",
|
||||
"Deactivate account": "Malaktivigi konton",
|
||||
"Always show the window menu bar": "Ĉiam montri la fenestran menubreton",
|
||||
"A device's public name is visible to people you communicate with": "Publika nomo de aparato estas videbla de homoj, kun kiuj vi komunikas",
|
||||
"Upgrade the room": "Gradaltigi la ĉambron",
|
||||
"Enable room encryption": "Ŝalti ĉifradon de la ĉambro",
|
||||
"Error changing power level requirement": "Eraris ŝanĝo de postulo de potenconivelo",
|
||||
|
@ -1721,7 +1606,6 @@
|
|||
"Trust": "Fido",
|
||||
"%(name)s (%(userId)s)": "%(name)s (%(userId)s)",
|
||||
"Multiple integration managers": "Pluraj kunigiloj",
|
||||
"Use the new, faster, composer for writing messages": "Uzi la novan, pli rapidan verkilon de mesaĝoj",
|
||||
"Show previews/thumbnails for images": "Montri antaŭrigardojn/bildetojn je bildoj",
|
||||
"You should <b>remove your personal data</b> from identity server <idserver /> before disconnecting. Unfortunately, identity server <idserver /> is currently offline or cannot be reached.": "Vi <b>forigu viajn personajn datumojn</b> de identiga servilo <idserver /> antaŭ ol vi malkonektiĝos. Bedaŭrinde, identiga servilo <idserver /> estas nuntempe eksterreta kaj ne eblas ĝin atingi.",
|
||||
"You should:": "Vi:",
|
||||
|
@ -1809,7 +1693,6 @@
|
|||
"Hide advanced": "Kaŝi specialajn",
|
||||
"Show advanced": "Montri specialajn",
|
||||
"Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "Bloki aliĝojn al ĉi tiu ĉambro de uzantoj el aliaj Matrix-serviloj (Ĉi tiun agordon ne eblas poste ŝanĝi!)",
|
||||
"To verify that this device can be trusted, please check that the key you see in User Settings on that device matches the key below:": "Por kontroli ke tiu ĉi aparato estas fidinda, bonvolu kontroli, ke la ŝlosilo, kiun vi vidas en viaj Agordoj de uzanto je tiu aparato, akordas kun la ŝlosilo sube:",
|
||||
"Please fill why you're reporting.": "Bonvolu skribi, kial vi raportas.",
|
||||
"Report Content to Your Homeserver Administrator": "Raporti enhavon al la administrantode via hejmservilo",
|
||||
"Reporting this message will send its unique 'event ID' to the administrator of your homeserver. If messages in this room are encrypted, your homeserver administrator will not be able to read the message text or view any files or images.": "Per raporto de ĝi tiu mesaĝo vi sendos ĝian unikan « eventan identigilon » al la administranto de via hejmservilo. Se mesaĝoj en ĉi tiu ĉambro estas ĉifrataj, la administranto de via hejmservilo ne povos legi la tekston de la mesaĝo, nek rigardi dosierojn aŭ bildojn.",
|
||||
|
@ -1839,7 +1722,6 @@
|
|||
"%(senderName)s placed a video call.": "%(senderName)s metis vidvokon.",
|
||||
"%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s metis vidvokon. (mankas subteno en ĉi tiu foliumilo)",
|
||||
"Try out new ways to ignore people (experimental)": "Elprovi novajn manierojn malatenti homojn (eksperimente)",
|
||||
"Send verification requests in direct message, including a new verification UX in the member panel.": "Sendadi kontrolajn petojn per rektaj mesaĝoj, inkluzive novan kontrolan ilaron en la membra panelo.",
|
||||
"Match system theme": "Similiĝi la sisteman haŭton",
|
||||
"My Ban List": "Mia listo de forbaroj",
|
||||
"This is your list of users/servers you have blocked - don't leave the room!": "Ĉi tio estas la listo de uzantoj/serviloj, kiujn vi forbaris – ne eliru el la ĉambro!",
|
||||
|
@ -1890,5 +1772,48 @@
|
|||
"Lock": "Seruro",
|
||||
"Other users may not trust it": "Aliaj uzantoj eble ne kredas ĝin",
|
||||
"Later": "Pli poste",
|
||||
"Verify": "Kontroli"
|
||||
"Verify": "Kontroli",
|
||||
"Set up encryption": "Agordi ĉifradon",
|
||||
"Upgrade": "Gradaltigi",
|
||||
"Cannot connect to integration manager": "Ne povas konektiĝi al kunigilo",
|
||||
"The integration manager is offline or it cannot reach your homeserver.": "La kunigilo estas eksterreta aŭ ne povas atingi vian hejmservilon",
|
||||
"Backup has a <validity>valid</validity> signature from this user": "Savkopio havas <validity>validan</validity> subskribon de ĉi tiu uzanto",
|
||||
"Backup has a <validity>invalid</validity> signature from this user": "Savkopio havas <validity>nevalidan</validity> subskribon de ĉi tiu uzanto",
|
||||
"This room is end-to-end encrypted": "Ĉi tiu ĉambro uzas tutvojan ĉifradon",
|
||||
"Everyone in this room is verified": "Ĉiu en la ĉambro estas kontrolita",
|
||||
"This message cannot be decrypted": "Ĉi tiun mesaĝon ne eblas malĉifri",
|
||||
"Unencrypted": "Neĉifrita",
|
||||
"Send a reply…": "Sendi respondon…",
|
||||
"Send a message…": "Sendi mesaĝon…",
|
||||
"Direct Messages": "Rektaj mesaĝoj",
|
||||
"<userName/> wants to chat": "<userName/> volas babili",
|
||||
"Start chatting": "Ekbabili",
|
||||
"Reject & Ignore user": "Rifuzi kaj malatenti uzanton",
|
||||
"Unknown Command": "Nekonata komando",
|
||||
"Send as message": "Sendi mesaĝon",
|
||||
"Failed to connect to integration manager": "Malsukcesis konekton al kunigilo",
|
||||
"Verify User": "Kontroli uzanton",
|
||||
"For extra security, verify this user by checking a one-time code on both of your devices.": "Por plia sekureco, kontrolu ĉi tiun uzanton per unufoja kodo aperonta sur ambaŭ el viaj aparatoj.",
|
||||
"Start Verification": "Komenci kontrolon",
|
||||
"Trusted": "Fidata",
|
||||
"Not trusted": "Nefidata",
|
||||
"Direct message": "Rekta mesaĝo",
|
||||
"Security": "Sekureco",
|
||||
"Reactions": "Reagoj",
|
||||
"More options": "Pliaj elektebloj",
|
||||
"Integrations are disabled": "Kunigoj estas malŝaltitaj",
|
||||
"Integrations not allowed": "Kunigoj ne estas permesitaj",
|
||||
"Suggestions": "Proponoj",
|
||||
"Automatically invite users": "Memage inviti uzantojn",
|
||||
"Upgrade private room": "Gradaltigi privatan ĉambron",
|
||||
"Upgrade public room": "Gradaltigi publikan ĉambron",
|
||||
"Notification settings": "Sciigaj agordoj",
|
||||
"Take picture": "Foti",
|
||||
"Start": "Komenci",
|
||||
"Done": "Fini",
|
||||
"Go Back": "Reiri",
|
||||
"Verify other users in their profile.": "Kontrolu aliajn uzantojn en iliaj profiloj.",
|
||||
"Upgrade your encryption": "Gradaltigi vian ĉifradon",
|
||||
"Encryption upgraded": "Ĉifrado gradaltigita",
|
||||
"Encryption setup complete": "Agordo de ĉifrado finita"
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue