Merge branch 'develop' of https://github.com/matrix-org/matrix-react-sdk into fix-1px-jump
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
src/components/structures/RoomDirectory.js
|
src/components/structures/RoomDirectory.js
|
||||||
src/components/structures/RoomStatusBar.js
|
src/components/structures/RoomStatusBar.js
|
||||||
src/components/structures/RoomView.js
|
|
||||||
src/components/structures/ScrollPanel.js
|
src/components/structures/ScrollPanel.js
|
||||||
src/components/structures/SearchBox.js
|
src/components/structures/SearchBox.js
|
||||||
src/components/structures/UploadBar.js
|
src/components/structures/UploadBar.js
|
||||||
|
|
|
@ -94,6 +94,7 @@
|
||||||
"react-focus-lock": "^2.4.1",
|
"react-focus-lock": "^2.4.1",
|
||||||
"react-transition-group": "^4.4.1",
|
"react-transition-group": "^4.4.1",
|
||||||
"resize-observer-polyfill": "^1.5.1",
|
"resize-observer-polyfill": "^1.5.1",
|
||||||
|
"rfc4648": "^1.4.0",
|
||||||
"sanitize-html": "^1.27.1",
|
"sanitize-html": "^1.27.1",
|
||||||
"tar-js": "^0.3.0",
|
"tar-js": "^0.3.0",
|
||||||
"text-encoding-utf-8": "^1.0.2",
|
"text-encoding-utf-8": "^1.0.2",
|
||||||
|
|
|
@ -155,9 +155,12 @@
|
||||||
@import "./views/messages/_UnknownBody.scss";
|
@import "./views/messages/_UnknownBody.scss";
|
||||||
@import "./views/messages/_ViewSourceEvent.scss";
|
@import "./views/messages/_ViewSourceEvent.scss";
|
||||||
@import "./views/messages/_common_CryptoEvent.scss";
|
@import "./views/messages/_common_CryptoEvent.scss";
|
||||||
|
@import "./views/right_panel/_BaseCard.scss";
|
||||||
@import "./views/right_panel/_EncryptionInfo.scss";
|
@import "./views/right_panel/_EncryptionInfo.scss";
|
||||||
|
@import "./views/right_panel/_RoomSummaryCard.scss";
|
||||||
@import "./views/right_panel/_UserInfo.scss";
|
@import "./views/right_panel/_UserInfo.scss";
|
||||||
@import "./views/right_panel/_VerificationPanel.scss";
|
@import "./views/right_panel/_VerificationPanel.scss";
|
||||||
|
@import "./views/right_panel/_WidgetCard.scss";
|
||||||
@import "./views/room_settings/_AliasSettings.scss";
|
@import "./views/room_settings/_AliasSettings.scss";
|
||||||
@import "./views/rooms/_AppsDrawer.scss";
|
@import "./views/rooms/_AppsDrawer.scss";
|
||||||
@import "./views/rooms/_Autocomplete.scss";
|
@import "./views/rooms/_Autocomplete.scss";
|
||||||
|
|
|
@ -18,6 +18,14 @@ limitations under the License.
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_RoomHeader_buttons + .mx_HeaderButtons {
|
||||||
|
// remove the | separator line for when next to RoomHeaderButtons
|
||||||
|
// TODO: remove this once when we redo communities and make the right panel similar to the new rooms one
|
||||||
|
&::before {
|
||||||
|
content: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.mx_HeaderButtons::before {
|
.mx_HeaderButtons::before {
|
||||||
content: "";
|
content: "";
|
||||||
background-color: $header-divider-color;
|
background-color: $header-divider-color;
|
||||||
|
|
|
@ -25,6 +25,7 @@ limitations under the License.
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
// margin left to not allow the handle to not encroach on the space for the scrollbar
|
// margin left to not allow the handle to not encroach on the space for the scrollbar
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
|
height: calc(100vh - 51px); // height of .mx_RoomHeader.light-panel
|
||||||
|
|
||||||
&:hover .mx_RightPanel_ResizeHandle {
|
&:hover .mx_RightPanel_ResizeHandle {
|
||||||
// Need to use important to override element style attributes
|
// Need to use important to override element style attributes
|
||||||
|
|
|
@ -68,16 +68,14 @@ limitations under the License.
|
||||||
mask-repeat: no-repeat;
|
mask-repeat: no-repeat;
|
||||||
mask-size: contain;
|
mask-size: contain;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RightPanel_membersButton::before {
|
&:hover {
|
||||||
mask-image: url('$(res)/img/element-icons/room/members.svg');
|
background: rgba($accent-color, 0.1);
|
||||||
mask-position: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RightPanel_filesButton::before {
|
&::before {
|
||||||
mask-image: url('$(res)/img/element-icons/room/files.svg');
|
background-color: $accent-color;
|
||||||
mask-position: center;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RightPanel_notifsButton::before {
|
.mx_RightPanel_notifsButton::before {
|
||||||
|
@ -85,6 +83,11 @@ limitations under the License.
|
||||||
mask-position: center;
|
mask-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_RightPanel_roomSummaryButton::before {
|
||||||
|
mask-image: url('$(res)/img/element-icons/room/room-summary.svg');
|
||||||
|
mask-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_RightPanel_groupMembersButton::before {
|
.mx_RightPanel_groupMembersButton::before {
|
||||||
mask-image: url('$(res)/img/element-icons/community-members.svg');
|
mask-image: url('$(res)/img/element-icons/community-members.svg');
|
||||||
mask-position: center;
|
mask-position: center;
|
||||||
|
@ -96,23 +99,11 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RightPanel_headerButton_highlight {
|
.mx_RightPanel_headerButton_highlight {
|
||||||
background: rgba($accent-color, 0.25);
|
|
||||||
// make the icon the accent color too
|
|
||||||
&::before {
|
&::before {
|
||||||
background-color: $accent-color !important;
|
background-color: $accent-color !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RightPanel_headerButton:not(.mx_RightPanel_headerButton_highlight) {
|
|
||||||
&:hover {
|
|
||||||
background: rgba($accent-color, 0.1);
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
background-color: $accent-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RightPanel_headerButton_badge {
|
.mx_RightPanel_headerButton_badge {
|
||||||
font-size: $font-8px;
|
font-size: $font-8px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
@ -146,7 +137,7 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RightPanel_empty {
|
.mx_RightPanel_empty {
|
||||||
margin-right: -42px;
|
margin-right: -28px;
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|
|
@ -15,7 +15,6 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_UserMenu {
|
.mx_UserMenu {
|
||||||
|
|
||||||
// to make the menu button sort of aligned with the explore button below
|
// to make the menu button sort of aligned with the explore button below
|
||||||
padding-right: 6px;
|
padding-right: 6px;
|
||||||
|
|
||||||
|
@ -59,7 +58,7 @@ limitations under the License.
|
||||||
mask-position: center;
|
mask-position: center;
|
||||||
mask-size: contain;
|
mask-size: contain;
|
||||||
mask-repeat: no-repeat;
|
mask-repeat: no-repeat;
|
||||||
background: $primary-fg-color;
|
background: $tertiary-fg-color;
|
||||||
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
|
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,6 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
span.mx_IconizedContextMenu_label { // labels
|
span.mx_IconizedContextMenu_label { // labels
|
||||||
padding-left: 14px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
|
@ -91,6 +90,10 @@ limitations under the License.
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_IconizedContextMenu_icon + .mx_IconizedContextMenu_label {
|
||||||
|
padding-left: 14px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
166
res/css/views/right_panel/_BaseCard.scss
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
/*
|
||||||
|
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_BaseCard {
|
||||||
|
padding: 0 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.mx_BaseCard_header {
|
||||||
|
margin: 8px 0;
|
||||||
|
|
||||||
|
> h2 {
|
||||||
|
margin: 0 44px;
|
||||||
|
font-size: $font-18px;
|
||||||
|
font-weight: $font-semi-bold;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_BaseCard_back, .mx_BaseCard_close {
|
||||||
|
position: absolute;
|
||||||
|
background-color: rgba(141, 151, 165, 0.2);
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
margin: 12px;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center;
|
||||||
|
background-color: $rightpanel-button-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_BaseCard_back {
|
||||||
|
border-radius: 4px;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
mask-size: 22px;
|
||||||
|
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_BaseCard_close {
|
||||||
|
border-radius: 10px;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
mask-image: url('$(res)/img/icons-close.svg');
|
||||||
|
mask-size: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_AutoHideScrollbar {
|
||||||
|
// collapse the margin into a padding to move the scrollbar into the right gutter
|
||||||
|
margin-right: -8px;
|
||||||
|
padding-right: 8px;
|
||||||
|
min-height: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_BaseCard_Group {
|
||||||
|
margin: 20px 0 16px;
|
||||||
|
|
||||||
|
& > * {
|
||||||
|
margin-left: 12px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> h1 {
|
||||||
|
color: $tertiary-fg-color;
|
||||||
|
font-size: $font-12px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_BaseCard_Button {
|
||||||
|
padding: 10px 38px 10px 12px;
|
||||||
|
margin: 0;
|
||||||
|
position: relative;
|
||||||
|
font-size: $font-13px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(141, 151, 165, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 6px;
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center;
|
||||||
|
background-color: $icon-button-color;
|
||||||
|
transform: rotate(270deg);
|
||||||
|
mask-size: 20px;
|
||||||
|
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_BaseCard_footer {
|
||||||
|
padding-top: 4px;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
|
||||||
|
.mx_AccessibleButton_kind_secondary {
|
||||||
|
color: $secondary-fg-color;
|
||||||
|
background-color: rgba(141, 151, 165, 0.2);
|
||||||
|
font-weight: $font-semi-bold;
|
||||||
|
font-size: $font-14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_AccessibleButton_disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_FilePanel,
|
||||||
|
.mx_UserInfo,
|
||||||
|
.mx_NotificationPanel,
|
||||||
|
.mx_MemberList {
|
||||||
|
&.mx_BaseCard {
|
||||||
|
padding: 32px 0 0;
|
||||||
|
|
||||||
|
.mx_AutoHideScrollbar {
|
||||||
|
margin-right: unset;
|
||||||
|
padding-right: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
147
res/css/views/right_panel/_RoomSummaryCard.scss
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
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_RoomSummaryCard {
|
||||||
|
.mx_BaseCard_header {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-weight: $font-semi-bold;
|
||||||
|
font-size: $font-18px;
|
||||||
|
margin: 12px 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSummaryCard_alias {
|
||||||
|
font-size: $font-13px;
|
||||||
|
color: $secondary-fg-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2, .mx_RoomSummaryCard_alias {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSummaryCard_avatar {
|
||||||
|
display: inline-flex;
|
||||||
|
|
||||||
|
.mx_RoomSummaryCard_e2ee {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
width: 54px;
|
||||||
|
height: 54px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #737d8c;
|
||||||
|
margin-top: -3px; // alignment
|
||||||
|
margin-left: -10px; // overlap
|
||||||
|
border: 3px solid $dark-panel-bg-color;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 13px;
|
||||||
|
left: 13px;
|
||||||
|
height: 28px;
|
||||||
|
width: 28px;
|
||||||
|
mask-size: cover;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center;
|
||||||
|
mask-image: url('$(res)/img/e2e/disabled.svg');
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSummaryCard_e2ee_secure {
|
||||||
|
background-color: #5abff2;
|
||||||
|
&::before {
|
||||||
|
mask-image: url('$(res)/img/e2e/normal.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSummaryCard_aboutGroup {
|
||||||
|
.mx_RoomSummaryCard_Button {
|
||||||
|
padding-left: 44px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
left: 10px;
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center;
|
||||||
|
background-color: $icon-button-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSummaryCard_appsGroup {
|
||||||
|
.mx_RoomSummaryCard_Button {
|
||||||
|
padding-left: 12px;
|
||||||
|
color: $tertiary-fg-color;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: $primary-fg-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
vertical-align: top;
|
||||||
|
margin-right: 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSummaryCard_icon_app_pinned::after {
|
||||||
|
mask-image: url('$(res)/img/element-icons/room/pin-upright.svg');
|
||||||
|
background-color: $accent-color;
|
||||||
|
transform: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_AccessibleButton_kind_link {
|
||||||
|
padding: 0;
|
||||||
|
margin-top: 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
font-size: $font-13px;
|
||||||
|
font-weight: $font-semi-bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSummaryCard_icon_people::before {
|
||||||
|
mask-image: url("$(res)/img/element-icons/room/members.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSummaryCard_icon_files::before {
|
||||||
|
mask-image: url('$(res)/img/element-icons/room/files.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSummaryCard_icon_share::before {
|
||||||
|
mask-image: url('$(res)/img/element-icons/room/share.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSummaryCard_icon_settings::before {
|
||||||
|
mask-image: url('$(res)/img/element-icons/settings.svg');
|
||||||
|
}
|
|
@ -15,7 +15,9 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_UserInfo {
|
.mx_UserInfo.mx_BaseCard {
|
||||||
|
// UserInfo has a circular image at the top so it fits between the back & close buttons
|
||||||
|
padding-top: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
62
res/css/views/right_panel/_WidgetCard.scss
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
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_WidgetCard {
|
||||||
|
height: 100%;
|
||||||
|
display: contents;
|
||||||
|
|
||||||
|
.mx_AppTileFullWidth {
|
||||||
|
max-width: unset;
|
||||||
|
height: 100%;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.mx_WidgetCard_noEdit {
|
||||||
|
.mx_AccessibleButton_kind_secondary {
|
||||||
|
margin: 0 12px;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
// expand the Pin to room primary action
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_WidgetCard_optionsButton {
|
||||||
|
position: relative;
|
||||||
|
height: 18px;
|
||||||
|
width: 26px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
top: 6px;
|
||||||
|
left: 20px;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center;
|
||||||
|
mask-size: contain;
|
||||||
|
mask-image: url('$(res)/img/element-icons/room/ellipsis.svg');
|
||||||
|
background-color: $secondary-fg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_WidgetCard_maxPinnedTooltip {
|
||||||
|
background-color: $notice-primary-color;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
|
@ -15,18 +15,39 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
$MiniAppTileHeight: 114px;
|
||||||
the tile title bar is 5 (top border) + 12 (title, buttons) + 5 (bottom padding) px = 22px
|
|
||||||
the body is assumed to be 300px (assumed by at least the sticker pickerm, perhaps elsewhere),
|
|
||||||
so the body height would be 300px - 22px (room for title bar) = 278px
|
|
||||||
BUT! the sticker picker also assumes it's a little less high than that because the iframe
|
|
||||||
for the sticker picker doesn't have any padding or margin on it's bottom.
|
|
||||||
so subtracking another 5px, which brings us at 273px.
|
|
||||||
*/
|
|
||||||
$AppsDrawerBodyHeight: 273px;
|
|
||||||
|
|
||||||
.mx_AppsDrawer {
|
.mx_AppsDrawer {
|
||||||
margin: 5px;
|
margin: 5px 5px 5px 18px;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.mx_AppsContainer_resizerHandle {
|
||||||
|
cursor: ns-resize;
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
// Override styles from library
|
||||||
|
width: unset !important;
|
||||||
|
height: 4px !important;
|
||||||
|
|
||||||
|
// This is positioned directly below frame
|
||||||
|
position: absolute;
|
||||||
|
bottom: -8px !important; // override from library
|
||||||
|
|
||||||
|
// Together, these make the bar 64px wide
|
||||||
|
// These are also overridden from the library
|
||||||
|
left: calc(50% - 32px) !important;
|
||||||
|
right: calc(50% - 32px) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.mx_AppsContainer_resizerHandle {
|
||||||
|
opacity: 0.8;
|
||||||
|
background: $primary-fg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AppsDrawer_hidden {
|
.mx_AppsDrawer_hidden {
|
||||||
|
@ -36,15 +57,23 @@ $AppsDrawerBodyHeight: 273px;
|
||||||
.mx_AppsContainer {
|
.mx_AppsContainer {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: stretch;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_AppsDrawer_minimised .mx_AppsContainer {
|
||||||
|
// override the re-resizable inline styles
|
||||||
|
height: inherit !important;
|
||||||
|
min-height: inherit !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AddWidget_button {
|
.mx_AddWidget_button {
|
||||||
order: 2;
|
order: 2;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 5px auto 5px auto;
|
margin: -3px auto 5px 0;
|
||||||
color: $accent-color;
|
color: $accent-color;
|
||||||
font-size: $font-12px;
|
font-size: $font-12px;
|
||||||
}
|
}
|
||||||
|
@ -65,40 +94,52 @@ $AppsDrawerBodyHeight: 273px;
|
||||||
.mx_AppTile {
|
.mx_AppTile {
|
||||||
max-width: 960px;
|
max-width: 960px;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
margin-right: 5px;
|
|
||||||
border: 5px solid $widget-menu-bar-bg-color;
|
border: 5px solid $widget-menu-bar-bg-color;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
.mx_AppTile:last-child {
|
& + .mx_AppTile {
|
||||||
margin-right: 1px;
|
margin-left: 5px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AppTileFullWidth {
|
.mx_AppTileFullWidth {
|
||||||
max-width: 960px;
|
max-width: 960px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: 5px solid $widget-menu-bar-bg-color;
|
border: 5px solid $widget-menu-bar-bg-color;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AppTile_mini {
|
.mx_AppTile_mini {
|
||||||
max-width: 960px;
|
max-width: 960px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: $MiniAppTileHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AppTile_persistedWrapper {
|
.mx_AppTile.mx_AppTile_minimised,
|
||||||
height: $AppsDrawerBodyHeight;
|
.mx_AppTileFullWidth.mx_AppTile_minimised,
|
||||||
|
.mx_AppTile_mini.mx_AppTile_minimised {
|
||||||
|
height: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_AppTile .mx_AppTile_persistedWrapper,
|
||||||
|
.mx_AppTileFullWidth .mx_AppTile_persistedWrapper,
|
||||||
.mx_AppTile_mini .mx_AppTile_persistedWrapper {
|
.mx_AppTile_mini .mx_AppTile_persistedWrapper {
|
||||||
height: 114px;
|
flex: 1;
|
||||||
min-width: 300px;
|
}
|
||||||
|
|
||||||
|
.mx_AppTile_persistedWrapper div {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AppTileMenuBar {
|
.mx_AppTileMenuBar {
|
||||||
|
@ -110,6 +151,7 @@ $AppsDrawerBodyHeight: 273px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AppTileMenuBar_expanded {
|
.mx_AppTileMenuBar_expanded {
|
||||||
|
@ -172,7 +214,7 @@ $AppsDrawerBodyHeight: 273px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AppTileBody {
|
.mx_AppTileBody {
|
||||||
height: $AppsDrawerBodyHeight;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
@ -183,6 +225,13 @@ $AppsDrawerBodyHeight: 273px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_AppTile .mx_AppTileBody,
|
||||||
|
.mx_AppTileFullWidth .mx_AppTileBody,
|
||||||
|
.mx_AppTile_mini .mx_AppTileBody_mini {
|
||||||
|
height: inherit;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_AppTileBody_mini iframe {
|
.mx_AppTileBody_mini iframe {
|
||||||
border: none;
|
border: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -191,7 +240,7 @@ $AppsDrawerBodyHeight: 273px;
|
||||||
|
|
||||||
.mx_AppTileBody iframe {
|
.mx_AppTileBody iframe {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: $AppsDrawerBodyHeight;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -331,7 +380,7 @@ form.mx_Custom_Widget_Form div {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: $AppsDrawerBodyHeight;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AppLoading .mx_Spinner {
|
.mx_AppLoading .mx_Spinner {
|
||||||
|
@ -358,3 +407,16 @@ form.mx_Custom_Widget_Form div {
|
||||||
.mx_AppLoading iframe {
|
.mx_AppLoading iframe {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_AppsDrawer_minimised .mx_AppsContainer_resizerHandle {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Avoid apptile iframes capturing mouse event focus when resizing */
|
||||||
|
.mx_AppsDrawer_resizing iframe {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_AppsDrawer_resizing .mx_AppTile_persistedWrapper {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
|
@ -236,10 +236,6 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomHeader_settingsButton::before {
|
|
||||||
mask-image: url('$(res)/img/element-icons/settings.svg');
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RoomHeader_forgetButton::before {
|
.mx_RoomHeader_forgetButton::before {
|
||||||
mask-image: url('$(res)/img/element-icons/leave.svg');
|
mask-image: url('$(res)/img/element-icons/leave.svg');
|
||||||
width: 26px;
|
width: 26px;
|
||||||
|
@ -249,14 +245,6 @@ limitations under the License.
|
||||||
mask-image: url('$(res)/img/element-icons/room/search-inset.svg');
|
mask-image: url('$(res)/img/element-icons/room/search-inset.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomHeader_shareButton::before {
|
|
||||||
mask-image: url('$(res)/img/element-icons/room/share.svg');
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RoomHeader_manageIntegsButton::before {
|
|
||||||
mask-image: url('$(res)/img/element-icons/room/integrations.svg');
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RoomHeader_showPanel {
|
.mx_RoomHeader_showPanel {
|
||||||
height: 16px;
|
height: 16px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,10 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_AppTile_persistedWrapper div {
|
||||||
|
min-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_IncomingCallBox {
|
.mx_IncomingCallBox {
|
||||||
min-width: 250px;
|
min-width: 250px;
|
||||||
background-color: $primary-bg-color;
|
background-color: $primary-bg-color;
|
||||||
|
|
5
res/img/e2e/disabled.svg
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M15.38 12.27C15.76 11.42 16 10.43 16 9.27V3.05L8.99997 1L5.21997 2.11L15.38 12.27Z" fill="#010101"/>
|
||||||
|
<path d="M2.21 2.98999L2 3.04999V9.26999C2 15.63 9 17 9 17C9 17 11.71 16.47 13.76 14.53L2.21 2.98999Z" fill="#010101"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.46967 0.46967C0.762563 0.176777 1.23744 0.176777 1.53033 0.46967L16.7203 15.6597C17.0132 15.9526 17.0132 16.4274 16.7203 16.7203C16.4274 17.0132 15.9526 17.0132 15.6597 16.7203L0.46967 1.53033C0.176777 1.23744 0.176777 0.762563 0.46967 0.46967Z" fill="#010101"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 648 B |
|
@ -1,3 +1,3 @@
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M1.77777 8.24003V2.71114L7.99999 0.888916L14.2222 2.71114V8.24003C14.2222 13.8934 7.99999 15.1111 7.99999 15.1111C7.99999 15.1111 1.77777 13.8934 1.77777 8.24003Z" fill="#020202"/>
|
<path d="M2 9.27V3.05L9 1L16 3.05V9.27C16 15.63 9 17 9 17C9 17 2 15.63 2 9.27Z" fill="#020202"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 293 B After Width: | Height: | Size: 204 B |
|
@ -1,3 +1,3 @@
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.77783 2.71114V8.24003C1.77783 13.8934 8.00005 15.1111 8.00005 15.1111C8.00005 15.1111 14.2223 13.8934 14.2223 8.24003V2.71114L8.00005 0.888916L1.77783 2.71114ZM10.6139 4.90635C10.7827 4.74635 11.0494 4.75524 11.2094 4.92413C11.3516 5.08413 11.3516 5.32413 11.2272 5.48413L7.47608 10.0263L7.44941 10.0619C7.20052 10.3641 6.74719 10.4086 6.44497 10.1597C6.41812 10.1463 6.39635 10.1227 6.37581 10.1005C6.36914 10.0933 6.36261 10.0862 6.35608 10.0797L4.74719 8.23079C4.56941 8.01746 4.58719 7.69746 4.80052 7.51968C4.9783 7.35968 5.23608 7.35968 5.42274 7.48413L6.8183 8.46191L10.6139 4.90635Z" fill="#0DBD8B"/>
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 3.05V9.27C2 15.63 9 17 9 17C9 17 16 15.63 16 9.27V3.05L9 1L2 3.05ZM11.9405 5.5196C12.1305 5.3396 12.4305 5.3496 12.6105 5.5396C12.7705 5.7196 12.7705 5.9896 12.6305 6.1696L8.41047 11.2796L8.38047 11.3196C8.10047 11.6596 7.59047 11.7096 7.25047 11.4296C7.22027 11.4145 7.19577 11.388 7.17266 11.363C7.16517 11.3549 7.15782 11.347 7.15047 11.3396L5.34047 9.2596C5.14047 9.0196 5.16047 8.6596 5.40047 8.4596C5.60047 8.2796 5.89047 8.2796 6.10047 8.4196L7.67047 9.5196L11.9405 5.5196Z" fill="#010101"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 764 B After Width: | Height: | Size: 658 B |
|
@ -1,3 +1,3 @@
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.77783 2.71114V8.24003C1.77783 13.8934 8.00005 15.1111 8.00005 15.1111C8.00005 15.1111 14.2223 13.8934 14.2223 8.24003V2.71114L8.00005 0.888916L1.77783 2.71114ZM7.92899 3.91112C7.42232 3.94668 7.04899 4.39113 7.09343 4.89779L7.37788 8.45335C7.40455 8.76446 7.64455 9.00446 7.95566 9.03113H8.00899C8.33788 9.03113 8.61343 8.78224 8.6401 8.45335L8.92455 4.89779V4.75557C8.87121 4.2489 8.42677 3.87557 7.92899 3.91112ZM8 11.5556C8.43201 11.5556 8.78222 11.2054 8.78222 10.7733C8.78222 10.3413 8.43201 9.99112 8 9.99112C7.56799 9.99112 7.21777 10.3413 7.21777 10.7733C7.21777 11.2054 7.56799 11.5556 8 11.5556Z" fill="#FF4B55"/>
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 9.27V3.05L9 1L16 3.05V9.27C16 15.63 9 17 9 17C9 17 2 15.63 2 9.27ZM8.92011 4.39997C8.35011 4.43997 7.93011 4.93997 7.98011 5.50997L8.30011 9.50997C8.33011 9.85997 8.60011 10.13 8.95011 10.16H9.01011C9.38011 10.16 9.69011 9.87997 9.72011 9.50997L10.0401 5.50997V5.34997C9.98011 4.77997 9.48011 4.35997 8.92011 4.39997ZM9.88012 12.12C9.88012 12.606 9.48613 13 9.00012 13C8.51411 13 8.12012 12.606 8.12012 12.12C8.12012 11.634 8.51411 11.24 9.00012 11.24C9.48613 11.24 9.88012 11.634 9.88012 12.12Z" fill="#020202"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 779 B After Width: | Height: | Size: 673 B |
11
res/img/element-icons/room/default_app.svg
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="20" height="20" fill="url(#paint0_linear)"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 3V9.5H0.00390625L0.00390625 10.5H2V17H0.00390625L0.00390625 18H2V20H3V18H9.5039V20.0005H10.5039V18H17V20H18V18H20.0039V17H18V10.5H20.0039V9.5H18V3H20.0039V2H18V0L17 0V2H10.5039V0.000488281L9.5039 0.000488281V2H3V0L2 0V2H0.00390625L0.00390625 3H2ZM17 3H10.5039V9.5H17V3ZM17 10.5H10.5039V17H17V10.5ZM9.5039 10.5V17H3V10.5H9.5039ZM9.5039 3V9.5H3V3H9.5039Z" fill="white" fill-opacity="0.3" style="mix-blend-mode:lighten"/>
|
||||||
|
<circle opacity="0.8" cx="10.0039" cy="10" r="7.5" stroke="white"/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear" x1="10" y1="0" x2="10" y2="20" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#60A6FF"/>
|
||||||
|
<stop offset="1" stop-color="#418DED"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 900 B |
6
res/img/element-icons/room/default_cal.svg
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="1.99461" y="1.00002" width="18" height="18" rx="2" fill="white" stroke="#FF4B55" stroke-width="2"/>
|
||||||
|
<rect x="2.96777" y="2" width="16.9843" height="5" fill="#FF4B55"/>
|
||||||
|
<rect x="4.96533" y="9" width="2.99723" height="3" rx="0.25" fill="#FF4B55"/>
|
||||||
|
<rect x="11.9585" y="13.0005" width="2.99723" height="3" rx="0.25" fill="#FF4B55"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 442 B |
5
res/img/element-icons/room/default_clock.svg
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="1.49609" y="0.500488" width="19" height="19" rx="3.5" fill="#17191C" stroke="#17191C"/>
|
||||||
|
<path d="M18.9961 10.0005C18.9961 14.4188 15.4144 18.0005 10.9961 18.0005C6.57782 18.0005 2.99609 14.4188 2.99609 10.0005C2.99609 5.58221 6.57782 2.00049 10.9961 2.00049C15.4144 2.00049 18.9961 5.58221 18.9961 10.0005Z" fill="white"/>
|
||||||
|
<path d="M10.9961 6.00049V9.81299L13.4961 11.5005" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 569 B |
4
res/img/element-icons/room/default_doc.svg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="-0.000976562" y="0.000488281" width="20" height="20" rx="4" fill="#FCC639"/>
|
||||||
|
<path d="M1.99902 7.00049H17.999V16.5005C17.999 17.3289 17.3274 18.0005 16.499 18.0005H3.49902C2.6706 18.0005 1.99902 17.3289 1.99902 16.5005V7.00049Z" fill="white"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 364 B |
5
res/img/element-icons/room/ellipsis.svg
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<circle cx="15.5" cy="10" r="1.5" transform="rotate(180 15.5 10)" fill="#15191E"/>
|
||||||
|
<circle cx="10" cy="10" r="1.5" transform="rotate(180 10 10)" fill="#15191E"/>
|
||||||
|
<circle cx="4.5" cy="10" r="1.5" transform="rotate(180 4.5 10)" fill="#15191E"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 358 B |
7
res/img/element-icons/room/pin-upright.svg
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11 18.5982V15H13V18.5982C13 20.5 12.2383 22 12 22C11.7617 22 11 20.5 11 18.5982Z" fill="black"/>
|
||||||
|
<path d="M9.5 6C9.17534 5.83333 7.78566 5.2 6.61693 4C5.4482 2.8 6.12239 2 7.13026 2H12V6H9.5Z" fill="black"/>
|
||||||
|
<path d="M14.5 6C14.8247 5.83333 16.2143 5.2 17.3831 4C18.5518 2.8 17.8776 2 16.8697 2H12V6H14.5Z" fill="black"/>
|
||||||
|
<path d="M9.42857 6H14.5714L15 10H9L9.42857 6Z" fill="black"/>
|
||||||
|
<path d="M12 9C8.93114 9 6.32353 10.6927 5.37867 13.0483C4.96746 14.0735 5.89543 15 7 15H17C18.1046 15 19.0325 14.0735 18.6213 13.0483C17.6765 10.6927 15.0689 9 12 9Z" fill="black"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 681 B |
3
res/img/element-icons/room/room-summary.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM10 12C10 12.5523 10.4477 13 11 13V16.5C11 17.0523 11.4477 17.5 12 17.5H13.5C14.0523 17.5 14.5 17.0523 14.5 16.5C14.5 15.9477 14.0523 15.5 13.5 15.5H13V12C13 11.4477 12.5523 11 12 11H11C10.4477 11 10 11.4477 10 12ZM12 10C12.8284 10 13.5 9.32843 13.5 8.5C13.5 7.67157 12.8284 7 12 7C11.1716 7 10.5 7.67157 10.5 8.5C10.5 9.32843 11.1716 10 12 10Z" fill="black"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 630 B |
2
src/@types/global.d.ts
vendored
|
@ -29,6 +29,7 @@ import {ActiveRoomObserver} from "../ActiveRoomObserver";
|
||||||
import {Notifier} from "../Notifier";
|
import {Notifier} from "../Notifier";
|
||||||
import type {Renderer} from "react-dom";
|
import type {Renderer} from "react-dom";
|
||||||
import RightPanelStore from "../stores/RightPanelStore";
|
import RightPanelStore from "../stores/RightPanelStore";
|
||||||
|
import WidgetStore from "../stores/WidgetStore";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -51,6 +52,7 @@ declare global {
|
||||||
mxSettingsStore: SettingsStore;
|
mxSettingsStore: SettingsStore;
|
||||||
mxNotifier: typeof Notifier;
|
mxNotifier: typeof Notifier;
|
||||||
mxRightPanelStore: RightPanelStore;
|
mxRightPanelStore: RightPanelStore;
|
||||||
|
mxWidgetStore: WidgetStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Document {
|
interface Document {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
Copyright 2017, 2018 New Vector Ltd
|
Copyright 2017, 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");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -67,6 +67,7 @@ import {generateHumanReadableId} from "./utils/NamingUtils";
|
||||||
import {Jitsi} from "./widgets/Jitsi";
|
import {Jitsi} from "./widgets/Jitsi";
|
||||||
import {WidgetType} from "./widgets/WidgetType";
|
import {WidgetType} from "./widgets/WidgetType";
|
||||||
import {SettingLevel} from "./settings/SettingLevel";
|
import {SettingLevel} from "./settings/SettingLevel";
|
||||||
|
import {base32} from "rfc4648";
|
||||||
|
|
||||||
global.mxCalls = {
|
global.mxCalls = {
|
||||||
//room_id: MatrixCall
|
//room_id: MatrixCall
|
||||||
|
@ -388,10 +389,21 @@ async function _startCallApp(roomId, type) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const confId = `JitsiConference${generateHumanReadableId()}`;
|
|
||||||
const jitsiDomain = Jitsi.getInstance().preferredDomain;
|
const jitsiDomain = Jitsi.getInstance().preferredDomain;
|
||||||
|
const jitsiAuth = await Jitsi.getInstance().getJitsiAuth();
|
||||||
|
let confId;
|
||||||
|
if (jitsiAuth === 'openidtoken-jwt') {
|
||||||
|
// Create conference ID from room ID
|
||||||
|
// For compatibility with Jitsi, use base32 without padding.
|
||||||
|
// More details here:
|
||||||
|
// https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification
|
||||||
|
confId = base32.stringify(Buffer.from(roomId), { pad: false });
|
||||||
|
} else {
|
||||||
|
// Create a random human readable conference ID
|
||||||
|
confId = `JitsiConference${generateHumanReadableId()}`;
|
||||||
|
}
|
||||||
|
|
||||||
let widgetUrl = WidgetUtils.getLocalJitsiWrapperUrl();
|
let widgetUrl = WidgetUtils.getLocalJitsiWrapperUrl({auth: jitsiAuth});
|
||||||
|
|
||||||
// TODO: Remove URL hacks when the mobile clients eventually support v2 widgets
|
// TODO: Remove URL hacks when the mobile clients eventually support v2 widgets
|
||||||
const parsedUrl = new URL(widgetUrl);
|
const parsedUrl = new URL(widgetUrl);
|
||||||
|
@ -403,6 +415,7 @@ async function _startCallApp(roomId, type) {
|
||||||
conferenceId: confId,
|
conferenceId: confId,
|
||||||
isAudioOnly: type === 'voice',
|
isAudioOnly: type === 'voice',
|
||||||
domain: jitsiDomain,
|
domain: jitsiDomain,
|
||||||
|
auth: jitsiAuth,
|
||||||
};
|
};
|
||||||
|
|
||||||
const widgetId = (
|
const widgetId = (
|
||||||
|
|
|
@ -154,6 +154,19 @@ export const Commands = [
|
||||||
},
|
},
|
||||||
category: CommandCategories.messages,
|
category: CommandCategories.messages,
|
||||||
}),
|
}),
|
||||||
|
new Command({
|
||||||
|
command: 'lenny',
|
||||||
|
args: '<message>',
|
||||||
|
description: _td('Prepends ( ͡° ͜ʖ ͡°) to a plain-text message'),
|
||||||
|
runFn: function(roomId, args) {
|
||||||
|
let message = '( ͡° ͜ʖ ͡°)';
|
||||||
|
if (args) {
|
||||||
|
message = message + ' ' + args;
|
||||||
|
}
|
||||||
|
return success(MatrixClientPeg.get().sendTextMessage(roomId, message));
|
||||||
|
},
|
||||||
|
category: CommandCategories.messages,
|
||||||
|
}),
|
||||||
new Command({
|
new Command({
|
||||||
command: 'plain',
|
command: 'plain',
|
||||||
args: '<message>',
|
args: '<message>',
|
||||||
|
|
|
@ -186,7 +186,14 @@ export default class WidgetMessaging {
|
||||||
isUserWidget: this.isUserWidget,
|
isUserWidget: this.isUserWidget,
|
||||||
|
|
||||||
onFinished: async (confirm) => {
|
onFinished: async (confirm) => {
|
||||||
const responseBody = {success: confirm};
|
const responseBody = {
|
||||||
|
// Legacy (early draft) fields
|
||||||
|
success: confirm,
|
||||||
|
|
||||||
|
// New style MSC1960 fields
|
||||||
|
state: confirm ? "allowed" : "blocked",
|
||||||
|
original_request_id: ev.requestId, // eslint-disable-line camelcase
|
||||||
|
};
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
const credentials = await MatrixClientPeg.get().getOpenIdToken();
|
const credentials = await MatrixClientPeg.get().getOpenIdToken();
|
||||||
Object.assign(responseBody, credentials);
|
Object.assign(responseBody, credentials);
|
||||||
|
|
|
@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {CSSProperties, useRef, useState} from "react";
|
import React, {CSSProperties, RefObject, useRef, useState} from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
|
||||||
|
@ -416,8 +416,8 @@ export const aboveLeftOf = (elementRect: DOMRect, chevronFace = ChevronFace.None
|
||||||
return menuOptions;
|
return menuOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useContextMenu = () => {
|
export const useContextMenu = (): [boolean, RefObject<HTMLElement>, () => void, () => void, (val: boolean) => void] => {
|
||||||
const button = useRef(null);
|
const button = useRef<HTMLElement>(null);
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const open = () => {
|
const open = () => {
|
||||||
setIsOpen(true);
|
setIsOpen(true);
|
||||||
|
|
|
@ -23,6 +23,8 @@ import * as sdk from '../../index';
|
||||||
import {MatrixClientPeg} from '../../MatrixClientPeg';
|
import {MatrixClientPeg} from '../../MatrixClientPeg';
|
||||||
import EventIndexPeg from "../../indexing/EventIndexPeg";
|
import EventIndexPeg from "../../indexing/EventIndexPeg";
|
||||||
import { _t } from '../../languageHandler';
|
import { _t } from '../../languageHandler';
|
||||||
|
import BaseCard from "../views/right_panel/BaseCard";
|
||||||
|
import {RightPanelPhases} from "../../stores/RightPanelStorePhases";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Component which shows the filtered file using a TimelinePanel
|
* Component which shows the filtered file using a TimelinePanel
|
||||||
|
@ -30,6 +32,7 @@ import { _t } from '../../languageHandler';
|
||||||
class FilePanel extends React.Component {
|
class FilePanel extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
roomId: PropTypes.string.isRequired,
|
roomId: PropTypes.string.isRequired,
|
||||||
|
onClose: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is used to track if a decrypted event was a live event and should be
|
// This is used to track if a decrypted event was a live event and should be
|
||||||
|
@ -188,18 +191,26 @@ class FilePanel extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
return <div className="mx_FilePanel mx_RoomView_messageListWrapper">
|
return <BaseCard
|
||||||
|
className="mx_FilePanel mx_RoomView_messageListWrapper"
|
||||||
|
onClose={this.props.onClose}
|
||||||
|
previousPhase={RightPanelPhases.RoomSummary}
|
||||||
|
>
|
||||||
<div className="mx_RoomView_empty">
|
<div className="mx_RoomView_empty">
|
||||||
{ _t("You must <a>register</a> to use this functionality",
|
{ _t("You must <a>register</a> to use this functionality",
|
||||||
{},
|
{},
|
||||||
{ 'a': (sub) => <a href="#/register" key="sub">{ sub }</a> })
|
{ 'a': (sub) => <a href="#/register" key="sub">{ sub }</a> })
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</BaseCard>;
|
||||||
} else if (this.noRoom) {
|
} else if (this.noRoom) {
|
||||||
return <div className="mx_FilePanel mx_RoomView_messageListWrapper">
|
return <BaseCard
|
||||||
|
className="mx_FilePanel mx_RoomView_messageListWrapper"
|
||||||
|
onClose={this.props.onClose}
|
||||||
|
previousPhase={RightPanelPhases.RoomSummary}
|
||||||
|
>
|
||||||
<div className="mx_RoomView_empty">{ _t("You must join the room to see its files") }</div>
|
<div className="mx_RoomView_empty">{ _t("You must join the room to see its files") }</div>
|
||||||
</div>;
|
</BaseCard>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// wrap a TimelinePanel with the jump-to-event bits turned off.
|
// wrap a TimelinePanel with the jump-to-event bits turned off.
|
||||||
|
@ -215,7 +226,12 @@ class FilePanel extends React.Component {
|
||||||
// console.log("rendering TimelinePanel for timelineSet " + this.state.timelineSet.room.roomId + " " +
|
// console.log("rendering TimelinePanel for timelineSet " + this.state.timelineSet.room.roomId + " " +
|
||||||
// "(" + this.state.timelineSet._timelines.join(", ") + ")" + " with key " + this.props.roomId);
|
// "(" + this.state.timelineSet._timelines.join(", ") + ")" + " with key " + this.props.roomId);
|
||||||
return (
|
return (
|
||||||
<div className="mx_FilePanel" role="tabpanel">
|
<BaseCard
|
||||||
|
className="mx_FilePanel"
|
||||||
|
onClose={this.props.onClose}
|
||||||
|
previousPhase={RightPanelPhases.RoomSummary}
|
||||||
|
withoutScrollContainer
|
||||||
|
>
|
||||||
<TimelinePanel
|
<TimelinePanel
|
||||||
manageReadReceipts={false}
|
manageReadReceipts={false}
|
||||||
manageReadMarkers={false}
|
manageReadMarkers={false}
|
||||||
|
@ -226,13 +242,17 @@ class FilePanel extends React.Component {
|
||||||
resizeNotifier={this.props.resizeNotifier}
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
empty={emptyState}
|
empty={emptyState}
|
||||||
/>
|
/>
|
||||||
</div>
|
</BaseCard>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<div className="mx_FilePanel" role="tabpanel">
|
<BaseCard
|
||||||
|
className="mx_FilePanel"
|
||||||
|
onClose={this.props.onClose}
|
||||||
|
previousPhase={RightPanelPhases.RoomSummary}
|
||||||
|
>
|
||||||
<Loader />
|
<Loader />
|
||||||
</div>
|
</BaseCard>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1322,7 +1322,7 @@ export default class GroupView extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
<GroupHeaderButtons />
|
<GroupHeaderButtons />
|
||||||
</div>
|
</div>
|
||||||
<MainSplit panel={rightPanel}>
|
<MainSplit panel={rightPanel} resizeNotifier={this.props.resizeNotifier}>
|
||||||
<AutoHideScrollbar className="mx_GroupView_body">
|
<AutoHideScrollbar className="mx_GroupView_body">
|
||||||
{ this._getMembershipSection() }
|
{ this._getMembershipSection() }
|
||||||
{ this._getGroupSection() }
|
{ this._getGroupSection() }
|
||||||
|
|
|
@ -76,7 +76,6 @@ interface IProps {
|
||||||
hideToSRUsers: boolean;
|
hideToSRUsers: boolean;
|
||||||
resizeNotifier: ResizeNotifier;
|
resizeNotifier: ResizeNotifier;
|
||||||
middleDisabled: boolean;
|
middleDisabled: boolean;
|
||||||
initialEventPixelOffset: number;
|
|
||||||
leftDisabled: boolean;
|
leftDisabled: boolean;
|
||||||
rightDisabled: boolean;
|
rightDisabled: boolean;
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
|
@ -257,6 +256,12 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
window.localStorage.setItem("mx_lhs_size", '' + size);
|
window.localStorage.setItem("mx_lhs_size", '' + size);
|
||||||
this.props.resizeNotifier.notifyLeftHandleResized();
|
this.props.resizeNotifier.notifyLeftHandleResized();
|
||||||
},
|
},
|
||||||
|
onResizeStart: () => {
|
||||||
|
this.props.resizeNotifier.startResizing();
|
||||||
|
},
|
||||||
|
onResizeStop: () => {
|
||||||
|
this.props.resizeNotifier.stopResizing();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const resizer = new Resizer(
|
const resizer = new Resizer(
|
||||||
this._resizeContainer.current,
|
this._resizeContainer.current,
|
||||||
|
@ -629,7 +634,6 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
thirdPartyInvite={this.props.thirdPartyInvite}
|
thirdPartyInvite={this.props.thirdPartyInvite}
|
||||||
oobData={this.props.roomOobData}
|
oobData={this.props.roomOobData}
|
||||||
viaServers={this.props.viaServers}
|
viaServers={this.props.viaServers}
|
||||||
eventPixelOffset={this.props.initialEventPixelOffset}
|
|
||||||
key={this.props.currentRoomId || 'roomview'}
|
key={this.props.currentRoomId || 'roomview'}
|
||||||
disabled={this.props.middleDisabled}
|
disabled={this.props.middleDisabled}
|
||||||
ConferenceHandler={this.props.ConferenceHandler}
|
ConferenceHandler={this.props.ConferenceHandler}
|
||||||
|
@ -650,12 +654,13 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PageTypes.UserView:
|
case PageTypes.UserView:
|
||||||
pageElement = <UserView userId={this.props.currentUserId} />;
|
pageElement = <UserView userId={this.props.currentUserId} resizeNotifier={this.props.resizeNotifier} />;
|
||||||
break;
|
break;
|
||||||
case PageTypes.GroupView:
|
case PageTypes.GroupView:
|
||||||
pageElement = <GroupView
|
pageElement = <GroupView
|
||||||
groupId={this.props.currentGroupId}
|
groupId={this.props.currentGroupId}
|
||||||
isNew={this.props.currentGroupIsNew}
|
isNew={this.props.currentGroupIsNew}
|
||||||
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
/>;
|
/>;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,18 @@ import React from 'react';
|
||||||
import { Resizable } from 're-resizable';
|
import { Resizable } from 're-resizable';
|
||||||
|
|
||||||
export default class MainSplit extends React.Component {
|
export default class MainSplit extends React.Component {
|
||||||
_onResized = (event, direction, refToElement, delta) => {
|
_onResizeStart = () => {
|
||||||
|
this.props.resizeNotifier.startResizing();
|
||||||
|
};
|
||||||
|
|
||||||
|
_onResize = () => {
|
||||||
|
this.props.resizeNotifier.notifyRightHandleResized();
|
||||||
|
};
|
||||||
|
|
||||||
|
_onResizeStop = (event, direction, refToElement, delta) => {
|
||||||
|
this.props.resizeNotifier.stopResizing();
|
||||||
window.localStorage.setItem("mx_rhs_size", this._loadSidePanelSize().width + delta.width);
|
window.localStorage.setItem("mx_rhs_size", this._loadSidePanelSize().width + delta.width);
|
||||||
}
|
};
|
||||||
|
|
||||||
_loadSidePanelSize() {
|
_loadSidePanelSize() {
|
||||||
let rhsSize = parseInt(window.localStorage.getItem("mx_rhs_size"), 10);
|
let rhsSize = parseInt(window.localStorage.getItem("mx_rhs_size"), 10);
|
||||||
|
@ -58,7 +67,9 @@ export default class MainSplit extends React.Component {
|
||||||
bottomLeft: false,
|
bottomLeft: false,
|
||||||
topLeft: false,
|
topLeft: false,
|
||||||
}}
|
}}
|
||||||
onResizeStop={this._onResized}
|
onResizeStart={this._onResizeStart}
|
||||||
|
onResize={this._onResize}
|
||||||
|
onResizeStop={this._onResizeStop}
|
||||||
className="mx_RightPanel_ResizeWrapper"
|
className="mx_RightPanel_ResizeWrapper"
|
||||||
handleClasses={{left: "mx_RightPanel_ResizeHandle"}}
|
handleClasses={{left: "mx_RightPanel_ResizeHandle"}}
|
||||||
>
|
>
|
||||||
|
|
|
@ -17,14 +17,21 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
import { _t } from '../../languageHandler';
|
import { _t } from '../../languageHandler';
|
||||||
import {MatrixClientPeg} from "../../MatrixClientPeg";
|
import {MatrixClientPeg} from "../../MatrixClientPeg";
|
||||||
import * as sdk from "../../index";
|
import * as sdk from "../../index";
|
||||||
|
import BaseCard from "../views/right_panel/BaseCard";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Component which shows the global notification list using a TimelinePanel
|
* Component which shows the global notification list using a TimelinePanel
|
||||||
*/
|
*/
|
||||||
class NotificationPanel extends React.Component {
|
class NotificationPanel extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
onClose: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
// wrap a TimelinePanel with the jump-to-event bits turned off.
|
// wrap a TimelinePanel with the jump-to-event bits turned off.
|
||||||
const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
||||||
|
@ -35,28 +42,27 @@ class NotificationPanel extends React.Component {
|
||||||
<p>{_t('You have no visible notifications in this room.')}</p>
|
<p>{_t('You have no visible notifications in this room.')}</p>
|
||||||
</div>);
|
</div>);
|
||||||
|
|
||||||
|
let content;
|
||||||
const timelineSet = MatrixClientPeg.get().getNotifTimelineSet();
|
const timelineSet = MatrixClientPeg.get().getNotifTimelineSet();
|
||||||
if (timelineSet) {
|
if (timelineSet) {
|
||||||
return (
|
content = (
|
||||||
<div className="mx_NotificationPanel" role="tabpanel">
|
<TimelinePanel
|
||||||
<TimelinePanel
|
manageReadReceipts={false}
|
||||||
manageReadReceipts={false}
|
manageReadMarkers={false}
|
||||||
manageReadMarkers={false}
|
timelineSet={timelineSet}
|
||||||
timelineSet={timelineSet}
|
showUrlPreview={false}
|
||||||
showUrlPreview={false}
|
tileShape="notif"
|
||||||
tileShape="notif"
|
empty={emptyState}
|
||||||
empty={emptyState}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
console.error("No notifTimelineSet available!");
|
console.error("No notifTimelineSet available!");
|
||||||
return (
|
content = <Loader />;
|
||||||
<div className="mx_NotificationPanel" role="tabpanel">
|
|
||||||
<Loader />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return <BaseCard className="mx_NotificationPanel" onClose={this.props.onClose} withoutScrollContainer>
|
||||||
|
{ content }
|
||||||
|
</BaseCard>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,9 @@ import {RightPanelPhases, RIGHT_PANEL_PHASES_NO_ARGS} from "../../stores/RightPa
|
||||||
import RightPanelStore from "../../stores/RightPanelStore";
|
import RightPanelStore from "../../stores/RightPanelStore";
|
||||||
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
||||||
import {Action} from "../../dispatcher/actions";
|
import {Action} from "../../dispatcher/actions";
|
||||||
|
import RoomSummaryCard from "../views/right_panel/RoomSummaryCard";
|
||||||
|
import WidgetCard from "../views/right_panel/WidgetCard";
|
||||||
|
import defaultDispatcher from "../../dispatcher/dispatcher";
|
||||||
|
|
||||||
export default class RightPanel extends React.Component {
|
export default class RightPanel extends React.Component {
|
||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
|
@ -47,10 +50,10 @@ export default class RightPanel extends React.Component {
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
...RightPanelStore.getSharedInstance().roomPanelPhaseParams,
|
||||||
phase: this._getPhaseFromProps(),
|
phase: this._getPhaseFromProps(),
|
||||||
isUserPrivilegedInGroup: null,
|
isUserPrivilegedInGroup: null,
|
||||||
member: this._getUserForPanel(),
|
member: this._getUserForPanel(),
|
||||||
verificationRequest: RightPanelStore.getSharedInstance().roomPanelPhaseParams.verificationRequest,
|
|
||||||
};
|
};
|
||||||
this.onAction = this.onAction.bind(this);
|
this.onAction = this.onAction.bind(this);
|
||||||
this.onRoomStateMember = this.onRoomStateMember.bind(this);
|
this.onRoomStateMember = this.onRoomStateMember.bind(this);
|
||||||
|
@ -102,10 +105,6 @@ export default class RightPanel extends React.Component {
|
||||||
}
|
}
|
||||||
return RightPanelPhases.RoomMemberInfo;
|
return RightPanelPhases.RoomMemberInfo;
|
||||||
} else {
|
} else {
|
||||||
if (!RIGHT_PANEL_PHASES_NO_ARGS.includes(rps.roomPanelPhase)) {
|
|
||||||
dis.dispatch({action: Action.SetRightPanelPhase, phase: RightPanelPhases.RoomMemberList});
|
|
||||||
return RightPanelPhases.RoomMemberList;
|
|
||||||
}
|
|
||||||
return rps.roomPanelPhase;
|
return rps.roomPanelPhase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,6 +185,7 @@ export default class RightPanel extends React.Component {
|
||||||
event: payload.event,
|
event: payload.event,
|
||||||
verificationRequest: payload.verificationRequest,
|
verificationRequest: payload.verificationRequest,
|
||||||
verificationRequestPromise: payload.verificationRequestPromise,
|
verificationRequestPromise: payload.verificationRequestPromise,
|
||||||
|
widgetId: payload.widgetId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,6 +213,14 @@ export default class RightPanel extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onClose = () => {
|
||||||
|
// the RightPanelStore has no way of knowing which mode room/group it is in, so we handle closing here
|
||||||
|
defaultDispatcher.dispatch({
|
||||||
|
action: Action.ToggleRightPanel,
|
||||||
|
type: this.props.groupId ? "group" : "room",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const MemberList = sdk.getComponent('rooms.MemberList');
|
const MemberList = sdk.getComponent('rooms.MemberList');
|
||||||
const UserInfo = sdk.getComponent('right_panel.UserInfo');
|
const UserInfo = sdk.getComponent('right_panel.UserInfo');
|
||||||
|
@ -225,36 +233,42 @@ export default class RightPanel extends React.Component {
|
||||||
const GroupRoomInfo = sdk.getComponent('groups.GroupRoomInfo');
|
const GroupRoomInfo = sdk.getComponent('groups.GroupRoomInfo');
|
||||||
|
|
||||||
let panel = <div />;
|
let panel = <div />;
|
||||||
|
const roomId = this.props.room ? this.props.room.roomId : undefined;
|
||||||
|
|
||||||
switch (this.state.phase) {
|
switch (this.state.phase) {
|
||||||
case RightPanelPhases.RoomMemberList:
|
case RightPanelPhases.RoomMemberList:
|
||||||
if (this.props.room.roomId) {
|
if (roomId) {
|
||||||
panel = <MemberList roomId={this.props.room.roomId} key={this.props.room.roomId} />;
|
panel = <MemberList roomId={roomId} key={roomId} onClose={this.onClose} />;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RightPanelPhases.GroupMemberList:
|
case RightPanelPhases.GroupMemberList:
|
||||||
if (this.props.groupId) {
|
if (this.props.groupId) {
|
||||||
panel = <GroupMemberList groupId={this.props.groupId} key={this.props.groupId} />;
|
panel = <GroupMemberList groupId={this.props.groupId} key={this.props.groupId} />;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RightPanelPhases.GroupRoomList:
|
case RightPanelPhases.GroupRoomList:
|
||||||
panel = <GroupRoomList groupId={this.props.groupId} key={this.props.groupId} />;
|
panel = <GroupRoomList groupId={this.props.groupId} key={this.props.groupId} />;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RightPanelPhases.RoomMemberInfo:
|
case RightPanelPhases.RoomMemberInfo:
|
||||||
case RightPanelPhases.EncryptionPanel:
|
case RightPanelPhases.EncryptionPanel:
|
||||||
panel = <UserInfo
|
panel = <UserInfo
|
||||||
user={this.state.member}
|
user={this.state.member}
|
||||||
roomId={this.props.room.roomId}
|
room={this.props.room}
|
||||||
key={this.props.room.roomId || this.state.member.userId}
|
key={roomId || this.state.member.userId}
|
||||||
onClose={this.onCloseUserInfo}
|
onClose={this.onCloseUserInfo}
|
||||||
phase={this.state.phase}
|
phase={this.state.phase}
|
||||||
verificationRequest={this.state.verificationRequest}
|
verificationRequest={this.state.verificationRequest}
|
||||||
verificationRequestPromise={this.state.verificationRequestPromise}
|
verificationRequestPromise={this.state.verificationRequestPromise}
|
||||||
/>;
|
/>;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RightPanelPhases.Room3pidMemberInfo:
|
case RightPanelPhases.Room3pidMemberInfo:
|
||||||
panel = <ThirdPartyMemberInfo event={this.state.event} key={this.props.room.roomId} />;
|
panel = <ThirdPartyMemberInfo event={this.state.event} key={roomId} />;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RightPanelPhases.GroupMemberInfo:
|
case RightPanelPhases.GroupMemberInfo:
|
||||||
panel = <UserInfo
|
panel = <UserInfo
|
||||||
user={this.state.member}
|
user={this.state.member}
|
||||||
|
@ -262,17 +276,28 @@ export default class RightPanel extends React.Component {
|
||||||
key={this.state.member.userId}
|
key={this.state.member.userId}
|
||||||
onClose={this.onCloseUserInfo} />;
|
onClose={this.onCloseUserInfo} />;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RightPanelPhases.GroupRoomInfo:
|
case RightPanelPhases.GroupRoomInfo:
|
||||||
panel = <GroupRoomInfo
|
panel = <GroupRoomInfo
|
||||||
groupRoomId={this.state.groupRoomId}
|
groupRoomId={this.state.groupRoomId}
|
||||||
groupId={this.props.groupId}
|
groupId={this.props.groupId}
|
||||||
key={this.state.groupRoomId} />;
|
key={this.state.groupRoomId} />;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RightPanelPhases.NotificationPanel:
|
case RightPanelPhases.NotificationPanel:
|
||||||
panel = <NotificationPanel />;
|
panel = <NotificationPanel onClose={this.onClose} />;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RightPanelPhases.FilePanel:
|
case RightPanelPhases.FilePanel:
|
||||||
panel = <FilePanel roomId={this.props.room.roomId} resizeNotifier={this.props.resizeNotifier} />;
|
panel = <FilePanel roomId={roomId} resizeNotifier={this.props.resizeNotifier} onClose={this.onClose} />;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RightPanelPhases.RoomSummary:
|
||||||
|
panel = <RoomSummaryCard room={this.props.room} onClose={this.onClose} />;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RightPanelPhases.Widget:
|
||||||
|
panel = <WidgetCard room={this.props.room} widgetId={this.state.widgetId} onClose={this.onClose} />;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,7 @@ export default class ScrollPanel extends React.Component {
|
||||||
this._pendingFillRequests = {b: null, f: null};
|
this._pendingFillRequests = {b: null, f: null};
|
||||||
|
|
||||||
if (this.props.resizeNotifier) {
|
if (this.props.resizeNotifier) {
|
||||||
this.props.resizeNotifier.on("middlePanelResized", this.onResize);
|
this.props.resizeNotifier.on("middlePanelResizedNoisy", this.onResize);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.resetScrollState();
|
this.resetScrollState();
|
||||||
|
@ -193,11 +193,12 @@ export default class ScrollPanel extends React.Component {
|
||||||
this.unmounted = true;
|
this.unmounted = true;
|
||||||
|
|
||||||
if (this.props.resizeNotifier) {
|
if (this.props.resizeNotifier) {
|
||||||
this.props.resizeNotifier.removeListener("middlePanelResized", this.onResize);
|
this.props.resizeNotifier.removeListener("middlePanelResizedNoisy", this.onResize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onScroll = ev => {
|
onScroll = ev => {
|
||||||
|
if (this.props.resizeNotifier.isResizing) return; // skip scroll events caused by resizing
|
||||||
debuglog("onScroll", this._getScrollNode().scrollTop);
|
debuglog("onScroll", this._getScrollNode().scrollTop);
|
||||||
this._scrollTimeout.restart();
|
this._scrollTimeout.restart();
|
||||||
this._saveScrollState();
|
this._saveScrollState();
|
||||||
|
@ -207,6 +208,7 @@ export default class ScrollPanel extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
onResize = () => {
|
onResize = () => {
|
||||||
|
debuglog("onResize");
|
||||||
this.checkScroll();
|
this.checkScroll();
|
||||||
// update preventShrinkingState if present
|
// update preventShrinkingState if present
|
||||||
if (this.preventShrinkingState) {
|
if (this.preventShrinkingState) {
|
||||||
|
@ -236,7 +238,6 @@ export default class ScrollPanel extends React.Component {
|
||||||
// when scrolled all the way down. E.g. Chrome 72 on debian.
|
// when scrolled all the way down. E.g. Chrome 72 on debian.
|
||||||
// so check difference <= 1;
|
// so check difference <= 1;
|
||||||
return Math.abs(sn.scrollHeight - (sn.scrollTop + sn.clientHeight)) <= 1;
|
return Math.abs(sn.scrollHeight - (sn.scrollTop + sn.clientHeight)) <= 1;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// returns the vertical height in the given direction that can be removed from
|
// returns the vertical height in the given direction that can be removed from
|
||||||
|
|
|
@ -104,8 +104,8 @@ class TimelinePanel extends React.Component {
|
||||||
// shape property to be passed to EventTiles
|
// shape property to be passed to EventTiles
|
||||||
tileShape: PropTypes.string,
|
tileShape: PropTypes.string,
|
||||||
|
|
||||||
// placeholder text to use if the timeline is empty
|
// placeholder to use if the timeline is empty
|
||||||
empty: PropTypes.string,
|
empty: PropTypes.node,
|
||||||
|
|
||||||
// whether to show reactions for an event
|
// whether to show reactions for an event
|
||||||
showReactions: PropTypes.bool,
|
showReactions: PropTypes.bool,
|
||||||
|
|
|
@ -80,7 +80,9 @@ export default class UserView extends React.Component {
|
||||||
const RightPanel = sdk.getComponent('structures.RightPanel');
|
const RightPanel = sdk.getComponent('structures.RightPanel');
|
||||||
const MainSplit = sdk.getComponent('structures.MainSplit');
|
const MainSplit = sdk.getComponent('structures.MainSplit');
|
||||||
const panel = <RightPanel user={this.state.member} />;
|
const panel = <RightPanel user={this.state.member} />;
|
||||||
return (<MainSplit panel={panel}><HomePage /></MainSplit>);
|
return (<MainSplit panel={panel} resizeNotifier={this.props.resizeNotifier}>
|
||||||
|
<HomePage />
|
||||||
|
</MainSplit>);
|
||||||
} else {
|
} else {
|
||||||
return (<div />);
|
return (<div />);
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,11 @@ export default class LoginComponent extends React.Component {
|
||||||
'm.login.cas': () => this._renderSsoStep("cas"),
|
'm.login.cas': () => this._renderSsoStep("cas"),
|
||||||
'm.login.sso': () => this._renderSsoStep("sso"),
|
'm.login.sso': () => this._renderSsoStep("sso"),
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
UNSAFE_componentWillMount() {
|
||||||
this._initLoginLogic();
|
this._initLoginLogic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ interface IOptionListProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IOptionProps extends React.ComponentProps<typeof MenuItem> {
|
interface IOptionProps extends React.ComponentProps<typeof MenuItem> {
|
||||||
iconClassName: string;
|
iconClassName?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ICheckboxProps extends React.ComponentProps<typeof MenuItemCheckbox> {
|
interface ICheckboxProps extends React.ComponentProps<typeof MenuItemCheckbox> {
|
||||||
|
@ -92,7 +92,7 @@ export const IconizedContextMenuCheckbox: React.FC<ICheckboxProps> = ({
|
||||||
|
|
||||||
export const IconizedContextMenuOption: React.FC<IOptionProps> = ({label, iconClassName, ...props}) => {
|
export const IconizedContextMenuOption: React.FC<IOptionProps> = ({label, iconClassName, ...props}) => {
|
||||||
return <MenuItem {...props} label={label}>
|
return <MenuItem {...props} label={label}>
|
||||||
<span className={classNames("mx_IconizedContextMenu_icon", iconClassName)} />
|
{ iconClassName && <span className={classNames("mx_IconizedContextMenu_icon", iconClassName)} /> }
|
||||||
<span className="mx_IconizedContextMenu_label">{label}</span>
|
<span className="mx_IconizedContextMenu_label">{label}</span>
|
||||||
</MenuItem>;
|
</MenuItem>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,6 +26,9 @@ export default class WidgetContextMenu extends React.Component {
|
||||||
// Callback for when the revoke button is clicked. Required.
|
// Callback for when the revoke button is clicked. Required.
|
||||||
onRevokeClicked: PropTypes.func.isRequired,
|
onRevokeClicked: PropTypes.func.isRequired,
|
||||||
|
|
||||||
|
// Callback for when the unpin button is clicked. Required.
|
||||||
|
onUnpinClicked: PropTypes.func.isRequired,
|
||||||
|
|
||||||
// Callback for when the snapshot button is clicked. Button not shown
|
// Callback for when the snapshot button is clicked. Button not shown
|
||||||
// without a callback.
|
// without a callback.
|
||||||
onSnapshotClicked: PropTypes.func,
|
onSnapshotClicked: PropTypes.func,
|
||||||
|
@ -70,6 +73,8 @@ export default class WidgetContextMenu extends React.Component {
|
||||||
this.proxyClick(this.props.onRevokeClicked);
|
this.proxyClick(this.props.onRevokeClicked);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onUnpinClicked = () => this.proxyClick(this.props.onUnpinClicked);
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const options = [];
|
const options = [];
|
||||||
|
|
||||||
|
@ -81,6 +86,12 @@ export default class WidgetContextMenu extends React.Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.push(
|
||||||
|
<MenuItem className="mx_WidgetContextMenu_option" onClick={this.onUnpinClicked} key="unpin">
|
||||||
|
{_t("Unpin")}
|
||||||
|
</MenuItem>,
|
||||||
|
);
|
||||||
|
|
||||||
if (this.props.onReloadClicked) {
|
if (this.props.onReloadClicked) {
|
||||||
options.push(
|
options.push(
|
||||||
<MenuItem className='mx_WidgetContextMenu_option' onClick={this.onReloadClicked} key='reload'>
|
<MenuItem className='mx_WidgetContextMenu_option' onClick={this.onReloadClicked} key='reload'>
|
||||||
|
|
|
@ -42,6 +42,8 @@ import {WidgetType} from "../../../widgets/WidgetType";
|
||||||
import {Capability} from "../../../widgets/WidgetApi";
|
import {Capability} from "../../../widgets/WidgetApi";
|
||||||
import {sleep} from "../../../utils/promise";
|
import {sleep} from "../../../utils/promise";
|
||||||
import {SettingLevel} from "../../../settings/SettingLevel";
|
import {SettingLevel} from "../../../settings/SettingLevel";
|
||||||
|
import WidgetStore from "../../../stores/WidgetStore";
|
||||||
|
import {Action} from "../../../dispatcher/actions";
|
||||||
|
|
||||||
const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:'];
|
const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:'];
|
||||||
const ENABLE_REACT_PERF = false;
|
const ENABLE_REACT_PERF = false;
|
||||||
|
@ -100,6 +102,8 @@ export default class AppTile extends React.Component {
|
||||||
_getNewState(newProps) {
|
_getNewState(newProps) {
|
||||||
// This is a function to make the impact of calling SettingsStore slightly less
|
// This is a function to make the impact of calling SettingsStore slightly less
|
||||||
const hasPermissionToLoad = () => {
|
const hasPermissionToLoad = () => {
|
||||||
|
if (this._usingLocalWidget()) return true;
|
||||||
|
|
||||||
const currentlyAllowedWidgets = SettingsStore.getValue("allowedWidgets", newProps.room.roomId);
|
const currentlyAllowedWidgets = SettingsStore.getValue("allowedWidgets", newProps.room.roomId);
|
||||||
return !!currentlyAllowedWidgets[newProps.app.eventId];
|
return !!currentlyAllowedWidgets[newProps.app.eventId];
|
||||||
};
|
};
|
||||||
|
@ -310,35 +314,12 @@ export default class AppTile extends React.Component {
|
||||||
if (this.props.onEditClick) {
|
if (this.props.onEditClick) {
|
||||||
this.props.onEditClick();
|
this.props.onEditClick();
|
||||||
} else {
|
} else {
|
||||||
// TODO: Open the right manager for the widget
|
WidgetUtils.editWidget(this.props.room, this.props.app);
|
||||||
if (SettingsStore.getValue("feature_many_integration_managers")) {
|
|
||||||
IntegrationManagers.sharedInstance().openAll(
|
|
||||||
this.props.room,
|
|
||||||
'type_' + this.props.app.type,
|
|
||||||
this.props.app.id,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
IntegrationManagers.sharedInstance().getPrimaryManager().open(
|
|
||||||
this.props.room,
|
|
||||||
'type_' + this.props.app.type,
|
|
||||||
this.props.app.id,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onSnapshotClick() {
|
_onSnapshotClick() {
|
||||||
console.log("Requesting widget snapshot");
|
WidgetUtils.snapshotWidget(this.props.app);
|
||||||
ActiveWidgetStore.getWidgetMessaging(this.props.app.id).getScreenshot()
|
|
||||||
.catch((err) => {
|
|
||||||
console.error("Failed to get screenshot", err);
|
|
||||||
})
|
|
||||||
.then((screenshot) => {
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'picture_snapshot',
|
|
||||||
file: screenshot,
|
|
||||||
}, true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -419,6 +400,10 @@ export default class AppTile extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onUnpinClicked = () => {
|
||||||
|
WidgetStore.instance.unpinWidget(this.props.app.id);
|
||||||
|
}
|
||||||
|
|
||||||
_onRevokeClicked() {
|
_onRevokeClicked() {
|
||||||
console.info("Revoke widget permissions - %s", this.props.app.id);
|
console.info("Revoke widget permissions - %s", this.props.app.id);
|
||||||
this._revokeWidgetPermission();
|
this._revokeWidgetPermission();
|
||||||
|
@ -490,12 +475,20 @@ export default class AppTile extends React.Component {
|
||||||
if (payload.widgetId === this.props.app.id) {
|
if (payload.widgetId === this.props.app.id) {
|
||||||
switch (payload.action) {
|
switch (payload.action) {
|
||||||
case 'm.sticker':
|
case 'm.sticker':
|
||||||
if (this._hasCapability('m.sticker')) {
|
if (this._hasCapability('m.sticker')) {
|
||||||
dis.dispatch({action: 'post_sticker_message', data: payload.data});
|
dis.dispatch({action: 'post_sticker_message', data: payload.data});
|
||||||
} else {
|
} else {
|
||||||
console.warn('Ignoring sticker message. Invalid capability');
|
console.warn('Ignoring sticker message. Invalid capability');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Action.AppTileDelete:
|
||||||
|
this._onDeleteClick();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Action.AppTileRevoke:
|
||||||
|
this._onRevokeClicked();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -613,6 +606,15 @@ export default class AppTile extends React.Component {
|
||||||
return uriFromTemplate(u, vars);
|
return uriFromTemplate(u, vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether we're using a local version of the widget rather than loading the
|
||||||
|
* actual widget URL
|
||||||
|
* @returns {bool} true If using a local version of the widget
|
||||||
|
*/
|
||||||
|
_usingLocalWidget() {
|
||||||
|
return WidgetType.JITSI.matches(this.props.app.type);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the URL used in the iframe
|
* Get the URL used in the iframe
|
||||||
* In cases where we supply our own UI for a widget, this is an internal
|
* In cases where we supply our own UI for a widget, this is an internal
|
||||||
|
@ -626,7 +628,10 @@ export default class AppTile extends React.Component {
|
||||||
|
|
||||||
if (WidgetType.JITSI.matches(this.props.app.type)) {
|
if (WidgetType.JITSI.matches(this.props.app.type)) {
|
||||||
console.log("Replacing Jitsi widget URL with local wrapper");
|
console.log("Replacing Jitsi widget URL with local wrapper");
|
||||||
url = WidgetUtils.getLocalJitsiWrapperUrl({forLocalRender: true});
|
url = WidgetUtils.getLocalJitsiWrapperUrl({
|
||||||
|
forLocalRender: true,
|
||||||
|
auth: this.props.app.data ? this.props.app.data.auth : null,
|
||||||
|
});
|
||||||
url = this._addWurlParams(url);
|
url = this._addWurlParams(url);
|
||||||
} else {
|
} else {
|
||||||
url = this._getSafeUrl(this.state.widgetUrl);
|
url = this._getSafeUrl(this.state.widgetUrl);
|
||||||
|
@ -637,7 +642,10 @@ export default class AppTile extends React.Component {
|
||||||
_getPopoutUrl() {
|
_getPopoutUrl() {
|
||||||
if (WidgetType.JITSI.matches(this.props.app.type)) {
|
if (WidgetType.JITSI.matches(this.props.app.type)) {
|
||||||
return this._templatedUrl(
|
return this._templatedUrl(
|
||||||
WidgetUtils.getLocalJitsiWrapperUrl({forLocalRender: false}),
|
WidgetUtils.getLocalJitsiWrapperUrl({
|
||||||
|
forLocalRender: false,
|
||||||
|
auth: this.props.app.data ? this.props.app.data.auth : null,
|
||||||
|
}),
|
||||||
this.props.app.type,
|
this.props.app.type,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -804,14 +812,16 @@ export default class AppTile extends React.Component {
|
||||||
const showMinimiseButton = this.props.showMinimise && this.props.show;
|
const showMinimiseButton = this.props.showMinimise && this.props.show;
|
||||||
const showMaximiseButton = this.props.showMinimise && !this.props.show;
|
const showMaximiseButton = this.props.showMinimise && !this.props.show;
|
||||||
|
|
||||||
let appTileClass;
|
let appTileClasses;
|
||||||
if (this.props.miniMode) {
|
if (this.props.miniMode) {
|
||||||
appTileClass = 'mx_AppTile_mini';
|
appTileClasses = {mx_AppTile_mini: true};
|
||||||
} else if (this.props.fullWidth) {
|
} else if (this.props.fullWidth) {
|
||||||
appTileClass = 'mx_AppTileFullWidth';
|
appTileClasses = {mx_AppTileFullWidth: true};
|
||||||
} else {
|
} else {
|
||||||
appTileClass = 'mx_AppTile';
|
appTileClasses = {mx_AppTile: true};
|
||||||
}
|
}
|
||||||
|
appTileClasses.mx_AppTile_minimised = !this.props.show;
|
||||||
|
appTileClasses = classNames(appTileClasses);
|
||||||
|
|
||||||
const menuBarClasses = classNames({
|
const menuBarClasses = classNames({
|
||||||
mx_AppTileMenuBar: true,
|
mx_AppTileMenuBar: true,
|
||||||
|
@ -831,6 +841,7 @@ export default class AppTile extends React.Component {
|
||||||
contextMenu = (
|
contextMenu = (
|
||||||
<ContextMenu {...aboveLeftOf(elementRect, null)} onFinished={this._closeContextMenu}>
|
<ContextMenu {...aboveLeftOf(elementRect, null)} onFinished={this._closeContextMenu}>
|
||||||
<WidgetContextMenu
|
<WidgetContextMenu
|
||||||
|
onUnpinClicked={this._onUnpinClicked}
|
||||||
onRevokeClicked={this._onRevokeClicked}
|
onRevokeClicked={this._onRevokeClicked}
|
||||||
onEditClicked={showEditButton ? this._onEditClick : undefined}
|
onEditClicked={showEditButton ? this._onEditClick : undefined}
|
||||||
onDeleteClicked={showDeleteButton ? this._onDeleteClick : undefined}
|
onDeleteClicked={showDeleteButton ? this._onDeleteClick : undefined}
|
||||||
|
@ -843,7 +854,7 @@ export default class AppTile extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
<div className={appTileClass} id={this.props.app.id}>
|
<div className={appTileClasses} id={this.props.app.id}>
|
||||||
{ this.props.showMenubar &&
|
{ this.props.showMenubar &&
|
||||||
<div ref={this._menu_bar} className={menuBarClasses} onClick={this.onClickMenuBar}>
|
<div ref={this._menu_bar} className={menuBarClasses} onClick={this.onClickMenuBar}>
|
||||||
<span className="mx_AppTileMenuBarTitle" style={{pointerEvents: (this.props.handleMinimisePointerEvents ? 'all' : false)}}>
|
<span className="mx_AppTileMenuBarTitle" style={{pointerEvents: (this.props.handleMinimisePointerEvents ? 'all' : false)}}>
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2017 New Vector 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 { _t } from '../../../languageHandler';
|
|
||||||
import {IntegrationManagers} from "../../../integrations/IntegrationManagers";
|
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
|
||||||
import AccessibleTooltipButton from "./AccessibleTooltipButton";
|
|
||||||
|
|
||||||
export default class ManageIntegsButton extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
onManageIntegrations = (ev) => {
|
|
||||||
ev.preventDefault();
|
|
||||||
|
|
||||||
const managers = IntegrationManagers.sharedInstance();
|
|
||||||
if (!managers.hasManager()) {
|
|
||||||
managers.openNoManagerDialog();
|
|
||||||
} else {
|
|
||||||
if (SettingsStore.getValue("feature_many_integration_managers")) {
|
|
||||||
managers.openAll(this.props.room);
|
|
||||||
} else {
|
|
||||||
managers.getPrimaryManager().open(this.props.room);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let integrationsButton = <div />;
|
|
||||||
if (IntegrationManagers.sharedInstance().hasManager()) {
|
|
||||||
integrationsButton = (
|
|
||||||
<AccessibleTooltipButton
|
|
||||||
className='mx_RoomHeader_button mx_RoomHeader_manageIntegsButton'
|
|
||||||
title={_t("Manage Integrations")}
|
|
||||||
onClick={this.onManageIntegrations}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return integrationsButton;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ManageIntegsButton.propTypes = {
|
|
||||||
room: PropTypes.object.isRequired,
|
|
||||||
};
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import {throttle} from "lodash";
|
||||||
import ResizeObserver from 'resize-observer-polyfill';
|
import ResizeObserver from 'resize-observer-polyfill';
|
||||||
|
|
||||||
import dis from '../../../dispatcher/dispatcher';
|
import dis from '../../../dispatcher/dispatcher';
|
||||||
|
@ -156,7 +156,7 @@ export default class PersistedElement extends React.Component {
|
||||||
child.style.display = visible ? 'block' : 'none';
|
child.style.display = visible ? 'block' : 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
updateChildPosition(child, parent) {
|
updateChildPosition = throttle((child, parent) => {
|
||||||
if (!child || !parent) return;
|
if (!child || !parent) return;
|
||||||
|
|
||||||
const parentRect = parent.getBoundingClientRect();
|
const parentRect = parent.getBoundingClientRect();
|
||||||
|
@ -167,9 +167,9 @@ export default class PersistedElement extends React.Component {
|
||||||
width: parentRect.width + 'px',
|
width: parentRect.width + 'px',
|
||||||
height: parentRect.height + 'px',
|
height: parentRect.height + 'px',
|
||||||
});
|
});
|
||||||
}
|
}, 100, {trailing: true, leading: true});
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <div ref={this.collectChildContainer}></div>;
|
return <div ref={this.collectChildContainer} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ export default class PersistentApp extends React.Component {
|
||||||
userId={MatrixClientPeg.get().credentials.userId}
|
userId={MatrixClientPeg.get().credentials.userId}
|
||||||
show={true}
|
show={true}
|
||||||
creatorUserId={app.creatorUserId}
|
creatorUserId={app.creatorUserId}
|
||||||
widgetPageTitle={(app.data && app.data.title) ? app.data.title : ''}
|
widgetPageTitle={WidgetUtils.getWidgetDataTitle(app)}
|
||||||
waitForIframeLoad={app.waitForIframeLoad}
|
waitForIframeLoad={app.waitForIframeLoad}
|
||||||
whitelistCapabilities={capWhitelist}
|
whitelistCapabilities={capWhitelist}
|
||||||
showDelete={false}
|
showDelete={false}
|
||||||
|
|
|
@ -57,11 +57,14 @@ export default class PowerSelector extends React.Component {
|
||||||
customValue: this.props.value,
|
customValue: this.props.value,
|
||||||
selectValue: 0,
|
selectValue: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
this._initStateFromProps(this.props);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
|
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
UNSAFE_componentWillMount() {
|
||||||
|
this._initStateFromProps(this.props);
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
UNSAFE_componentWillReceiveProps(newProps) {
|
UNSAFE_componentWillReceiveProps(newProps) {
|
||||||
this._initStateFromProps(newProps);
|
this._initStateFromProps(newProps);
|
||||||
|
|
93
src/components/views/right_panel/BaseCard.tsx
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
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, {ReactNode} from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
|
||||||
|
import {_t} from "../../../languageHandler";
|
||||||
|
import AccessibleButton from "../elements/AccessibleButton";
|
||||||
|
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||||
|
import {SetRightPanelPhasePayload} from "../../../dispatcher/payloads/SetRightPanelPhasePayload";
|
||||||
|
import {Action} from "../../../dispatcher/actions";
|
||||||
|
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
header?: ReactNode;
|
||||||
|
footer?: ReactNode;
|
||||||
|
className?: string;
|
||||||
|
withoutScrollContainer?: boolean;
|
||||||
|
previousPhase?: RightPanelPhases;
|
||||||
|
onClose?(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IGroupProps {
|
||||||
|
className?: string;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Group: React.FC<IGroupProps> = ({ className, title, children }) => {
|
||||||
|
return <div className={classNames("mx_BaseCard_Group", className)}>
|
||||||
|
<h1>{title}</h1>
|
||||||
|
{children}
|
||||||
|
</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const BaseCard: React.FC<IProps> = ({
|
||||||
|
onClose,
|
||||||
|
className,
|
||||||
|
header,
|
||||||
|
footer,
|
||||||
|
withoutScrollContainer,
|
||||||
|
previousPhase,
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
let backButton;
|
||||||
|
if (previousPhase) {
|
||||||
|
const onBackClick = () => {
|
||||||
|
defaultDispatcher.dispatch<SetRightPanelPhasePayload>({
|
||||||
|
action: Action.SetRightPanelPhase,
|
||||||
|
phase: previousPhase,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
backButton = <AccessibleButton className="mx_BaseCard_back" onClick={onBackClick} title={_t("Back")} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
let closeButton;
|
||||||
|
if (onClose) {
|
||||||
|
closeButton = <AccessibleButton className="mx_BaseCard_close" onClick={onClose} title={_t("Close")} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!withoutScrollContainer) {
|
||||||
|
children = <AutoHideScrollbar>
|
||||||
|
{ children }
|
||||||
|
</AutoHideScrollbar>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classNames("mx_BaseCard", className)}>
|
||||||
|
<div className="mx_BaseCard_header">
|
||||||
|
{ backButton }
|
||||||
|
{ closeButton }
|
||||||
|
{ header }
|
||||||
|
</div>
|
||||||
|
{ children }
|
||||||
|
{ footer && <div className="mx_BaseCard_footer">{ footer }</div> }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BaseCard;
|
|
@ -96,8 +96,7 @@ export default abstract class HeaderButtons extends React.Component<IProps, ISta
|
||||||
public abstract renderButtons(): JSX.Element[];
|
public abstract renderButtons(): JSX.Element[];
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
// inline style as this will be swapped around in future commits
|
return <div className="mx_HeaderButtons">
|
||||||
return <div className="mx_HeaderButtons" role="tablist">
|
|
||||||
{this.renderButtons()}
|
{this.renderButtons()}
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,14 +19,18 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { _t } from '../../../languageHandler';
|
import {_t} from '../../../languageHandler';
|
||||||
import HeaderButton from './HeaderButton';
|
import HeaderButton from './HeaderButton';
|
||||||
import HeaderButtons, {HeaderKind} from './HeaderButtons';
|
import HeaderButtons, {HeaderKind} from './HeaderButtons';
|
||||||
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
||||||
import {Action} from "../../../dispatcher/actions";
|
import {Action} from "../../../dispatcher/actions";
|
||||||
import {ActionPayload} from "../../../dispatcher/payloads";
|
import {ActionPayload} from "../../../dispatcher/payloads";
|
||||||
|
import RightPanelStore from "../../../stores/RightPanelStore";
|
||||||
|
|
||||||
const MEMBER_PHASES = [
|
const ROOM_INFO_PHASES = [
|
||||||
|
RightPanelPhases.RoomSummary,
|
||||||
|
RightPanelPhases.Widget,
|
||||||
|
RightPanelPhases.FilePanel,
|
||||||
RightPanelPhases.RoomMemberList,
|
RightPanelPhases.RoomMemberList,
|
||||||
RightPanelPhases.RoomMemberInfo,
|
RightPanelPhases.RoomMemberInfo,
|
||||||
RightPanelPhases.EncryptionPanel,
|
RightPanelPhases.EncryptionPanel,
|
||||||
|
@ -54,22 +58,21 @@ export default class RoomHeaderButtons extends HeaderButtons {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onMembersClicked = () => {
|
private onRoomSummaryClicked = () => {
|
||||||
if (this.state.phase === RightPanelPhases.RoomMemberInfo) {
|
// use roomPanelPhase rather than this.state.phase as it remembers the latest one if we close
|
||||||
// send the active phase to trigger a toggle
|
const lastPhase = RightPanelStore.getSharedInstance().roomPanelPhase;
|
||||||
// XXX: we should pass refireParams here but then it won't collapse as we desire it to
|
if (ROOM_INFO_PHASES.includes(lastPhase)) {
|
||||||
this.setPhase(RightPanelPhases.RoomMemberInfo);
|
if (this.state.phase === lastPhase) {
|
||||||
|
this.setPhase(lastPhase);
|
||||||
|
} else {
|
||||||
|
this.setPhase(lastPhase, RightPanelStore.getSharedInstance().roomPanelPhaseParams);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// This toggles for us, if needed
|
// This toggles for us, if needed
|
||||||
this.setPhase(RightPanelPhases.RoomMemberList);
|
this.setPhase(RightPanelPhases.RoomSummary);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private onFilesClicked = () => {
|
|
||||||
// This toggles for us, if needed
|
|
||||||
this.setPhase(RightPanelPhases.FilePanel);
|
|
||||||
};
|
|
||||||
|
|
||||||
private onNotificationsClicked = () => {
|
private onNotificationsClicked = () => {
|
||||||
// This toggles for us, if needed
|
// This toggles for us, if needed
|
||||||
this.setPhase(RightPanelPhases.NotificationPanel);
|
this.setPhase(RightPanelPhases.NotificationPanel);
|
||||||
|
@ -77,24 +80,22 @@ export default class RoomHeaderButtons extends HeaderButtons {
|
||||||
|
|
||||||
public renderButtons() {
|
public renderButtons() {
|
||||||
return [
|
return [
|
||||||
<HeaderButton key="membersButton" name="membersButton"
|
<HeaderButton
|
||||||
title={_t('Members')}
|
key="notifsButton"
|
||||||
isHighlighted={this.isPhase(MEMBER_PHASES)}
|
name="notifsButton"
|
||||||
onClick={this.onMembersClicked}
|
|
||||||
analytics={['Right Panel', 'Member List Button', 'click']}
|
|
||||||
/>,
|
|
||||||
<HeaderButton key="filesButton" name="filesButton"
|
|
||||||
title={_t('Files')}
|
|
||||||
isHighlighted={this.isPhase(RightPanelPhases.FilePanel)}
|
|
||||||
onClick={this.onFilesClicked}
|
|
||||||
analytics={['Right Panel', 'File List Button', 'click']}
|
|
||||||
/>,
|
|
||||||
<HeaderButton key="notifsButton" name="notifsButton"
|
|
||||||
title={_t('Notifications')}
|
title={_t('Notifications')}
|
||||||
isHighlighted={this.isPhase(RightPanelPhases.NotificationPanel)}
|
isHighlighted={this.isPhase(RightPanelPhases.NotificationPanel)}
|
||||||
onClick={this.onNotificationsClicked}
|
onClick={this.onNotificationsClicked}
|
||||||
analytics={['Right Panel', 'Notification List Button', 'click']}
|
analytics={['Right Panel', 'Notification List Button', 'click']}
|
||||||
/>,
|
/>,
|
||||||
|
<HeaderButton
|
||||||
|
key="roomSummaryButton"
|
||||||
|
name="roomSummaryButton"
|
||||||
|
title={_t('Room Info')}
|
||||||
|
isHighlighted={this.isPhase(ROOM_INFO_PHASES)}
|
||||||
|
onClick={this.onRoomSummaryClicked}
|
||||||
|
analytics={['Right Panel', 'Room Summary Button', 'click']}
|
||||||
|
/>,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
243
src/components/views/right_panel/RoomSummaryCard.tsx
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
/*
|
||||||
|
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, {useCallback, useState, useEffect, useContext} from "react";
|
||||||
|
import classNames from "classnames";
|
||||||
|
import {Room} from "matrix-js-sdk/src/models/room";
|
||||||
|
import {getHttpUriForMxc} from "matrix-js-sdk/src/content-repo";
|
||||||
|
|
||||||
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
|
import { useIsEncrypted } from '../../../hooks/useIsEncrypted';
|
||||||
|
import BaseCard, { Group } from "./BaseCard";
|
||||||
|
import { _t } from '../../../languageHandler';
|
||||||
|
import RoomAvatar from "../avatars/RoomAvatar";
|
||||||
|
import AccessibleButton from "../elements/AccessibleButton";
|
||||||
|
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||||
|
import {Action} from "../../../dispatcher/actions";
|
||||||
|
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
||||||
|
import {SetRightPanelPhasePayload} from "../../../dispatcher/payloads/SetRightPanelPhasePayload";
|
||||||
|
import Modal from "../../../Modal";
|
||||||
|
import ShareDialog from '../dialogs/ShareDialog';
|
||||||
|
import {useEventEmitter} from "../../../hooks/useEventEmitter";
|
||||||
|
import WidgetEchoStore from "../../../stores/WidgetEchoStore";
|
||||||
|
import WidgetUtils from "../../../utils/WidgetUtils";
|
||||||
|
import {IntegrationManagers} from "../../../integrations/IntegrationManagers";
|
||||||
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
|
import TextWithTooltip from "../elements/TextWithTooltip";
|
||||||
|
import BaseAvatar from "../avatars/BaseAvatar";
|
||||||
|
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||||
|
import WidgetStore, {IApp} from "../../../stores/WidgetStore";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
room: Room;
|
||||||
|
onClose(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAppsSectionProps {
|
||||||
|
room: Room;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IButtonProps {
|
||||||
|
className: string;
|
||||||
|
onClick(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Button: React.FC<IButtonProps> = ({ children, className, onClick }) => {
|
||||||
|
return <AccessibleButton
|
||||||
|
className={classNames("mx_BaseCard_Button mx_RoomSummaryCard_Button", className)}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
{ children }
|
||||||
|
</AccessibleButton>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useWidgets = (room: Room) => {
|
||||||
|
const [apps, setApps] = useState<IApp[]>(WidgetStore.instance.getApps(room));
|
||||||
|
|
||||||
|
const updateApps = useCallback(() => {
|
||||||
|
// Copy the array so that we always trigger a re-render, as some updates mutate the array of apps/settings
|
||||||
|
setApps([...WidgetStore.instance.getApps(room)]);
|
||||||
|
}, [room]);
|
||||||
|
|
||||||
|
useEffect(updateApps, [room]);
|
||||||
|
useEventEmitter(WidgetEchoStore, "update", updateApps);
|
||||||
|
useEventEmitter(WidgetStore.instance, room.roomId, updateApps);
|
||||||
|
|
||||||
|
return apps;
|
||||||
|
};
|
||||||
|
|
||||||
|
const AppsSection: React.FC<IAppsSectionProps> = ({ room }) => {
|
||||||
|
const cli = useContext(MatrixClientContext);
|
||||||
|
const apps = useWidgets(room);
|
||||||
|
|
||||||
|
const onManageIntegrations = () => {
|
||||||
|
const managers = IntegrationManagers.sharedInstance();
|
||||||
|
if (!managers.hasManager()) {
|
||||||
|
managers.openNoManagerDialog();
|
||||||
|
} else {
|
||||||
|
if (SettingsStore.getValue("feature_many_integration_managers")) {
|
||||||
|
managers.openAll(room);
|
||||||
|
} else {
|
||||||
|
managers.getPrimaryManager().open(room);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return <Group className="mx_RoomSummaryCard_appsGroup" title={_t("Apps")}>
|
||||||
|
{ apps.map(app => {
|
||||||
|
const name = WidgetUtils.getWidgetName(app);
|
||||||
|
const dataTitle = WidgetUtils.getWidgetDataTitle(app);
|
||||||
|
const subtitle = dataTitle && " - " + dataTitle;
|
||||||
|
|
||||||
|
let iconUrls = [require("../../../../res/img/element-icons/room/default_app.svg")];
|
||||||
|
// heuristics for some better icons until Widgets support their own icons
|
||||||
|
if (app.type.includes("meeting") || app.type.includes("calendar")) {
|
||||||
|
iconUrls = [require("../../../../res/img/element-icons/room/default_cal.svg")];
|
||||||
|
} else if (app.type.includes("pad") || app.type.includes("doc") || app.type.includes("calc")) {
|
||||||
|
iconUrls = [require("../../../../res/img/element-icons/room/default_doc.svg")];
|
||||||
|
} else if (app.type.includes("clock")) {
|
||||||
|
iconUrls = [require("../../../../res/img/element-icons/room/default_clock.svg")];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app.avatar_url) { // MSC2765
|
||||||
|
iconUrls.unshift(getHttpUriForMxc(cli.getHomeserverUrl(), app.avatar_url, 20, 20, "crop"));
|
||||||
|
}
|
||||||
|
|
||||||
|
const isPinned = WidgetStore.instance.isPinned(app.id);
|
||||||
|
const classes = classNames("mx_RoomSummaryCard_icon_app", {
|
||||||
|
mx_RoomSummaryCard_icon_app_pinned: isPinned,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isPinned) {
|
||||||
|
const onClick = () => {
|
||||||
|
WidgetStore.instance.unpinWidget(app.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
return <AccessibleTooltipButton
|
||||||
|
key={app.id}
|
||||||
|
className={classNames("mx_BaseCard_Button mx_RoomSummaryCard_Button", classes)}
|
||||||
|
onClick={onClick}
|
||||||
|
title={_t("Unpin app")}
|
||||||
|
>
|
||||||
|
<BaseAvatar name={app.id} urls={iconUrls} width={20} height={20} />
|
||||||
|
<span>{name}</span>
|
||||||
|
{ subtitle }
|
||||||
|
</AccessibleTooltipButton>
|
||||||
|
}
|
||||||
|
|
||||||
|
const onOpenWidgetClick = () => {
|
||||||
|
defaultDispatcher.dispatch<SetRightPanelPhasePayload>({
|
||||||
|
action: Action.SetRightPanelPhase,
|
||||||
|
phase: RightPanelPhases.Widget,
|
||||||
|
refireParams: {
|
||||||
|
widgetId: app.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button key={app.id} className={classes} onClick={onOpenWidgetClick}>
|
||||||
|
<BaseAvatar name={app.id} urls={iconUrls} width={20} height={20} />
|
||||||
|
<span>{name}</span>
|
||||||
|
{ subtitle }
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}) }
|
||||||
|
|
||||||
|
<AccessibleButton kind="link" onClick={onManageIntegrations}>
|
||||||
|
{ apps.length > 0 ? _t("Edit apps, bridges & bots") : _t("Add apps, bridges & bots") }
|
||||||
|
</AccessibleButton>
|
||||||
|
</Group>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onRoomMembersClick = () => {
|
||||||
|
defaultDispatcher.dispatch<SetRightPanelPhasePayload>({
|
||||||
|
action: Action.SetRightPanelPhase,
|
||||||
|
phase: RightPanelPhases.RoomMemberList,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onRoomFilesClick = () => {
|
||||||
|
defaultDispatcher.dispatch<SetRightPanelPhasePayload>({
|
||||||
|
action: Action.SetRightPanelPhase,
|
||||||
|
phase: RightPanelPhases.FilePanel,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onRoomSettingsClick = () => {
|
||||||
|
defaultDispatcher.dispatch({ action: "open_room_settings" });
|
||||||
|
};
|
||||||
|
|
||||||
|
const useMemberCount = (room: Room) => {
|
||||||
|
const [count, setCount] = useState(room.getJoinedMembers().length);
|
||||||
|
useEventEmitter(room.currentState, "RoomState.members", () => {
|
||||||
|
setCount(room.getJoinedMembers().length);
|
||||||
|
});
|
||||||
|
return count;
|
||||||
|
};
|
||||||
|
|
||||||
|
const RoomSummaryCard: React.FC<IProps> = ({ room, onClose }) => {
|
||||||
|
const cli = useContext(MatrixClientContext);
|
||||||
|
|
||||||
|
const onShareRoomClick = () => {
|
||||||
|
Modal.createTrackedDialog('share room dialog', '', ShareDialog, {
|
||||||
|
target: room,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const isRoomEncrypted = useIsEncrypted(cli, room);
|
||||||
|
|
||||||
|
const alias = room.getCanonicalAlias() || room.getAltAliases()[0] || "";
|
||||||
|
const header = <React.Fragment>
|
||||||
|
<div className="mx_RoomSummaryCard_avatar" role="presentation">
|
||||||
|
<RoomAvatar room={room} height={54} width={54} viewAvatarOnClick />
|
||||||
|
<TextWithTooltip
|
||||||
|
tooltip={isRoomEncrypted ? _t("Encrypted") : _t("Not encrypted")}
|
||||||
|
class={classNames("mx_RoomSummaryCard_e2ee", {
|
||||||
|
mx_RoomSummaryCard_e2ee_secure: isRoomEncrypted,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 title={room.name}>{ room.name }</h2>
|
||||||
|
<div className="mx_RoomSummaryCard_alias" title={alias}>
|
||||||
|
{ alias }
|
||||||
|
</div>
|
||||||
|
</React.Fragment>;
|
||||||
|
|
||||||
|
const memberCount = useMemberCount(room);
|
||||||
|
|
||||||
|
return <BaseCard header={header} className="mx_RoomSummaryCard" onClose={onClose}>
|
||||||
|
<Group title={_t("About")} className="mx_RoomSummaryCard_aboutGroup">
|
||||||
|
<Button className="mx_RoomSummaryCard_icon_people" onClick={onRoomMembersClick}>
|
||||||
|
{_t("%(count)s people", { count: memberCount })}
|
||||||
|
</Button>
|
||||||
|
<Button className="mx_RoomSummaryCard_icon_files" onClick={onRoomFilesClick}>
|
||||||
|
{_t("Show files")}
|
||||||
|
</Button>
|
||||||
|
<Button className="mx_RoomSummaryCard_icon_share" onClick={onShareRoomClick}>
|
||||||
|
{_t("Share room")}
|
||||||
|
</Button>
|
||||||
|
<Button className="mx_RoomSummaryCard_icon_settings" onClick={onRoomSettingsClick}>
|
||||||
|
{_t("Room settings")}
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
<AppsSection room={room} />
|
||||||
|
</BaseCard>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RoomSummaryCard;
|
|
@ -20,7 +20,7 @@ limitations under the License.
|
||||||
import React, {useCallback, useMemo, useState, useEffect, useContext} from 'react';
|
import React, {useCallback, useMemo, useState, useEffect, useContext} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import {Group, RoomMember, User} from 'matrix-js-sdk';
|
import {Group, RoomMember, User, Room} from 'matrix-js-sdk';
|
||||||
import dis from '../../../dispatcher/dispatcher';
|
import dis from '../../../dispatcher/dispatcher';
|
||||||
import Modal from '../../../Modal';
|
import Modal from '../../../Modal';
|
||||||
import * as sdk from '../../../index';
|
import * as sdk from '../../../index';
|
||||||
|
@ -31,7 +31,6 @@ import AccessibleButton from '../elements/AccessibleButton';
|
||||||
import SdkConfig from '../../../SdkConfig';
|
import SdkConfig from '../../../SdkConfig';
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import {EventTimeline} from "matrix-js-sdk";
|
import {EventTimeline} from "matrix-js-sdk";
|
||||||
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
|
|
||||||
import RoomViewStore from "../../../stores/RoomViewStore";
|
import RoomViewStore from "../../../stores/RoomViewStore";
|
||||||
import MultiInviter from "../../../utils/MultiInviter";
|
import MultiInviter from "../../../utils/MultiInviter";
|
||||||
import GroupStore from "../../../stores/GroupStore";
|
import GroupStore from "../../../stores/GroupStore";
|
||||||
|
@ -46,6 +45,7 @@ import { useAsyncMemo } from '../../../hooks/useAsyncMemo';
|
||||||
import { verifyUser, legacyVerifyUser, verifyDevice } from '../../../verification';
|
import { verifyUser, legacyVerifyUser, verifyDevice } from '../../../verification';
|
||||||
import {Action} from "../../../dispatcher/actions";
|
import {Action} from "../../../dispatcher/actions";
|
||||||
import {useIsEncrypted} from "../../../hooks/useIsEncrypted";
|
import {useIsEncrypted} from "../../../hooks/useIsEncrypted";
|
||||||
|
import BaseCard from "./BaseCard";
|
||||||
|
|
||||||
const _disambiguateDevices = (devices) => {
|
const _disambiguateDevices = (devices) => {
|
||||||
const names = Object.create(null);
|
const names = Object.create(null);
|
||||||
|
@ -451,7 +451,7 @@ const _isMuted = (member, powerLevelContent) => {
|
||||||
return member.powerLevel < levelToSend;
|
return member.powerLevel < levelToSend;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useRoomPowerLevels = (cli, room) => {
|
export const useRoomPowerLevels = (cli, room) => {
|
||||||
const [powerLevels, setPowerLevels] = useState({});
|
const [powerLevels, setPowerLevels] = useState({});
|
||||||
|
|
||||||
const update = useCallback(() => {
|
const update = useCallback(() => {
|
||||||
|
@ -1364,16 +1364,9 @@ const BasicUserInfo = ({room, member, groupId, devices, isRoomEncrypted}) => {
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const UserInfoHeader = ({onClose, member, e2eStatus}) => {
|
const UserInfoHeader = ({member, e2eStatus}) => {
|
||||||
const cli = useContext(MatrixClientContext);
|
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 onMemberAvatarClick = useCallback(() => {
|
||||||
const avatarUrl = member.getMxcAvatarUrl ? member.getMxcAvatarUrl() : member.avatarUrl;
|
const avatarUrl = member.getMxcAvatarUrl ? member.getMxcAvatarUrl() : member.avatarUrl;
|
||||||
if (!avatarUrl) return;
|
if (!avatarUrl) return;
|
||||||
|
@ -1448,7 +1441,6 @@ const UserInfoHeader = ({onClose, member, e2eStatus}) => {
|
||||||
|
|
||||||
const displayName = member.name || member.displayname;
|
const displayName = member.name || member.displayname;
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
{ closeButton }
|
|
||||||
{ avatarElement }
|
{ avatarElement }
|
||||||
|
|
||||||
<div className="mx_UserInfo_container mx_UserInfo_separator">
|
<div className="mx_UserInfo_container mx_UserInfo_separator">
|
||||||
|
@ -1471,11 +1463,9 @@ const UserInfoHeader = ({onClose, member, e2eStatus}) => {
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const UserInfo = ({user, groupId, roomId, onClose, phase=RightPanelPhases.RoomMemberInfo, ...props}) => {
|
const UserInfo = ({user, groupId, room, onClose, phase=RightPanelPhases.RoomMemberInfo, ...props}) => {
|
||||||
const cli = useContext(MatrixClientContext);
|
const cli = useContext(MatrixClientContext);
|
||||||
|
|
||||||
// Load room if we are given a room id and memoize it - this can be undefined for User Info/Group Member Info
|
|
||||||
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
|
// 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 member = useMemo(() => room ? (room.getMember(user.userId) || user) : user, [room, user]);
|
||||||
|
|
||||||
|
@ -1510,15 +1500,16 @@ const UserInfo = ({user, groupId, roomId, onClose, phase=RightPanelPhases.RoomMe
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
let previousPhase: RightPanelPhases;
|
||||||
<div className={classes.join(" ")} role="tabpanel">
|
// We have no previousPhase for when viewing a UserInfo from a Group or without a Room at this time
|
||||||
<AutoHideScrollbar className="mx_UserInfo_scrollContainer">
|
if (room) {
|
||||||
<UserInfoHeader member={member} e2eStatus={e2eStatus} onClose={onClose} />
|
previousPhase = RightPanelPhases.RoomMemberList;
|
||||||
|
}
|
||||||
|
|
||||||
{ content }
|
const header = <UserInfoHeader member={member} e2eStatus={e2eStatus} onClose={onClose} />;
|
||||||
</AutoHideScrollbar>
|
return <BaseCard className={classes.join(" ")} header={header} onClose={onClose} previousPhase={previousPhase}>
|
||||||
</div>
|
{ content }
|
||||||
);
|
</BaseCard>;
|
||||||
};
|
};
|
||||||
|
|
||||||
UserInfo.propTypes = {
|
UserInfo.propTypes = {
|
||||||
|
@ -1529,7 +1520,7 @@ UserInfo.propTypes = {
|
||||||
]).isRequired,
|
]).isRequired,
|
||||||
group: PropTypes.instanceOf(Group),
|
group: PropTypes.instanceOf(Group),
|
||||||
groupId: PropTypes.string,
|
groupId: PropTypes.string,
|
||||||
roomId: PropTypes.string,
|
room: PropTypes.instanceOf(Room),
|
||||||
|
|
||||||
onClose: PropTypes.func,
|
onClose: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
205
src/components/views/right_panel/WidgetCard.tsx
Normal file
|
@ -0,0 +1,205 @@
|
||||||
|
/*
|
||||||
|
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, {useContext, useEffect} from "react";
|
||||||
|
import {Room} from "matrix-js-sdk/src/models/room";
|
||||||
|
|
||||||
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
|
import BaseCard from "./BaseCard";
|
||||||
|
import WidgetUtils from "../../../utils/WidgetUtils";
|
||||||
|
import AccessibleButton from "../elements/AccessibleButton";
|
||||||
|
import AppTile from "../elements/AppTile";
|
||||||
|
import {_t} from "../../../languageHandler";
|
||||||
|
import {useWidgets} from "./RoomSummaryCard";
|
||||||
|
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
||||||
|
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||||
|
import {SetRightPanelPhasePayload} from "../../../dispatcher/payloads/SetRightPanelPhasePayload";
|
||||||
|
import {Action} from "../../../dispatcher/actions";
|
||||||
|
import WidgetStore from "../../../stores/WidgetStore";
|
||||||
|
import ActiveWidgetStore from "../../../stores/ActiveWidgetStore";
|
||||||
|
import {ChevronFace, ContextMenuButton, useContextMenu} from "../../structures/ContextMenu";
|
||||||
|
import IconizedContextMenu, {
|
||||||
|
IconizedContextMenuOption,
|
||||||
|
IconizedContextMenuOptionList,
|
||||||
|
} from "../context_menus/IconizedContextMenu";
|
||||||
|
import {AppTileActionPayload} from "../../../dispatcher/payloads/AppTileActionPayload";
|
||||||
|
import {Capability} from "../../../widgets/WidgetApi";
|
||||||
|
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
room: Room;
|
||||||
|
widgetId: string;
|
||||||
|
onClose(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const WidgetCard: React.FC<IProps> = ({ room, widgetId, onClose }) => {
|
||||||
|
const cli = useContext(MatrixClientContext);
|
||||||
|
|
||||||
|
const apps = useWidgets(room);
|
||||||
|
const app = apps.find(a => a.id === widgetId);
|
||||||
|
const isPinned = app && WidgetStore.instance.isPinned(app.id);
|
||||||
|
|
||||||
|
const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!app || isPinned) {
|
||||||
|
// stop showing this card
|
||||||
|
defaultDispatcher.dispatch<SetRightPanelPhasePayload>({
|
||||||
|
action: Action.SetRightPanelPhase,
|
||||||
|
phase: RightPanelPhases.RoomSummary,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [app, isPinned]);
|
||||||
|
|
||||||
|
// Don't render anything as we are about to transition
|
||||||
|
if (!app || isPinned) return null;
|
||||||
|
|
||||||
|
const header = <React.Fragment>
|
||||||
|
<h2>{ WidgetUtils.getWidgetName(app) }</h2>
|
||||||
|
</React.Fragment>;
|
||||||
|
|
||||||
|
const canModify = WidgetUtils.canUserModifyWidgets(room.roomId);
|
||||||
|
|
||||||
|
let contextMenu;
|
||||||
|
if (menuDisplayed) {
|
||||||
|
let snapshotButton;
|
||||||
|
if (ActiveWidgetStore.widgetHasCapability(app.id, Capability.Screenshot)) {
|
||||||
|
const onSnapshotClick = () => {
|
||||||
|
WidgetUtils.snapshotWidget(app);
|
||||||
|
closeMenu();
|
||||||
|
};
|
||||||
|
|
||||||
|
snapshotButton = <IconizedContextMenuOption onClick={onSnapshotClick} label={_t("Take a picture")} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
let deleteButton;
|
||||||
|
if (canModify) {
|
||||||
|
const onDeleteClick = () => {
|
||||||
|
defaultDispatcher.dispatch<AppTileActionPayload>({
|
||||||
|
action: Action.AppTileDelete,
|
||||||
|
widgetId: app.id,
|
||||||
|
});
|
||||||
|
closeMenu();
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteButton = <IconizedContextMenuOption onClick={onDeleteClick} label={_t("Remove for everyone")} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
const onRevokeClick = () => {
|
||||||
|
defaultDispatcher.dispatch<AppTileActionPayload>({
|
||||||
|
action: Action.AppTileRevoke,
|
||||||
|
widgetId: app.id,
|
||||||
|
});
|
||||||
|
closeMenu();
|
||||||
|
};
|
||||||
|
|
||||||
|
const rect = handle.current.getBoundingClientRect();
|
||||||
|
contextMenu = (
|
||||||
|
<IconizedContextMenu
|
||||||
|
chevronFace={ChevronFace.None}
|
||||||
|
right={window.innerWidth - rect.right}
|
||||||
|
bottom={window.innerHeight - rect.top}
|
||||||
|
onFinished={closeMenu}
|
||||||
|
>
|
||||||
|
<IconizedContextMenuOptionList>
|
||||||
|
{ snapshotButton }
|
||||||
|
{ deleteButton }
|
||||||
|
<IconizedContextMenuOption onClick={onRevokeClick} label={_t("Remove for me")} />
|
||||||
|
</IconizedContextMenuOptionList>
|
||||||
|
</IconizedContextMenu>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const onPinClick = () => {
|
||||||
|
WidgetStore.instance.pinWidget(app.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onEditClick = () => {
|
||||||
|
WidgetUtils.editWidget(room, app);
|
||||||
|
};
|
||||||
|
|
||||||
|
let editButton;
|
||||||
|
if (canModify) {
|
||||||
|
editButton = <AccessibleButton kind="secondary" onClick={onEditClick}>
|
||||||
|
{ _t("Edit") }
|
||||||
|
</AccessibleButton>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pinButtonClasses = canModify ? "" : "mx_WidgetCard_widePinButton";
|
||||||
|
|
||||||
|
let pinButton;
|
||||||
|
if (WidgetStore.instance.canPin(app.id)) {
|
||||||
|
pinButton = <AccessibleButton
|
||||||
|
kind="secondary"
|
||||||
|
onClick={onPinClick}
|
||||||
|
className={pinButtonClasses}
|
||||||
|
>
|
||||||
|
{ _t("Pin to room") }
|
||||||
|
</AccessibleButton>;
|
||||||
|
} else {
|
||||||
|
pinButton = <AccessibleTooltipButton
|
||||||
|
title={_t("You can only pin 2 apps at a time")}
|
||||||
|
tooltipClassName="mx_WidgetCard_maxPinnedTooltip"
|
||||||
|
kind="secondary"
|
||||||
|
className={pinButtonClasses}
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
{ _t("Pin to room") }
|
||||||
|
</AccessibleTooltipButton>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const footer = <React.Fragment>
|
||||||
|
{ editButton }
|
||||||
|
{ pinButton }
|
||||||
|
<ContextMenuButton
|
||||||
|
kind="secondary"
|
||||||
|
className="mx_WidgetCard_optionsButton"
|
||||||
|
inputRef={handle}
|
||||||
|
onClick={openMenu}
|
||||||
|
isExpanded={menuDisplayed}
|
||||||
|
label={_t("Options")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{ contextMenu }
|
||||||
|
</React.Fragment>;
|
||||||
|
|
||||||
|
return <BaseCard
|
||||||
|
header={header}
|
||||||
|
footer={footer}
|
||||||
|
className={classNames("mx_WidgetCard", {
|
||||||
|
mx_WidgetCard_noEdit: !canModify,
|
||||||
|
})}
|
||||||
|
onClose={onClose}
|
||||||
|
previousPhase={RightPanelPhases.RoomSummary}
|
||||||
|
withoutScrollContainer
|
||||||
|
>
|
||||||
|
<AppTile
|
||||||
|
app={app}
|
||||||
|
fullWidth
|
||||||
|
show
|
||||||
|
showMenubar={false}
|
||||||
|
room={room}
|
||||||
|
userId={cli.getUserId()}
|
||||||
|
creatorUserId={app.creatorUserId}
|
||||||
|
widgetPageTitle={WidgetUtils.getWidgetDataTitle(app)}
|
||||||
|
waitForIframeLoad={app.waitForIframeLoad}
|
||||||
|
whitelistCapabilities={WidgetUtils.getCapWhitelistForAppTypeInRoomId(app.type, room.roomId)}
|
||||||
|
/>
|
||||||
|
</BaseCard>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default WidgetCard;
|
|
@ -15,11 +15,12 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React, {useState} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
import classNames from 'classnames';
|
||||||
|
import {Resizable} from "re-resizable";
|
||||||
|
|
||||||
import AppTile from '../elements/AppTile';
|
import AppTile from '../elements/AppTile';
|
||||||
import Modal from '../../../Modal';
|
|
||||||
import dis from '../../../dispatcher/dispatcher';
|
import dis from '../../../dispatcher/dispatcher';
|
||||||
import * as sdk from '../../../index';
|
import * as sdk from '../../../index';
|
||||||
import * as ScalarMessaging from '../../../ScalarMessaging';
|
import * as ScalarMessaging from '../../../ScalarMessaging';
|
||||||
|
@ -29,14 +30,15 @@ import WidgetEchoStore from "../../../stores/WidgetEchoStore";
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
import {IntegrationManagers} from "../../../integrations/IntegrationManagers";
|
import {IntegrationManagers} from "../../../integrations/IntegrationManagers";
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
|
import {useLocalStorageState} from "../../../hooks/useLocalStorageState";
|
||||||
// The maximum number of widgets that can be added in a room
|
import ResizeNotifier from "../../../utils/ResizeNotifier";
|
||||||
const MAX_WIDGETS = 2;
|
import WidgetStore from "../../../stores/WidgetStore";
|
||||||
|
|
||||||
export default class AppsDrawer extends React.Component {
|
export default class AppsDrawer extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
userId: PropTypes.string.isRequired,
|
userId: PropTypes.string.isRequired,
|
||||||
room: PropTypes.object.isRequired,
|
room: PropTypes.object.isRequired,
|
||||||
|
resizeNotifier: PropTypes.instanceOf(ResizeNotifier).isRequired,
|
||||||
showApps: PropTypes.bool, // Should apps be rendered
|
showApps: PropTypes.bool, // Should apps be rendered
|
||||||
hide: PropTypes.bool, // If rendered, should apps drawer be visible
|
hide: PropTypes.bool, // If rendered, should apps drawer be visible
|
||||||
};
|
};
|
||||||
|
@ -56,17 +58,13 @@ export default class AppsDrawer extends React.Component {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
ScalarMessaging.startListening();
|
ScalarMessaging.startListening();
|
||||||
MatrixClientPeg.get().on('RoomState.events', this.onRoomStateEvents);
|
WidgetStore.instance.on(this.props.room.roomId, this._updateApps);
|
||||||
WidgetEchoStore.on('update', this._updateApps);
|
|
||||||
this.dispatcherRef = dis.register(this.onAction);
|
this.dispatcherRef = dis.register(this.onAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
ScalarMessaging.stopListening();
|
ScalarMessaging.stopListening();
|
||||||
if (MatrixClientPeg.get()) {
|
WidgetStore.instance.off(this.props.room.roomId, this._updateApps);
|
||||||
MatrixClientPeg.get().removeListener('RoomState.events', this.onRoomStateEvents);
|
|
||||||
}
|
|
||||||
WidgetEchoStore.removeListener('update', this._updateApps);
|
|
||||||
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
|
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,28 +93,11 @@ export default class AppsDrawer extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onRoomStateEvents = (ev, state) => {
|
_getApps = () => WidgetStore.instance.getApps(this.props.room, true);
|
||||||
if (ev.getRoomId() !== this.props.room.roomId || ev.getType() !== 'im.vector.modular.widgets') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._updateApps();
|
|
||||||
};
|
|
||||||
|
|
||||||
_getApps() {
|
|
||||||
const widgets = WidgetEchoStore.getEchoedRoomWidgets(
|
|
||||||
this.props.room.roomId, WidgetUtils.getRoomWidgets(this.props.room),
|
|
||||||
);
|
|
||||||
return widgets.map((ev) => {
|
|
||||||
return WidgetUtils.makeAppConfig(
|
|
||||||
ev.getStateKey(), ev.getContent(), ev.getSender(), ev.getRoomId(), ev.getId(),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateApps = () => {
|
_updateApps = () => {
|
||||||
const apps = this._getApps();
|
|
||||||
this.setState({
|
this.setState({
|
||||||
apps: apps,
|
apps: this._getApps(),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -139,18 +120,6 @@ export default class AppsDrawer extends React.Component {
|
||||||
|
|
||||||
onClickAddWidget = (e) => {
|
onClickAddWidget = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// Display a warning dialog if the max number of widgets have already been added to the room
|
|
||||||
const apps = this._getApps();
|
|
||||||
if (apps && apps.length >= MAX_WIDGETS) {
|
|
||||||
const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog');
|
|
||||||
const errorMsg = `The maximum number of ${MAX_WIDGETS} widgets have already been added to this room.`;
|
|
||||||
console.error(errorMsg);
|
|
||||||
Modal.createDialog(ErrorDialog, {
|
|
||||||
title: _t('Cannot add any more widgets'),
|
|
||||||
description: _t('The maximum permitted number of widgets have already been added to this room.'),
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._launchManageIntegrations();
|
this._launchManageIntegrations();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -161,19 +130,19 @@ export default class AppsDrawer extends React.Component {
|
||||||
return (<AppTile
|
return (<AppTile
|
||||||
key={app.id}
|
key={app.id}
|
||||||
app={app}
|
app={app}
|
||||||
fullWidth={arr.length<2 ? true : false}
|
fullWidth={arr.length < 2}
|
||||||
room={this.props.room}
|
room={this.props.room}
|
||||||
userId={this.props.userId}
|
userId={this.props.userId}
|
||||||
show={this.props.showApps}
|
show={this.props.showApps}
|
||||||
creatorUserId={app.creatorUserId}
|
creatorUserId={app.creatorUserId}
|
||||||
widgetPageTitle={(app.data && app.data.title) ? app.data.title : ''}
|
widgetPageTitle={WidgetUtils.getWidgetDataTitle(app)}
|
||||||
waitForIframeLoad={app.waitForIframeLoad}
|
waitForIframeLoad={app.waitForIframeLoad}
|
||||||
whitelistCapabilities={capWhitelist}
|
whitelistCapabilities={capWhitelist}
|
||||||
/>);
|
/>);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (apps.length == 0) {
|
if (apps.length === 0) {
|
||||||
return <div></div>;
|
return <div />;
|
||||||
}
|
}
|
||||||
|
|
||||||
let addWidget;
|
let addWidget;
|
||||||
|
@ -202,14 +171,68 @@ export default class AppsDrawer extends React.Component {
|
||||||
spinner = <Loader />;
|
spinner = <Loader />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const classes = classNames({
|
||||||
|
"mx_AppsDrawer": true,
|
||||||
|
"mx_AppsDrawer_hidden": this.props.hide,
|
||||||
|
"mx_AppsDrawer_fullWidth": apps.length < 2,
|
||||||
|
"mx_AppsDrawer_minimised": !this.props.showApps,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'mx_AppsDrawer' + (this.props.hide ? ' mx_AppsDrawer_hidden' : '')}>
|
<div className={classes}>
|
||||||
<div id='apps' className='mx_AppsContainer'>
|
<PersistentVResizer
|
||||||
|
id={"apps-drawer_" + this.props.room.roomId}
|
||||||
|
minHeight={100}
|
||||||
|
maxHeight={this.props.maxHeight ? this.props.maxHeight - 50 : undefined}
|
||||||
|
handleClass="mx_AppsContainer_resizerHandle"
|
||||||
|
className="mx_AppsContainer"
|
||||||
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
|
>
|
||||||
{ apps }
|
{ apps }
|
||||||
{ spinner }
|
{ spinner }
|
||||||
</div>
|
</PersistentVResizer>
|
||||||
{ this._canUserModify() && addWidget }
|
{ this._canUserModify() && addWidget }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PersistentVResizer = ({
|
||||||
|
id,
|
||||||
|
minHeight,
|
||||||
|
maxHeight,
|
||||||
|
className,
|
||||||
|
handleWrapperClass,
|
||||||
|
handleClass,
|
||||||
|
resizeNotifier,
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const [height, setHeight] = useLocalStorageState("pvr_" + id, 280); // old fixed height was 273px
|
||||||
|
const [resizing, setResizing] = useState(false);
|
||||||
|
|
||||||
|
return <Resizable
|
||||||
|
size={{height: Math.min(height, maxHeight)}}
|
||||||
|
minHeight={minHeight}
|
||||||
|
maxHeight={maxHeight}
|
||||||
|
onResizeStart={() => {
|
||||||
|
if (!resizing) setResizing(true);
|
||||||
|
resizeNotifier.startResizing();
|
||||||
|
}}
|
||||||
|
onResize={() => {
|
||||||
|
resizeNotifier.notifyTimelineHeightChanged();
|
||||||
|
}}
|
||||||
|
onResizeStop={(e, dir, ref, d) => {
|
||||||
|
setHeight(height + d.height);
|
||||||
|
if (resizing) setResizing(false);
|
||||||
|
resizeNotifier.stopResizing();
|
||||||
|
}}
|
||||||
|
handleWrapperClass={handleWrapperClass}
|
||||||
|
handleClasses={{bottom: handleClass}}
|
||||||
|
className={classNames(className, {
|
||||||
|
mx_AppsDrawer_resizing: resizing,
|
||||||
|
})}
|
||||||
|
enable={{bottom: true}}
|
||||||
|
>
|
||||||
|
{ children }
|
||||||
|
</Resizable>;
|
||||||
|
};
|
||||||
|
|
|
@ -204,6 +204,7 @@ export default class AuxPanel extends React.Component {
|
||||||
maxHeight={this.props.maxHeight}
|
maxHeight={this.props.maxHeight}
|
||||||
showApps={this.props.showApps}
|
showApps={this.props.showApps}
|
||||||
hide={this.props.hideAppsDrawer}
|
hide={this.props.hideAppsDrawer}
|
||||||
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
let stateViews = null;
|
let stateViews = null;
|
||||||
|
|
|
@ -20,13 +20,14 @@ import React from 'react';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import SdkConfig from '../../../SdkConfig';
|
import SdkConfig from '../../../SdkConfig';
|
||||||
import dis from '../../../dispatcher/dispatcher';
|
import dis from '../../../dispatcher/dispatcher';
|
||||||
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
|
|
||||||
import {isValid3pidInvite} from "../../../RoomInvite";
|
import {isValid3pidInvite} from "../../../RoomInvite";
|
||||||
import rate_limited_func from "../../../ratelimitedfunc";
|
import rate_limited_func from "../../../ratelimitedfunc";
|
||||||
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||||
import * as sdk from "../../../index";
|
import * as sdk from "../../../index";
|
||||||
import CallHandler from "../../../CallHandler";
|
import CallHandler from "../../../CallHandler";
|
||||||
import {CommunityPrototypeStore} from "../../../stores/CommunityPrototypeStore";
|
import {CommunityPrototypeStore} from "../../../stores/CommunityPrototypeStore";
|
||||||
|
import BaseCard from "../right_panel/BaseCard";
|
||||||
|
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
||||||
|
|
||||||
const INITIAL_LOAD_NUM_MEMBERS = 30;
|
const INITIAL_LOAD_NUM_MEMBERS = 30;
|
||||||
const INITIAL_LOAD_NUM_INVITED = 5;
|
const INITIAL_LOAD_NUM_INVITED = 5;
|
||||||
|
@ -438,7 +439,13 @@ export default class MemberList extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
if (this.state.loading) {
|
if (this.state.loading) {
|
||||||
const Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
return <div className="mx_MemberList"><Spinner /></div>;
|
return <BaseCard
|
||||||
|
className="mx_MemberList"
|
||||||
|
onClose={this.props.onClose}
|
||||||
|
previousPhase={RightPanelPhases.RoomSummary}
|
||||||
|
>
|
||||||
|
<Spinner />
|
||||||
|
</BaseCard>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SearchBox = sdk.getComponent('structures.SearchBox');
|
const SearchBox = sdk.getComponent('structures.SearchBox');
|
||||||
|
@ -485,25 +492,29 @@ export default class MemberList extends React.Component {
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
const footer = (
|
||||||
<div className="mx_MemberList" role="tabpanel">
|
<SearchBox
|
||||||
{ inviteButton }
|
className="mx_MemberList_query mx_textinput_icon mx_textinput_search"
|
||||||
<AutoHideScrollbar>
|
placeholder={ _t('Filter room members') }
|
||||||
<div className="mx_MemberList_wrapper">
|
onSearch={ this.onSearchQueryChanged } />
|
||||||
<TruncatedList className="mx_MemberList_section mx_MemberList_joined" truncateAt={this.state.truncateAtJoined}
|
|
||||||
createOverflowElement={this._createOverflowTileJoined}
|
|
||||||
getChildren={this._getChildrenJoined}
|
|
||||||
getChildCount={this._getChildCountJoined} />
|
|
||||||
{ invitedHeader }
|
|
||||||
{ invitedSection }
|
|
||||||
</div>
|
|
||||||
</AutoHideScrollbar>
|
|
||||||
|
|
||||||
<SearchBox className="mx_MemberList_query mx_textinput_icon mx_textinput_search"
|
|
||||||
placeholder={ _t('Filter room members') }
|
|
||||||
onSearch={ this.onSearchQueryChanged } />
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return <BaseCard
|
||||||
|
className="mx_MemberList"
|
||||||
|
header={inviteButton}
|
||||||
|
footer={footer}
|
||||||
|
onClose={this.props.onClose}
|
||||||
|
previousPhase={RightPanelPhases.RoomSummary}
|
||||||
|
>
|
||||||
|
<div className="mx_MemberList_wrapper">
|
||||||
|
<TruncatedList className="mx_MemberList_section mx_MemberList_joined" truncateAt={this.state.truncateAtJoined}
|
||||||
|
createOverflowElement={this._createOverflowTileJoined}
|
||||||
|
getChildren={this._getChildrenJoined}
|
||||||
|
getChildCount={this._getChildCountJoined} />
|
||||||
|
{ invitedHeader }
|
||||||
|
{ invitedSection }
|
||||||
|
</div>
|
||||||
|
</BaseCard>;
|
||||||
}
|
}
|
||||||
|
|
||||||
onInviteButtonClick = () => {
|
onInviteButtonClick = () => {
|
||||||
|
|
|
@ -18,14 +18,11 @@ limitations under the License.
|
||||||
import React, {createRef} from 'react';
|
import React, {createRef} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import * as sdk from '../../../index';
|
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||||
import Modal from "../../../Modal";
|
|
||||||
import RateLimitedFunc from '../../../ratelimitedfunc';
|
import RateLimitedFunc from '../../../ratelimitedfunc';
|
||||||
|
|
||||||
import { linkifyElement } from '../../../HtmlUtils';
|
import { linkifyElement } from '../../../HtmlUtils';
|
||||||
import ManageIntegsButton from '../elements/ManageIntegsButton';
|
|
||||||
import {CancelButton} from './SimpleRoomHeader';
|
import {CancelButton} from './SimpleRoomHeader';
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import RoomHeaderButtons from '../right_panel/RoomHeaderButtons';
|
import RoomHeaderButtons from '../right_panel/RoomHeaderButtons';
|
||||||
|
@ -114,13 +111,6 @@ export default class RoomHeader extends React.Component {
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
};
|
};
|
||||||
|
|
||||||
onShareRoomClick = (ev) => {
|
|
||||||
const ShareDialog = sdk.getComponent("dialogs.ShareDialog");
|
|
||||||
Modal.createTrackedDialog('share room dialog', '', ShareDialog, {
|
|
||||||
target: this.props.room,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
_hasUnreadPins() {
|
_hasUnreadPins() {
|
||||||
const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
|
const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
|
||||||
if (!currentPinEvent) return false;
|
if (!currentPinEvent) return false;
|
||||||
|
@ -150,7 +140,6 @@ export default class RoomHeader extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
let searchStatus = null;
|
let searchStatus = null;
|
||||||
let cancelButton = null;
|
let cancelButton = null;
|
||||||
let settingsButton = null;
|
|
||||||
let pinnedEventsButton = null;
|
let pinnedEventsButton = null;
|
||||||
|
|
||||||
if (this.props.onCancelClick) {
|
if (this.props.onCancelClick) {
|
||||||
|
@ -214,14 +203,6 @@ export default class RoomHeader extends React.Component {
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.onSettingsClick) {
|
|
||||||
settingsButton =
|
|
||||||
<AccessibleTooltipButton
|
|
||||||
className="mx_RoomHeader_button mx_RoomHeader_settingsButton"
|
|
||||||
onClick={this.props.onSettingsClick}
|
|
||||||
title={_t("Settings")} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.onPinnedClick && SettingsStore.getValue('feature_pinning')) {
|
if (this.props.onPinnedClick && SettingsStore.getValue('feature_pinning')) {
|
||||||
let pinsIndicator = null;
|
let pinsIndicator = null;
|
||||||
if (this._hasUnreadPins()) {
|
if (this._hasUnreadPins()) {
|
||||||
|
@ -258,26 +239,9 @@ export default class RoomHeader extends React.Component {
|
||||||
title={_t("Search")} />;
|
title={_t("Search")} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
let shareRoomButton;
|
|
||||||
if (this.props.inRoom) {
|
|
||||||
shareRoomButton =
|
|
||||||
<AccessibleTooltipButton
|
|
||||||
className="mx_RoomHeader_button mx_RoomHeader_shareButton"
|
|
||||||
onClick={this.onShareRoomClick}
|
|
||||||
title={_t('Share room')} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
let manageIntegsButton;
|
|
||||||
if (this.props.room && this.props.room.roomId && this.props.inRoom) {
|
|
||||||
manageIntegsButton = <ManageIntegsButton room={this.props.room} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
const rightRow =
|
const rightRow =
|
||||||
<div className="mx_RoomHeader_buttons">
|
<div className="mx_RoomHeader_buttons">
|
||||||
{ settingsButton }
|
|
||||||
{ pinnedEventsButton }
|
{ pinnedEventsButton }
|
||||||
{ shareRoomButton }
|
|
||||||
{ manageIntegsButton }
|
|
||||||
{ forgetButton }
|
{ forgetButton }
|
||||||
{ searchButton }
|
{ searchButton }
|
||||||
</div>;
|
</div>;
|
||||||
|
|
48
src/contexts/RoomContext.ts
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
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 { createContext } from "react";
|
||||||
|
|
||||||
|
import {IState} from "../components/structures/RoomView";
|
||||||
|
|
||||||
|
const RoomContext = createContext<IState>({
|
||||||
|
roomLoading: true,
|
||||||
|
peekLoading: false,
|
||||||
|
shouldPeek: true,
|
||||||
|
membersLoaded: false,
|
||||||
|
numUnreadMessages: 0,
|
||||||
|
draggingFile: false,
|
||||||
|
searching: false,
|
||||||
|
guestsCanJoin: false,
|
||||||
|
canPeek: false,
|
||||||
|
showApps: false,
|
||||||
|
isAlone: false,
|
||||||
|
isPeeking: false,
|
||||||
|
showingPinned: false,
|
||||||
|
showReadReceipts: true,
|
||||||
|
showRightPanel: true,
|
||||||
|
joining: false,
|
||||||
|
atEndOfLiveTimeline: true,
|
||||||
|
atEndOfLiveTimelineInit: false,
|
||||||
|
showTopUnreadMessagesBar: false,
|
||||||
|
statusBarVisible: false,
|
||||||
|
canReact: false,
|
||||||
|
canReply: false,
|
||||||
|
useIRCLayout: false,
|
||||||
|
matrixClientIsReady: false,
|
||||||
|
});
|
||||||
|
RoomContext.displayName = "RoomContext";
|
||||||
|
export default RoomContext;
|
|
@ -94,4 +94,14 @@ export enum Action {
|
||||||
* Trigged after the phase of the right panel is set. Should be used with AfterRightPanelPhaseChangePayload.
|
* Trigged after the phase of the right panel is set. Should be used with AfterRightPanelPhaseChangePayload.
|
||||||
*/
|
*/
|
||||||
AfterRightPanelPhaseChange = "after_right_panel_phase_change",
|
AfterRightPanelPhaseChange = "after_right_panel_phase_change",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests that the AppTile deletes the widget. Should be used with the AppTileActionPayload.
|
||||||
|
*/
|
||||||
|
AppTileDelete = "appTile_delete",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests that the AppTile revokes the widget. Should be used with the AppTileActionPayload.
|
||||||
|
*/
|
||||||
|
AppTileRevoke = "appTile_revoke",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -14,12 +14,10 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createContext } from "react";
|
import { ActionPayload } from "../payloads";
|
||||||
|
import { Action } from "../actions";
|
||||||
|
|
||||||
const RoomContext = createContext({
|
export interface AppTileActionPayload extends ActionPayload {
|
||||||
canReact: undefined,
|
action: Action.AppTileDelete | Action.AppTileRevoke;
|
||||||
canReply: undefined,
|
widgetId: string;
|
||||||
room: undefined,
|
}
|
||||||
});
|
|
||||||
RoomContext.displayName = "RoomContext";
|
|
||||||
export default RoomContext;
|
|
|
@ -34,4 +34,5 @@ export interface SetRightPanelPhaseRefireParams {
|
||||||
groupRoomId?: string;
|
groupRoomId?: string;
|
||||||
// XXX: The type for event should 'view_3pid_invite' action's payload
|
// XXX: The type for event should 'view_3pid_invite' action's payload
|
||||||
event?: any;
|
event?: any;
|
||||||
|
widgetId?: string;
|
||||||
}
|
}
|
||||||
|
|
44
src/hooks/useLocalStorageState.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
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 {Dispatch, SetStateAction, useCallback, useEffect, useState} from "react";
|
||||||
|
|
||||||
|
const getValue = <T>(key: string, initialValue: T): T => {
|
||||||
|
try {
|
||||||
|
const item = window.localStorage.getItem(key);
|
||||||
|
return item ? JSON.parse(item) : initialValue;
|
||||||
|
} catch (error) {
|
||||||
|
return initialValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hook behaving like useState but persisting the value to localStorage. Returns same as useState
|
||||||
|
export const useLocalStorageState = <T>(key: string, initialValue: T) => {
|
||||||
|
const lsKey = "mx_" + key;
|
||||||
|
|
||||||
|
const [value, setValue] = useState<T>(getValue(lsKey, initialValue));
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setValue(getValue(lsKey, initialValue));
|
||||||
|
}, [lsKey, initialValue]);
|
||||||
|
|
||||||
|
const _setValue: Dispatch<SetStateAction<T>> = useCallback((v: T) => {
|
||||||
|
window.localStorage.setItem(lsKey, JSON.stringify(v));
|
||||||
|
setValue(v);
|
||||||
|
}, [lsKey]);
|
||||||
|
|
||||||
|
return [value, _setValue];
|
||||||
|
};
|
|
@ -889,12 +889,12 @@
|
||||||
"Go back to set it again.": "Gehe zurück und setze es erneut.",
|
"Go back to set it again.": "Gehe zurück und setze es erneut.",
|
||||||
"Download": "Herunterladen",
|
"Download": "Herunterladen",
|
||||||
"<b>Print it</b> and store it somewhere safe": "<b>Drucke ihn aus</b> und lagere ihn an einem sicheren Ort",
|
"<b>Print it</b> and store it somewhere safe": "<b>Drucke ihn aus</b> und lagere ihn an einem sicheren Ort",
|
||||||
"<b>Save it</b> on a USB key or backup drive": "<b>Speichere ihn</b> auf einem USB-Schlüssel oder Sicherungsslaufwerk",
|
"<b>Save it</b> on a USB key or backup drive": "<b>Speichere ihn</b> auf einem USB-Schlüssel oder Sicherungslaufwerk",
|
||||||
"<b>Copy it</b> to your personal cloud storage": "<b>Kopiere ihn</b> in deinen persönlichen Cloud-Speicher",
|
"<b>Copy it</b> to your personal cloud storage": "<b>Kopiere ihn</b> in deinen persönlichen Cloud-Speicher",
|
||||||
"Unable to create key backup": "Konnte Schlüsselsicherung nicht erstellen",
|
"Unable to create key backup": "Konnte Schlüsselsicherung nicht erstellen",
|
||||||
"Retry": "Erneut probieren",
|
"Retry": "Erneut probieren",
|
||||||
"Unable to restore backup": "Konnte Sicherung nicht wiederherstellen",
|
"Unable to restore backup": "Konnte Schlüsselsicherung nicht wiederherstellen",
|
||||||
"No backup found!": "Keine Sicherung gefunden!",
|
"No backup found!": "Keine Schlüsselsicherung gefunden!",
|
||||||
"This looks like a valid recovery key!": "Dies sieht wie ein gültiger Wiederherstellungsschlüssel aus!",
|
"This looks like a valid recovery key!": "Dies sieht wie ein gültiger Wiederherstellungsschlüssel aus!",
|
||||||
"Not a valid recovery key": "Kein valider Wiederherstellungsschlüssel",
|
"Not a valid recovery key": "Kein valider Wiederherstellungsschlüssel",
|
||||||
"There was an error joining the room": "Es gab einen Fehler beim Raum-Beitreten",
|
"There was an error joining the room": "Es gab einen Fehler beim Raum-Beitreten",
|
||||||
|
@ -934,7 +934,7 @@
|
||||||
"Use a longer keyboard pattern with more turns": "Nutze ein längeres Tastaturmuster mit mehr Abwechslung",
|
"Use a longer keyboard pattern with more turns": "Nutze ein längeres Tastaturmuster mit mehr Abwechslung",
|
||||||
"Straight rows of keys are easy to guess": "Gerade Reihen von Tasten sind einfach zu erraten",
|
"Straight rows of keys are easy to guess": "Gerade Reihen von Tasten sind einfach zu erraten",
|
||||||
"Custom user status messages": "Angepasste Nutzerstatus-Nachrichten",
|
"Custom user status messages": "Angepasste Nutzerstatus-Nachrichten",
|
||||||
"Unable to load key backup status": "Konnte Status des Schlüsselbackups nicht laden",
|
"Unable to load key backup status": "Konnte Status der Schlüsselsicherung nicht laden",
|
||||||
"Don't ask again": "Nicht erneut fragen",
|
"Don't ask again": "Nicht erneut fragen",
|
||||||
"Set up": "Einrichten",
|
"Set up": "Einrichten",
|
||||||
"Please review and accept all of the homeserver's policies": "Bitte prüfen und akzeptieren Sie alle Richtlinien des Heimservers",
|
"Please review and accept all of the homeserver's policies": "Bitte prüfen und akzeptieren Sie alle Richtlinien des Heimservers",
|
||||||
|
@ -942,7 +942,7 @@
|
||||||
"That doesn't look like a valid email address": "Sieht nicht nach einer validen E-Mail-Adresse aus",
|
"That doesn't look like a valid email address": "Sieht nicht nach einer validen E-Mail-Adresse aus",
|
||||||
"Unable to load commit detail: %(msg)s": "Konnte Commit-Details nicht laden: %(msg)s",
|
"Unable to load commit detail: %(msg)s": "Konnte Commit-Details nicht laden: %(msg)s",
|
||||||
"Checking...": "Überprüfe...",
|
"Checking...": "Überprüfe...",
|
||||||
"Unable to load backup status": "Konnte Backupstatus nicht laden",
|
"Unable to load backup status": "Konnte Sicherungsstatus nicht laden",
|
||||||
"Failed to decrypt %(failedCount)s sessions!": "Konnte %(failedCount)s Sitzungen nicht entschlüsseln!",
|
"Failed to decrypt %(failedCount)s sessions!": "Konnte %(failedCount)s Sitzungen nicht entschlüsseln!",
|
||||||
"Access your secure message history and set up secure messaging by entering your recovery passphrase.": "Greifen Sie auf Ihre sichere Nachrichtenhistorie zu und richten Sie einen sicheren Nachrichtenversand ein, indem Sie Ihre Wiederherstellungspassphrase eingeben.",
|
"Access your secure message history and set up secure messaging by entering your recovery passphrase.": "Greifen Sie auf Ihre sichere Nachrichtenhistorie zu und richten Sie einen sicheren Nachrichtenversand ein, indem Sie Ihre Wiederherstellungspassphrase eingeben.",
|
||||||
"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>",
|
"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>",
|
||||||
|
@ -992,7 +992,7 @@
|
||||||
"You've successfully verified this user.": "Du hast diesen Benutzer erfolgreich verifiziert.",
|
"You've successfully verified this user.": "Du hast diesen Benutzer erfolgreich verifiziert.",
|
||||||
"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.",
|
"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",
|
"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.",
|
"Verify this user by confirming the following number appears on their screen.": "Verifiziere diese Nutzer!n, indem du bestätigst, dass die folgende Nummer auf dessen Bildschirm erscheint.",
|
||||||
"Yes": "Ja",
|
"Yes": "Ja",
|
||||||
"No": "Nein",
|
"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.",
|
"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.",
|
||||||
|
@ -1111,7 +1111,7 @@
|
||||||
"Ignored users": "Ignorierte Benutzer",
|
"Ignored users": "Ignorierte Benutzer",
|
||||||
"Key backup": "Schlüsselsicherung",
|
"Key backup": "Schlüsselsicherung",
|
||||||
"Gets or sets the room topic": "Frage das Thema des Raums ab oder setze es",
|
"Gets or sets the room topic": "Frage das Thema des Raums ab oder setze es",
|
||||||
"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.",
|
"Verify this user by confirming the following emoji appear on their screen.": "Verifiziere diese Nutzer!n, indem du bestätigst, 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.",
|
"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",
|
"Request media permissions": "Medienberechtigungen anfordern",
|
||||||
"Main address": "Primäre Adresse",
|
"Main address": "Primäre Adresse",
|
||||||
|
@ -1128,7 +1128,7 @@
|
||||||
"Back up your keys before signing out to avoid losing them.": "Sichere deine Schlüssel bevor du dich abmeldest, damit du sie nicht verlierst.",
|
"Back up your keys before signing out to avoid losing them.": "Sichere deine Schlüssel bevor du dich abmeldest, damit du sie nicht verlierst.",
|
||||||
"Start using Key Backup": "Beginne Schlüsselsicherung zu nutzen",
|
"Start using Key Backup": "Beginne Schlüsselsicherung zu nutzen",
|
||||||
"Credits": "Danksagungen",
|
"Credits": "Danksagungen",
|
||||||
"Starting backup...": "Starte Backup...",
|
"Starting backup...": "Starte Sicherung...",
|
||||||
"Success!": "Erfolgreich!",
|
"Success!": "Erfolgreich!",
|
||||||
"Your keys are being backed up (the first backup could take a few minutes).": "Deine Schlüssel werden gesichert (Das erste Backup könnte ein paar Minuten in Anspruch nehmen).",
|
"Your keys are being backed up (the first backup could take a few minutes).": "Deine Schlüssel werden gesichert (Das erste Backup könnte ein paar Minuten in Anspruch nehmen).",
|
||||||
"Voice & Video": "Sprach- & Videoanruf",
|
"Voice & Video": "Sprach- & Videoanruf",
|
||||||
|
@ -1380,11 +1380,11 @@
|
||||||
"Manage": "Verwalten",
|
"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.",
|
"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",
|
"Enable": "Aktivieren",
|
||||||
"Connecting to integration manager...": "Verbinden zum Integrationsmanager...",
|
"Connecting to integration manager...": "Verbinde mit Integrationsmanager...",
|
||||||
"Cannot connect to integration manager": "Verbindung zum Integrationsmanager fehlgeschlagen",
|
"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.",
|
"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",
|
"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 has a signature from <verify>unknown</verify> user with ID %(deviceId)s": "Die Sicherung hat eine Signatur von <verify>unbekanntem/r</verify> Nutzer!n mit ID %(deviceId)s",
|
||||||
"Backup key stored: ": "Backup Schlüssel gespeichert: ",
|
"Backup key stored: ": "Backup Schlüssel gespeichert: ",
|
||||||
"Clear notifications": "Benachrichtigungen löschen",
|
"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?",
|
"Disconnect from the identity server <current /> and connect to <new /> instead?": "Verbindung vom Identitätsserver <current /> trennen und stattdessen zu <new /> verbinden?",
|
||||||
|
@ -1431,9 +1431,9 @@
|
||||||
"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!": "ACHTUNG: SCHLÜSSEL-VERIFIZIERUNG FEHLGESCHLAGEN! Der Signierschlüssel für %(userId)s und Sitzung %(deviceId)s ist \"%(fprint)s\", was nicht mit dem bereitgestellten Schlüssel \"%(fingerprint)s\" übereinstimmt. Das könnte bedeuten, dass deine Kommunikation abgehört wird!",
|
"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!": "ACHTUNG: SCHLÜSSEL-VERIFIZIERUNG FEHLGESCHLAGEN! Der Signierschlüssel für %(userId)s und Sitzung %(deviceId)s ist \"%(fprint)s\", was nicht mit dem bereitgestellten Schlüssel \"%(fingerprint)s\" übereinstimmt. Das könnte bedeuten, dass deine Kommunikation abgehört wird!",
|
||||||
"Never send encrypted messages to unverified sessions from this session": "Sende niemals verschlüsselte Nachrichten von dieser Sitzung zu unverifizierten Sitzungen",
|
"Never send encrypted messages to unverified sessions from this session": "Sende niemals verschlüsselte Nachrichten von dieser Sitzung zu unverifizierten Sitzungen",
|
||||||
"Never send encrypted messages to unverified sessions in this room from this session": "Sende niemals verschlüsselte Nachrichten von dieser Sitzung zu unverifizierten Sitzungen in diesem Raum",
|
"Never send encrypted messages to unverified sessions in this room from this session": "Sende niemals verschlüsselte Nachrichten von dieser Sitzung zu unverifizierten Sitzungen in diesem Raum",
|
||||||
"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.": "Durch die Änderung des Passworts werden derzeit alle End-zu-End-Verschlüsselungsschlüssel in allen Sitzungen zurückgesetzt, sodass der verschlüsselte Chat-Verlauf nicht mehr lesbar ist, es sei denn, Sie exportieren zuerst Ihre Raumschlüssel und importieren sie anschließend wieder. In Zukunft wird dies verbessert werden.",
|
"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.": "Durch die Änderung des Passworts werden derzeit alle Ende-zu-Ende-Verschlüsselungsschlüssel in allen Sitzungen zurückgesetzt, sodass der verschlüsselte Chat-Verlauf nicht mehr lesbar ist, es sei denn, du exportierst zuerst deine Raumschlüssel und importierst sie anschließend wieder. In Zukunft wird dies verbessert werden.",
|
||||||
"Delete %(count)s sessions|other": "Lösche %(count)s Sitzungen",
|
"Delete %(count)s sessions|other": "Lösche %(count)s Sitzungen",
|
||||||
"Backup is not signed by any of your sessions": "Die Sicherung ist von keiner Ihrer Sitzungen unterzeichnet",
|
"Backup is not signed by any of your sessions": "Die Sicherung wurde von keiner deiner Sitzungen unterzeichnet",
|
||||||
"Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Ihr Passwort wurde erfolgreich geändert. Sie erhalten keine Push-Benachrichtigungen zu anderen Sitzungen, bis Sie sich wieder bei diesen anmelden",
|
"Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Ihr Passwort wurde erfolgreich geändert. Sie erhalten keine Push-Benachrichtigungen zu anderen Sitzungen, bis Sie sich wieder bei diesen anmelden",
|
||||||
"Notification sound": "Benachrichtigungston",
|
"Notification sound": "Benachrichtigungston",
|
||||||
"Set a new custom sound": "Setze einen neuen benutzerdefinierten Ton",
|
"Set a new custom sound": "Setze einen neuen benutzerdefinierten Ton",
|
||||||
|
@ -1569,7 +1569,7 @@
|
||||||
"%(senderName)s removed the alternative addresses %(addresses)s for this room.|one": "%(senderName)s hat die alternative Adresse %(addresses)s für diesen Raum entfernt.",
|
"%(senderName)s removed the alternative addresses %(addresses)s for this room.|one": "%(senderName)s hat die alternative Adresse %(addresses)s für diesen Raum entfernt.",
|
||||||
"%(senderName)s changed the alternative addresses for this room.": "%(senderName)s hat die alternative Adresse für diesen Raum geändert.",
|
"%(senderName)s changed the alternative addresses for this room.": "%(senderName)s hat die alternative Adresse für diesen Raum geändert.",
|
||||||
"%(senderName)s changed the main and alternative addresses for this room.": "%(senderName)s hat die Haupt- und Alternativadresse für diesen Raum geändert.",
|
"%(senderName)s changed the main and alternative addresses for this room.": "%(senderName)s hat die Haupt- und Alternativadresse für diesen Raum geändert.",
|
||||||
"%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s entfernte die Ausschluss-Regel für Nutzer, die %(glob)s entsprechen",
|
"%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s entfernte die Ausschluss-Regel für Nutzer!nnen, die %(glob)s entsprechen",
|
||||||
"%(senderName)s removed the rule banning rooms matching %(glob)s": "%(senderName)s entfernte die Ausschluss-Regel für Räume, die %(glob)s entsprechen",
|
"%(senderName)s removed the rule banning rooms matching %(glob)s": "%(senderName)s entfernte die Ausschluss-Regel für Räume, die %(glob)s entsprechen",
|
||||||
"%(senderName)s removed the rule banning servers matching %(glob)s": "%(senderName)s entfernte die Ausschluss-Regel für Server, die %(glob)s entsprechen",
|
"%(senderName)s removed the rule banning servers matching %(glob)s": "%(senderName)s entfernte die Ausschluss-Regel für Server, die %(glob)s entsprechen",
|
||||||
"%(senderName)s removed a ban rule matching %(glob)s": "%(senderName)s entfernte die Ausschluss-Regel, die %(glob)s entspricht",
|
"%(senderName)s removed a ban rule matching %(glob)s": "%(senderName)s entfernte die Ausschluss-Regel, die %(glob)s entspricht",
|
||||||
|
@ -1631,8 +1631,8 @@
|
||||||
"Copy": "In Zwischenablage kopieren",
|
"Copy": "In Zwischenablage kopieren",
|
||||||
"Make a copy of your recovery key": "Speichere deinen Wiederherstellungsschlüssel",
|
"Make a copy of your recovery key": "Speichere deinen Wiederherstellungsschlüssel",
|
||||||
"Sends a message as html, without interpreting it as markdown": "Verschickt eine Nachricht im html-Format, ohne sie in Markdown zu formatieren",
|
"Sends a message as html, without interpreting it as markdown": "Verschickt eine Nachricht im html-Format, ohne sie in Markdown zu formatieren",
|
||||||
"Show rooms with unread notifications first": "Räume mit nicht gelesenen Benachrichtungen zuerst zeigen",
|
"Show rooms with unread notifications first": "Räume mit ungelesenen Benachrichtigungen zuerst zeigen",
|
||||||
"Show shortcuts to recently viewed rooms above the room list": "Kurzbefehle zu den kürzlich gesichteteten Räumen über der Raumliste anzeigen",
|
"Show shortcuts to recently viewed rooms above the room list": "Kurzbefehle zu den kürzlich gesichteten Räumen über der Raumliste anzeigen",
|
||||||
"Use Single Sign On to continue": "Verwende Single Sign on um fortzufahren",
|
"Use Single Sign On to continue": "Verwende Single Sign on um fortzufahren",
|
||||||
"Confirm adding this email address by using Single Sign On to prove your identity.": "Bestätige die hinzugefügte E-Mail-Adresse mit Single Sign-On, um deine Identität nachzuweisen.",
|
"Confirm adding this email address by using Single Sign On to prove your identity.": "Bestätige die hinzugefügte E-Mail-Adresse mit Single Sign-On, um deine Identität nachzuweisen.",
|
||||||
"Single Sign On": "Single Sign-On",
|
"Single Sign On": "Single Sign-On",
|
||||||
|
@ -1732,12 +1732,12 @@
|
||||||
"Upgrade": "Hochstufen",
|
"Upgrade": "Hochstufen",
|
||||||
"Verify the new login accessing your account: %(name)s": "Verifiziere die neue Anmeldung an deinem Konto: %(name)s",
|
"Verify the new login accessing your account: %(name)s": "Verifiziere die neue Anmeldung an deinem Konto: %(name)s",
|
||||||
"From %(deviceName)s (%(deviceId)s)": "Von %(deviceName)s (%(deviceId)s)",
|
"From %(deviceName)s (%(deviceId)s)": "Von %(deviceName)s (%(deviceId)s)",
|
||||||
"Your homeserver does not support cross-signing.": "Dein Heimserver unterstützt Cross-Signing nicht.",
|
"Your homeserver does not support cross-signing.": "Dein Heimserver unterstützt kein Cross-Signing.",
|
||||||
"Cross-signing and secret storage are enabled.": "Cross-signing und der sichere Speicher wurden eingerichtet.",
|
"Cross-signing and secret storage are enabled.": "Cross-signing und der sichere Speicher wurden eingerichtet.",
|
||||||
"Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Dein Konto hat eine Cross-Signing Identität im sicheren Speicher, aber dieser wird von dieser Sitzung noch nicht vertraut.",
|
"Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Dein Konto hat eine Cross-Signing-Identität im sicheren Speicher, der von dieser Sitzung jedoch noch nicht vertraut wird.",
|
||||||
"Cross-signing and secret storage are not yet set up.": "Cross-Signing und der sichere Speicher sind noch nicht eingerichtet.",
|
"Cross-signing and secret storage are not yet set up.": "Cross-Signing und der sichere Speicher sind noch nicht eingerichtet.",
|
||||||
"Reset cross-signing and secret storage": "Setze Cross-Signing und den sicheren Speicher zurück",
|
"Reset cross-signing and secret storage": "Cross-Signing und den sicheren Speicher zurücksetzen",
|
||||||
"Bootstrap cross-signing and secret storage": "Richte cross-signing und den sicheren Speicher ein",
|
"Bootstrap cross-signing and secret storage": "Richte Cross-Signing und den sicheren Speicher ein",
|
||||||
"unexpected type": "unbekannter Typ",
|
"unexpected type": "unbekannter Typ",
|
||||||
"Cross-signing public keys:": "Öffentliche Cross-Signing-Schlüssel:",
|
"Cross-signing public keys:": "Öffentliche Cross-Signing-Schlüssel:",
|
||||||
"in memory": "im Speicher",
|
"in memory": "im Speicher",
|
||||||
|
@ -1750,13 +1750,13 @@
|
||||||
"Session backup key:": "Sitzungswiederherstellungsschlüssel:",
|
"Session backup key:": "Sitzungswiederherstellungsschlüssel:",
|
||||||
"Secret storage public key:": "Öffentlicher Schlüssel des sicheren Speichers:",
|
"Secret storage public key:": "Öffentlicher Schlüssel des sicheren Speichers:",
|
||||||
"in account data": "in den Kontodaten",
|
"in account data": "in den Kontodaten",
|
||||||
"Homeserver feature support:": "Heimserverunterstützung:",
|
"Homeserver feature support:": "Home-Server-Funktionsunterstützung:",
|
||||||
"exists": "existiert",
|
"exists": "existiert",
|
||||||
"Delete sessions|other": "Lösche Sitzungen",
|
"Delete sessions|other": "Lösche Sitzungen",
|
||||||
"Delete sessions|one": "Lösche Sitzung",
|
"Delete sessions|one": "Lösche Sitzung",
|
||||||
"Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Alle Sitzungen einzeln verifizieren, anstatt auch Sitzungen zu vertrauen, die durch Cross-Signing verifiziert sind.",
|
"Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Alle Sitzungen einzeln verifizieren, anstatt auch Sitzungen zu vertrauen, die durch Cross-Signing verifiziert sind.",
|
||||||
"Securely cache encrypted messages locally for them to appear in search results, using ": "Der Zwischenspeicher für die lokale Suche in verschlüsselten Nachrichten benötigt ",
|
"Securely cache encrypted messages locally for them to appear in search results, using ": "Der Zwischenspeicher für die lokale Suche in verschlüsselten Nachrichten benötigt ",
|
||||||
" to store messages from ": " um Nachrichten aus ",
|
" to store messages from ": " um Nachrichten zu speichern von ",
|
||||||
"%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with <nativeLink>search components added</nativeLink>.": "%(brand)s benötigt weitere Komponenten um verschlüsselte Nachrichten lokal zu durchsuchen. Wenn du diese Funktion testen möchtest kannst du dir deine eigene Version von %(brand)s Desktop mit der <nativeLink>integrierten Suchfunktion bauen</nativeLink>.",
|
"%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with <nativeLink>search components added</nativeLink>.": "%(brand)s benötigt weitere Komponenten um verschlüsselte Nachrichten lokal zu durchsuchen. Wenn du diese Funktion testen möchtest kannst du dir deine eigene Version von %(brand)s Desktop mit der <nativeLink>integrierten Suchfunktion bauen</nativeLink>.",
|
||||||
"Backup has a <validity>valid</validity> signature from this user": "Die Sicherung hat eine <validity>gültige</validity> Signatur dieses Benutzers",
|
"Backup has a <validity>valid</validity> signature from this user": "Die Sicherung hat eine <validity>gültige</validity> Signatur dieses Benutzers",
|
||||||
"Backup has a <validity>invalid</validity> signature from this user": "Die Sicherung hat eine <validity>ungültige</validity> Signatur dieses Benutzers",
|
"Backup has a <validity>invalid</validity> signature from this user": "Die Sicherung hat eine <validity>ungültige</validity> Signatur dieses Benutzers",
|
||||||
|
@ -2094,7 +2094,7 @@
|
||||||
"A widget located at %(widgetUrl)s would like to verify your identity. By allowing this, the widget will be able to verify your user ID, but not perform actions as you.": "Ein Widget unter %(widgetUrl)s möchte deine Identität überprüfen. Wenn du dies zulässt, kann das Widget deine Nutzer-ID überprüfen, jedoch keine Aktionen in deinem Namen ausführen.",
|
"A widget located at %(widgetUrl)s would like to verify your identity. By allowing this, the widget will be able to verify your user ID, but not perform actions as you.": "Ein Widget unter %(widgetUrl)s möchte deine Identität überprüfen. Wenn du dies zulässt, kann das Widget deine Nutzer-ID überprüfen, jedoch keine Aktionen in deinem Namen ausführen.",
|
||||||
"Unable to access secret storage. Please verify that you entered the correct recovery passphrase.": "Der sichere Speicher konnte nicht geladen werden. Bitte stelle sicher dass du die richtige Wiederherstellungspassphrase eingegeben hast.",
|
"Unable to access secret storage. Please verify that you entered the correct recovery passphrase.": "Der sichere Speicher konnte nicht geladen werden. Bitte stelle sicher dass du die richtige Wiederherstellungspassphrase eingegeben hast.",
|
||||||
"Backup could not be decrypted with this recovery key: please verify that you entered the correct recovery key.": "Die Sicherung konnte nicht mit dem angegebenen Wiederherstellungsschlüssel entschlüsselt werden: Bitte überprüfe ob du den richtigen Wiederherstellungsschlüssel eingegeben hast.",
|
"Backup could not be decrypted with this recovery key: please verify that you entered the correct recovery key.": "Die Sicherung konnte nicht mit dem angegebenen Wiederherstellungsschlüssel entschlüsselt werden: Bitte überprüfe ob du den richtigen Wiederherstellungsschlüssel eingegeben hast.",
|
||||||
"Backup could not be decrypted with this recovery passphrase: please verify that you entered the correct recovery passphrase.": "Die Sicherung konnte mit diesem Wiederherstellungsschlüssel nicht entschlüsselt werden: Bitte überprüfe ob du den richtigen Wiederherstellungspassphrase eingegeben hast.",
|
"Backup could not be decrypted with this recovery passphrase: please verify that you entered the correct recovery passphrase.": "Die Sicherung konnte mit diesem Wiederherstellungsschlüssel nicht entschlüsselt werden: Bitte überprüfe ob du die richtige Wiederherstellungspassphrase eingegeben hast.",
|
||||||
"Nice, strong password!": "Super, ein starkes Passwort!",
|
"Nice, strong password!": "Super, ein starkes Passwort!",
|
||||||
"Other users can invite you to rooms using your contact details": "Andere Benutzer können dich mit deinen Kontaktdaten in Räume einladen",
|
"Other users can invite you to rooms using your contact details": "Andere Benutzer können dich mit deinen Kontaktdaten in Räume einladen",
|
||||||
"Set an email for account recovery. Use email or phone to optionally be discoverable by existing contacts.": "Lege eine E-Mail für die Kontowiederherstellung fest. Verwende optional E-Mail oder Telefon, um von Anderen gefunden zu werden.",
|
"Set an email for account recovery. Use email or phone to optionally be discoverable by existing contacts.": "Lege eine E-Mail für die Kontowiederherstellung fest. Verwende optional E-Mail oder Telefon, um von Anderen gefunden zu werden.",
|
||||||
|
@ -2423,5 +2423,39 @@
|
||||||
"Error leaving room": "Fehler beim Verlassen des Raums",
|
"Error leaving room": "Fehler beim Verlassen des Raums",
|
||||||
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Communities v2 Prototyp. Benötigt einen kompatiblen Heimserver. Höchst experimentell - mit Vorsicht verwenden.",
|
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Communities v2 Prototyp. Benötigt einen kompatiblen Heimserver. Höchst experimentell - mit Vorsicht verwenden.",
|
||||||
"Explore rooms in %(communityName)s": "Erkunde Räume in %(communityName)s",
|
"Explore rooms in %(communityName)s": "Erkunde Räume in %(communityName)s",
|
||||||
"Set up Secure Backup": "Sicherung einrichten"
|
"Set up Secure Backup": "Schlüsselsicherung einrichten",
|
||||||
|
"Information": "Information",
|
||||||
|
"Add another email": "Weitere E-Mail-Adresse hinzufügen",
|
||||||
|
"Send %(count)s invites|other": "%(count)s Einladungen senden",
|
||||||
|
"There was an error creating your community. The name may be taken or the server is unable to process your request.": "Beim Erstellen deiner Community ist ein Fehler aufgetreten. Entweder ist der Name schon vergeben oder der Server kann die Anfrage nicht verarbeiten.",
|
||||||
|
"Community ID: +<localpart />:%(domain)s": "Community-ID: +<localpart />:%(domain)s",
|
||||||
|
"Explore community rooms": "Entdecke Community Räume",
|
||||||
|
"You can change this later if needed.": "Falls nötig, kannst du es später noch ändern.",
|
||||||
|
"What's the name of your community or team?": "Welchen Namen hat deine Community oder dein Team?",
|
||||||
|
"Enter name": "Namen eingeben",
|
||||||
|
"Add image (optional)": "Bild hinzufügen (optional)",
|
||||||
|
"Create a room in %(communityName)s": "Erstelle einen Raum in %(communityName)s",
|
||||||
|
"Create community": "Erstelle Community",
|
||||||
|
"Cross-signing and secret storage are ready for use.": "Cross-Signing und der sichere Speicher sind bereit zur Benutzung.",
|
||||||
|
"Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.": "Cross-Signing ist bereit, aber der sichere Speicher wird noch nicht als Schlüsselbackup benutzt.",
|
||||||
|
"People you know on %(brand)s": "Leute, die du auf %(brand)s kennst",
|
||||||
|
"Send %(count)s invites|one": "%(count)s Einladung senden",
|
||||||
|
"Invite people to join %(communityName)s": "Lade Leute ein %(communityName)s beizutreten",
|
||||||
|
"An image will help people identify your community.": "Ein Bild hilft anderen, deine Community zu Identifizieren.",
|
||||||
|
"Use this when referencing your community to others. The community ID cannot be changed.": "Verwende dies, um deine Community von andere referenzieren zu lassen. Die Community-ID kann später nicht geändert werden.",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Private Räume können nur auf Einladung gefunden und betreten werden. Öffentliche Räume können von jedem/r gefunden und betreten werden.",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Private Räume können nur auf Einladung gefunden und betreten werden. Öffentliche Räume können von jedem/r in dieser Community gefunden und betreten werden.",
|
||||||
|
"You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Du solltest dies aktivieren, wenn der Raum nur für die Zusammenarbeit mit internen Teams auf deinem Heimserver verwendet wird. Dies kann später nicht mehr geändert werden.",
|
||||||
|
"You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "Du solltest dies deaktivieren, wenn der Raum für die Zusammenarbeit mit externen Teams auf deren Home-Server verwendet wird. Dies kann später nicht mehr geändert werden.",
|
||||||
|
"Block anyone not part of %(serverName)s from ever joining this room.": "Blockiere alle, die nicht Teil von %(serverName)s sind, diesen Raum jemals zu betreten.",
|
||||||
|
"Privacy": "Privatsphäre",
|
||||||
|
"There was an error updating your community. The server is unable to process your request.": "Beim Aktualisieren deiner Community ist ein Fehler aufgetreten. Der Server kann deine Anfrage nicht verarbeiten.",
|
||||||
|
"Update community": "Community aktualisieren",
|
||||||
|
"May include members not in %(communityName)s": "Kann Mitglieder enthalten, die nicht in %(communityName)s enthalten sind",
|
||||||
|
"Start a conversation with someone using their name, username (like <userId/>) or email address. This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>.": "Starte ein Gespräch mit jemandem unter Verwendung seines/ihres Namens, Nutzernamens (wie <userId/>) oder E-Mail-Adresse. Dadurch werden sie nicht zu %(communityName)s eingeladen. Klicke hier <a>hier</a>, um jemanden zu %(communityName)s einzuladen.",
|
||||||
|
"Failed to find the general chat for this community": "Der allgemeine Chat für diese Community konnte nicht gefunden werden",
|
||||||
|
"Community settings": "Community-Einstellungen",
|
||||||
|
"User settings": "Nutzer-Einstellungen",
|
||||||
|
"Community and user menu": "Community- und Nutzer-Menü",
|
||||||
|
"Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "Stellt ( ͡° ͜ʖ ͡°) einer Klartextnachricht voran"
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,6 +149,7 @@
|
||||||
"Command error": "Command error",
|
"Command error": "Command error",
|
||||||
"Usage": "Usage",
|
"Usage": "Usage",
|
||||||
"Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Prepends ¯\\_(ツ)_/¯ to a plain-text message",
|
"Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Prepends ¯\\_(ツ)_/¯ to a plain-text message",
|
||||||
|
"Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "Prepends ( ͡° ͜ʖ ͡°) to a plain-text message",
|
||||||
"Sends a message as plain text, without interpreting it as markdown": "Sends a message as plain text, without interpreting it as markdown",
|
"Sends a message as plain text, without interpreting it as markdown": "Sends a message as plain text, without interpreting it as markdown",
|
||||||
"Sends a message as html, without interpreting it as markdown": "Sends a message as html, without interpreting it as markdown",
|
"Sends a message as html, without interpreting it as markdown": "Sends a message as html, without interpreting it as markdown",
|
||||||
"Searches DuckDuckGo for results": "Searches DuckDuckGo for results",
|
"Searches DuckDuckGo for results": "Searches DuckDuckGo for results",
|
||||||
|
@ -386,6 +387,7 @@
|
||||||
"Common names and surnames are easy to guess": "Common names and surnames are easy to guess",
|
"Common names and surnames are easy to guess": "Common names and surnames are easy to guess",
|
||||||
"Straight rows of keys are easy to guess": "Straight rows of keys are easy to guess",
|
"Straight rows of keys are easy to guess": "Straight rows of keys are easy to guess",
|
||||||
"Short keyboard patterns are easy to guess": "Short keyboard patterns are easy to guess",
|
"Short keyboard patterns are easy to guess": "Short keyboard patterns are easy to guess",
|
||||||
|
"Unknown App": "Unknown App",
|
||||||
"Help us improve %(brand)s": "Help us improve %(brand)s",
|
"Help us improve %(brand)s": "Help us improve %(brand)s",
|
||||||
"Send <UsageDataLink>anonymous usage data</UsageDataLink> which helps us improve %(brand)s. This will use a <PolicyLink>cookie</PolicyLink>.": "Send <UsageDataLink>anonymous usage data</UsageDataLink> which helps us improve %(brand)s. This will use a <PolicyLink>cookie</PolicyLink>.",
|
"Send <UsageDataLink>anonymous usage data</UsageDataLink> which helps us improve %(brand)s. This will use a <PolicyLink>cookie</PolicyLink>.": "Send <UsageDataLink>anonymous usage data</UsageDataLink> which helps us improve %(brand)s. This will use a <PolicyLink>cookie</PolicyLink>.",
|
||||||
"I want to help": "I want to help",
|
"I want to help": "I want to help",
|
||||||
|
@ -1027,8 +1029,6 @@
|
||||||
"Remove %(phone)s?": "Remove %(phone)s?",
|
"Remove %(phone)s?": "Remove %(phone)s?",
|
||||||
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.",
|
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.",
|
||||||
"Phone Number": "Phone Number",
|
"Phone Number": "Phone Number",
|
||||||
"Cannot add any more widgets": "Cannot add any more widgets",
|
|
||||||
"The maximum permitted number of widgets have already been added to this room.": "The maximum permitted number of widgets have already been added to this room.",
|
|
||||||
"Add a widget": "Add a widget",
|
"Add a widget": "Add a widget",
|
||||||
"Drop File Here": "Drop File Here",
|
"Drop File Here": "Drop File Here",
|
||||||
"Drop file here to upload": "Drop file here to upload",
|
"Drop file here to upload": "Drop file here to upload",
|
||||||
|
@ -1113,10 +1113,8 @@
|
||||||
"(~%(count)s results)|other": "(~%(count)s results)",
|
"(~%(count)s results)|other": "(~%(count)s results)",
|
||||||
"(~%(count)s results)|one": "(~%(count)s result)",
|
"(~%(count)s results)|one": "(~%(count)s result)",
|
||||||
"Join Room": "Join Room",
|
"Join Room": "Join Room",
|
||||||
"Settings": "Settings",
|
|
||||||
"Forget room": "Forget room",
|
"Forget room": "Forget room",
|
||||||
"Search": "Search",
|
"Search": "Search",
|
||||||
"Share room": "Share room",
|
|
||||||
"Invites": "Invites",
|
"Invites": "Invites",
|
||||||
"Favourites": "Favourites",
|
"Favourites": "Favourites",
|
||||||
"People": "People",
|
"People": "People",
|
||||||
|
@ -1133,6 +1131,7 @@
|
||||||
"Can't see what you’re looking for?": "Can't see what you’re looking for?",
|
"Can't see what you’re looking for?": "Can't see what you’re looking for?",
|
||||||
"Explore all public rooms": "Explore all public rooms",
|
"Explore all public rooms": "Explore all public rooms",
|
||||||
"%(count)s results|other": "%(count)s results",
|
"%(count)s results|other": "%(count)s results",
|
||||||
|
"%(count)s results|one": "%(count)s result",
|
||||||
"This room": "This room",
|
"This room": "This room",
|
||||||
"Joining room …": "Joining room …",
|
"Joining room …": "Joining room …",
|
||||||
"Loading …": "Loading …",
|
"Loading …": "Loading …",
|
||||||
|
@ -1195,6 +1194,7 @@
|
||||||
"Favourited": "Favourited",
|
"Favourited": "Favourited",
|
||||||
"Favourite": "Favourite",
|
"Favourite": "Favourite",
|
||||||
"Low Priority": "Low Priority",
|
"Low Priority": "Low Priority",
|
||||||
|
"Settings": "Settings",
|
||||||
"Leave Room": "Leave Room",
|
"Leave Room": "Leave Room",
|
||||||
"Room options": "Room options",
|
"Room options": "Room options",
|
||||||
"%(count)s unread messages including mentions.|other": "%(count)s unread messages including mentions.",
|
"%(count)s unread messages including mentions.|other": "%(count)s unread messages including mentions.",
|
||||||
|
@ -1265,6 +1265,7 @@
|
||||||
"URL previews are disabled by default for participants in this room.": "URL previews are disabled by default for participants in this room.",
|
"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.",
|
"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.",
|
"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.",
|
||||||
|
"Back": "Back",
|
||||||
"Waiting for you to accept on your other session…": "Waiting for you to accept on your other session…",
|
"Waiting for you to accept on your other session…": "Waiting for you to accept on your other session…",
|
||||||
"Waiting for %(displayName)s to accept…": "Waiting for %(displayName)s to accept…",
|
"Waiting for %(displayName)s to accept…": "Waiting for %(displayName)s to accept…",
|
||||||
"Accepting…": "Accepting…",
|
"Accepting…": "Accepting…",
|
||||||
|
@ -1282,7 +1283,18 @@
|
||||||
"Yours, or the other users’ internet connection": "Yours, or the other users’ internet connection",
|
"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",
|
"Yours, or the other users’ session": "Yours, or the other users’ session",
|
||||||
"Members": "Members",
|
"Members": "Members",
|
||||||
"Files": "Files",
|
"Room Info": "Room Info",
|
||||||
|
"Apps": "Apps",
|
||||||
|
"Unpin app": "Unpin app",
|
||||||
|
"Edit apps, bridges & bots": "Edit apps, bridges & bots",
|
||||||
|
"Add apps, bridges & bots": "Add apps, bridges & bots",
|
||||||
|
"Not encrypted": "Not encrypted",
|
||||||
|
"About": "About",
|
||||||
|
"%(count)s people|other": "%(count)s people",
|
||||||
|
"%(count)s people|one": "%(count)s person",
|
||||||
|
"Show files": "Show files",
|
||||||
|
"Share room": "Share room",
|
||||||
|
"Room settings": "Room settings",
|
||||||
"Trusted": "Trusted",
|
"Trusted": "Trusted",
|
||||||
"Not trusted": "Not trusted",
|
"Not trusted": "Not trusted",
|
||||||
"%(count)s verified sessions|other": "%(count)s verified sessions",
|
"%(count)s verified sessions|other": "%(count)s verified sessions",
|
||||||
|
@ -1360,6 +1372,12 @@
|
||||||
"You cancelled verification.": "You cancelled verification.",
|
"You cancelled verification.": "You cancelled verification.",
|
||||||
"Verification cancelled": "Verification cancelled",
|
"Verification cancelled": "Verification cancelled",
|
||||||
"Compare emoji": "Compare emoji",
|
"Compare emoji": "Compare emoji",
|
||||||
|
"Take a picture": "Take a picture",
|
||||||
|
"Remove for everyone": "Remove for everyone",
|
||||||
|
"Remove for me": "Remove for me",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Pin to room": "Pin to room",
|
||||||
|
"You can only pin 2 apps at a time": "You can only pin 2 apps at a time",
|
||||||
"Sunday": "Sunday",
|
"Sunday": "Sunday",
|
||||||
"Monday": "Monday",
|
"Monday": "Monday",
|
||||||
"Tuesday": "Tuesday",
|
"Tuesday": "Tuesday",
|
||||||
|
@ -1377,7 +1395,6 @@
|
||||||
"Error decrypting audio": "Error decrypting audio",
|
"Error decrypting audio": "Error decrypting audio",
|
||||||
"React": "React",
|
"React": "React",
|
||||||
"Reply": "Reply",
|
"Reply": "Reply",
|
||||||
"Edit": "Edit",
|
|
||||||
"Message Actions": "Message Actions",
|
"Message Actions": "Message Actions",
|
||||||
"Attachment": "Attachment",
|
"Attachment": "Attachment",
|
||||||
"Error decrypting attachment": "Error decrypting attachment",
|
"Error decrypting attachment": "Error decrypting attachment",
|
||||||
|
@ -1488,7 +1505,6 @@
|
||||||
"Download this file": "Download this file",
|
"Download this file": "Download this file",
|
||||||
"Information": "Information",
|
"Information": "Information",
|
||||||
"Language Dropdown": "Language Dropdown",
|
"Language Dropdown": "Language Dropdown",
|
||||||
"Manage Integrations": "Manage Integrations",
|
|
||||||
"%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s",
|
"%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s",
|
||||||
"%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)sjoined %(count)s times",
|
"%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)sjoined %(count)s times",
|
||||||
"%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)sjoined",
|
"%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)sjoined",
|
||||||
|
@ -1668,7 +1684,6 @@
|
||||||
"Deactivating your account <b>does not by default cause us to forget messages you have sent.</b> If you would like us to forget your messages, please tick the box below.": "Deactivating your account <b>does not by default cause us to forget messages you have sent.</b> If you would like us to forget your messages, please tick the box below.",
|
"Deactivating your account <b>does not by default cause us to forget messages you have sent.</b> If you would like us to forget your messages, please tick the box below.": "Deactivating your account <b>does not by default cause us to forget messages you have sent.</b> If you would like us to forget your messages, please tick the box below.",
|
||||||
"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.",
|
"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)",
|
"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)",
|
||||||
"Back": "Back",
|
|
||||||
"Send": "Send",
|
"Send": "Send",
|
||||||
"Send Custom Event": "Send Custom Event",
|
"Send Custom Event": "Send Custom Event",
|
||||||
"You must specify an event type!": "You must specify an event type!",
|
"You must specify an event type!": "You must specify an event type!",
|
||||||
|
@ -1909,10 +1924,9 @@
|
||||||
"Set status": "Set status",
|
"Set status": "Set status",
|
||||||
"Set a new status...": "Set a new status...",
|
"Set a new status...": "Set a new status...",
|
||||||
"View Community": "View Community",
|
"View Community": "View Community",
|
||||||
|
"Unpin": "Unpin",
|
||||||
"Reload": "Reload",
|
"Reload": "Reload",
|
||||||
"Take picture": "Take picture",
|
"Take picture": "Take picture",
|
||||||
"Remove for everyone": "Remove for everyone",
|
|
||||||
"Remove for me": "Remove for me",
|
|
||||||
"This room is public": "This room is public",
|
"This room is public": "This room is public",
|
||||||
"Away": "Away",
|
"Away": "Away",
|
||||||
"User Status": "User Status",
|
"User Status": "User Status",
|
||||||
|
|
|
@ -618,5 +618,37 @@
|
||||||
"Try using turn.matrix.org": "Try using turn.matrix.org",
|
"Try using turn.matrix.org": "Try using turn.matrix.org",
|
||||||
"Messages": "Messages",
|
"Messages": "Messages",
|
||||||
"Actions": "Actions",
|
"Actions": "Actions",
|
||||||
"Other": "Other"
|
"Other": "Other",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Add Email Address": "Add Email Address",
|
||||||
|
"Confirm adding this phone number by using Single Sign On to prove your identity.": "Confirm adding this phone number by using Single Sign On to prove your identity.",
|
||||||
|
"Confirm adding phone number": "Confirm adding phone number",
|
||||||
|
"Click the button below to confirm adding this phone number.": "Click the button below to confirm adding this phone number.",
|
||||||
|
"Add Phone Number": "Add Phone Number",
|
||||||
|
"Whether you're using %(brand)s on a device where touch is the primary input mechanism": "Whether you're using %(brand)s on a device where touch is the primary input mechanism",
|
||||||
|
"Whether you're using %(brand)s as an installed Progressive Web App": "Whether you're using %(brand)s as an installed Progressive Web App",
|
||||||
|
"Your user agent": "Your user agent",
|
||||||
|
"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.": "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.",
|
||||||
|
"Cancel entering passphrase?": "Cancel entering passphrase?",
|
||||||
|
"Are you sure you want to cancel entering passphrase?": "Are you sure you want to cancel entering passphrase?",
|
||||||
|
"Go Back": "Go Back",
|
||||||
|
"Setting up keys": "Setting up keys",
|
||||||
|
"Room name or address": "Room name or address",
|
||||||
|
"Identity server has no terms of service": "Identity server has no terms of service",
|
||||||
|
"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.": "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.",
|
||||||
|
"Only continue if you trust the owner of the server.": "Only continue if you trust the owner of the server.",
|
||||||
|
"Trust": "Trust",
|
||||||
|
"%(name)s is requesting verification": "%(name)s is requesting verification",
|
||||||
|
"Sign In or Create Account": "Sign In or Create Account",
|
||||||
|
"Use your account or create a new one to continue.": "Use your account or create a new one to continue.",
|
||||||
|
"Create Account": "Create Account",
|
||||||
|
"Sign In": "Sign In",
|
||||||
|
"Custom (%(level)s)": "Custom (%(level)s)",
|
||||||
|
"Sends a message as plain text, without interpreting it as markdown": "Sends a message as plain text, without interpreting it as markdown",
|
||||||
|
"Sends a message as html, without interpreting it as markdown": "Sends a message as html, without interpreting it as markdown",
|
||||||
|
"You do not have the required permissions to use this command.": "You do not have the required permissions to use this command.",
|
||||||
|
"Error upgrading room": "Error upgrading room",
|
||||||
|
"Double check that your server supports the room version chosen and try again.": "Double check that your server supports the room version chosen and try again.",
|
||||||
|
"Changes the avatar of the current room": "Changes the avatar of the current room",
|
||||||
|
"Changes your avatar in all rooms": "Changes your avatar in all rooms"
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
"Deops user with given id": "Degrada al usuario con la ID dada",
|
"Deops user with given id": "Degrada al usuario con la ID dada",
|
||||||
"Default": "Por Defecto",
|
"Default": "Por Defecto",
|
||||||
"Disinvite": "Deshacer invitación",
|
"Disinvite": "Deshacer invitación",
|
||||||
"Displays action": "Muestra la acción",
|
"Displays action": "Hacer una acción",
|
||||||
"Download %(text)s": "Descargar %(text)s",
|
"Download %(text)s": "Descargar %(text)s",
|
||||||
"Email": "Correo electrónico",
|
"Email": "Correo electrónico",
|
||||||
"Email address": "Dirección de correo electrónico",
|
"Email address": "Dirección de correo electrónico",
|
||||||
|
@ -285,7 +285,7 @@
|
||||||
"Uploading %(filename)s and %(count)s others|one": "Subiendo %(filename)s y otros %(count)s",
|
"Uploading %(filename)s and %(count)s others|one": "Subiendo %(filename)s y otros %(count)s",
|
||||||
"Uploading %(filename)s and %(count)s others|other": "Subiendo %(filename)s y otros %(count)s",
|
"Uploading %(filename)s and %(count)s others|other": "Subiendo %(filename)s y otros %(count)s",
|
||||||
"Upload avatar": "Subir avatar",
|
"Upload avatar": "Subir avatar",
|
||||||
"Upload Failed": "No Se Pudo Subir",
|
"Upload Failed": "Subida fallida",
|
||||||
"Upload file": "Subir archivo",
|
"Upload file": "Subir archivo",
|
||||||
"Upload new:": "Subir nuevo:",
|
"Upload new:": "Subir nuevo:",
|
||||||
"Usage": "Uso",
|
"Usage": "Uso",
|
||||||
|
@ -397,7 +397,7 @@
|
||||||
"This Room": "Esta sala",
|
"This Room": "Esta sala",
|
||||||
"Resend": "Reenviar",
|
"Resend": "Reenviar",
|
||||||
"Room not found": "Sala no encontrada",
|
"Room not found": "Sala no encontrada",
|
||||||
"Messages containing my display name": "Mensajes que contienen mi nombre público",
|
"Messages containing my display name": "Mensajes que contengan mi nombre público",
|
||||||
"Messages in one-to-one chats": "Mensajes en conversaciones uno a uno",
|
"Messages in one-to-one chats": "Mensajes en conversaciones uno a uno",
|
||||||
"Unavailable": "No disponible",
|
"Unavailable": "No disponible",
|
||||||
"View Decrypted Source": "Ver Fuente Descifrada",
|
"View Decrypted Source": "Ver Fuente Descifrada",
|
||||||
|
@ -472,7 +472,7 @@
|
||||||
"Unhide Preview": "Mostrar Vista Previa",
|
"Unhide Preview": "Mostrar Vista Previa",
|
||||||
"Unable to join network": "No se puede unir a la red",
|
"Unable to join network": "No se puede unir a la red",
|
||||||
"Sorry, your browser is <b>not</b> able to run %(brand)s.": "¡Lo sentimos! Su navegador <b>no puede</b> ejecutar %(brand)s.",
|
"Sorry, your browser is <b>not</b> able to run %(brand)s.": "¡Lo sentimos! Su navegador <b>no puede</b> ejecutar %(brand)s.",
|
||||||
"Messages in group chats": "Mensajes en conversaciones en grupo",
|
"Messages in group chats": "Mensajes en conversaciones grupales",
|
||||||
"Yesterday": "Ayer",
|
"Yesterday": "Ayer",
|
||||||
"Error encountered (%(errorDetail)s).": "Error encontrado (%(errorDetail)s).",
|
"Error encountered (%(errorDetail)s).": "Error encontrado (%(errorDetail)s).",
|
||||||
"Low Priority": "Prioridad Baja",
|
"Low Priority": "Prioridad Baja",
|
||||||
|
@ -518,7 +518,7 @@
|
||||||
"Failed to invite the following users to %(groupId)s:": "No se pudo invitar a los siguientes usuarios a %(groupId)s:",
|
"Failed to invite the following users to %(groupId)s:": "No se pudo invitar a los siguientes usuarios a %(groupId)s:",
|
||||||
"Failed to invite users to community": "No se pudo invitar usuarios a la comunidad",
|
"Failed to invite users to community": "No se pudo invitar usuarios a la comunidad",
|
||||||
"Failed to invite users to %(groupId)s": "No se pudo invitar usuarios a %(groupId)s",
|
"Failed to invite users to %(groupId)s": "No se pudo invitar usuarios a %(groupId)s",
|
||||||
"Failed to add the following rooms to %(groupId)s:": "No se pudo añadir a las siguientes salas a %(groupId)s:",
|
"Failed to add the following rooms to %(groupId)s:": "No se pudieron añadir las siguientes salas a %(groupId)s:",
|
||||||
"Restricted": "Restringido",
|
"Restricted": "Restringido",
|
||||||
"Missing roomId.": "Falta el Id de sala.",
|
"Missing roomId.": "Falta el Id de sala.",
|
||||||
"Ignores a user, hiding their messages from you": "Ignora a un usuario, ocultando sus mensajes",
|
"Ignores a user, hiding their messages from you": "Ignora a un usuario, ocultando sus mensajes",
|
||||||
|
@ -537,7 +537,7 @@
|
||||||
"Not a valid %(brand)s keyfile": "No es un archivo de claves de %(brand)s válido",
|
"Not a valid %(brand)s keyfile": "No es un archivo de claves de %(brand)s válido",
|
||||||
"Message Pinning": "Mensajes con chincheta",
|
"Message Pinning": "Mensajes con chincheta",
|
||||||
"Always show encryption icons": "Mostrar siempre iconos de cifrado",
|
"Always show encryption icons": "Mostrar siempre iconos de cifrado",
|
||||||
"Automatically replace plain text Emoji": "Sustituir automáticamente Emojis de texto",
|
"Automatically replace plain text Emoji": "Reemplazar automáticamente texto por Emojis",
|
||||||
"Mirror local video feed": "Clonar transmisión de video local",
|
"Mirror local video feed": "Clonar transmisión de video local",
|
||||||
"Send analytics data": "Enviar datos de análisis de estadísticas",
|
"Send analytics data": "Enviar datos de análisis de estadísticas",
|
||||||
"Enable inline URL previews by default": "Habilitar vistas previas de URL en línea por defecto",
|
"Enable inline URL previews by default": "Habilitar vistas previas de URL en línea por defecto",
|
||||||
|
@ -802,7 +802,7 @@
|
||||||
"Old cryptography data detected": "Se detectó información de criptografía antigua",
|
"Old cryptography data detected": "Se detectó información de criptografía antigua",
|
||||||
"Data from an older version of %(brand)s 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.": "Se detectó una versión más antigua de %(brand)s. Esto habrá provocado que la criptografía de extremo a extremo funcione incorrectamente en la versión más antigua. Los mensajes cifrados de extremo a extremo intercambiados recientemente mientras usaba la versión más antigua puede que no sean descifrables con esta versión. Esto también puede hacer que fallen con la más reciente. Si experimenta problemas, desconecte y vuelva a ingresar. Para conservar el historial de mensajes, exporte y vuelva a importar sus claves.",
|
"Data from an older version of %(brand)s 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.": "Se detectó una versión más antigua de %(brand)s. Esto habrá provocado que la criptografía de extremo a extremo funcione incorrectamente en la versión más antigua. Los mensajes cifrados de extremo a extremo intercambiados recientemente mientras usaba la versión más antigua puede que no sean descifrables con esta versión. Esto también puede hacer que fallen con la más reciente. Si experimenta problemas, desconecte y vuelva a ingresar. Para conservar el historial de mensajes, exporte y vuelva a importar sus claves.",
|
||||||
"Your Communities": "Sus Comunidades",
|
"Your Communities": "Sus Comunidades",
|
||||||
"Did you know: you can use communities to filter your %(brand)s experience!": "Sabía que: puede usar comunidades para filtrar su experiencia con %(brand)s",
|
"Did you know: you can use communities to filter your %(brand)s experience!": "Sabía que: puede usar comunidades para filtrar su experiencia con %(brand)s !",
|
||||||
"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.": "Para configurar un filtro, arrastre un avatar de comunidad sobre el panel de filtro en la parte izquierda de la pantalla. Puede pulsar sobre un avatar en el panel de filtro en cualquier momento para ver solo las salas y personas asociadas con esa comunidad.",
|
"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.": "Para configurar un filtro, arrastre un avatar de comunidad sobre el panel de filtro en la parte izquierda de la pantalla. Puede pulsar sobre un avatar en el panel de filtro en cualquier momento para ver solo las salas y personas asociadas con esa comunidad.",
|
||||||
"Error whilst fetching joined communities": "Error al recuperar las comunidades a las que estás unido",
|
"Error whilst fetching joined communities": "Error al recuperar las comunidades a las que estás unido",
|
||||||
"Create a new community": "Crear una comunidad nueva",
|
"Create a new community": "Crear una comunidad nueva",
|
||||||
|
@ -927,22 +927,22 @@
|
||||||
"Custom user status messages": "Mensajes de estado de usuario personalizados",
|
"Custom user status messages": "Mensajes de estado de usuario personalizados",
|
||||||
"Group & filter rooms by custom tags (refresh to apply changes)": "Agrupa y filtra salas por etiquetas personalizadas (refresca para aplicar cambios)",
|
"Group & filter rooms by custom tags (refresh to apply changes)": "Agrupa y filtra salas por etiquetas personalizadas (refresca para aplicar cambios)",
|
||||||
"Render simple counters in room header": "Muestra contadores simples en la cabecera de la sala",
|
"Render simple counters in room header": "Muestra contadores simples en la cabecera de la sala",
|
||||||
"Enable Emoji suggestions while typing": "Habiliatar sugerencia de Emojis mientras se teclea",
|
"Enable Emoji suggestions while typing": "Habilitar sugerencia de Emojis mientras se teclea",
|
||||||
"Show a placeholder for removed messages": "Mostrar una marca para los mensaje borrados",
|
"Show a placeholder for removed messages": "Mostrar una marca para los mensaje borrados",
|
||||||
"Show join/leave messages (invites/kicks/bans unaffected)": "Mostrar mensajes de unir/salir (no afecta a invitaciones/pateos/baneos )",
|
"Show join/leave messages (invites/kicks/bans unaffected)": "Mostrar mensajes de entrada/salida (no afecta a invitaciones/expulsiones/baneos)",
|
||||||
"Show avatar changes": "Mostrar cambios de avatar",
|
"Show avatar changes": "Mostrar cambios de avatar",
|
||||||
"Show display name changes": "Muestra cambios en los nombres",
|
"Show display name changes": "Muestra cambios en los nombres",
|
||||||
"Show a reminder to enable Secure Message Recovery in encrypted rooms": "Mostrar ecordatorio para habilitar 'Recuperación Segura de Mensajes ' en sala cifradas",
|
"Show a reminder to enable Secure Message Recovery in encrypted rooms": "Mostrar un recordatorio para habilitar 'Recuperación Segura de Mensajes' en sala cifradas",
|
||||||
"Show avatars in user and room mentions": "Mostrar avatares en menciones a usuarios y salas",
|
"Show avatars in user and room mentions": "Mostrar avatares en menciones a usuarios y salas",
|
||||||
"Enable big emoji in chat": "Habilitar emojis grandes en el chat",
|
"Enable big emoji in chat": "Habilitar emojis grandes en el chat",
|
||||||
"Send typing notifications": "Enviar notificaciones de tecleo",
|
"Send typing notifications": "Enviar notificaciones de tecleo",
|
||||||
"Allow Peer-to-Peer for 1:1 calls": "Permitir conexión de pares en llamadas individuales",
|
"Allow Peer-to-Peer for 1:1 calls": "Permitir conexión de pares en llamadas individuales",
|
||||||
"Prompt before sending invites to potentially invalid matrix IDs": "Pedir confirmación antes de enviar invitaciones a IDs de matrix que parezcan inválidos",
|
"Prompt before sending invites to potentially invalid matrix IDs": "Pedir confirmación antes de enviar invitaciones a IDs de matrix que parezcan inválidas",
|
||||||
"Show developer tools": "Mostrar herramientas de desarrollador",
|
"Show developer tools": "Mostrar herramientas de desarrollador",
|
||||||
"Messages containing my username": "Mensajes que contengan mi nombre",
|
"Messages containing my username": "Mensajes que contengan mi nombre",
|
||||||
"Messages containing @room": "Mensajes que contengan @room",
|
"Messages containing @room": "Mensajes que contengan @room",
|
||||||
"Encrypted messages in one-to-one chats": "Mensajes cifrados en salas 1 a 1",
|
"Encrypted messages in one-to-one chats": "Mensajes cifrados en salas uno a uno",
|
||||||
"Encrypted messages in group chats": "Mensajes cifrados en chats grupales",
|
"Encrypted messages in group chats": "Mensajes cifrados en conversaciones grupales",
|
||||||
"The other party cancelled the verification.": "El otro lado canceló la verificación.",
|
"The other party cancelled the verification.": "El otro lado canceló la verificación.",
|
||||||
"Verified!": "¡Verificado!",
|
"Verified!": "¡Verificado!",
|
||||||
"You've successfully verified this user.": "Has verificado correctamente a este usuario.",
|
"You've successfully verified this user.": "Has verificado correctamente a este usuario.",
|
||||||
|
@ -1162,7 +1162,7 @@
|
||||||
"%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s hizo una llamada de vídeo (no soportada por este navegador)",
|
"%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s hizo una llamada de vídeo (no soportada por este navegador)",
|
||||||
"%(name)s (%(userId)s)": "%(name)s (%(userId)s)",
|
"%(name)s (%(userId)s)": "%(name)s (%(userId)s)",
|
||||||
"Try out new ways to ignore people (experimental)": "Pruebe nuevas formas de ignorar a usuarios (experimental)",
|
"Try out new ways to ignore people (experimental)": "Pruebe nuevas formas de ignorar a usuarios (experimental)",
|
||||||
"Match system theme": "Usar el tema del sistema",
|
"Match system theme": "Utilizar el mismo tema del sistema",
|
||||||
"Show previews/thumbnails for images": "Mostrar vistas previas para las imágenes",
|
"Show previews/thumbnails for images": "Mostrar vistas previas para las imágenes",
|
||||||
"When rooms are upgraded": "Cuando las salas son actualizadas",
|
"When rooms are upgraded": "Cuando las salas son actualizadas",
|
||||||
"My Ban List": "Mi lista de baneos",
|
"My Ban List": "Mi lista de baneos",
|
||||||
|
@ -1246,7 +1246,7 @@
|
||||||
"Are you sure you want to sign out?": "¿Estás seguro de que quieres salir?",
|
"Are you sure you want to sign out?": "¿Estás seguro de que quieres salir?",
|
||||||
"Message edits": "Ediciones del mensaje",
|
"Message edits": "Ediciones del mensaje",
|
||||||
"New session": "Nueva sesión",
|
"New session": "Nueva sesión",
|
||||||
"Use this session to verify your new one, granting it access to encrypted messages:": "Usa esta sesión para verificar tu nueva sesión, dándola acceso a mensajes encriptados:",
|
"Use this session to verify your new one, granting it access to encrypted messages:": "Usa esta sesión para verificar tu nueva sesión, dándole acceso a mensajes encriptados:",
|
||||||
"If you didn’t sign in to this session, your account may be compromised.": "Si no te conectaste a esta sesión, es posible que tu cuenta haya sido comprometida.",
|
"If you didn’t sign in to this session, your account may be compromised.": "Si no te conectaste a esta sesión, es posible que tu cuenta haya sido comprometida.",
|
||||||
"This wasn't me": "No fui yo",
|
"This wasn't me": "No fui yo",
|
||||||
"If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.": "Si encuentras algún error o quieres compartir una opinión, por favor, contacta con nosotros en GitHub.",
|
"If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.": "Si encuentras algún error o quieres compartir una opinión, por favor, contacta con nosotros en GitHub.",
|
||||||
|
@ -1318,7 +1318,7 @@
|
||||||
"Your user agent": "Tu agente de usuario",
|
"Your user agent": "Tu agente de usuario",
|
||||||
"If you cancel now, you won't complete verifying the other user.": "Si cancelas ahora, no completarás la verificación del otro usuario.",
|
"If you cancel now, you won't complete verifying the other user.": "Si cancelas ahora, no completarás la verificación del otro usuario.",
|
||||||
"If you cancel now, you won't complete verifying your other session.": "Si cancelas ahora, no completarás la verificación de tu otra sesión.",
|
"If you cancel now, you won't complete verifying your other session.": "Si cancelas ahora, no completarás la verificación de tu otra sesión.",
|
||||||
"Cancel entering passphrase?": "¿Cancelar la introducción de frase de contraseña?",
|
"Cancel entering passphrase?": "¿Cancelar el ingresar tu contraseña de recuperación?",
|
||||||
"%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s actualizó la regla bloqueando salas que coinciden con %(glob)s por %(reason)s",
|
"%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s actualizó la regla bloqueando salas que coinciden con %(glob)s por %(reason)s",
|
||||||
"%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s actualizó la regla bloqueando servidores que coinciden con %(glob)s por %(reason)s",
|
"%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s actualizó la regla bloqueando servidores que coinciden con %(glob)s por %(reason)s",
|
||||||
"%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s actualizó una regla de bloqueo correspondiente a %(glob)s por %(reason)s",
|
"%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s actualizó una regla de bloqueo correspondiente a %(glob)s por %(reason)s",
|
||||||
|
@ -1356,7 +1356,7 @@
|
||||||
"Compare unique emoji": "Comparar emoji único",
|
"Compare unique emoji": "Comparar emoji único",
|
||||||
"Compare a unique set of emoji if you don't have a camera on either device": "Comparar un conjunto de emojis si no tienes cámara en ninguno de los dispositivos",
|
"Compare a unique set of emoji if you don't have a camera on either device": "Comparar un conjunto de emojis si no tienes cámara en ninguno de los dispositivos",
|
||||||
"Start": "Inicio",
|
"Start": "Inicio",
|
||||||
"Waiting for %(displayName)s to verify…": "Esperando la verificación de %(displayName)s …",
|
"Waiting for %(displayName)s to verify…": "Esperando la verificación de %(displayName)s…",
|
||||||
"Review": "Revise",
|
"Review": "Revise",
|
||||||
"in secret storage": "en almacén secreto",
|
"in secret storage": "en almacén secreto",
|
||||||
"Secret storage public key:": "Clave pública del almacén secreto:",
|
"Secret storage public key:": "Clave pública del almacén secreto:",
|
||||||
|
@ -1436,7 +1436,7 @@
|
||||||
"If you cancel now, you won't complete your operation.": "Si cancela ahora, no completará la operación.",
|
"If you cancel now, you won't complete your operation.": "Si cancela ahora, no completará la operación.",
|
||||||
"Review where you’re logged in": "Revise dónde hizo su registro",
|
"Review where you’re logged in": "Revise dónde hizo su registro",
|
||||||
"New login. Was this you?": "Nuevo registro. ¿Fuiste tú?",
|
"New login. Was this you?": "Nuevo registro. ¿Fuiste tú?",
|
||||||
"%(name)s is requesting verification": "%(name)s solicita verificación",
|
"%(name)s is requesting verification": "%(name)s solicita verificación",
|
||||||
"Sign In or Create Account": "Iniciar sesión o Crear una cuenta",
|
"Sign In or Create Account": "Iniciar sesión o Crear una cuenta",
|
||||||
"Use your account or create a new one to continue.": "Usa tu cuenta existente o crea una nueva para continuar.",
|
"Use your account or create a new one to continue.": "Usa tu cuenta existente o crea una nueva para continuar.",
|
||||||
"Create Account": "Crear cuenta",
|
"Create Account": "Crear cuenta",
|
||||||
|
@ -1471,11 +1471,11 @@
|
||||||
"Show shortcuts to recently viewed rooms above the room list": "Mostrar atajos a las salas recientemente vistas por encima de la lista de salas",
|
"Show shortcuts to recently viewed rooms above the room list": "Mostrar atajos a las salas recientemente vistas por encima de la lista de salas",
|
||||||
"Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Permitir el servidor de respaldo de asistencia de llamadas turn.matrix.org cuando su servidor doméstico no lo ofrece (su dirección IP se compartiría durante una llamada)",
|
"Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Permitir el servidor de respaldo de asistencia de llamadas turn.matrix.org cuando su servidor doméstico no lo ofrece (su dirección IP se compartiría durante una llamada)",
|
||||||
"Send read receipts for messages (requires compatible homeserver to disable)": "Enviar recibos de lectura de mensajes (requiere un servidor local compatible para desactivarlo)",
|
"Send read receipts for messages (requires compatible homeserver to disable)": "Enviar recibos de lectura de mensajes (requiere un servidor local compatible para desactivarlo)",
|
||||||
"Manually verify all remote sessions": "Verifica manualmente todas las sesiones remotas",
|
"Manually verify all remote sessions": "Verificar manualmente todas las sesiones remotas",
|
||||||
"Confirm the emoji below are displayed on both sessions, in the same order:": "Confirma que los emoji de abajo se muestran en el mismo orden en ambas sesiones:",
|
"Confirm the emoji below are displayed on both sessions, in the same order:": "Confirma que los emoji de abajo se muestran en el mismo orden en ambas sesiones:",
|
||||||
"Verify this session by confirming the following number appears on its screen.": "Verifique esta sesión confirmando que el siguiente número aparece en su pantalla.",
|
"Verify this session by confirming the following number appears on its screen.": "Verifique esta sesión confirmando que el siguiente número aparece en su pantalla.",
|
||||||
"Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "Esperando a que su otra sesión, %(deviceName)s (%(deviceId)s), verifica…",
|
"Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "Esperando a que su otra sesión, %(deviceName)s (%(deviceId)s), verifica…",
|
||||||
"Cancelling…": "Anulando …",
|
"Cancelling…": "Anulando…",
|
||||||
"Verify all your sessions to ensure your account & messages are safe": "Verifica todas tus sesiones abiertas para asegurarte de que tu cuenta y tus mensajes estén seguros",
|
"Verify all your sessions to ensure your account & messages are safe": "Verifica todas tus sesiones abiertas para asegurarte de que tu cuenta y tus mensajes estén seguros",
|
||||||
"Set up": "Configurar",
|
"Set up": "Configurar",
|
||||||
"Verify the new login accessing your account: %(name)s": "Verifique el nuevo ingreso que está accediendo a su cuenta: %(name)s",
|
"Verify the new login accessing your account: %(name)s": "Verifique el nuevo ingreso que está accediendo a su cuenta: %(name)s",
|
||||||
|
@ -1614,7 +1614,7 @@
|
||||||
"Can't find this server or its room list": "No puedo encontrar este servidor o su lista de salas",
|
"Can't find this server or its room list": "No puedo encontrar este servidor o su lista de salas",
|
||||||
"All rooms": "Todas las salas",
|
"All rooms": "Todas las salas",
|
||||||
"Your server": "Tu",
|
"Your server": "Tu",
|
||||||
"Are you sure you want to remove <b>%(serverName)s</b>": "¿ Está seguro de querer eliminar <b>%(serverName)s</b>?",
|
"Are you sure you want to remove <b>%(serverName)s</b>": "¿Está seguro de querer eliminar <b>%(serverName)s</b> ?",
|
||||||
"Remove server": "Quitar servidor",
|
"Remove server": "Quitar servidor",
|
||||||
"Matrix": "Matrix",
|
"Matrix": "Matrix",
|
||||||
"Add a new server": "Añadir un nuevo servidor",
|
"Add a new server": "Añadir un nuevo servidor",
|
||||||
|
@ -1914,7 +1914,7 @@
|
||||||
"Unable to restore backup": "No se pudo restaurar la copia de seguridad",
|
"Unable to restore backup": "No se pudo restaurar la copia de seguridad",
|
||||||
"No backup found!": "¡No se encontró una copia de seguridad!",
|
"No backup found!": "¡No se encontró una copia de seguridad!",
|
||||||
"Keys restored": "Se restauraron las claves",
|
"Keys restored": "Se restauraron las claves",
|
||||||
"Failed to decrypt %(failedCount)s sessions!": "¡Error en descifrar %(failedCount) sesiones!",
|
"Failed to decrypt %(failedCount)s sessions!": "¡Error al descifrar %(failedCount)s sesiones!",
|
||||||
"Successfully restored %(sessionCount)s keys": "%(sessionCount)s claves restauradas con éxito",
|
"Successfully restored %(sessionCount)s keys": "%(sessionCount)s claves restauradas con éxito",
|
||||||
"<b>Warning</b>: you should only set up key backup from a trusted computer.": "<b>Advertencia</b>: deberías configurar la copia de seguridad de claves solamente usando un ordenador de confianza.",
|
"<b>Warning</b>: you should only set up key backup from a trusted computer.": "<b>Advertencia</b>: deberías configurar la copia de seguridad de claves solamente usando un ordenador de confianza.",
|
||||||
"Access your secure message history and set up secure messaging by entering your recovery passphrase.": "Acceda a su historial de mensajes seguros y configure la mensajería segura introduciendo su contraseña de recuperación.",
|
"Access your secure message history and set up secure messaging by entering your recovery passphrase.": "Acceda a su historial de mensajes seguros y configure la mensajería segura introduciendo su contraseña de recuperación.",
|
||||||
|
@ -2075,5 +2075,65 @@
|
||||||
"%(targetName)s changed their avatar": "%(targetName)s ha cambiado su avatar",
|
"%(targetName)s changed their avatar": "%(targetName)s ha cambiado su avatar",
|
||||||
"You changed the room name": "Has cambiado el nombre de la sala",
|
"You changed the room name": "Has cambiado el nombre de la sala",
|
||||||
"%(senderName)s changed the room name": "%(senderName)s cambio el nombre de la sala",
|
"%(senderName)s changed the room name": "%(senderName)s cambio el nombre de la sala",
|
||||||
"You invited %(targetName)s": "Has invitado a %(targetName)s"
|
"You invited %(targetName)s": "Has invitado a %(targetName)s",
|
||||||
|
"Are you sure you want to cancel entering passphrase?": "¿Estas seguro que quieres cancelar el ingresar tu contraseña de recuperación?",
|
||||||
|
"Go Back": "No cancelar",
|
||||||
|
"Joins room with given address": "Entrar a la sala con la dirección especificada",
|
||||||
|
"Unrecognised room address:": "No se encuentra la dirección de la sala:",
|
||||||
|
"Opens chat with the given user": "Abrir una conversación con el usuario especificado",
|
||||||
|
"Sends a message to the given user": "Enviar un mensaje al usuario especificado",
|
||||||
|
"Light": "Claro",
|
||||||
|
"Dark": "Oscuro",
|
||||||
|
"Unexpected server error trying to leave the room": "Error inesperado del servidor al abandonar esta sala",
|
||||||
|
"Error leaving room": "Error al salir de la sala",
|
||||||
|
"Your homeserver has exceeded its user limit.": "Tú servidor ha excedido su limite de usuarios.",
|
||||||
|
"Your homeserver has exceeded one of its resource limits.": "Tú servidor ha excedido el limite de sus recursos.",
|
||||||
|
"Contact your <a>server admin</a>.": "Contacta con el <a>administrador del servidor</a>.",
|
||||||
|
"The person who invited you already left the room.": "La persona que te invito abandono la sala.",
|
||||||
|
"The person who invited you already left the room, or their server is offline.": "La persona que te invito abandono la sala, o puede que su servidor se encuentre desconectado.",
|
||||||
|
"* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
|
||||||
|
"%(senderName)s: %(message)s": "%(senderName)s: %(message)s",
|
||||||
|
"%(senderName)s: %(reaction)s": "%(senderName)s: %(reaction)s",
|
||||||
|
"%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s",
|
||||||
|
"Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Tu nueva sesión se encuentra verificada ahora. Ahora tiene acceso a los mensajes encriptados y otros usuarios verán la sesión como verificada.",
|
||||||
|
"Your new session is now verified. Other users will see it as trusted.": "Tu sesión se encuentra ahora verificada. Otros usuarios la verán como confiable.",
|
||||||
|
"This session is encrypting history using the new recovery method.": "Esta sesión se encuentra encriptando el historial usando el nuevo método de verificación.",
|
||||||
|
"Change notification settings": "Cambiar los ajustes de notificaciones",
|
||||||
|
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Prototipo de comunidades v2. Requiere un servidor compatible. Altamente experimental - usar con precuación.",
|
||||||
|
"Font size": "Tamaño de la fuente",
|
||||||
|
"Use custom size": "Utilizar un tamaño personalizado",
|
||||||
|
"Use a more compact ‘Modern’ layout": "Usar un diseño más 'moderno' y compacto",
|
||||||
|
"Use a system font": "Utilizar una fuente del sistema",
|
||||||
|
"System font name": "Nombre de la fuente",
|
||||||
|
"Enable experimental, compact IRC style layout": "Activar el diseño de IRC compacto, en prueba",
|
||||||
|
"Uploading logs": "Subiendo registros",
|
||||||
|
"Downloading logs": "Descargando registro",
|
||||||
|
"Incoming voice call": "Llamada de voz entrante",
|
||||||
|
"Incoming video call": "Videollamada entrante",
|
||||||
|
"Incoming call": "Llamada entrante",
|
||||||
|
"Waiting for your other session to verify…": "Esperando a tu otra sesión confirme…",
|
||||||
|
"Your server isn't responding to some <a>requests</a>.": "Tú servidor no esta respondiendo a ciertas <a>solicitudes</a>.",
|
||||||
|
"There are advanced notifications which are not shown here.": "Hay configuraciones avanzadas que no se muestran aquí.",
|
||||||
|
"You might have configured them in a client other than %(brand)s. You cannot tune them in %(brand)s but they still apply.": "Puede que las hayas configurado en otro cliente además de %(brand)s. No puedes cambiarlas en %(brand)s pero sus efectos siguen aplicándose.",
|
||||||
|
"New version available. <a>Update now.</a>": "Nueva versión disponible. <a>Actualiza ahora.</a>",
|
||||||
|
"Hey you. You're the best!": "Oye tú. ¡Eres el mejor!",
|
||||||
|
"Size must be a number": "El tamaño debe ser un dígito",
|
||||||
|
"Custom font size can only be between %(min)s pt and %(max)s pt": "El tamaño de la fuente solo puede estar entre los valores %(min)s y %(max)s",
|
||||||
|
"Use between %(min)s pt and %(max)s pt": "Utiliza un valor entre %(min)s y %(max)s",
|
||||||
|
"Message layout": "Diseño del mensaje",
|
||||||
|
"Compact": "Compacto",
|
||||||
|
"Modern": "Moderno",
|
||||||
|
"Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Inserta el nombre de la fuente instalada en tu sistema y %(brand)s intentara utilizarla.",
|
||||||
|
"Customise your appearance": "Personaliza tu apariencia",
|
||||||
|
"Appearance Settings only affect this %(brand)s session.": "Cambiar las opciones de apariencia solo afecta esta %(brand)s sesión.",
|
||||||
|
"Please verify the room ID or address and try again.": "Por favor, verifica la ID o dirección de esta sala e inténtalo de nuevo.",
|
||||||
|
"Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "El administrador del servidor domestico ha deshabilitado la encriptación de extremo a extremo en salas privadas y mensajes directos.",
|
||||||
|
"To link to this room, please add an address.": "Para vincular esta sala, por favor añade una dirección.",
|
||||||
|
"The authenticity of this encrypted message can't be guaranteed on this device.": "La autenticidad de estos mensajes encriptados no pueden ser garantizados en este dispositivo.",
|
||||||
|
"No recently visited rooms": "No hay salas visitadas recientemente",
|
||||||
|
"People": "Gente",
|
||||||
|
"Explore public rooms": "Buscar salas publicas",
|
||||||
|
"Can't see what you’re looking for?": "¿No encuentras nada de lo que buscas?",
|
||||||
|
"Explore all public rooms": "Buscar todas las salas publicas",
|
||||||
|
"%(count)s results|other": "%(count)s resultados"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2425,5 +2425,39 @@
|
||||||
"Error leaving room": "Viga jututoast lahkumisel",
|
"Error leaving room": "Viga jututoast lahkumisel",
|
||||||
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Kogukondade v2 prototüüp. Eeldab, et koduserver toetab sellist funktsionaalsust. Lahendus on esialgne ja katseline - kui kasutad, siis väga ettevaatlikult.",
|
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Kogukondade v2 prototüüp. Eeldab, et koduserver toetab sellist funktsionaalsust. Lahendus on esialgne ja katseline - kui kasutad, siis väga ettevaatlikult.",
|
||||||
"Explore rooms in %(communityName)s": "Uuri jututubasid %(communityName)s kogukonnas",
|
"Explore rooms in %(communityName)s": "Uuri jututubasid %(communityName)s kogukonnas",
|
||||||
"Set up Secure Backup": "Võta kasutusele turvaline varundus"
|
"Set up Secure Backup": "Võta kasutusele turvaline varundus",
|
||||||
|
"Information": "Teave",
|
||||||
|
"Add another email": "Lisa veel üks e-posti aadress",
|
||||||
|
"People you know on %(brand)s": "%(brand)s kasutajad, keda sa tead",
|
||||||
|
"Send %(count)s invites|other": "Saada %(count)s kutset",
|
||||||
|
"Send %(count)s invites|one": "Saada %(count)s kutse",
|
||||||
|
"Invite people to join %(communityName)s": "Kutsu kasutajaid %(communityName)s kogukonna liikmeks",
|
||||||
|
"There was an error creating your community. The name may be taken or the server is unable to process your request.": "Kogukonna loomisel tekkis viga. Selline nimi kas on juba kasutusel või server ei saa hetkel seda päringut töödelda.",
|
||||||
|
"Community ID: +<localpart />:%(domain)s": "Kogukonna tunnus: +<localpart />:%(domain)s",
|
||||||
|
"Use this when referencing your community to others. The community ID cannot be changed.": "Viidates kogukonnale kasuta seda tunnust. Kogukonna tunnust ei ole võimalik muuta.",
|
||||||
|
"You can change this later if needed.": "Kui vaja, siis sa saad seda hiljem muuta.",
|
||||||
|
"What's the name of your community or team?": "Mis on sinu kogukonna või tiimi nimi?",
|
||||||
|
"Enter name": "Sisesta nimi",
|
||||||
|
"Add image (optional)": "Lisa pilt (kui soovid)",
|
||||||
|
"An image will help people identify your community.": "Pilt aitab inimestel teie kogukonda ära tunda.",
|
||||||
|
"Create community": "Loo kogukond",
|
||||||
|
"Explore community rooms": "Sirvi kogukonna jututubasid",
|
||||||
|
"Create a room in %(communityName)s": "Loo uus jututuba %(communityName)s kogukonda",
|
||||||
|
"Cross-signing and secret storage are ready for use.": "Risttunnustamine ja turvahoidla on kasutamiseks valmis.",
|
||||||
|
"Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.": "Risttunnustamine on kasutamiseks valmis, kuid turvahoidla ei ole hetkel krüptovõtmete varundamiseks kasutusel.",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Omavahelisi jututubasid on võimalik leida ning nendega liituda vaid kutse alusel. Avalikke jututubasid saavad kõik leida ning nendega liituda.",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Omavahelisi jututubasid on võimalik leida ning nendega liituda vaid kutse alusel. Selles kogukonnas saavad avalikke jututubasid kõik leida ning nendega liituda.",
|
||||||
|
"You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Sa võid sellise võimaluse kasutusele võtta, kui seda jututuba kasutatakse vaid organisatsioonisiseste tiimide ühistööks oma koduserveri piires. Seda ei saa hiljem muuta.",
|
||||||
|
"You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "Sa võid sellise võimaluse jätta kasutusele võtmata, kui seda jututuba kasutatakse erinevate väliste tiimide ühistööks kasutades erinevaid koduservereid. Seda ei saa hiljem muuta.",
|
||||||
|
"Block anyone not part of %(serverName)s from ever joining this room.": "Keela kõikide niisuguste kasutajate liitumine selle jututoaga, kelle kasutajakonto ei asu %(serverName)s koduserveris.",
|
||||||
|
"May include members not in %(communityName)s": "Siin võib leiduda kasutajaid, kes ei ole %(communityName)s kogukonna liikmed",
|
||||||
|
"Start a conversation with someone using their name, username (like <userId/>) or email address. This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>.": "Alusta vestust teise osapoolega tema nime, kasutajanime (näiteks <userId/>) või e-posti aadressi alusel. Sellega aga sa ei kutsu teda %(communityName)s kogukonna liikmeks. Kui soovid kedagi kutsuda %(communityName)s kogukonda, siis vajuta <a>siia</a>.",
|
||||||
|
"There was an error updating your community. The server is unable to process your request.": "Sinu kogukonna andmete uuendamisel tekkis viga. Server ei suuda sinu päringut töödelda.",
|
||||||
|
"Update community": "Uuenda kogukonda",
|
||||||
|
"Failed to find the general chat for this community": "Ei õnnestunud tuvastada selle kogukonna üldist rühmavestlust",
|
||||||
|
"Community settings": "Kogukonna seadistused",
|
||||||
|
"User settings": "Kasutaja seadistused",
|
||||||
|
"Community and user menu": "Kogukonna ja kasutaja menüü",
|
||||||
|
"Privacy": "Privaatsus",
|
||||||
|
"Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "Lisa ( ͡° ͜ʖ ͡°) smaili vormindamata sõnumi algusesse"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2377,5 +2377,23 @@
|
||||||
"%(brand)s Web": "%(brand)s Web",
|
"%(brand)s Web": "%(brand)s Web",
|
||||||
"%(brand)s Desktop": "%(brand)s Desktop",
|
"%(brand)s Desktop": "%(brand)s Desktop",
|
||||||
"%(brand)s iOS": "%(brand)s iOS",
|
"%(brand)s iOS": "%(brand)s iOS",
|
||||||
"%(brand)s X for Android": "%(brand)s X pour Android"
|
"%(brand)s X for Android": "%(brand)s X pour Android",
|
||||||
|
"Are you sure you want to cancel entering passphrase?": "Souhaitez-vous vraiment annuler l'entrée de la phrase de passe ?",
|
||||||
|
"Unexpected server error trying to leave the room": "Erreur de serveur inattendue en essayant de quitter le salon",
|
||||||
|
"Error leaving room": "Erreur en essayant de quitter le salon",
|
||||||
|
"The person who invited you already left the room.": "La personne vous ayant invité a déjà quitté le salon.",
|
||||||
|
"The person who invited you already left the room, or their server is offline.": "La personne vous ayant invité a déjà quitté le salon, ou son serveur est hors-ligne.",
|
||||||
|
"* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
|
||||||
|
"Change notification settings": "Modifier les paramètres de notification",
|
||||||
|
"Show message previews for reactions in DMs": "Afficher la prévisualisation des messages pour les réactions dans les messages privés",
|
||||||
|
"Show message previews for reactions in all rooms": "Afficher la prévisualisation des messages pour les réactions dans tous les salons",
|
||||||
|
"Enable advanced debugging for the room list": "Activer le débogage avancé pour la liste de salons",
|
||||||
|
"Uploading logs": "Téléversement des journaux",
|
||||||
|
"Downloading logs": "Téléchargement des journaux",
|
||||||
|
"Your server isn't responding to some <a>requests</a>.": "Votre serveur ne répond pas à certaines <a>requêtes</a>.",
|
||||||
|
"Cross-signing and secret storage are ready for use.": "La signature croisée et le coffre secret sont prêt à l'emploi.",
|
||||||
|
"Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.": "La signature croisée est prête à l'emploi, mais le coffre secret n'est pas actuellement utilisé pour sauvegarder vos clés.",
|
||||||
|
"Master private key:": "Clé privée maîtresse :",
|
||||||
|
"%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use <desktopLink>%(brand)s Desktop</desktopLink> for encrypted messages to appear in search results.": "%(brand)s ne peut actuellement mettre en cache vos messages chiffrés localement de manière sécurisée via le navigateur Web. Utilisez <desktopLink>%(brand)s Desktop</desktopLink> pour que les messages chiffrés apparaissent dans vos résultats de recherche.",
|
||||||
|
"There are advanced notifications which are not shown here.": "Des notifications avancées ne sont pas affichées ici."
|
||||||
}
|
}
|
||||||
|
|
|
@ -1884,7 +1884,7 @@
|
||||||
"Message layout": "Disposición da mensaxe",
|
"Message layout": "Disposición da mensaxe",
|
||||||
"Compact": "Compacta",
|
"Compact": "Compacta",
|
||||||
"Modern": "Moderna",
|
"Modern": "Moderna",
|
||||||
"Power level": "Poderío",
|
"Power level": "Nivel de permisos",
|
||||||
"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.": "Verifica este dispositivo para marcalo como confiable. Confiando neste dispositivo permite que ti e outras usuarias estedes máis tranquilas ao utilizar mensaxes cifradas.",
|
"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.": "Verifica este dispositivo para marcalo como confiable. Confiando neste dispositivo permite que ti e outras usuarias estedes máis tranquilas ao utilizar mensaxes cifradas.",
|
||||||
"Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "Ao verificar este dispositivo marcaralo como confiable, e as usuarias que confiaron en ti tamén confiarán nel.",
|
"Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "Ao verificar este dispositivo marcaralo como confiable, e as usuarias que confiaron en ti tamén confiarán nel.",
|
||||||
"Waiting for partner to confirm...": "Agardando a que o compañeiro confirme...",
|
"Waiting for partner to confirm...": "Agardando a que o compañeiro confirme...",
|
||||||
|
@ -2425,5 +2425,38 @@
|
||||||
"Error leaving room": "Erro ó saír da sala",
|
"Error leaving room": "Erro ó saír da sala",
|
||||||
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Prototipos de Comunidades v2. Require un servidor compatible. Característica experimental - usa con tino.",
|
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Prototipos de Comunidades v2. Require un servidor compatible. Característica experimental - usa con tino.",
|
||||||
"Explore rooms in %(communityName)s": "Explorar salas en %(communityName)s",
|
"Explore rooms in %(communityName)s": "Explorar salas en %(communityName)s",
|
||||||
"Set up Secure Backup": "Configurar Copia de apoio Segura"
|
"Set up Secure Backup": "Configurar Copia de apoio Segura",
|
||||||
|
"Cross-signing and secret storage are ready for use.": "A Sinatura-Cruzada e o almacenaxe segredo están listos para usar.",
|
||||||
|
"Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.": "A Sinatura-Cruzada está preparada para usala, mais o almacenaxe segredo aínda non foi usado para facer copia das chaves.",
|
||||||
|
"Explore community rooms": "Explorar salas da comunidade",
|
||||||
|
"Information": "Información",
|
||||||
|
"Add another email": "Engadir outro email",
|
||||||
|
"People you know on %(brand)s": "Persoas que coñeces en %(brand)s",
|
||||||
|
"Send %(count)s invites|other": "Enviar %(count)s convites",
|
||||||
|
"Send %(count)s invites|one": "Enviar %(count)s convite",
|
||||||
|
"Invite people to join %(communityName)s": "Convida a persoas a unirse a %(communityName)s",
|
||||||
|
"There was an error creating your community. The name may be taken or the server is unable to process your request.": "Algo fallou ó crear a túa comunidade. O nome podería estar pillado ou o servidor non pode procesar a túa solicitude.",
|
||||||
|
"Community ID: +<localpart />:%(domain)s": "ID da comunidade: +<localpart />:%(domain)s",
|
||||||
|
"Use this when referencing your community to others. The community ID cannot be changed.": "Usa esto cando queiras falar sobre a túa comunidade. O ID da comunidade non se pode cambiar.",
|
||||||
|
"You can change this later if needed.": "Podes cambiar esto máis tarde se o precisas.",
|
||||||
|
"What's the name of your community or team?": "¿Cómo se chama a túa comunidade ou equipo?",
|
||||||
|
"Enter name": "Escribe o nome",
|
||||||
|
"Add image (optional)": "Engade unha imaxe (optativo)",
|
||||||
|
"An image will help people identify your community.": "Unha imaxe axudaralle á xente a identificar a túa comunidade.",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "As salas privadas só se poden atopar e unirse por convite. As salas públicas son accesibles para calquera.",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "As salas privadas só poden ser atopadas e unirse por convite. As salas públicas son accesibles para calquera nesta comunidade.",
|
||||||
|
"You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Pode resultar útil se a sala vai ser utilizada só polo equipo de xestión interna do servidor. Non se pode cambiar máis tarde.",
|
||||||
|
"You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "Poderías desactivalo se a sala vai ser utilizada para colaborar con equipos externos que teñen o seu propio servidor. Esto non se pode cambiar máis tarde.",
|
||||||
|
"Create a room in %(communityName)s": "Crear unha sala en %(communityName)s",
|
||||||
|
"Block anyone not part of %(serverName)s from ever joining this room.": "Evitar que calquera externo a %(serverName)s se poida unir a esta sala.",
|
||||||
|
"Create community": "Crear comunidade",
|
||||||
|
"Privacy": "Privacidade",
|
||||||
|
"There was an error updating your community. The server is unable to process your request.": "Algo fallou ó actualizar a comunidade. O servidor non é quen de procesar a solicitude.",
|
||||||
|
"Update community": "Actualizar comunidade",
|
||||||
|
"May include members not in %(communityName)s": "Podería incluir membros que non están en %(communityName)s",
|
||||||
|
"Start a conversation with someone using their name, username (like <userId/>) or email address. This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>.": "Iniciar unha conversa con alguén utilizando o seu nome, nome de usuaria (como <userId/>) ou enderezo de email. Esto non as convidará a %(communityName)s. Para convidar a alguén a %(communityName)s, preme <a>aquí</a>.",
|
||||||
|
"Failed to find the general chat for this community": "Non se atopou o chat xenérico para esta comunidade",
|
||||||
|
"Community settings": "Axustes da comunidade",
|
||||||
|
"User settings": "Axustes de usuaria",
|
||||||
|
"Community and user menu": "Menú de usuaria e comunidade"
|
||||||
}
|
}
|
||||||
|
|
|
@ -483,7 +483,7 @@
|
||||||
"Community ID": "Közösség azonosító",
|
"Community ID": "Közösség azonosító",
|
||||||
"Add rooms to the community summary": "Szobák hozzáadása a közösségi összefoglalóhoz",
|
"Add rooms to the community summary": "Szobák hozzáadása a közösségi összefoglalóhoz",
|
||||||
"Add users to the community summary": "Felhasználók hozzáadása a közösségi összefoglalóhoz",
|
"Add users to the community summary": "Felhasználók hozzáadása a közösségi összefoglalóhoz",
|
||||||
"Failed to update community": "Közösség frissítése sikertelen",
|
"Failed to update community": "Közösség módosítása sikertelen",
|
||||||
"Leave Community": "Közösség elhagyása",
|
"Leave Community": "Közösség elhagyása",
|
||||||
"Add rooms to this community": "Szobák hozzáadása ehhez a közösséghez",
|
"Add rooms to this community": "Szobák hozzáadása ehhez a közösséghez",
|
||||||
"%(inviter)s has invited you to join this community": "%(inviter)s meghívott ebbe a közösségbe",
|
"%(inviter)s has invited you to join this community": "%(inviter)s meghívott ebbe a közösségbe",
|
||||||
|
@ -2413,5 +2413,49 @@
|
||||||
"You’re all caught up": "Mindent elolvastál",
|
"You’re all caught up": "Mindent elolvastál",
|
||||||
"You have no visible notifications in this room.": "Nincsenek látható értesítéseid ebben a szobában.",
|
"You have no visible notifications in this room.": "Nincsenek látható értesítéseid ebben a szobában.",
|
||||||
"%(brand)s Android": "%(brand)s Android",
|
"%(brand)s Android": "%(brand)s Android",
|
||||||
"Explore public rooms": "Nyilvános szobák felderítése"
|
"Explore public rooms": "Nyilvános szobák felderítése",
|
||||||
|
"Unexpected server error trying to leave the room": "Váratlan szerver hiba lépett fel a szobából való kilépés közben",
|
||||||
|
"Error leaving room": "A szoba elhagyásakor hiba történt",
|
||||||
|
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Közösségek v2 prototípus. Kompatibilis matrix szervert igényel. Erősen kísérleti állapotban van - körültekintően használd.",
|
||||||
|
"Uploading logs": "Napló feltöltése folyamatban",
|
||||||
|
"Downloading logs": "Napló letöltése folyamatban",
|
||||||
|
"Can't see what you’re looking for?": "Nem találod amit keresel?",
|
||||||
|
"Explore all public rooms": "Fedezd fel a nyilvános szobákat",
|
||||||
|
"%(count)s results|other": "%(count)s találat",
|
||||||
|
"Information": "Információ",
|
||||||
|
"Preparing to download logs": "Napló előkészítése feltöltéshez",
|
||||||
|
"Download logs": "Napló letöltése",
|
||||||
|
"Add another email": "Másik e-mail hozzáadása",
|
||||||
|
"People you know on %(brand)s": "Akiket ismerhetsz itt: %(brand)s",
|
||||||
|
"Send %(count)s invites|other": "%(count)s meghívó küldése",
|
||||||
|
"Send %(count)s invites|one": "%(count)s meghívó küldése",
|
||||||
|
"Invite people to join %(communityName)s": "Hívj meg embereket ide: %(communityName)s",
|
||||||
|
"There was an error creating your community. The name may be taken or the server is unable to process your request.": "A közösség létrehozásánál hiba történt. A név már foglalt vagy a szerver nem tudja feldolgozni a kérést.",
|
||||||
|
"Community ID: +<localpart />:%(domain)s": "Közösség azon.: +<localpart />:%(domain)s",
|
||||||
|
"Use this when referencing your community to others. The community ID cannot be changed.": "Ha másoknál hivatkozol a közösségre ezt használd. A közösség azonosítót nem lehet megváltoztatni.",
|
||||||
|
"You can change this later if needed.": "Később megváltoztathatod ha kell.",
|
||||||
|
"What's the name of your community or team?": "Mi a közösséged vagy csoportod neve?",
|
||||||
|
"Enter name": "Név megadása",
|
||||||
|
"Add image (optional)": "Kép hozzáadása (opcionális)",
|
||||||
|
"An image will help people identify your community.": "A kép segít az embereknek a közösség azonosításában.",
|
||||||
|
"Explore rooms in %(communityName)s": "Fedezd fel a szobákat itt: %(communityName)s",
|
||||||
|
"Create community": "Közösség létrehozása",
|
||||||
|
"Set up Secure Backup": "Biztonsági mentés beállítása",
|
||||||
|
"Explore community rooms": "Fedezd fel a közösségi szobákat",
|
||||||
|
"Create a room in %(communityName)s": "Készíts szobát itt: %(communityName)s",
|
||||||
|
"Cross-signing and secret storage are ready for use.": "Az eszközök közti hitelesítés és a biztonsági tároló kész a használatra.",
|
||||||
|
"Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.": "Az eszközök közti hitelesítés kész a használatra, de a biztonsági tároló nincs használva a kulcsok mentéséhez.",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Privát szobák csak meghívóval találhatók meg és meghívóval lehet belépni. A nyilvános szobákat bárki megtalálhatja és be is léphet.",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Privát szobák csak meghívóval találhatók meg és meghívóval lehet belépni. A nyilvános szobákat a közösség bármely tagja megtalálhatja és be is léphet.",
|
||||||
|
"You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Beállíthatod, ha a szobát csak egy belső csoport használja majd a matrix szervereden. Ezt később nem lehet megváltoztatni.",
|
||||||
|
"You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "Ne engedélyezd ezt, ha a szobát külső csapat is használja másik matrix szerverről. Később nem lehet megváltoztatni.",
|
||||||
|
"Block anyone not part of %(serverName)s from ever joining this room.": "A szobába való belépés megtagadása mindenkitől ki nem ezt a matrix szervert használja: %(serverName)s.",
|
||||||
|
"There was an error updating your community. The server is unable to process your request.": "A közösség módosításakor hiba történt. A szerver nem tudja feldolgozni a kérést.",
|
||||||
|
"Update community": "Közösség módosítása",
|
||||||
|
"May include members not in %(communityName)s": "Olyan tagok is lehetnek akik nincsenek ebben a közösségben: %(communityName)s",
|
||||||
|
"Start a conversation with someone using their name, username (like <userId/>) or email address. This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>.": "Kezdj beszélgetést valakivel akár a neve, felhasználói neve (mint <userId/>) vagy az e-mail címe segítségével. %(communityName)s közösségbe nem lesznek meghívva. Ha valakit meg szeretnél hívni ide: %(communityName)s, kattints <a>ide</a>.",
|
||||||
|
"Failed to find the general chat for this community": "Ehhez a közösséghez nem található általános csevegés",
|
||||||
|
"Community settings": "Közösségi beállítások",
|
||||||
|
"User settings": "Felhasználói beállítások",
|
||||||
|
"Community and user menu": "Közösségi és felhasználói menü"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2423,5 +2423,34 @@
|
||||||
"Explore all public rooms": "Esplora tutte le stanze pubbliche",
|
"Explore all public rooms": "Esplora tutte le stanze pubbliche",
|
||||||
"%(count)s results|other": "%(count)s risultati",
|
"%(count)s results|other": "%(count)s risultati",
|
||||||
"Preparing to download logs": "Preparazione al download dei log",
|
"Preparing to download logs": "Preparazione al download dei log",
|
||||||
"Download logs": "Scarica i log"
|
"Download logs": "Scarica i log",
|
||||||
|
"Unexpected server error trying to leave the room": "Errore inaspettato del server tentando di abbandonare la stanza",
|
||||||
|
"Error leaving room": "Errore uscendo dalla stanza",
|
||||||
|
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Prototipi di comunità v2. Richiede un homeserver compatibile. Altamente sperimentale - usa con attenzione.",
|
||||||
|
"Cross-signing and secret storage are ready for use.": "La firma incrociata e l'archivio segreto sono pronti all'uso.",
|
||||||
|
"Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.": "La firma incrociata è pronta all'uso, ma l'archivio segreto attualmente non è usato per fare il backup delle tue chiavi.",
|
||||||
|
"Explore community rooms": "Esplora stanze della comunità",
|
||||||
|
"Information": "Informazione",
|
||||||
|
"Add another email": "Aggiungi un'altra email",
|
||||||
|
"People you know on %(brand)s": "Persone che conosci su %(brand)s",
|
||||||
|
"Send %(count)s invites|other": "Manda %(count)s inviti",
|
||||||
|
"Send %(count)s invites|one": "Manda %(count)s invito",
|
||||||
|
"Invite people to join %(communityName)s": "Invita persone ad unirsi a %(communityName)s",
|
||||||
|
"There was an error creating your community. The name may be taken or the server is unable to process your request.": "Si è verificato un errore nella creazione della comunità. Il nome potrebbe essere già in uso o il server non riesce ad elaborare la richiesta.",
|
||||||
|
"Community ID: +<localpart />:%(domain)s": "ID comunità: +<localpart />:%(domain)s",
|
||||||
|
"Use this when referencing your community to others. The community ID cannot be changed.": "Usalo quando ti riferisci alla comunità con gli altri. L'ID della comunità non può essere cambiato.",
|
||||||
|
"You can change this later if needed.": "Puoi cambiarlo più tardi se necessario.",
|
||||||
|
"What's the name of your community or team?": "Qual è il nome della tua comunità o squadra?",
|
||||||
|
"Enter name": "Inserisci nome",
|
||||||
|
"Add image (optional)": "Aggiungi immagine (facoltativo)",
|
||||||
|
"An image will help people identify your community.": "Un'immagine aiuterà le persone ad identificare la tua comunità.",
|
||||||
|
"Create a room in %(communityName)s": "Crea una stanza in %(communityName)s",
|
||||||
|
"Explore rooms in %(communityName)s": "Esplora le stanze in %(communityName)s",
|
||||||
|
"Create community": "Crea comunità",
|
||||||
|
"Set up Secure Backup": "Imposta il Backup Sicuro",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Le stanze private possono essere trovate e visitate solo con invito. Le stanze pubbliche invece sono aperte a tutti.",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Le stanze private possono essere trovate e visitate solo con invito. Le stanze pubbliche invece sono aperte a tutti i membri di questa comunità.",
|
||||||
|
"You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Dovresti attivarlo se questa stanza verrà usata solo per collaborazioni tra squadre interne nel tuo homeserver. Non può essere cambiato in seguito.",
|
||||||
|
"You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "Dovresti disattivarlo se questa stanza verrà usata per collaborazioni con squadre esterne che hanno il loro homeserver. Non può essere cambiato in seguito.",
|
||||||
|
"Block anyone not part of %(serverName)s from ever joining this room.": "Blocca l'accesso alla stanza per chiunque non faccia parte di %(serverName)s."
|
||||||
}
|
}
|
||||||
|
|
|
@ -480,7 +480,7 @@
|
||||||
"Compact": "Akussem",
|
"Compact": "Akussem",
|
||||||
"Modern": "Atrar",
|
"Modern": "Atrar",
|
||||||
"Online": "Srid",
|
"Online": "Srid",
|
||||||
"Mention": "Abder",
|
"Mention": "Abdar",
|
||||||
"Verify session": "Asenqed n tɣimit",
|
"Verify session": "Asenqed n tɣimit",
|
||||||
"Message edits": "Tiẓrigin n yizen",
|
"Message edits": "Tiẓrigin n yizen",
|
||||||
"Your account is not secure": "Amiḍan-ik·im d araɣelsan",
|
"Your account is not secure": "Amiḍan-ik·im d araɣelsan",
|
||||||
|
@ -649,7 +649,7 @@
|
||||||
"Connecting to integration manager...": "Tuqqna ɣer umsefrak n useddu...",
|
"Connecting to integration manager...": "Tuqqna ɣer umsefrak n useddu...",
|
||||||
"Cannot connect to integration manager": "Ur nessaweḍ ara ad neqqen ɣer umsefrak n useddu",
|
"Cannot connect to integration manager": "Ur nessaweḍ ara ad neqqen ɣer umsefrak n useddu",
|
||||||
"Delete Backup": "Kkes aḥraz",
|
"Delete Backup": "Kkes aḥraz",
|
||||||
"Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Iznan yettwawgelhen ttuḥerzen s uwgelhen n yixef ɣer yixef. Ala kečč d unermas (inermasen) i yesεan tisura akken ad ɣren iznan-a.",
|
"Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Iznan yettwawgelhen ttuḥerzen s uwgelhen n yixef ɣer yixef. Ala kečč d uɣerwaḍ (yiɣerwaḍen) i yesεan tisura akken ad ɣren iznan-a.",
|
||||||
"This session is backing up your keys. ": "Tiɣimit tḥerrez tisura-inek·inem. ",
|
"This session is backing up your keys. ": "Tiɣimit tḥerrez tisura-inek·inem. ",
|
||||||
"Connect this session to Key Backup": "Qqen tiɣimit-a ɣer uḥraz n tsarut",
|
"Connect this session to Key Backup": "Qqen tiɣimit-a ɣer uḥraz n tsarut",
|
||||||
"Server Name": "Isem n uqeddac",
|
"Server Name": "Isem n uqeddac",
|
||||||
|
@ -1592,7 +1592,7 @@
|
||||||
"Your homeserver has exceeded one of its resource limits.": "Aqeddac-inek·inem agejdan iɛedda yiwet seg tlisa-ines tiɣbula.",
|
"Your homeserver has exceeded one of its resource limits.": "Aqeddac-inek·inem agejdan iɛedda yiwet seg tlisa-ines tiɣbula.",
|
||||||
"Contact your <a>server admin</a>.": "Nermes anedbal-inek·inem <a>n uqeddac</a>.",
|
"Contact your <a>server admin</a>.": "Nermes anedbal-inek·inem <a>n uqeddac</a>.",
|
||||||
"To return to your account in future you need to set a password": "Akken ad tuɣaleḍ ɣer umiḍan-ik·im ɣer sdat tesriḍ ad tesbaduḍ awal uffir",
|
"To return to your account in future you need to set a password": "Akken ad tuɣaleḍ ɣer umiḍan-ik·im ɣer sdat tesriḍ ad tesbaduḍ awal uffir",
|
||||||
"New spinner design": "Afeṣṣel amaynut n usezzay ",
|
"New spinner design": "Afeṣṣel amaynut n tuzzya",
|
||||||
"Render simple counters in room header": "Err amsiḍen afessa ɣef uqerru n texxamt",
|
"Render simple counters in room header": "Err amsiḍen afessa ɣef uqerru n texxamt",
|
||||||
"Multiple integration managers": "Imsefrak n waṭas n yimsidaf",
|
"Multiple integration managers": "Imsefrak n waṭas n yimsidaf",
|
||||||
"Try out new ways to ignore people (experimental)": "Ɛreḍ iberdan-nniḍen i tigtin n yimdanen (armitan)",
|
"Try out new ways to ignore people (experimental)": "Ɛreḍ iberdan-nniḍen i tigtin n yimdanen (armitan)",
|
||||||
|
@ -1876,12 +1876,12 @@
|
||||||
"Send read receipts for messages (requires compatible homeserver to disable)": "Azen inagan n tɣuri i yiznan (yesra aqeddac agejdan yemṣadan i wakken ad yens)",
|
"Send read receipts for messages (requires compatible homeserver to disable)": "Azen inagan n tɣuri i yiznan (yesra aqeddac agejdan yemṣadan i wakken ad yens)",
|
||||||
"Show previews/thumbnails for images": "Sken tiskanin/tinfulin i tugniwin",
|
"Show previews/thumbnails for images": "Sken tiskanin/tinfulin i tugniwin",
|
||||||
"How fast should messages be downloaded.": "Acḥal i ilaq ad yili urured i wakken ad d-adren yiznan.",
|
"How fast should messages be downloaded.": "Acḥal i ilaq ad yili urured i wakken ad d-adren yiznan.",
|
||||||
"Enable experimental, compact IRC style layout": "Rmed aseflu n wanaw n IRC armitan, ussid ",
|
"Enable experimental, compact IRC style layout": "Rmed aseflu n uɣanib n IRC armitan, ussid",
|
||||||
"Waiting for %(displayName)s to verify…": "Aṛaǧu n %(displayName)s i usenqed...",
|
"Waiting for %(displayName)s to verify…": "Aṛaǧu n %(displayName)s i usenqed…",
|
||||||
"Securely cache encrypted messages locally for them to appear in search results, using ": "Ḥrez iznan iwgelhanen idiganen s wudem awurman i wakken ad d-banen deg yigmaḍ n unadi, s useqdec ",
|
"Securely cache encrypted messages locally for them to appear in search results, using ": "Ḥrez iznan iwgelhanen idiganen s wudem awurman i wakken ad d-banen deg yigmaḍ n unadi, s useqdec ",
|
||||||
"Securely cache encrypted messages locally for them to appear in search results.": "Ḥrez iznan iwgelhanen idiganen s wudem awurman i wakken ad d-banen deg yigmaḍ n unadi.",
|
"Securely cache encrypted messages locally for them to appear in search results.": "Ḥrez iznan iwgelhanen idiganen s wudem awurman i wakken ad d-banen deg yigmaḍ n unadi.",
|
||||||
"The integration manager is offline or it cannot reach your homeserver.": "Amsefrak n umsidef ha-t-an beṛṛa n tuqqna neɣ ur yezmir ara ad yaweḍ ɣer uqeddac-ik·im agejdan.",
|
"The integration manager is offline or it cannot reach your homeserver.": "Amsefrak n umsidef ha-t-an beṛṛa n tuqqna neɣ ur yezmir ara ad yaweḍ ɣer uqeddac-ik·im agejdan.",
|
||||||
"This backup is trusted because it has been restored on this session": "Aḥraz yettwaḍman acku yuɣal-d seg tɣimit-a ",
|
"This backup is trusted because it has been restored on this session": "Aḥraz yettwaḍman acku yuɣal-d seg tɣimit-a",
|
||||||
"Back up your keys before signing out to avoid losing them.": "Ḥrez tisura-ik·im send tuffɣa i wakken ur ttruḥunt ara.",
|
"Back up your keys before signing out to avoid losing them.": "Ḥrez tisura-ik·im send tuffɣa i wakken ur ttruḥunt ara.",
|
||||||
"Error saving email notification preferences": "Tuccḍa deg usekles n yismenyaf n ulɣu n yimayl",
|
"Error saving email notification preferences": "Tuccḍa deg usekles n yismenyaf n ulɣu n yimayl",
|
||||||
"An error occurred whilst saving your email notification preferences.": "Tella-d tuccḍa lawan n usekles n yismenyaf n ulɣu n yimayl.",
|
"An error occurred whilst saving your email notification preferences.": "Tella-d tuccḍa lawan n usekles n yismenyaf n ulɣu n yimayl.",
|
||||||
|
@ -1901,7 +1901,7 @@
|
||||||
"This session, or the other session": "Tiɣimita, neɣ tiɣimit tayeḍ",
|
"This session, or the other session": "Tiɣimita, neɣ tiɣimit tayeḍ",
|
||||||
"If you didn’t sign in to this session, your account may be compromised.": "Ma yella ur teqqineḍ ara ɣer tɣimit-a, amiḍan-ik·im yezmer ad yettwaker.",
|
"If you didn’t sign in to this session, your account may be compromised.": "Ma yella ur teqqineḍ ara ɣer tɣimit-a, amiḍan-ik·im yezmer ad yettwaker.",
|
||||||
"Please fill why you're reporting.": "Ttxil-k·m ini-aɣ-d ayɣer i d-tettazneḍ alɣu.",
|
"Please fill why you're reporting.": "Ttxil-k·m ini-aɣ-d ayɣer i d-tettazneḍ alɣu.",
|
||||||
"Report Content to Your Homeserver Administrator": "Ttxil-k·m azen aneqqis i unedbal-ik·im n usebter agejdan.",
|
"Report Content to Your Homeserver Administrator": "Ttxil-k·m azen aneqqis i unedbal-ik·im n usebter agejdan",
|
||||||
"Wrong Recovery Key": "Mačči d tasarut-ik·im n uɛeddi tagi",
|
"Wrong Recovery Key": "Mačči d tasarut-ik·im n uɛeddi tagi",
|
||||||
"Invalid Recovery Key": "Tasarut-ik·im n uɛeddi d tarameɣtut",
|
"Invalid Recovery Key": "Tasarut-ik·im n uɛeddi d tarameɣtut",
|
||||||
"Security Phrase": "Tafyirt n tɣellist",
|
"Security Phrase": "Tafyirt n tɣellist",
|
||||||
|
@ -1911,7 +1911,7 @@
|
||||||
"Unable to load backup status": "Yegguma ad d-yali waddad n uḥraz",
|
"Unable to load backup status": "Yegguma ad d-yali waddad n uḥraz",
|
||||||
"Recovery key mismatch": "Tasarut n tririt ur temṣada ara",
|
"Recovery key mismatch": "Tasarut n tririt ur temṣada ara",
|
||||||
"No backup found!": "Ulac aḥraz yettwafen!",
|
"No backup found!": "Ulac aḥraz yettwafen!",
|
||||||
"Failed to decrypt %(failedCount)s sessions!": "Awgelhen n tɣimiyin %(failedCount)s ur yeddi ara",
|
"Failed to decrypt %(failedCount)s sessions!": "Tukksa n uwgelhen n tɣimiyin %(failedCount)s ur yeddi ara!",
|
||||||
"Successfully restored %(sessionCount)s keys": "Tiririt n tsura n %(sessionCount)s yedda akken iwata",
|
"Successfully restored %(sessionCount)s keys": "Tiririt n tsura n %(sessionCount)s yedda akken iwata",
|
||||||
"This looks like a valid recovery key!": "Ayagi yettban am wakken tasarut n tririt d tameɣtut!",
|
"This looks like a valid recovery key!": "Ayagi yettban am wakken tasarut n tririt d tameɣtut!",
|
||||||
"Not a valid recovery key": "Tasarut n tririt mačči d tameɣtut",
|
"Not a valid recovery key": "Tasarut n tririt mačči d tameɣtut",
|
||||||
|
@ -1928,7 +1928,7 @@
|
||||||
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use %(brand)s with an existing Matrix account on a different homeserver.": "Tzemreḍ ad tesqedceḍ tixtiṛiyin n uqeddac udmawan i wakken ad teqqneḍ ɣer iqeddacen-nniḍen n Matrix s ufran n URL n uqeddac agejdan yemgaraden. Ayagi ad ak-yeǧǧ ad tesqedceḍ %(brand)s s umiḍan n Matrix yellan ɣef uqeddac agejdan yemgaraden.",
|
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use %(brand)s with an existing Matrix account on a different homeserver.": "Tzemreḍ ad tesqedceḍ tixtiṛiyin n uqeddac udmawan i wakken ad teqqneḍ ɣer iqeddacen-nniḍen n Matrix s ufran n URL n uqeddac agejdan yemgaraden. Ayagi ad ak-yeǧǧ ad tesqedceḍ %(brand)s s umiḍan n Matrix yellan ɣef uqeddac agejdan yemgaraden.",
|
||||||
"Confirm your identity by entering your account password below.": "Sentem timagit-ik·im s usekcem n wawal uffir n umiḍan-ik·im ddaw.",
|
"Confirm your identity by entering your account password below.": "Sentem timagit-ik·im s usekcem n wawal uffir n umiḍan-ik·im ddaw.",
|
||||||
"Please review and accept all of the homeserver's policies": "Ttxil-k·m senqed syen qbel tisertiyin akk n uqeddac agejdan",
|
"Please review and accept all of the homeserver's policies": "Ttxil-k·m senqed syen qbel tisertiyin akk n uqeddac agejdan",
|
||||||
"Please review and accept the policies of this homeserver:": "Ttxil-k·m senqed syen qbel tisertiyin n uqeddac-a agejdan",
|
"Please review and accept the policies of this homeserver:": "Ttxil-k·m senqed syen qbel tisertiyin n uqeddac-a agejdan:",
|
||||||
"An email has been sent to %(emailAddress)s": "Yettwazen yimayl ɣer %(emailAddress)s",
|
"An email has been sent to %(emailAddress)s": "Yettwazen yimayl ɣer %(emailAddress)s",
|
||||||
"Token incorrect": "Ajuṭu d arameɣtu",
|
"Token incorrect": "Ajuṭu d arameɣtu",
|
||||||
"Identity Server URL": "URL n uqeddac n timagit",
|
"Identity Server URL": "URL n uqeddac n timagit",
|
||||||
|
@ -2003,12 +2003,12 @@
|
||||||
"Read Marker off-screen lifetime (ms)": "Ɣer tanzagt n tudert n tecreḍt beṛṛa n ugdil (ms)",
|
"Read Marker off-screen lifetime (ms)": "Ɣer tanzagt n tudert n tecreḍt beṛṛa n ugdil (ms)",
|
||||||
"Unignore": "Ur yettwazgel ara",
|
"Unignore": "Ur yettwazgel ara",
|
||||||
"Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "Anedbal-ik·im n uqeddac issens awgelhen seg yixef ɣer yixef s wudem amezwer deg texxamin tusligin & yiznan usriden.",
|
"Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "Anedbal-ik·im n uqeddac issens awgelhen seg yixef ɣer yixef s wudem amezwer deg texxamin tusligin & yiznan usriden.",
|
||||||
"Manage the names of and sign out of your sessions below or <a>verify them in your User Profile</a>.": "Sefrek ismawen syen ffeɣ seg tɣimiyin-ik·im ddaw neɣ <q> senqed-itent deg umaɣnu-ik·im n useqdac</a>.",
|
"Manage the names of and sign out of your sessions below or <a>verify them in your User Profile</a>.": "Sefrek ismawen syen ffeɣ seg tɣimiyin-ik·im ddaw neɣ <q>senqed-itent deg umaɣnu-ik·im n useqdac</a>.",
|
||||||
"A session's public name is visible to people you communicate with": "Isem n tiɣimit tazayezt yettban i yimdanen wukud tettmeslayeḍ",
|
"A session's public name is visible to people you communicate with": "Isem n tiɣimit tazayezt yettban i yimdanen wukud tettmeslayeḍ",
|
||||||
"%(brand)s collects anonymous analytics to allow us to improve the application.": "%(brand)s ileqqeḍ tasleḍt tudrigt i wakken ad aɣ-iɛawen ad nesnerni asnas.",
|
"%(brand)s collects anonymous analytics to allow us to improve the application.": "%(brand)s ileqqeḍ tasleḍt tudrigt i wakken ad aɣ-iɛawen ad nesnerni asnas.",
|
||||||
"You have ignored this user, so their message is hidden. <a>Show anyways.</a>": "Tzegleḍ useqdac-a, ihi iznan-ines ffren. <a>Ɣas akken sken-iten-id.</a>",
|
"You have ignored this user, so their message is hidden. <a>Show anyways.</a>": "Tzegleḍ useqdac-a, ihi iznan-ines ffren. <a>Ɣas akken sken-iten-id.</a>",
|
||||||
"You cancelled verifying %(name)s": "Tesfesxeḍ asenqed n %(name)s",
|
"You cancelled verifying %(name)s": "Tesfesxeḍ asenqed n %(name)s",
|
||||||
"Declining …": "Tigtin...",
|
"Declining …": "Tigtin…",
|
||||||
"You sent a verification request": "Tuzneḍ asuter n usenqed",
|
"You sent a verification request": "Tuzneḍ asuter n usenqed",
|
||||||
"Error decrypting video": "Tuccḍa deg uwgelhen n tvidyut",
|
"Error decrypting video": "Tuccḍa deg uwgelhen n tvidyut",
|
||||||
"Reactions": "Tisedmirin",
|
"Reactions": "Tisedmirin",
|
||||||
|
@ -2074,5 +2074,341 @@
|
||||||
"Without setting up Secure Message Recovery, you'll lose your secure message history when you log out.": "War aswel n Secure Message Recovery, ad tmedleḍ amazray-ik·im n yiznan uffiren ma yella teffɣeḍ.",
|
"Without setting up Secure Message Recovery, you'll lose your secure message history when you log out.": "War aswel n Secure Message Recovery, ad tmedleḍ amazray-ik·im n yiznan uffiren ma yella teffɣeḍ.",
|
||||||
"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.": "Ma yella ur tesbaduḍ ara tarrayt n tririt tamaynut, yezmer ad yili umaker ara iɛerḍen ad yekcem ɣer umiḍan-ik·im. Beddel awal uffir n umiḍan-ik·im syen sbadu tarrayt n tririt tamaynut din din deg yiɣewwaren.",
|
"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.": "Ma yella ur tesbaduḍ ara tarrayt n tririt tamaynut, yezmer ad yili umaker ara iɛerḍen ad yekcem ɣer umiḍan-ik·im. Beddel awal uffir n umiḍan-ik·im syen sbadu tarrayt n tririt tamaynut din din deg yiɣewwaren.",
|
||||||
"This session has detected that your recovery passphrase and key for Secure Messages have been removed.": "Tiɣimit-a tufa-d tafyirt-ik·im tuffirt n tririt d tsarut-ik·im n yiznan uffiren ttwakksent.",
|
"This session has detected that your recovery passphrase and key for Secure Messages have been removed.": "Tiɣimit-a tufa-d tafyirt-ik·im tuffirt n tririt d tsarut-ik·im n yiznan uffiren ttwakksent.",
|
||||||
"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.": "Ma yella ur tekkiseḍ ara tarrayt n tririt tamaynut, yezmer ad yili umaker ara iɛerḍen ad yekcem ɣer umiḍan-ik·im. Beddel awal uffir n umiḍan-ik·im syen sbadu tarrayt n tririt tamaynut din din deg yiɣewwaren."
|
"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.": "Ma yella ur tekkiseḍ ara tarrayt n tririt tamaynut, yezmer ad yili umaker ara iɛerḍen ad yekcem ɣer umiḍan-ik·im. Beddel awal uffir n umiḍan-ik·im syen sbadu tarrayt n tririt tamaynut din din deg yiɣewwaren.",
|
||||||
|
"Mirror local video feed": "Asbani n usuddem n tvidyut tadigant",
|
||||||
|
"Low bandwidth mode": "Askar n tehri n tesfift adday",
|
||||||
|
"Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Sireg aqeddac n tallalt i yisawalen n ufran aneggaru turn.matrix.org ma yili aqeddac-ik·im agejdan ur d-yettmudd ara yiwen (tansa-ik·im n IP ad tettwabḍu lawan n usiwel)",
|
||||||
|
"Compare a unique set of emoji if you don't have a camera on either device": "Serwes tagrumma n yimujiten asufen ma yella ur tesɛiḍ ara takamiṛat ɣef yiwen seg sin yibenkan",
|
||||||
|
"Unable to find a supported verification method.": "D awezɣi ad d-naf tarrayt n usenqed yettusefraken.",
|
||||||
|
"Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "Deg uṛaǧu n tɣimit-ik·im tayeḍ, %(deviceName)s (%(deviceId)s), i usenqed…",
|
||||||
|
"To be secure, do this in person or use a trusted way to communicate.": "I wakken ad tḍemneḍ taɣellistik·im, eg ayagi s timmad-ik·im neɣ seqdec abrid n teywalt iɣef ara tettekleḍ.",
|
||||||
|
"You may need to manually permit %(brand)s to access your microphone/webcam": "Ilaq-ak·am ahat ad tesirgeḍ s ufus %(brand)s i unekcum ɣer usawaḍ/webcam",
|
||||||
|
"This room is not accessible by remote Matrix servers": "Anekcum er texxamt-a ulamek s yiqeddacen n Matrix inmeggagen",
|
||||||
|
"No users have specific privileges in this room": "Ulac aqeddac yesan taseglut tuzzigtt deg texxamt-a",
|
||||||
|
"Select the roles required to change various parts of the room": "Fren timlilin yettusran i usnifel n yiḥricen yemgaraden n texxamt",
|
||||||
|
"Guests cannot join this room even if explicitly invited.": "Ur zmiren ara inebgawen ad d-rnun ɣer texxamt-a alamma ttusnubegten-d s tidet.",
|
||||||
|
"Once enabled, encryption cannot be disabled.": "Akken ara yettwarmad, awgelhen ur yettizmir ara ad yens.",
|
||||||
|
"Click the link in the email you received to verify and then click continue again.": "Sit ɣef useɣwen yella deg yimayl i teṭṭfeḍ i usenqed syen sit tikkelt tayeḍ ad tkemmleḍ.",
|
||||||
|
"Discovery options will appear once you have added an email above.": "Tixtiṛiyin n usnirem ad d-banent akken ara ternuḍ imayl s ufella.",
|
||||||
|
"Discovery options will appear once you have added a phone number above.": "Tixtiṛiyin n usnirem ad d-banent akken ara ternuḍ uṭṭun n tilifun s ufella.",
|
||||||
|
"The maximum permitted number of widgets have already been added to this room.": "Amḍan afellay yettusirgen n yiwiǧiten yettwarna yakan ɣer texxamt-a.",
|
||||||
|
"This room doesn't exist. Are you sure you're at the right place?": "Taxxamt-a ulac-itt. Tetteḥqeḍ aql-ak·akem deg wadeg i iṣeḥḥan?",
|
||||||
|
"Try again later, or ask a room admin to check if you have access.": "Ɛreḍ tikkelt-nniḍen ticki, neɣ suter deg unedbal n texxamt ad iwali ma tzemreḍ ad tkecmeḍ.",
|
||||||
|
"%(errcode)s was returned while trying to access the room. If you think you're seeing this message in error, please <issueLink>submit a bug report</issueLink>.": "%(errcode)s yuɣal-d lawan n uneɛruḍ n unekcum ɣer texxamt. Ma yella izen-a twalaḍ-t ur tebniḍ fell-as, ttxil-k·m <issueLink>azen aneqqis n wabug</issueLink>.",
|
||||||
|
"Never lose encrypted messages": "Ur ttamdal ara akk iznan iwgelhanen",
|
||||||
|
"Messages in this room are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Iznan deg texxamt-a ttwaḥerzen s uwgelhen n yixef ɣer yixef. Ala kečč·kemm d uɣerwaḍ (yiɣerwaḍen) i yesεan tisura akken ad ɣren iznan-a.",
|
||||||
|
"Securely back up your keys to avoid losing them. <a>Learn more.</a>": "Ḥrez tisura-k·m s wudem aɣelsan i wakken ur ak·am-ttṛuḥunt ara. <a>Issin ugar</a>",
|
||||||
|
"Unrecognised command: %(commandText)s": "Taladna d tarussint: %(commandText)s",
|
||||||
|
"Hint: Begin your message with <code>//</code> to start it with a slash.": "Taxballut: Bdu izen-ik·im s <code>//</code> i wakken ad t-tebduḍ s uṣlac.",
|
||||||
|
"Failed to connect to integration manager": "Tuqqna ɣer umsefrak n umsidef ur yeddi ara",
|
||||||
|
"Jump to first unread message.": "Ɛeddi ɣer yizen amezwaru ur nettwaɣra ara.",
|
||||||
|
"Error updating main address": "Tuccḍa deg usali n tensa tagejdant",
|
||||||
|
"You don't have permission to delete the address.": "Ur tesɛiḍ ara tisirag i wakken ad tekkseḍ tansa.",
|
||||||
|
"This room has no local addresses": "Taxxamt-a ur tesɛi ara tansiwin tidiganin",
|
||||||
|
"Error updating flair": "Tuccḍa deg uleqqem n lbenna",
|
||||||
|
"'%(groupId)s' is not a valid community ID": "'%(groupId)s' mačči d asulay n temɣiwent ameɣtu",
|
||||||
|
"Use bots, bridges, widgets and sticker packs": "Seqdec abuten, tileggiyin, iwiǧiten d tɣawsiwin n umyintaḍ",
|
||||||
|
"To continue you need to accept the terms of this service.": "I wakken ad tkemmleḍ tesriḍ ad tqebleḍ tiwtilin n umeẓlu-a.",
|
||||||
|
"This file is <b>too large</b> to upload. The file size limit is %(limit)s but this file is %(sizeOfThisFile)s.": "Afaylu-a <b>ɣezzif aṭas</b> i wakken ad d-yali. Talast n teɣzi n ufaylu d %(limit)s maca afaylu-a d %(sizeOfThisFile)s.",
|
||||||
|
"These files are <b>too large</b> to upload. The file size limit is %(limit)s.": "Ifuyla-a <b>ɣezzifit aṭas</b> i wakken ad d-alin. Talast n teɣzi n ufaylu d %(limit)s.",
|
||||||
|
"Some files are <b>too large</b> to be uploaded. The file size limit is %(limit)s.": "Kra n yifuyla <b>ɣezzifit aṭas</b> i wakken ad d-alin. Talast n teɣzi n ufaylu d %(limit)s.",
|
||||||
|
"Upload %(count)s other files|other": "Sali-d %(count)s ifuyla-nniḍen",
|
||||||
|
"Upload %(count)s other files|one": "Sali-d %(count)s afaylu-nniḍen",
|
||||||
|
"Upload Error": "Tuccḍa deg usali",
|
||||||
|
"A widget would like to verify your identity": "Awiǧit yebɣa ad issenqed timagit-inek·inem",
|
||||||
|
"Remember my selection for this widget": "Cfu ɣef tefrant-inu i uwiǧit-a",
|
||||||
|
"Wrong file type": "Anaw n yifuyla d arameɣtu",
|
||||||
|
"Looks good!": "Yettban igerrez!",
|
||||||
|
"Enter your Security Phrase or <button>Use your Security Key</button> to continue.": "Sekcem tafyirt-ik·im n tɣellist neɣ <button>seqdec tasarut n tɣellist</buttout> i wakken ad tkemmleḍ.",
|
||||||
|
"<b>Warning</b>: you should only set up key backup from a trusted computer.": "<b>Ɣur-k·m</b>: ilaq ad tesbaduḍ aḥraz n tsarut seg uselkim kan iɣef tettekleḍ.",
|
||||||
|
"<b>Warning</b>: You should only set up key backup from a trusted computer.": "<b>Ɣur-k·m</b>: Ilaq ad tesbaduḍ aḥraz n tsarut seg uselkim kan iɣef tettekleḍ.",
|
||||||
|
"Please check your email to continue registration.": "Ttxil-k·m senqed imayl-ik·im i wakken ad tkemmleḍ asekles.",
|
||||||
|
"A text message has been sent to %(msisdn)s": "Izen aḍris yettwazen ɣer %(msisdn)s",
|
||||||
|
"Please enter the code it contains:": "Ttxil-k·m sekcem tangalt yellan deg-s:",
|
||||||
|
"Unable to validate homeserver/identity server": "Asentem n uqeddac agejdan/uqeddac n timagit d awezɣi",
|
||||||
|
"Use lowercase letters, numbers, dashes and underscores only": "Seqdec kan isekkilen imeẓẓyanen, izwilen, ijerriden d yidurren kan",
|
||||||
|
"Join millions for free on the largest public server": "Rnu ɣer yimelyan n yimdanen baṭel ɣef uqeddac azayez ameqqran akk",
|
||||||
|
"Premium hosting for organisations <a>Learn more</a>": "Tanezduɣt n Premium i tkebbaniyin <a>Issin ugar</a>",
|
||||||
|
"Find other public servers or use a custom server": "Af-d iqeddacen-nniḍen izuyaz neɣ seqdec aqeddac udmawan",
|
||||||
|
"Sign in to your Matrix account on <underlinedServerName />": "Qqen ɣer umiḍan-ik·im Matrix ɣef <underlinedServerName />",
|
||||||
|
"Want more than a community? <a>Get your own server</a>": "Tebɣiḍ ugar n temɣiwent? <a>Awi aqeddac-inek·inem kečč·kemm</a>",
|
||||||
|
"%(inviter)s has invited you to join this community": "%(inviter)s inced-ik·ikem ad ternuḍ ɣer temɣiwent-a",
|
||||||
|
"Did you know: you can use communities to filter your %(brand)s experience!": "Teẓriḍ: tzemreḍ ad tesqedceḍ timɣiwnin i usizdeg n tarmit-ik·im %(brand)s!",
|
||||||
|
"Error whilst fetching joined communities": "Tuccḍa deg tririt n temɣiwanin i d-yernan",
|
||||||
|
"You have no visible notifications in this room.": "Ulac ɣur-k·m ilɣa i d-yettbanen deg texxamt-a.",
|
||||||
|
"%(brand)s failed to get the public room list.": "%(brand)s ur yeddi ara wawway n tebdart n texxamt tazayezt.",
|
||||||
|
"The homeserver may be unavailable or overloaded.": "Aqeddac agejdan yezmer ad yili ulac-it neɣ iɛedda nnig uɛebbi.",
|
||||||
|
"Delete the room address %(alias)s and remove %(name)s from the directory?": "Kkes tansa n texxamt %(alias)s rnu kkes %(name)s seg ukaram?",
|
||||||
|
"remove %(name)s from the directory.": "kkes %(name)s seg ukaram.",
|
||||||
|
"The server may be unavailable or overloaded": "Aqeddac yezmer ad yili ulac-it neɣ iɛedda nnig uɛebbi",
|
||||||
|
"%(brand)s does not know how to join a room on this network": "%(brand)s ur yeẓri ara amek ara yernu ɣer texxamt deg uzeṭṭa-a",
|
||||||
|
"Couldn't find a matching Matrix room": "D awezɣi tiftin n texxamt n Matrix yemṣadan",
|
||||||
|
"Unable to look up room ID from server": "Anadi n usulay n texxamt ɣef uqeddac d awezɣi",
|
||||||
|
"%(count)s of your messages have not been sent.|other": "Kra seg yiznan-inek·inem ur ttwaznen ara.",
|
||||||
|
"Connectivity to the server has been lost.": "Tṛuḥ tuqqna ɣer uqeddac.",
|
||||||
|
"Sent messages will be stored until your connection has returned.": "Iznan yettwaznen ad ttwakelsen alamma tuɣal-d tuqqna.",
|
||||||
|
"You seem to be uploading files, are you sure you want to quit?": "Aql-ak·akem tessalayeḍ-d ifuyla, tebɣiḍ stidet ad teffɣeḍ?",
|
||||||
|
"Server may be unavailable, overloaded, or search timed out :(": "Aqeddac yezmer ulac-it, iɛedda aɛebbi i ilaqen neɣ yekfa wakud n unadi:(",
|
||||||
|
"You have %(count)s unread notifications in a prior version of this room.|other": "Ɣur-k·m %(count)s ilɣa ur nettwaɣra ara deg lqem yezrin n texxamt-a.",
|
||||||
|
"You have %(count)s unread notifications in a prior version of this room.|one": "Ɣur-k·m %(count)s ilɣa ur nettwaɣra ara deg lqem yezrin n texxamt-a.",
|
||||||
|
"The email address linked to your account must be entered.": "Tansa n yimayl i icudden ɣer umiḍan-ik·im ilaq ad tettwasekcem.",
|
||||||
|
"No identity server is configured: add one in server settings to reset your password.": "Ulac aqeddac n timagit yettusiwlen: rnu yiwen deg yiɣewwaren n uqeddac i wakken ad twennzeḍ awal-ik·im uffir.",
|
||||||
|
"Please note you are logging into the %(hs)s server, not matrix.org.": "Ttxil-k·m gar tamawt aql-ak·akem tkecmeḍ ɣer uqeddac %(hs)s, neɣ matrix.org.",
|
||||||
|
"Failed to perform homeserver discovery": "Tifin n uqeddac agejdan tegguma ad teddu",
|
||||||
|
"The phone number entered looks invalid": "Uṭṭun n tilifun yettwaskecmen yettban d arameɣtu",
|
||||||
|
"This homeserver doesn't offer any login flows which are supported by this client.": "Aqeddac-a agejdan ur d-yettmuddu ara akk aseddem n tuqqna i yettwasefraken sɣur umsaɣ-a.",
|
||||||
|
"Error: Problem communicating with the given homeserver.": "Tuccḍa: Ugur n teywalt d uqeddac agejdan i d-yettunefken.",
|
||||||
|
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Aznuzwir n temɣiwnin v2. Yesra aqeddac agejdan yemṣadan. D armitan aṭas - aseqdec-ines s leḥder.",
|
||||||
|
"Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Senqed yal tiɣimit yettwasqedcen sɣur aseqdac weḥd-s i ucraḍ fell-as d tuttkilt, war attkal ɣef yibenkan yettuzemlen s uzmel anmidag.",
|
||||||
|
"%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with <nativeLink>search components added</nativeLink>.": "%(brand)s xuṣṣent kra n yisegran yettusran i tuffra s wudem aɣelsan n yiznan iwgelhanen idiganen. Ma yella tebɣiḍ ad tgeḍ tarmit s tmahilt-a, snulfu-d tanarit %(brand)s tudmawant s <nativeLink>unadi n yisegran yettwarnan</nativeLink>.",
|
||||||
|
"%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use <desktopLink>%(brand)s Desktop</desktopLink> for encrypted messages to appear in search results.": "%(brand)s ur yezmir ara ad iffer s wudem aɣelsan iznan iwgelhanen idiganen mi ara iteddu ɣef yiminig web. Seqdec <desktopLink>tanarit</desktopLink> i yiznan iwgelhanen i wakken ad d-banen deg yigmaḍ n unadi.",
|
||||||
|
"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.": "Tiɣimit-a d <b>ur tḥerrez ara tisura-inek·inem</b>, maca ɣur-k·m aḥraz yellan yakan tzemreḍ ad d-terreḍ seg-s d tmerna ɣer sdat.",
|
||||||
|
"Connect this session to key backup before signing out to avoid losing any keys that may only be on this session.": "Qqen tiɣimit-a ɣer uḥraz n tsura send ad teffɣeḍ seg tuqqna i wakken ad tḍemneḍ ur ttruḥunt ara tsura i yellan kan deg tɣimit-a.",
|
||||||
|
"We recommend that you remove your email addresses and phone numbers from the identity server before disconnecting.": "Ad ak·akem-nwelleh ad tekkseḍ tansiwin n yimayl d wuṭṭunen n tilifun seg uqeddac n timagit send tuffɣa seg tuqqna.",
|
||||||
|
"You are currently using <server></server> to discover and be discoverable by existing contacts you know. You can change your identity server below.": "Aql-ak·akem akka tura tseqdaceḍ <server></server>i wakken ad d-tafeḍ daɣen ad d-tettwafeḍ sɣur inermisen yellan i tessneḍ. Tzemreḍ ad tbeddleḍ aqeddac-ik·im n timagit ddaw.",
|
||||||
|
"If you don't want to use <server /> to discover and be discoverable by existing contacts you know, enter another identity server below.": "Ma yella ur tebɣiḍ ara ad tesqedceḍ <server /> i wakken ad d-tafeḍ daɣen ad d-tettwafeḍ sɣur inermisen yellan i tessneḍ, sekcem aqeddac-nniḍen n timagit ddaw.",
|
||||||
|
"You are not currently using an identity server. To discover and be discoverable by existing contacts you know, add one below.": "Akka tura ur tesseqdaceḍ ula d yiwen n uqeddac n timagit. I wakken ad d-tafeḍ daɣen ad d-tettwafeḍ sɣur yinermisen yellan i tessneḍ, rnu yiwen ddaw.",
|
||||||
|
"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.": "Tuffɣa seg tuqqna n uqeddac-ik·im n timaqit anamek-is dayen ur yettuɣal yiwen ad ak·akem-id-yaf, daɣen ur tettizmireḍ ara ad d-necdeḍ wiyaḍ s yimayl neɣ s tiliɣri.",
|
||||||
|
"Using an identity server is optional. If you choose not to use an identity server, you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Aseqdec n uqeddac n timagit d afrayan. Ma yella tferneḍ ur tesseqdaceḍ ara aqeddac n timagit, dayen ur tettuɣaleḍ ara ad tettwafeḍ sɣur iseqdac wiyaḍ rnu ur tettizmireḍ ara ad d-necdeḍ s yimayl neɣ s tiliɣri.",
|
||||||
|
"Use an Integration Manager <b>(%(serverName)s)</b> to manage bots, widgets, and sticker packs.": "Seqdec amsefrak n umsidef <b>(%(serverName)s)</b> i usefrek n yibuten, n yiwiǧiten d tɣawsiwin n usenteḍ.",
|
||||||
|
"Use an Integration Manager to manage bots, widgets, and sticker packs.": "Seqdec amsefrak n umsidef i usefrek n yibuten, n yiwiǧiten d tɣawsiwin n usenteḍ.",
|
||||||
|
"Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "Imsefrak n yimsidaf remmsen-d isefka n uswel, syen ad uɣalen zemren ad beddlen iwiǧiten, ad aznen tinubgiwin ɣer texxamin, ad yesbadu daɣen tazmert n yiswiren s yiswiren deg ubdil-ik·im.",
|
||||||
|
"Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Awal-ik·im uffir yettusnifel akken iwata. Ur d-tremmseḍ ara d umatu ilɣa ɣef tɣimiyin-nniḍen alamma tɛaqdeḍ teqqneḍ ɣer-sent",
|
||||||
|
"Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Qbel tiwtilin n umeẓlu n uqeddac n timagit (%(serverName)s) i wakken ad tsirgeḍ iman-ik·im ad d-tettwafeḍ s yimayl neɣ s wuṭṭun n tiliɣri.",
|
||||||
|
"Ignoring people is done through ban lists which contain rules for who to ban. Subscribing to a ban list means the users/servers blocked by that list will be hidden from you.": "Tiririt n yimdanen deg rrif yettwaxdam deg tebdarin n uzgal ideg llan ilugan ɣef yimdanen ara yettwazeglen. Amulteɣ ɣer tebdart n uzgal anamek-is iseqdacen/iqeddacen yettusweḥlen s tebdart-a ad akȧm-ttwaffren.",
|
||||||
|
"Your personal ban list holds all the users/servers you personally don't want to see messages from. After ignoring your first user/server, a new room will show up in your room list named 'My Ban List' - stay in this room to keep the ban list in effect.": "Tabdart-ik·im n uzgal tudmawant deg-s akk iseqdacen/iqeddacen wid iwumi ur tebɣiḍ ara ad twaliḍ iznan-nsen. Mi ara terreḍ aseqdac/aqeddac amezwaru deg rrif, ad d-tban texxamt tamaynut deg tebdart n texxamin isem-is \"Tabdart-iw n uzgal\" - qqim deg texxamt-a i wakken tabdart n uzgal ad teddu.",
|
||||||
|
"Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Aqader n tudert-ik·im tabaḍnit tesɛa aṭas azal ɣer-neɣ, ɣef waya ur nleqqeḍ ara akk isefka udmawanen neɣ ad neǧǧ ad d-banen deg tddadanin-nneɣ.",
|
||||||
|
"<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>Ɣur-k·m</b>: Aleqqem n texxamt <i>ur issinig ara iɛeggalen n texxamt s wudem awurman ɣer lqem amaynut n texxamt. </i>Ad d-nesuffeɣ aseɣwen n texxamt tamaynut deg lqem n texxamt taqdimt. Imttekkiyen n texxamt ad siten kan ɣef useɣwen-nni i wakken ad ttekkin deg texxamt tamaynut.",
|
||||||
|
"An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.": "Tella-d tuccḍa mi ara nettbeddil isutar n tezmert n uswis n texxamt. Ḍmen tesɛiḍ tisirag i iwulmen syen ɛreḍ tikkelt-nniḍen.",
|
||||||
|
"An error occurred changing the user's power level. Ensure you have sufficient permissions and try again.": "Tella-d tuccḍa mi ara nettbeddil tazmert n uswir n useqdac. Senqed ma tesɛiḍ tisirag i iwulmen syen ales tikkelt-nniḍen.",
|
||||||
|
"Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. <a>Learn more about encryption.</a>": "Akken ara tremdeḍ awgelhen i texxamt ur yettizmir ara ad yekkes. Iznan n texxamt tawgelhant ur tent-yettwali ara uqeddac, ala wid yettekkan deg texxamt. Armad n uwgelhen ur yettaǧǧa ara kra n yiṛubuten d kra n tleggiyin ad ddun akken iwata. <a>Issin ugar ɣef uwgelhen.</a>",
|
||||||
|
"Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.": "Isnifal n unekcum ɣer umazray ad ddun deg yiznan i d-iteddun deg texxamt-a. Timeẓriwt n umazray yellan ur yettbeddil ara.",
|
||||||
|
"We've sent you an email to verify your address. Please follow the instructions there and then click the button below.": "Nuzen-ak·am-n imayl i wakken ad tesneqdeḍ tansa-inek·inem. Ttxil-k·m ḍfer iwellihen yellan deg-s syen sit ɣef tqeffalt ddaw.",
|
||||||
|
"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.": "Isutar n beṭṭu n tsarut ttwaznen ɣer tɣimiyin-nniḍen s wudem awurman. Ma yella tugiḍ neɣ tunfeḍ i usuter n beṭṭu n tsarut ɣef tɣimiyin-nniḍen, sit dagi i wallus n usuter n tsura i tɣimit-a.",
|
||||||
|
"If your other sessions do not have the key for this message you will not be able to decrypt them.": "Ma yella tiɣimiyin-nniḍen ur sɛint ara tasarut i yizen-a ur tettizmireḍ ara ad asen-tekkseḍ awgelhen.",
|
||||||
|
"An error (%(errcode)s) was returned while trying to validate your invite. You could try to pass this information on to a room admin.": "Tuccḍa (%(errcode)s) tuɣal-d mi ara nettaɛraḍ ad nsentem tinubga-inek·inem. Tzemreḍ ad tremseḍ talɣut-a i unedbal n texxamt.",
|
||||||
|
"Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Aleqqem n texxamt-a ad tsens tummant tamirant n texxamt yerna ad ternu taxxamt yettuleqqmen s yisem-nni kan.",
|
||||||
|
"You can use <code>/help</code> to list available commands. Did you mean to send this as a message?": "Tzemreḍ ad tesqedceḍ <code>tallalt</code> i wakken ad twaliḍ tabdart n tiludna yellan. Tbɣiḍ ad tceggɛeḍ ayagi d izen?",
|
||||||
|
"You don't currently have any stickerpacks enabled": "Ulac ɣer-k·m akka tura ikemmusen n yimyintaḍ yettwaremden",
|
||||||
|
"Stickerpack": "Akemmus n yimyintaḍ",
|
||||||
|
"Could not revoke the invite. The server may be experiencing a temporary problem or you do not have sufficient permissions to revoke the invite.": "Tigtin n tinubga d awezɣi. Aqeddac yettmagar-d ahat ugur akka tura neɣ ur tesɛiḍ tisirag i iwulmen i wakken ad tagiḍ tinubga-a.",
|
||||||
|
"There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.": "Tellad-d tuccḍa deg uleqqem n tansa tagejdant n texxamt. Ur ittusireg ara ula sɣur aqeddac neɣ d tuccḍa kan meẓẓiyen i d-yeḍran.",
|
||||||
|
"There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "Tella-d tuccḍa deg uleqqem n tansiwin-nniḍen n texxamt. Ur yettusireg ara waya sɣur aqeddac neɣ d tuccḍa kan meẓẓiyen i d-yeḍran.",
|
||||||
|
"There was an error creating that address. It may not be allowed by the server or a temporary failure occurred.": "Tella-d tuccḍa deg tmerna n tansa-a. Ur yettusireg ara waya sɣur aqeddac neɣ d tuccḍa kan meẓẓiyen i d-yeḍran.",
|
||||||
|
"There was an error removing that address. It may no longer exist or a temporary error occurred.": "Tella-d tuccḍa deg tukksa n tansa-a. Ahat dayen ur telli ara neɣ d tuccḍa meẓẓiyen i d-yeḍran.",
|
||||||
|
"Published addresses can be used by anyone on any server to join your room. To publish an address, it needs to be set as a local address first.": "Tansiwin i d-yettusuffɣen ur yezmir ula d yiwen ad tent-isseqdec ɣef yiqeddacen akk i wakken ad yekcem ɣer texxamt-ik·im. I wakken ad tsuffɣeḍ tansa, ilaq ad tettusbadu deg tazwara d tansa tadigant.",
|
||||||
|
"No other published addresses yet, add one below": "Ulac tansiwin i d-yeffɣen akka tura, rnu yiwet ddaw",
|
||||||
|
"New published address (e.g. #alias:server)": "Tansa tamynut i d-yettusuffɣen (am. #alias:server)",
|
||||||
|
"Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)": "Sbadu tansiwin i texxamt-a i wakken iseqdacen ad ttafen s uqeddac-ik·im agejdan (%(localDomain)s)",
|
||||||
|
"There was an error updating the flair for this room. The server may not allow it or a temporary error occurred.": "Tella-d tuccḍa deg uleqqem n tsakezt n texxamt-a. Ahat aqeddac ur t-isireg ara neɣ d tuccḍa meẓẓiyen i d-yellan.",
|
||||||
|
"Showing flair for these communities:": "Sken tasakezt i temɣiwnin-a:",
|
||||||
|
"This room is not showing flair for any communities": "Taxxamt-a ur d-teskin ara tasakezt ula i yiwet n temɣiwent",
|
||||||
|
"New community ID (e.g. +foo:%(localDomain)s)": "Asulay n temɣiwent tamaynut (d am. +foo:%(localDomain)s)",
|
||||||
|
"Publish this room to the public in %(domain)s's room directory?": "Suffeɣ-d taxxamt-a deg ukaram azayez n texxamt n %(domain)s?",
|
||||||
|
"You have <a>enabled</a> URL previews by default.": "<a>tremdeḍ</a> tiskanin n URL s wudem amezwer.",
|
||||||
|
"You have <a>disabled</a> URL previews by default.": "<a>tsenseḍ</a> tiskanin n URL s wudem amezwer.",
|
||||||
|
"URL previews are enabled by default for participants in this room.": "Tiskanin n URL ttwaremdent s wudem amezwer i yimttekkiyen n texxamt-a.",
|
||||||
|
"URL previews are disabled by default for participants in this room.": "Tiskanin n URL ttwasensnt s wudem amezwer i yimttekkiyen n texxamt-a.",
|
||||||
|
"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.": "Deg texxamin yettwawgelhen, am texxamt-a, tiskanin n URL ttwasensnt s wudem amezwer i wakken ad neḍmen belli aqeddac agejdan (anida tiskanin ttwasirwent) ur yettizmir ara ad yelqeḍ talɣut ɣef yiseɣwan i d-ibanen deg texxamt-a.",
|
||||||
|
"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.": "Ma yili yiwet iger-d aseɣwen deg yizen-ines, taskant n URL tezmer ad tettwaskan i wakken ad d-imudd ugar n talɣut ɣef useɣwen-a am uzwel, aglam d tugna n usmel.",
|
||||||
|
"Waiting for you to accept on your other session…": "Deg uṛaǧu ad tqebleḍ deg tɣimit-inek·inem tayeḍ…",
|
||||||
|
"Waiting for %(displayName)s to accept…": "Aṛaǧu n %(displayName)s i uqbal…",
|
||||||
|
"Messages in this room are end-to-end encrypted.": "Iznan deg texxamt-a ttwawgelhen seg yixef ɣer yixef.",
|
||||||
|
"Your messages are secured and only you and the recipient have the unique keys to unlock them.": "Iznan-inek·inem d iɣelsanen, ala kečč d uɣerwaḍ i yesɛan tisura tasufin i wakken ad asen-kksen awgelhen.",
|
||||||
|
"Messages in this room are not end-to-end encrypted.": "Iznan deg texxamt-a ur ttwawgelhen ara seg yixef ɣer yixef.",
|
||||||
|
"In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.": "Deg texxamt yettwawgelhen, iznan-inek·inem d iɣelsanen ala kečč d uɣerwaḍ i yesɛan tisura tasufin i wakken ad asen-kksen awgelhen.",
|
||||||
|
"For extra security, verify this user by checking a one-time code on both of your devices.": "I wugar n tɣellist, senqed aseqdac-a s usenqed n tengalt i yiwet n tikkelt ɣef yibenkan-ik·im i sin.",
|
||||||
|
"One of the following may be compromised:": "Yiwen seg wayen i d-iteddun yezmer ad yettwaker:",
|
||||||
|
"The homeserver the user you’re verifying is connected to": "Aqeddac agejdan wuɣur yeqqen useqdac i tessenqadeḍ",
|
||||||
|
"Yours, or the other users’ internet connection": "Tuqqna-inek·inem n internet neɣ tin n yiseqdac-nniḍen",
|
||||||
|
"Information": "Talɣut",
|
||||||
|
"Download logs": "Sider imisen",
|
||||||
|
"GitHub issue": "Ugur Github",
|
||||||
|
"Unable to load commit detail: %(msg)s": "D awezɣi ad d-tali telqayt n usentem: %(msg)s",
|
||||||
|
"Add another email": "Rnu imayl wayeḍ",
|
||||||
|
"People you know on %(brand)s": "Imdanen i ak·akem-yessnen deg %(brand)s",
|
||||||
|
"Send %(count)s invites|other": "Azen %(count)s tinubgiwin",
|
||||||
|
"Send %(count)s invites|one": "Azen %(count)s tinubga",
|
||||||
|
"Invite people to join %(communityName)s": "Nced-d imdanen ad d-rnun ɣer %(communityName)s",
|
||||||
|
"You cannot delete this message. (%(code)s)": "Ur tezmireḍ ara ad tekkseḍ izen-a. (%(code)s)",
|
||||||
|
"Destroy cross-signing keys?": "Erẓ tisura n uzmul anmidag?",
|
||||||
|
"Clear cross-signing keys": "Sfeḍ tisura n uzmul anmidag",
|
||||||
|
"Clear all data in this session?": "Sfeḍ akk isefka seg tɣimit-a?",
|
||||||
|
"Community ID: +<localpart />:%(domain)s": "Asulay n temɣiwent: +<localpart />:%(domain)s",
|
||||||
|
"You can change this later if needed.": "Tzemreḍ ad tesnifleḍ ayagi ticki ma yella yettusra.",
|
||||||
|
"What's the name of your community or team?": "D acu-t yisem n temɣiwent-ik·im neɣ n terbaɛt-ik·im?",
|
||||||
|
"Enter name": "Sekcem isem",
|
||||||
|
"Add image (optional)": "Rnu tugna (d afrayan)",
|
||||||
|
"An image will help people identify your community.": "Tugna ad tɛiwen imdanen ad ɛeqlen tamɣiwent-ik·im.",
|
||||||
|
"Community IDs cannot be empty.": "Isulayen n temɣiwent ur ilaq ara ad ilin d ilmawen.",
|
||||||
|
"Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Isulayen n temɣiwent ilaq ad sɛun kan isekkilen a-z, 0-9, or '=_-./'",
|
||||||
|
"Something went wrong whilst creating your community": "Tella-d tuccḍa mi ara trennuḍ tamɣiwent-ik·im",
|
||||||
|
"Community ID": "Asulay n temɣiwent",
|
||||||
|
"Create a public room": "Rnu taxxamt tazayezt",
|
||||||
|
"Create a private room": "Rnu taxxamt tusligt",
|
||||||
|
"Hide advanced": "Ffer talqayt",
|
||||||
|
"Show advanced": "Sken talqayt",
|
||||||
|
"Create Room": "Rnu taxxamt",
|
||||||
|
"Incompatible Database": "Taffa n yisefka ur temada ara",
|
||||||
|
"To continue, please enter your password:": "I wakken ad tkemmle, ttxil-k·m sekcem awal uffir n umiḍan-ik·im:",
|
||||||
|
"Recently Direct Messaged": "Izen usrid n melmi kan",
|
||||||
|
"You must join the room to see its files": "Ilaq-ak·am ad ternuḍ ɣer texxamt i wakken ad twaliḍ ifuyla",
|
||||||
|
"The user '%(displayName)s' could not be removed from the summary.": "Aseqdac '%(displayName)s' ur yzmir ara ad yettwakkes seg ugzul.",
|
||||||
|
"You’re all caught up": "Tettwafem akken ma tellam",
|
||||||
|
"%(brand)s failed to get the protocol list from the homeserver. The homeserver may be too old to support third party networks.": "%(brand)s awway n tebdart n uneggaf n uqeddac agejdan ur yeddi ara. Aqeddac agejdan ahat d aqbur aas i wakken ad issefrek izewan n wis tlata.",
|
||||||
|
"Fetching third party location failed": "Tiririt n wadge wis tlata ur teddi ara",
|
||||||
|
"If you can't find the room you're looking for, ask for an invite or <a>Create a new room</a>.": "Ma yella ur tufi texxamt i tettqellibe, suter tinubga ne <a>rnu taxxamt tamaynut</a>.",
|
||||||
|
"Explore rooms in %(communityName)s": "Snirem taxxamt deg %(communityName)s",
|
||||||
|
"Create community": "Rnu tamɣiwent",
|
||||||
|
"Set up Secure Backup": "Sebadu aḥraz aɣelsan",
|
||||||
|
"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.": "Ma yella tgiḍ aya war ma tebniḍ, tzemreḍ ad tsewleḍ iznan uffiren deg tɣimit-a ayen ara yalsen awgelhen n umazray n yiznan n texxamt-a s tarrayt n tririt tamaynut.",
|
||||||
|
"Explore community rooms": "Snirem tixxamin n temɣiwent",
|
||||||
|
"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.": "Ur tettizmireḍ ara ad tesfesxeḍ asnifel-a acku tettṣubbuḍ deg usellun-unek·inem, ma yella d kečč·kemm i d aseqdac aneglam n texxamt-a, d awezɣi ad d-terreḍ ula d yiwet n tseglut.",
|
||||||
|
"Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Iznan deg texxamt-a ttwawgelhen seg yixef ɣer yixef. Issin ugar & senqed aseqdac-a deg umaɣnu-ines n useqdac.",
|
||||||
|
"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?": "Aql-ak·akem ad tettuwellheḍ ɣer usmel n wis tlata i wakken ad tizmireḍ ad tsestbeḍ amiḍan-ik·im i useqdec d %(integrationsUrl)s. Tebɣiḍ ad tkemmleḍ?",
|
||||||
|
"Unable to find profiles for the Matrix IDs listed below - would you like to invite them anyway?": "D awezɣi ad d-naf imuɣna n yisulay Matrix i d-yettwabdaren ddaw - tebɣiḍ ad ten-id-tnecdeḍ ɣas akken?",
|
||||||
|
"Reminder: Your browser is unsupported, so your experience may be unpredictable.": "Asmekti: Iming-ik·im ur yettusefrak ara, ihi tarmit-ik·im yezmer ur d-tettili ara.",
|
||||||
|
"Before submitting logs, you must <a>create a GitHub issue</a> to describe your problem.": "Send ad tazneḍ iɣmisen-ik·im, ilaq <a>ad ternuḍ ugur deg Github</a> i wakken ad d-tgelmeḍ ugur-inek·inem.",
|
||||||
|
"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.": "S tidet tebɣiḍ ad tekkseḍ aneḍru-a? Err deg uqerru-k·m ma yella tekkseḍ asnifel n yisem neɣ asentel n texxamt, yemzer asnifel-a ad yettusefsex.",
|
||||||
|
"Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Asfaḍ akk n yisefka seg tɣimit-a ad yili i lebda. Ad ak-ruḥen yiznan yettwawgelhen ala ma yella tisura ttwaḥerzent.",
|
||||||
|
"There was an error creating your community. The name may be taken or the server is unable to process your request.": "Tella-d tuccḍa deg tmerna n temɣiwent-ik·im. Yezmer isem yettwaddem neɣ aqeddac ur yezmir ara ad isleḍ asuter-ik·im.",
|
||||||
|
"Use this when referencing your community to others. The community ID cannot be changed.": "Seqdec aya mi ara tselɣuḍ tamɣiwent-ik·im i wiyaḍ. Asulay n temɣiwent ur yezmir ara ad yettusnifel.",
|
||||||
|
"Set a room address to easily share your room with other people.": "Sbadu tansa n texxamt i wakken ad ak·am-yishil beṭṭu-ines d yimdanen-nniḍen.",
|
||||||
|
"This room is private, and can only be joined by invitation.": "Taxxamt-a d tusligt, anekcum ɣur-s ala s tinubga.",
|
||||||
|
"You can’t disable this later. Bridges & most bots won’t work yet.": "Ur tezmireḍ ara ad tsenseḍ aya ticki. Tileggiyin d tuget n wabuten ur teddun ara akka tura.",
|
||||||
|
"Create a room in %(communityName)s": "Rnu taxxamt deg %(communityName)s",
|
||||||
|
"Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "Sewḥel iseqdacen n yiqeddacen-nniḍen igejdanen ad d-rnun ɣer texxamt-a (Iɣewwaren-a ur tettizmireḍ ara ad ten-tesnifleḍ mbeɛd!)",
|
||||||
|
"Are you sure you want to deactivate your account? This is irreversible.": "S tidet tebɣiḍ ad tsenseḍ amiḍăn-ik·im? Ulac tuɣalin ɣer deffir.",
|
||||||
|
"There was a problem communicating with the server. Please try again.": "Tella-d tuccḍa mi ara nettaɛraḍ ad nemmeslay d uqeddac. Ɛreḍ tikkelt-nniḍen.",
|
||||||
|
"Server did not require any authentication": "Aqeddac ur isuter ara akk asesteb",
|
||||||
|
"Server did not return valid authentication information.": "Aqeddac ur d-yerri ara talɣut n usesteb tameɣtut.",
|
||||||
|
"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)": "Ttxil-k·m ttu akk iznan i yuzneɣ mi ara senseɣ amiḍan-iw (<b>Ɣur-k·m:</b> iseqdacen ara d-yernun ad walin idiwenniyen ur nemmid ara)",
|
||||||
|
"Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Senqed aseqdac-a i wakken ad tcerḍeḍ fell-as d uttkil. Iseqdac uttkilen ad ak·am-d-awin lehna meqqren meqqren i uqerru mi ara tesseqdaceḍ iznan yettwawgelhen seg yixef ɣer yixef.",
|
||||||
|
"Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "Asenqed n useqdac-a ad yecreḍ ɣef tɣimit-is tettwattkal, yerna ad yecreḍ ula ɣef tɣimit-ik·im tettwattkal i netta·nettat.",
|
||||||
|
"Enable 'Manage Integrations' in Settings to do this.": "Rmed 'imsidaf n usefrek' deg yiɣewwaren i tigin n waya.",
|
||||||
|
"Your %(brand)s doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "%(brand)s-ik·im ur ak·am yefki ara tisirag i useqdec n umsefrak n umsidef i wakken ad tgeḍ aya. Ttxil-k·m nermes anedbal.",
|
||||||
|
"To continue, use Single Sign On to prove your identity.": "I ukemmel, seqdec n unekcum asuf i ubeggen n timagit-ik·im.",
|
||||||
|
"Click the button below to confirm your identity.": "Sit ɣef tqeffalt ddaw i wakken ad tesnetmeḍ timagit-ik·im.",
|
||||||
|
"We couldn't create your DM. Please check the users you want to invite and try again.": "D awezɣi ad ternuḍ izen-inek·inem uslig. Ttxil-k·m senqed iseqdacen i tebɣiḍ ad d-tnecdeḍ syen ɛreḍ tikkelt-nniḍen.",
|
||||||
|
"Something went wrong trying to invite the users.": "Yella wayen ur nteddu ara akken ilaq i wakken ad d-tesnubegteḍ iseqdacen.",
|
||||||
|
"We couldn't invite those users. Please check the users you want to invite and try again.": "Ur nezmir ara ad d-nesnubget iseqdacen-a. Ttxil-k·m wali iseqdac i tebɣiḍ ad d-tesnubegteḍ syen ɛreḍ tikkelt-nniḍen.",
|
||||||
|
"The following users might not exist or are invalid, and cannot be invited: %(csvNames)s": "Iseqdac i d-iteddun ahat ulac-iten neɣ d arimeɣta, ur zmiren ad d-ttusnubegten: %(csvNames)s",
|
||||||
|
"You'll lose access to your encrypted messages": "Tesruḥeḍ anekcum ɣer yiznan-ik·im yettwawgelhen",
|
||||||
|
"Are you sure you want to sign out?": "D tidet tebɣiḍ ad teffɣeḍ?",
|
||||||
|
"Confirm by comparing the following with the User Settings in your other session:": "Sentem s userwes gar wayen i d-iteddun d yiɣewwaren n useqdac deg tɣimit-ik·im tayeḍ:",
|
||||||
|
"Confirm this user's session by comparing the following with their User Settings:": "Sentem tiɣimit n useqdac-a s userwes gar wayen i d-iteddun d yiɣewwaren-is n useqdac:",
|
||||||
|
"If they don't match, the security of your communication may be compromised.": "Ma yella ur mṣadan ara, taɣellist n teywalt-ik·im tezmer ad tettwaker.",
|
||||||
|
"Your homeserver doesn't seem to support this feature.": "Aqeddac-ik·im agejdan ur yettban ara yessefrak tamahilt-a.",
|
||||||
|
"The internet connection either session is using": "Tuqqna n internet yettusqedcen deg yal tiɣimit",
|
||||||
|
"We recommend you change your password and recovery key in Settings immediately": "Ad ak·akem-nwellah ad tesnifleḍ awal-ik·im uffir d tsarut n tririt deg yiɣewwaren tura tura",
|
||||||
|
"Use this session to verify your new one, granting it access to encrypted messages:": "Seqdec tiɣimit-a i usenqed tiɣimit-ik·im tamaynut, s tikci n uzref i wakken ad tekcem ɣer yiznan yettwawgelhen:",
|
||||||
|
"If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.": "Ma yella tettemliliḍ-d abugen neɣ tesɛiḍ tamawin i beṭṭu, ttxil-k·m selɣu-aɣ-d deg Github.",
|
||||||
|
"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.": "I tallalt n ussinef n wuguren i d-yettuɣalen, ttxil-k·m <existingIssuesLink>wali uguren yellan</existingIssuesLink> deg tazwara (syen rnu yiwen +1) neɣ <newIssueLink>rnu ugur amaynut</newIssueLink> ma yella ur t-tufiḍ ara.",
|
||||||
|
"Report bugs & give feedback": "Azen abugen & efk-d tamawt",
|
||||||
|
"Create a new room with the same name, description and avatar": "Rnu taxxamt tamaynut s yisem-nni, aglam-nni d uvaṭar-nni",
|
||||||
|
"Attach files from chat or just drag and drop them anywhere in a room.": "Seddu ifuyla seg udiwenni neɣ ger-iten, tserseḍ-ten deg kra n wadeg deg texxamt.",
|
||||||
|
"<h1>HTML for your community's page</h1>\n<p>\n Use the long description to introduce new members to the community, or distribute\n some important <a href=\"foo\">links</a>\n</p>\n<p>\n You can even use 'img' tags\n</p>\n": "<h1>HTML i usebter n temɣiwent-ik·im</h1>\n<p>\n Seqdec aglam ɣezzifen i wakken ad teskecmeḍ iɛeggalen imaynuten ɣer temɣiwent, neɣ bḍu\n kra n yiseɣwan <a href=\"foo\">yesɛan azal</a>\n</p>\n<p>\n Tzemreḍ daɣen ad tesqedceḍ tibzimin 'img'\n</p>\n",
|
||||||
|
"Failed to add the following rooms to the summary of %(groupId)s:": "Ur teddi ara tmerna n texxamin i d-iteddun ɣer ugzul n %(groupId)s:",
|
||||||
|
"Failed to remove the room from the summary of %(groupId)s": "Ur teddi ara tukksa n texxamt seg ugzul n %(groupId)s",
|
||||||
|
"The room '%(roomName)s' could not be removed from the summary.": "Taxxamt '%(roomName)s' ur tezmir ara ad tettwakkes seg ugzul.",
|
||||||
|
"Failed to add the following users to the summary of %(groupId)s:": "Timerna n yiseqdac i d-iteddun ɣer ugzul n %(groupId)s ur yedi ara:",
|
||||||
|
"Failed to remove a user from the summary of %(groupId)s": "Ur teddi ara tukksa n useqdac seg ugzul n %(groupId)s",
|
||||||
|
"Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Sentem timagit-ik·im s usenqed n yinekcam-a seg yiwet gar tɣimiyin-inek·inem-nniḍen, serreḥ-as ad tekcem ɣer yiznan yettwawgelhen.",
|
||||||
|
"Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Tiɣimit-ik·im tamaynut dayen tettwasenqed tura. Ɣur-s anekcum ɣer yiznan yettwawgelhen, iseqdac-nniḍen daɣen ad asen-d-tban tettwattkal.",
|
||||||
|
"Without completing security on this session, it won’t have access to encrypted messages.": "Ma yella ur temmid ara tɣellist n tɣimit-a, ur yettili ara unekcum ɣer yiznan yettwawgelhen.",
|
||||||
|
"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.": "Err-d anekcum ɣer umiḍan-ik·im, rnu err-d tisura n uwgelhen yettwakelsen deg tɣimit-a. Mebla yis-sent, ur tettizmireḍ ara ad teɣreḍ akk iznan-inek·inem deg yal tiɣimit.",
|
||||||
|
"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.": "Ɣur-k·m: Isefka-inek·inem udmawanen (ula d tisura tiwgelhanin) ad qqimen ttwakelsent deg tɣimit-a. Sfeḍ-itent ma yella dayen ur tseqdaceḍ ara tiɣimit-a, neɣ tebɣiḍ ad tkecmeḍ ɣer umiḍan-nniḍen.",
|
||||||
|
"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.": "Akala-a ad ak·am-imudd tisirag ad d-tsifḍeḍ tisura i d-tremseḍ deg texxamin yettwawgelhen i ufaylu adigan. Syen tzemreḍ ad tketreḍ afaylu deg umsaɣ-nniḍen n Matrix ɣer sdat, ihi amsaɣ-a mazal-it yezmer ad yekkes awgelhen i yiznan-a.",
|
||||||
|
"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.": "Afaylu n usifeḍ ad isireg yal yiwen i izemren ad t-iɣer ad yekkes awgelhen i yal izen yettwawgelhen i tzemreḍ ad twaliḍ, ihi ilaq ad t-tḥerzeḍ deg wadeg aɣelsan. I tallalt ɣef waya, ilaq ad teskecmeḍ tafyirt tuffirt ddaw, ara yettusqedcen i uwgelhen n yisefka i yettusifḍen. Ad tizmireḍ kan ad tketreḍ isefka s useqdec n tefyirt-nni kan.",
|
||||||
|
"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.": "Akala-a ad ak·am-yefk tizirag ad tketreḍ tisura tiwgelhanin i d-tsifḍeḍ uqbel seg umsaɣ-nniḍen n Matrix. Syen ad tizmireḍ ad tekkseḍ awgelhen i yal izen iwumi yezmer umsaɣ-nniḍen ad as-t-yekkes.",
|
||||||
|
"The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Afaylu n usifeḍ ad yettummesten s tefyirt tuffirt. Ilaq ad teskecmeḍ tafyirt tuffirt da, i wakken ad tekkseḍ awgelhen i ufaylu.",
|
||||||
|
"Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.": "Seḥbiber iman-ik·im ɣef uḍegger n unekcum ɣer yiznann & yisefka yettwawgelhe s uḥraz n tsura n uwgelhen ɣef uqeddac-inek·inem.",
|
||||||
|
"We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.": "Ad d-nsirw tasarut n tɣellist i kečč·kemm ara tḥerzeḍ deg wadeg yettwaḍemnen, am yimsefrak n wawalen uufiren neɣ deg usenduq.",
|
||||||
|
"Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Leqqem tiimit-a i wakken ad as-teǧǧeḍ ad tsenqed n tɣimiyin-nniḍen, s tikci n uzref ad tekcem ɣer yiznan yettwawgelhen d ucraḍ fell-asen ttwattkalen i yiseqdac-nniḍen.",
|
||||||
|
"Enter a security phrase only you know, as it’s used to safeguard your data. To be secure, you shouldn’t re-use your account password.": "Sekcem tafyirt tuffirt n uɛeddi i tessneḍ kan kečč, acku tettwaseqdac i uḥraz n yisefka-inek·inem. I wakken ad tiliḍ deg tɣellist, ur ilaq ara ad talseḍ aseqdec n wawal uffir n umiḍan-ik·im.",
|
||||||
|
"Store your Security Key somewhere safe, like a password manager or a safe, as it’s used to safeguard your encrypted data.": "Kles tasarut-ik·im n tɣellist deg wadeg yettwaḍemnen, am umsefrak n wawalen uffiren neɣ deg usenduq, i yettwaseqdacen i uḥraz n yisefka-ik·im iwgelhanen.",
|
||||||
|
"If you cancel now, you may lose encrypted messages & data if you lose access to your logins.": "Ma yella teffeḍ tura, ilaq ad tmedleḍ iznan & isefka yettwawgelhen ma yella tesruḥeḍ anekcum ɣer yinekcam-ik·im.",
|
||||||
|
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Ur tettizmireḍ ara ad tesfesxeḍ asnifel-a acku tessebɣaseḍ aseqdac ad yesɛu aswir n tezmert am kečč·kemm.",
|
||||||
|
"Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?": "Asemmet n useqdac-a ad t-isuffeɣ yerna ur as-yettaǧǧa ara ad yales ad yeqqen. Daɣen, ad ffɣen akk seg texxamin ideg llan. Tigawt-a dayen ur tettwasefsax ara. S tidet tebɣiḍ ad tsemmteḍ aseqdac-a?",
|
||||||
|
"The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.": "Tiɣimit ara tettaɛraḍeḍ ad tt-tesneqdeḍ ur tessefrak ara tangalt n uḍummu QR neɣ asenqed n yimujit, d ayen i yessefrak %(brand)s. Ɛreḍ amsaɣ-nniḍen.",
|
||||||
|
"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.": "Iɣmisen n temseɣtit deg-sen isefka n useqdec n usnas am yisem n useqdec, am yisulayen neɣ am yismawen i yettunefken i texxamin neɣ i yigrawen ɣer wuɣur terziḍ d yismawen n useqdac n yiseqdacen-nniḍen. Ulac deg-sen iznan.",
|
||||||
|
"If there is additional context that would help in analysing the issue, such as what you were doing at the time, room IDs, user IDs, etc., please include those things here.": "Ma yella umnaḍ-nniḍen ara iɛawnen deg tesleḍt n wugur, am wamek akken i txeddmeḍ zik, isulay n texxamt, isulay n useqdac, atg., ttxil-k·m rnu iferdisen-a da.",
|
||||||
|
"Deleting cross-signing keys is permanent. Anyone you have verified with will see security alerts. You almost certainly don't want to do this, unless you've lost every device you can cross-sign from.": "Tukksa n tsura n uzmul anmidag ad yili i lebda. Yal amdan i tesneqdeḍ ad iwali ilɣa n tɣellist. Maca ur tebɣiḍ ara ad txedmeḍ aya, ala ma yella tesruḥeḍ ibenkan akk ara ak·akem-yeǧǧen ad tkecmeḍ seg-s.",
|
||||||
|
"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 %(brand)s to do this": "I wakken ur tesruḥuyeḍ ara amazray n udiwenni, ilaq ad tsifḍeḍ tisura seg texxam-ik·im send ad teffɣeḍ seg tuqqna. Tesriḍ ad tuɣaleḍ ɣer lqem amaynut n %(brand)s i wakken ad tgeḍ aya",
|
||||||
|
"You've previously used a newer version of %(brand)s with this session. To use this version again with end to end encryption, you will need to sign out and back in again.": "Tesxedmeḍ yakan lqem akk aneggaru n %(brand)s s tɣimit-a. I useqdec n lqem-a i tikkelt-nniḍen s uwgelhen seg yixef ɣer yixef, tesriḍ ad teffɣeḍ syen ad talseḍ anekcum i tikkelt-nniḍen.",
|
||||||
|
"Start a conversation with someone using their name, username (like <userId/>) or email address.": "Bdu adiwenni d walbeɛḍ s useqdec n yisem-is, n yisem-is n useqdac (am <userId/>) neɣ tansa-ines n yimayl.",
|
||||||
|
"Invite someone using their name, username (like <userId/>), email address or <a>share this room</a>.": "Nced-d albeɛḍ s useqdec n yisem-is, s yisem-is n useqdac (am <userId/>), s tansa-ines n yimayl neɣ <a>bḍu taxxamt-a</a>.",
|
||||||
|
"Update any local room aliases to point to the new room": "Leqqem ismawen yettunefken i yal taxxamt tadigant akken ad tsekneḍ ɣer texxamt tamaynut",
|
||||||
|
"Stop users from speaking in the old version of the room, and post a message advising users to move to the new room": "Seḥbes iseqdacen ɣef umeslay deg lqem aqbur n texxamt, syen aru izen anida ara twellheḍ iseqdacen ad d-uɣalen ɣer texxamt tamaynut",
|
||||||
|
"Put a link back to the old room at the start of the new room so people can see old messages": "Sers aseɣwen deg texxamt taqburt mi ara tebdu kan texxamt tamaynut i wakken imdanen ad izmiren ad walin iznan iqburen",
|
||||||
|
"Upgrading a room is an advanced action and is usually recommended when a room is unstable due to bugs, missing features or security vulnerabilities.": "Aleqqem n texxamt d tigawt leqqayen rnu yezga yettuwelleh-d mi ara tili texxamt ur terkid ara ssebba n wabugen, tukksa n tmahilin neɣ iɣisan deg tɣellist.",
|
||||||
|
"This usually only affects how the room is processed on the server. If you're having problems with your %(brand)s, please <a>report a bug</a>.": "Aya yettḥaz kan s umata amek tetteg texxamt tasleḍt ɣef uqeddac. Ma yella temlaleḍ-d uguren d %(brand)s-inek·inem, ttxil-k·m <a>azen-d abug</a>.",
|
||||||
|
"You'll upgrade this room from <oldVersion /> to <newVersion />.": "Tleqqmeḍ taxxamt-a seg <oldVersion /> ɣer <newVersion />.",
|
||||||
|
"Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Aqeddac-inek·inem ur d-yettarra ara ɣef kra n yisutar-ik·im. Ha-tent-a kra n ssebbat i izemren ad ilint.",
|
||||||
|
"The server (%(serverName)s) took too long to respond.": "Aqeddac (%(serverName)s) yeṭṭef aṭas n wakud i wakken ad d-yerr.",
|
||||||
|
"Your firewall or anti-virus is blocking the request.": "Aɣrab n tmes neɣ amgelavirus inek·inem yessewḥal isutar.",
|
||||||
|
"A browser extension is preventing the request.": "Asiɣzef n yiminig tessewḥel asuter.",
|
||||||
|
"We encountered an error trying to restore your previous session.": "Nemlal-d tuccḍa mi ara d-nettarra tiɣimit-ik·im yezrin.",
|
||||||
|
"If you have previously used a more recent version of %(brand)s, your session may be incompatible with this version. Close this window and return to the more recent version.": "Ma yella tesqedceḍ yakan lqem n melmi kan n %(brand)s, tiɣimit-ik·im tezmer ur tettemṣada ara d lqem-a. Mdel afaylu-a syen uɣal ɣer lqem n melmi kan.",
|
||||||
|
"Cross-signing and secret storage are ready for use.": "Azmul anmidag d uklas uffir wejden i useqdec.",
|
||||||
|
"Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.": "Azmul anmidag yewjed i useqdec, maca aklas uffir akka tura ur yettuseqdac ara i uḥraz n tsura.",
|
||||||
|
"This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. <b>This action is irreversible.</b>": "Amiḍan-ik·im ad yuɣal ur yettwaseqdac ara i lebda. Ur tettizmireḍ ara ad tkecmeḍ, daɣen ulac win ara yizmiren ad issekle asulay-a n useqdac. Ad yerr amiḍăn-ik·im ad yettwakkes seg meṛṛa tixxamin ideg tettekkaḍ, rnu ad yekkes akk talqayt seg uqeddac-ik·im n timagit. <b>Ulac tuɣalin ɣer deffir deg tigawt-a.</b>",
|
||||||
|
"Deactivating your account <b>does not by default cause us to forget messages you have sent.</b> If you would like us to forget your messages, please tick the box below.": "Asemmet n umiḍan-ik·im <b>ur aɣ-isettu ara iznan i tuzneḍ s wudem amezwer. </b> Ma yella teɣiḍ ad nettu iznan-ik·im, ttxil-k·m mwati tabewwaḍt ddaaw.",
|
||||||
|
"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.": "Abani n yiznan deg Matrix kifkif d wid n yimayl. Mi ara nettu iznan-ik·im, aya yebɣa ad d-yini iznan i tuzneḍ ur ttwabḍan ara ula d yiwen useqdac amaynut neɣ wid ur njerred ara, maca iseqdacen yettujerrden i yesɛan yakan anekcum ɣer yiznan-a mazal ad sɛun anekcum ɣer unɣal-nsen.",
|
||||||
|
"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.": "Senqed ibenk-a i wakken ad tcerḍeḍ fell-as yettwattkal. Attkal n yibenk-a ad imudd i kečč·kemm d yiseqdacen-nniḍen lehna n uqerru mi ara tesqedcem awgelhen seg yixef ɣer yixef.",
|
||||||
|
"Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "Asenqed n yibenk-a ad yettucreḍ fall-as yettuklal, syen iseqdacen yettusneqden yid-k·m ad tteklen ɣef yibenk-a.",
|
||||||
|
"You've previously used %(brand)s 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, %(brand)s needs to resync your account.": "Tesqedceḍ yakan %(brand)s ɣef %(host)s s usali ẓẓayen d yiɛeggalen i iremden. Deg lqem-a asali ẓẓayen yensa. Am tkatut tuffirt tadigant ur temṣada ara gar sin-a n yiɣewwaren, %(brand)s yesra allus n umtawi amiḍan-ik·im.",
|
||||||
|
"If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Ma yella ileqman-nniḍen n %(brand)s mazal-iten ldin deg yiccer-nniḍen, ttxil-k·m mdel-it acku aseqec n %(brand)s deg yiwet n tnezduɣt s usali ẓẓayenurmid, asensi-nsen ɣef tikkelt ad d-yeglu s wuguren.",
|
||||||
|
"%(brand)s now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!": "%(brand)s tura isseqdac drus n tkatut seg 3 ɣer 5 n tikkal, s usali n talɣut n yiseqdac-nniḍen ma yili tettusra. Ttxil-k·m rǧu s leɛqel alamma nules amtawi d useqdac!",
|
||||||
|
"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:": "Aleqqem n texxamt-a yesra amdal n tummant tamirant n texxamt d tmerna n texxamt tamaynut deg wadeg-is. I tikci n tarmit i igerrzen iwumi nezmer i yiɛeggalen n texxamt, ad neg:",
|
||||||
|
"Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Asfaḍ n uklas n yiminig-ik·im yezmer ad iṣeggem ugur, maca aya ad ak·akem-isuffeɣ seg tuqqna rnu akk imazrayen n udiwenni yettwawgelhen ur d-ttbanen.",
|
||||||
|
"To help us prevent this in future, please <a>send us logs</a>.": "I wakken ad aɣ-tɛiwneḍ ur d-iḍerru ara waya ɣer sdat, ttxil-k·m <a>azen-aɣ-d iɣmisen</a>.",
|
||||||
|
"Some session data, including encrypted message keys, is missing. Sign out and sign in to fix this, restoring keys from backup.": "Kra n yisefka n tɣimit, daɣen tisura n yiznan yettwawgelhen, ttwakksen. Ffeɣ syen ales anekcum i wakken ad tṣeggmeḍ aya, err-d tisura seg uḥraz.",
|
||||||
|
"Your browser likely removed this data when running low on disk space.": "Yezmer iminig-ik·im yekkes isefka-a mi t-txuṣṣ tallunt ɣef uḍebsi.",
|
||||||
|
"A widget located at %(widgetUrl)s would like to verify your identity. By allowing this, the widget will be able to verify your user ID, but not perform actions as you.": "Awiǧit ha-t-an deg %(widgetUrl)s yesra ad isenqed timagit-ik·im. Ma yella tqebleḍ aya, awiǧit yezmer ad isenqed asulay-inek·inem n useqdac, maca ur iteg ara tigawin am kečč·kemm.",
|
||||||
|
"Unable to access secret storage. Please verify that you entered the correct recovery passphrase.": "D awezɣi ad yili unekcum ɣer uklas uffir. Ttxil-k·m sefqed ma teskecmeḍ tafyirt tuffirt n uɛeddi tameɣtut.",
|
||||||
|
"Backup could not be decrypted with this recovery key: please verify that you entered the correct recovery key.": "Aḥraz ue yezmir ara ad yekkes awgelhen s tsarut-a n uɛeddi: ttxil-k·m sefqed ma d tasarut n uɛeddi tameɣtut i teskecmeḍ.",
|
||||||
|
"Backup could not be decrypted with this recovery passphrase: please verify that you entered the correct recovery passphrase.": "Aḥraz ur yezmir ara ad yekkes awgelhen s tefyirt-a tuffirt n uɛeddi: sefqed ma yella d tafyirt tuffirt n uɛeddi tameɣtut i teskecmeḍ.",
|
||||||
|
"If you've forgotten your recovery passphrase you can <button1>use your recovery key</button1> or <button2>set up new recovery options</button2>": "Ma yella tettuḍ tafyirt-ik tuffirt n uɛeddi, tzemreḍ <button1>ad tesqedceḍ tasarut-ik·im n uɛeddi</button1> neɣ <button2>sbadu tixtiṛiyin timaynutin n uɛeddi</button2>",
|
||||||
|
"If you've forgotten your recovery key you can <button>set up new recovery options</button>": "Ma yella tettuḍ tasarut-ik·im n uɛeddi, tzemreḍ <button>ad tesbaduḍ tixtiṛiyin timaynutin n uɛeddi</button>",
|
||||||
|
"%(count)s <resendText>Resend all</resendText> or <cancelText>cancel all</cancelText> now. You can also select individual messages to resend or cancel.|other": "<resendText>Wennez kullec</resendText> neɣ <cancelText>sefsex kullec</cancelText> tura. Tzemreḍ daɣen ad tferneḍ iznan udmawanen i uwennez neɣ i usefsex.",
|
||||||
|
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Ɛerḍeɣ ad d-saliɣ tazmilt tufrint tesnakudt n texxamt-a, maca ur ssawḍeɣ ara ad t-naf.",
|
||||||
|
"A verification email will be sent to your inbox to confirm setting your new password.": "Imayl n usenqed ad yettwazen ɣer tbewwaḍt-ik·im n yimayl i usentem n yiɣewwaren n wawal-ik·im uffir.",
|
||||||
|
"Access your secure message history and set up secure messaging by entering your recovery passphrase.": "Kcem ɣer umazray aɣelsan n yiznan-inek·inem syen sbadu tirawt taɣelsant s usekcem n tefyirt tuffirt n uɛeddi.",
|
||||||
|
"Access your secure message history and set up secure messaging by entering your recovery key.": "Kcem ɣer umazray aɣelsan n yiznan-ik·im syen sbadu tirawt taɣelsant s usekcem n tsarut n uɛeddi.",
|
||||||
|
"Missing captcha public key in homeserver configuration. Please report this to your homeserver administrator.": "Txuṣṣ tsarut tazayezt n captcha deg umtawi n uqeddac agejdan. Ttxil-k·m azen aneqqis ɣef waya i unedbal n uqeddac-ik·im agejdan.",
|
||||||
|
"Enter the location of your Element Matrix Services homeserver. It may use your own domain name or be a subdomain of <a>element.io</a>.": "Sekcem adeg n uqeddac-ik·im agejdan n umeẓlu n Element Matrix. Yezmer ad iseqdec isem n taɣult-ik·im uzzig neɣ ad yili d taɣult tarnawt n <a>element.io</a>.",
|
||||||
|
"No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Ulac aqeddac n timagit yettusiwlen, ɣef waya ur tettizmireḍ ara ad ternuḍ tansa n yimayl i wakken ad twennzeḍ awal-ik·im uffir ɣer sdat.",
|
||||||
|
"If you don't specify an email address, you won't be able to reset your password. Are you sure?": "Ma yella ur d-tefrineḍ ara tansa n yimayl, ur tettizmireḍ ara ad twennzeḍ awal-ik·im uffir. Tebɣiḍ?",
|
||||||
|
"Set an email for account recovery. Use email or phone to optionally be discoverable by existing contacts.": "Sbadu imayl i tririt n umiḍan. Seqdec imayl neɣ tiliɣri i wakken ad tettwaf s uxtiṛi sɣur inermisen i yellan.",
|
||||||
|
"Set an email for account recovery. Use email to optionally be discoverable by existing contacts.": "Sbadu imayl i tririt n umiḍan. Seqdec imayl s ufran i wakken ad d-iban i yinermisen i yellan.",
|
||||||
|
"%(brand)s uses many advanced browser features, some of which are not available or experimental in your current browser.": "%(brand)s isseqdac aṭas n tmahilin leqqayen n yiminig, kra seg-sent ulac-itent neɣ d tirmitanin deg yiminig-ik·im amiran.",
|
||||||
|
"With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "S yiminig-ik·im amiran, ameẓraw d umḥulfan n usnas zemren ad ilin mačči akk d imeɣta, rnu kra neɣ akk timahilin zemrent ur teddunt ara. Ma yella tebɣiḍ ɣas akken ad t-tɛerḍeḍ tzemreḍ ad tkemmleḍ, maca ur tseɛɛuḍ ara akk tallalt ma yella temlaleḍ-d d wuguren!",
|
||||||
|
"You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Aql-ak·akem d (t)anedbal(t) n temɣiwent-a. Ur tettizmireḍ ara ad tɛawdeḍ anekcum alamma s tinubga n unedbal-nniḍen.",
|
||||||
|
"Changes made to your community <bold1>name</bold1> and <bold2>avatar</bold2> might not be seen by other users for up to 30 minutes.": "Isnifal i d-yellan ɣef <bold1>isem</bold1> d <bold2>avaṭar</bold2> i temɣiwent-ik·im ur ttmeẓran ara sɣur yiseqdacen-nniḍen alamma d 30 tesdidin .",
|
||||||
|
"These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Tixxamin-a ttwaskanent i yiɛeggalen n temɣiwent ɣef usebter n temɣiwent. Iɛeggalen n temɣiwent zemren ad ttekkin deg texxamin s usiti fell-asent.",
|
||||||
|
"Your community hasn't got a Long Description, a HTML page to show to community members.<br />Click here to open settings and give it one!": "Tamɣiwent-ik·im ur tesɛi ara aglam ɣezzifen, asebter HTML i uskan n yiɛeggalen n temɣiwent.<br />Sit da i wakken ad teldiḍ iɣewwaren syen rnu yiwet!",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Tixxamin tusligin zemrent ad ttwafent, timerna ɣer-sent s tinubga kan. Tixxamin tizuyaz zemrent ad ttwafent, yal wa yezmer ad yernu ɣer-sent.",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Tixxamin tusligin zemrent ad ttwafent, timerna ɣer-sent s tinubga kan. Tixxamin tizuyaz zemrent ad ttwafent, yal wa yezmer ad yernu ɣer-sent deg temɣiwent-a.",
|
||||||
|
"You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Ilaq ad tesremdeḍ aya ma yella taxxamt ad tettwaseqdec kan i uttekki d trebbaɛ tigensanin ɣef uqeddac-ik·im agejdan. Ayagi ur yettubeddal ara ɣer sdat.",
|
||||||
|
"You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "Ilaq ad tsenseḍ aya ma yella taxxamt ad tettuseqdac i uttekki d trebbaɛ tuffiɣin i yesɛan aqeddac-nsent agejdan. Aya ur yettwabeddal ara ɣer sdat.",
|
||||||
|
"Block anyone not part of %(serverName)s from ever joining this room.": "Asewḥel n yal amdan ur nettekki ara deg %(serverName)s ur d-irennu ara akk ɣer texamt-a.",
|
||||||
|
"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.": "Timenna ɣef yizen-a ad yazen \"asulay n uneḍru\" asuf i unedbal n uqeddac agejdan. Ma yella iznan n texxamt-a ttwawgelhen, anedbal-ik·im n uqeddac agejdan ur yettizmir ara ad d-iɣer aḍris n yizen neɣ senqed ifuyla neɣ tugniwin.",
|
||||||
|
"To continue using the %(homeserverDomain)s homeserver you must review and agree to our terms and conditions.": "I wakken ad tkemmleḍ aseqdec n uqeddac agejdan n %(homeserverDomain)s ilaq ad talseḍ asenqed syen ad tqebleḍ tiwtilin-nneɣ s umata.",
|
||||||
|
"Data from an older version of %(brand)s 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.": "Isefka n lqem aqbur n %(brand)s ttwafen. Ayagi ad d-yeglu s yir tamahalt n uwgelhen seg yixef ɣer yixef deg lqem aqbur. Iznan yettwawgelhen seg yixef ɣer yixef yettumbeddalen yakan mi akken yettuseqdac lqem aqbur yezmer ur asen-ittekkes ara uwgelhen deg lqem-a. Aya yezmer daɣen ad d-yeglu asefsex n yiznan yettumbeddalen s lqem-a. Ma yella temlaleḍ-d uguren, ffeɣ syen tuɣaleḍ-d tikkelt-nniḍen. I wakken ad tḥerzeḍ amazray n yiznan, sifeḍ rnu ales kter tisura-ik·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.": "I usbadu n umsizdeg, jbed-d avaṭar n temɣiwent ɣer ugalis n umsizdeg deg tama tazelmaḍt akk n ugdil. Tzemreḍ ad tsiteḍ ɣef avaṭar deg ugalis n yimsizdeg deg yal akud i wakken ad twaliḍ tixxamin kan d yimdanen yettwaqqnen d temɣiwent-a.",
|
||||||
|
"Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Rnu tamɣiwent i wakken ad d-tesdukkleḍ akk iseqdac d texxamin! Snulfu-d asebter agejdan i ucraḍ n tallunt-ik·im deg umaḍal n Matrix.",
|
||||||
|
"You can't send any messages until you review and agree to <consentLink>our terms and conditions</consentLink>.": "Ur tezmireḍ ara ad tazneḍ iznan alamma tesneqdeḍ syen ad tqebleḍ <consentLink>tiwtilin-nneɣ</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.": "Izen-ik·im ur yettwazen ara acku aqeddac-a agejdan iɛedda talast n useqdac urmid n wayyur. Ttxil-k·m <a>nermes anedbal-ik·im n umeẓlu</a> i wakken ad tkemmleḍ aseqdec ameẓlu.",
|
||||||
|
"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.": "Izen-ik·im ur yettwazen ara acku aqeddac-a agejdan iɛedda talast n yiɣbula. Ttxil-k·m <a>nermes anedbal-ik·im n umeẓlu</a> i wakken ad tkemmleḍ aseqdec ameẓlu.",
|
||||||
|
"%(count)s <resendText>Resend all</resendText> or <cancelText>cancel all</cancelText> now. You can also select individual messages to resend or cancel.|one": "<resendText>Ales tuzna n yizen</resendText> neɣ <cancelText>sefsex izen</cancelText> tura.",
|
||||||
|
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tɛerḍeḍ ad d-tsaliḍ tazmilt tufrint deg tesnakudt n teamt, maca ur tesɛiḍ ara tisirag ad d-tsekneḍ izen i d-teɛniḍ.",
|
||||||
|
"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.": "Asnifel n wawal-ik·im uffir ad iwennez akk tisura n uwgelhen seg yixef ɣer yixef deg meṛṛa n tɣimiyin-ik·im, s tririt n umazray n udiwenni awgelhan ur yettwaɣra ara. Sbadu aḥraz n tsarut neɣ sifeḍ tisura n texxamt-ik·im seg texxamt-nniḍen send awennez n wawal-ik·im uffir.",
|
||||||
|
"An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Imayl yettwazen ɣer %(emailAddress)s. Akken ara tḍefreḍ aseɣwen i yellan deg-s, sit ddaw.",
|
||||||
|
"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.": "Aql-ak·akem teffɣeḍ seg meṛṛa tiɣimiyin syen ur d-teṭṭifeḍ ara akk ilɣa n Push. I wakken ad talseḍ armad n yilɣa, kcem tikkelt-nniḍen ɣef yal ibenk.",
|
||||||
|
"Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or <a>enable unsafe scripts</a>.": "Ur tessawḍeḍ ara ad teqqneḍ ɣer uqeddac agejdan s HTTP mi ara yili URL n HTTPS deg ufeggag n yiminig-ik·im. Seqdec HTTPS neɣ <a>sermed isekripten ariɣelsanen</a>.",
|
||||||
|
"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.": "Yegguma ad yeqqen ɣer uqeddac agejdan - ttxil-k·m senqed tuqqna-inek·inem, tḍemneḍ belli <a>aselken n SSL n uqeddac agejdan</a> yettwattkal, rnu aseɣzan n yiminig-nni ur issewḥal ara isutar.",
|
||||||
|
"Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).": "Amiḍan-ik·im amaynut (%(newAccountId)s) yettwaseklas, maca teqqneḍ yakan ɣer umiḍan wayeḍ (%(loggedInUserId)s).",
|
||||||
|
"Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.": "Tasarut-ik·im n tririt d azeṭṭa aɣelsan - tzemreḍ ad tt-tesqedceḍ i wakken ad d-terreḍ anekcum ɣer yiznan-ik·im yettwawgelhen ma yella tettuḍ tafyirt-ik·im tuffirt n tririt.",
|
||||||
|
"Trophy": "Arraz"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1416,5 +1416,30 @@
|
||||||
"To return to your account in future you need to set a password": "For å komme tilbake til kontoen din senere, må du velge et passord",
|
"To return to your account in future you need to set a password": "For å komme tilbake til kontoen din senere, må du velge et passord",
|
||||||
"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)": "Vennligst glem alle meldingene jeg har sendt når kontoen min er deaktivert (<b>Advarsel:</b> Dette vil føre til at fremtidige brukere ser en ufullstendig visning av samtaler)",
|
"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)": "Vennligst glem alle meldingene jeg har sendt når kontoen min er deaktivert (<b>Advarsel:</b> Dette vil føre til at fremtidige brukere ser en ufullstendig visning av samtaler)",
|
||||||
"To help us prevent this in future, please <a>send us logs</a>.": "For å hjelpe oss med å forhindre dette i fremtiden, vennligst <a>send oss loggfiler</a>.",
|
"To help us prevent this in future, please <a>send us logs</a>.": "For å hjelpe oss med å forhindre dette i fremtiden, vennligst <a>send oss loggfiler</a>.",
|
||||||
"No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Ingen identitetstjener er satt opp, så du kan ikke bruke en E-postadresse til å tilbakestille passordet ditt senere."
|
"No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Ingen identitetstjener er satt opp, så du kan ikke bruke en E-postadresse til å tilbakestille passordet ditt senere.",
|
||||||
|
"Incoming call": "Innkommende samtale",
|
||||||
|
"Lock": "Lås",
|
||||||
|
"Compact": "Kompakt",
|
||||||
|
"Modern": "Moderne",
|
||||||
|
"Server or user ID to ignore": "Tjener- eller bruker-ID-en som skal ignoreres",
|
||||||
|
"Show %(count)s more|other": "Vis %(count) til",
|
||||||
|
"Show %(count)s more|one": "Vis %(count) til",
|
||||||
|
"Use default": "Bruk standarden",
|
||||||
|
"Notification options": "Varselsinnstillinger",
|
||||||
|
"Room options": "Rominnstillinger",
|
||||||
|
"Your messages are not secure": "Dine meldinger er ikke sikre",
|
||||||
|
"Verification cancelled": "Verifiseringen ble avbrutt",
|
||||||
|
"Edited at %(date)s": "Redigert den %(date)s",
|
||||||
|
"Click to view edits": "Klikk for å vise redigeringer",
|
||||||
|
"This widget may use cookies.": "Denne modulen bruker kanskje infokapsler.",
|
||||||
|
"Confirm account deactivation": "Bekreft deaktivering av kontoen",
|
||||||
|
"Send Account Data": "Send kontodata",
|
||||||
|
"The server is offline.": "Denne tjeneren er offline.",
|
||||||
|
"Wrong file type": "Feil filtype",
|
||||||
|
"Looks good!": "Ser bra ut!",
|
||||||
|
"Security & privacy": "Sikkerhet og personvern",
|
||||||
|
"User menu": "Brukermeny",
|
||||||
|
"Use Recovery Key": "Bruk gjenopprettingsnøkkel",
|
||||||
|
"%(brand)s iOS": "%(brand)s iOS",
|
||||||
|
"%(brand)s Android": "%(brand)s Android"
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
"Failed to unban": "Não foi possível remover o banimento",
|
"Failed to unban": "Não foi possível remover o banimento",
|
||||||
"Favourite": "Favoritar",
|
"Favourite": "Favoritar",
|
||||||
"Favourites": "Favoritos",
|
"Favourites": "Favoritos",
|
||||||
"Filter room members": "Filtrar integrantes da sala",
|
"Filter room members": "Pesquisar participantes da sala",
|
||||||
"Forget room": "Esquecer sala",
|
"Forget room": "Esquecer sala",
|
||||||
"For security, this session has been signed out. Please sign in again.": "Por questões de segurança, esta sessão foi encerrada. Por gentileza conecte-se novamente.",
|
"For security, this session has been signed out. Please sign in again.": "Por questões de segurança, esta sessão foi encerrada. Por gentileza conecte-se novamente.",
|
||||||
"Guests cannot join this room even if explicitly invited.": "Visitantes não podem entrar nesta sala, mesmo se forem explicitamente convidadas/os.",
|
"Guests cannot join this room even if explicitly invited.": "Visitantes não podem entrar nesta sala, mesmo se forem explicitamente convidadas/os.",
|
||||||
|
@ -142,8 +142,8 @@
|
||||||
"%(targetName)s joined the room.": "%(targetName)s entrou na sala.",
|
"%(targetName)s joined the room.": "%(targetName)s entrou na sala.",
|
||||||
"%(senderName)s kicked %(targetName)s.": "%(senderName)s removeu %(targetName)s da sala.",
|
"%(senderName)s kicked %(targetName)s.": "%(senderName)s removeu %(targetName)s da sala.",
|
||||||
"%(targetName)s left the room.": "%(targetName)s saiu da sala.",
|
"%(targetName)s left the room.": "%(targetName)s saiu da sala.",
|
||||||
"%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s deixou o histórico futuro da sala visível para todos os membros da sala, a partir de quando foram convidados.",
|
"%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s deixou o histórico futuro da sala visível para todos os participantes da sala, a partir de quando foram convidados.",
|
||||||
"%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s deixou o histórico futuro da sala visível para todos os membros da sala, a partir de quando entraram.",
|
"%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s deixou o histórico futuro da sala visível para todos os participantes da sala, a partir de quando entraram.",
|
||||||
"%(senderName)s made future room history visible to all room members.": "%(senderName)s deixou o histórico futuro da sala visível para todas as pessoas da sala.",
|
"%(senderName)s made future room history visible to all room members.": "%(senderName)s deixou o histórico futuro da sala visível para todas as pessoas da sala.",
|
||||||
"%(senderName)s made future room history visible to anyone.": "%(senderName)s deixou o histórico futuro da sala visível para qualquer pessoa.",
|
"%(senderName)s made future room history visible to anyone.": "%(senderName)s deixou o histórico futuro da sala visível para qualquer pessoa.",
|
||||||
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s deixou o histórico futuro da sala visível para desconhecido (%(visibility)s).",
|
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s deixou o histórico futuro da sala visível para desconhecido (%(visibility)s).",
|
||||||
|
@ -212,7 +212,7 @@
|
||||||
"Failed to change power level": "Não foi possível alterar o nível de permissão",
|
"Failed to change power level": "Não foi possível alterar o nível de permissão",
|
||||||
"Failed to join room": "Não foi possível ingressar na sala",
|
"Failed to join room": "Não foi possível ingressar na sala",
|
||||||
"Failed to kick": "Não foi possível remover o usuário",
|
"Failed to kick": "Não foi possível remover o usuário",
|
||||||
"Failed to load timeline position": "Não foi possível carregar a posição na linha do tempo",
|
"Failed to load timeline position": "Não foi possível carregar um trecho da conversa",
|
||||||
"Failed to mute user": "Não foi possível remover notificações da/do usuária/o",
|
"Failed to mute user": "Não foi possível remover notificações da/do usuária/o",
|
||||||
"Failed to reject invite": "Não foi possível recusar o convite",
|
"Failed to reject invite": "Não foi possível recusar o convite",
|
||||||
"Failed to set display name": "Falha ao definir o nome e sobrenome",
|
"Failed to set display name": "Falha ao definir o nome e sobrenome",
|
||||||
|
@ -233,8 +233,8 @@
|
||||||
"%(count)s of your messages have not been sent.|other": "Algumas das suas mensagens não foram enviadas.",
|
"%(count)s of your messages have not been sent.|other": "Algumas das suas mensagens não foram enviadas.",
|
||||||
"Submit": "Enviar",
|
"Submit": "Enviar",
|
||||||
"This room has no local addresses": "Esta sala não tem endereços locais",
|
"This room has no local addresses": "Esta sala não tem endereços locais",
|
||||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tentei carregar um ponto específico na linha do tempo desta sala, mas parece que você não tem permissões para ver a mensagem em questão.",
|
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Não foi possível carregar um trecho específico da conversa desta sala, porque parece que você não tem permissão para ler a mensagem em questão.",
|
||||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Tentei carregar um ponto específico na linha do tempo desta sala, mas não o encontrei.",
|
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Não foi possível carregar um trecho específico da conversa desta sala.",
|
||||||
"You seem to be in a call, are you sure you want to quit?": "Parece que você está em uma chamada. Tem certeza que quer sair?",
|
"You seem to be in a call, are you sure you want to quit?": "Parece que você está em uma chamada. Tem certeza que quer sair?",
|
||||||
"You seem to be uploading files, are you sure you want to quit?": "Parece que você está enviando arquivos. Tem certeza que quer sair?",
|
"You seem to be uploading files, are you sure you want to quit?": "Parece que você está enviando arquivos. Tem certeza que quer sair?",
|
||||||
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Você não poderá desfazer essa alteração, pois está promovendo o usuário ao mesmo nível de permissão que você.",
|
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Você não poderá desfazer essa alteração, pois está promovendo o usuário ao mesmo nível de permissão que você.",
|
||||||
|
@ -332,7 +332,7 @@
|
||||||
"Add": "Adicionar",
|
"Add": "Adicionar",
|
||||||
"Error: Problem communicating with the given homeserver.": "Erro: problema de comunicação com o Servidor de Base fornecido.",
|
"Error: Problem communicating with the given homeserver.": "Erro: problema de comunicação com o Servidor de Base fornecido.",
|
||||||
"Failed to fetch avatar URL": "Falha ao obter o link da foto de perfil",
|
"Failed to fetch avatar URL": "Falha ao obter o link da foto de perfil",
|
||||||
"Home": "Início",
|
"Home": "Home",
|
||||||
"The phone number entered looks invalid": "O número de telefone inserido parece ser inválido",
|
"The phone number entered looks invalid": "O número de telefone inserido parece ser inválido",
|
||||||
"Uploading %(filename)s and %(count)s others|zero": "Enviando o arquivo %(filename)s",
|
"Uploading %(filename)s and %(count)s others|zero": "Enviando o arquivo %(filename)s",
|
||||||
"Uploading %(filename)s and %(count)s others|one": "Enviando o arquivo %(filename)s e %(count)s outros arquivos",
|
"Uploading %(filename)s and %(count)s others|one": "Enviando o arquivo %(filename)s e %(count)s outros arquivos",
|
||||||
|
@ -404,7 +404,7 @@
|
||||||
"The platform you're on": "A plataforma que você está usando",
|
"The platform you're on": "A plataforma que você está usando",
|
||||||
"Your language of choice": "O idioma que você selecionou",
|
"Your language of choice": "O idioma que você selecionou",
|
||||||
"Which officially provided instance you are using, if any": "Qual instância oficial você está usando, se for o caso",
|
"Which officially provided instance you are using, if any": "Qual instância oficial você está usando, se for o caso",
|
||||||
"Whether or not you're using the Richtext mode of the Rich Text Editor": "Se você está usando o editor de texto visual",
|
"Whether or not you're using the Richtext mode of the Rich Text Editor": "Se você está usando a formatação de texto no campo de texto",
|
||||||
"Your homeserver's URL": "O endereço do seu servidor local",
|
"Your homeserver's URL": "O endereço do seu servidor local",
|
||||||
"The information being sent to us to help make %(brand)s better includes:": "As informações que estão sendo enviadas para ajudar a melhorar o %(brand)s incluem:",
|
"The information being sent to us to help make %(brand)s better includes:": "As informações que estão sendo enviadas para ajudar a melhorar o %(brand)s incluem:",
|
||||||
"Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Quando esta página inclui informações identificáveis, como uma sala, ID de usuário ou de comunidade, estes dados são removidos antes de serem enviados ao servidor.",
|
"Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Quando esta página inclui informações identificáveis, como uma sala, ID de usuário ou de comunidade, estes dados são removidos antes de serem enviados ao servidor.",
|
||||||
|
@ -414,9 +414,9 @@
|
||||||
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s de %(monthName)s de %(fullYear)s",
|
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s de %(monthName)s de %(fullYear)s",
|
||||||
"Who would you like to add to this community?": "Quem você gostaria de adicionar a esta comunidade?",
|
"Who would you like to add to this community?": "Quem você gostaria de adicionar a esta comunidade?",
|
||||||
"Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Atenção: qualquer pessoa que você adicionar a esta comunidade estará publicamente visível para todas as pessoas que conheçam o ID da comunidade",
|
"Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Atenção: qualquer pessoa que você adicionar a esta comunidade estará publicamente visível para todas as pessoas que conheçam o ID da comunidade",
|
||||||
"Invite new community members": "Convidar novos integrantes para a comunidade",
|
"Invite new community members": "Convidar novos participantes para a comunidade",
|
||||||
"Which rooms would you like to add to this community?": "Quais salas você quer adicionar a esta comunidade?",
|
"Which rooms would you like to add to this community?": "Quais salas você quer adicionar a esta comunidade?",
|
||||||
"Show these rooms to non-members on the community page and room list?": "Exibir estas salas para não integrantes na página da comunidade e na lista de salas?",
|
"Show these rooms to non-members on the community page and room list?": "Exibir estas salas para não participantes na página da comunidade e na lista de salas?",
|
||||||
"Unable to create widget.": "Não foi possível criar o widget.",
|
"Unable to create widget.": "Não foi possível criar o widget.",
|
||||||
"You are now ignoring %(userId)s": "Agora você está bloqueando %(userId)s",
|
"You are now ignoring %(userId)s": "Agora você está bloqueando %(userId)s",
|
||||||
"Unignored user": "Usuário desbloqueado",
|
"Unignored user": "Usuário desbloqueado",
|
||||||
|
@ -432,7 +432,7 @@
|
||||||
"Mirror local video feed": "Espelhar o feed de vídeo local",
|
"Mirror local video feed": "Espelhar o feed de vídeo local",
|
||||||
"Enable inline URL previews by default": "Ativar, por padrão, a visualização de resumo de links",
|
"Enable inline URL previews by default": "Ativar, por padrão, a visualização de resumo de links",
|
||||||
"Enable URL previews for this room (only affects you)": "Ativar, para esta sala, a visualização de links (só afeta você)",
|
"Enable URL previews for this room (only affects you)": "Ativar, para esta sala, a visualização de links (só afeta você)",
|
||||||
"Enable URL previews by default for participants in this room": "Ativar, para todos os integrantes desta sala, a visualização de links",
|
"Enable URL previews by default for participants in this room": "Ativar, para todos os participantes desta sala, a visualização de links",
|
||||||
"Cannot add any more widgets": "Não é possível adicionar novos widgets",
|
"Cannot add any more widgets": "Não é possível adicionar novos widgets",
|
||||||
"The maximum permitted number of widgets have already been added to this room.": "O número máximo de widgets permitidos já foi atingido nesta sala.",
|
"The maximum permitted number of widgets have already been added to this room.": "O número máximo de widgets permitidos já foi atingido nesta sala.",
|
||||||
"Add a widget": "Adicionar um widget",
|
"Add a widget": "Adicionar um widget",
|
||||||
|
@ -452,7 +452,7 @@
|
||||||
"Send an encrypted reply…": "Digite sua resposta criptografada…",
|
"Send an encrypted reply…": "Digite sua resposta criptografada…",
|
||||||
"Send an encrypted message…": "Digite uma mensagem criptografada…",
|
"Send an encrypted message…": "Digite uma mensagem criptografada…",
|
||||||
"Jump to message": "Pular para mensagem",
|
"Jump to message": "Pular para mensagem",
|
||||||
"No pinned messages.": "Não há mensagens fixas.",
|
"No pinned messages.": "Nenhuma mensagem fixada.",
|
||||||
"Loading...": "Carregando...",
|
"Loading...": "Carregando...",
|
||||||
"Pinned Messages": "Mensagens fixas",
|
"Pinned Messages": "Mensagens fixas",
|
||||||
"%(duration)ss": "%(duration)ss",
|
"%(duration)ss": "%(duration)ss",
|
||||||
|
@ -472,9 +472,9 @@
|
||||||
"Community Invites": "Convites a comunidades",
|
"Community Invites": "Convites a comunidades",
|
||||||
"Banned by %(displayName)s": "Banido por %(displayName)s",
|
"Banned by %(displayName)s": "Banido por %(displayName)s",
|
||||||
"Publish this room to the public in %(domain)s's room directory?": "Quer publicar esta sala na lista pública de salas da %(domain)s?",
|
"Publish this room to the public in %(domain)s's room directory?": "Quer publicar esta sala na lista pública de salas da %(domain)s?",
|
||||||
"Members only (since the point in time of selecting this option)": "Apenas integrantes (a partir do momento em que esta opção for selecionada)",
|
"Members only (since the point in time of selecting this option)": "Apenas participantes (a partir do momento em que esta opção for selecionada)",
|
||||||
"Members only (since they were invited)": "Apenas integrantes (desde que foram convidadas/os)",
|
"Members only (since they were invited)": "Apenas participantes (desde que foram convidadas/os)",
|
||||||
"Members only (since they joined)": "Apenas integrantes (desde que entraram na sala)",
|
"Members only (since they joined)": "Apenas participantes (desde que entraram na sala)",
|
||||||
"Invalid community ID": "ID de comunidade inválido",
|
"Invalid community ID": "ID de comunidade inválido",
|
||||||
"'%(groupId)s' is not a valid community ID": "'%(groupId)s' não é um ID de comunidade válido",
|
"'%(groupId)s' is not a valid community ID": "'%(groupId)s' não é um ID de comunidade válido",
|
||||||
"Flair": "Ícone",
|
"Flair": "Ícone",
|
||||||
|
@ -500,11 +500,11 @@
|
||||||
"The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "A visibilidade da sala '%(roomName)s' na comunidade %(groupId)s não pôde ser atualizada.",
|
"The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "A visibilidade da sala '%(roomName)s' na comunidade %(groupId)s não pôde ser atualizada.",
|
||||||
"Visibility in Room List": "Visibilidade na lista de salas",
|
"Visibility in Room List": "Visibilidade na lista de salas",
|
||||||
"Visible to everyone": "Visível para todos",
|
"Visible to everyone": "Visível para todos",
|
||||||
"Only visible to community members": "Apenas visível para integrantes da comunidade",
|
"Only visible to community members": "Apenas visível para participantes da comunidade",
|
||||||
"Filter community rooms": "Filtrar salas da comunidade",
|
"Filter community rooms": "Filtrar salas da comunidade",
|
||||||
"Something went wrong when trying to get your communities.": "Não foi possível carregar suas comunidades.",
|
"Something went wrong when trying to get your communities.": "Não foi possível carregar suas comunidades.",
|
||||||
"Display your community flair in rooms configured to show it.": "Mostrar o ícone da sua comunidade nas salas que o permitem.",
|
"Display your community flair in rooms configured to show it.": "Mostrar o ícone da sua comunidade nas salas que o permitem.",
|
||||||
"You're not currently a member of any communities.": "Atualmente você não é integrante de nenhuma comunidade.",
|
"You're not currently a member of any communities.": "No momento, você não é participante de nenhuma comunidade.",
|
||||||
"Allow": "Permitir",
|
"Allow": "Permitir",
|
||||||
"Delete Widget": "Apagar widget",
|
"Delete Widget": "Apagar widget",
|
||||||
"Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Remover um widget o remove para todas as pessoas desta sala. Tem certeza que quer remover este widget?",
|
"Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Remover um widget o remove para todas as pessoas desta sala. Tem certeza que quer remover este widget?",
|
||||||
|
@ -581,7 +581,7 @@
|
||||||
"example": "exemplo",
|
"example": "exemplo",
|
||||||
"Create": "Criar",
|
"Create": "Criar",
|
||||||
"To get started, please pick a username!": "Para começar, escolha um nome de usuário!",
|
"To get started, please pick a username!": "Para começar, escolha um nome de usuário!",
|
||||||
"<h1>HTML for your community's page</h1>\n<p>\n Use the long description to introduce new members to the community, or distribute\n some important <a href=\"foo\">links</a>\n</p>\n<p>\n You can even use 'img' tags\n</p>\n": "<h1>HTML para a página da sua comunidade</h1>\n<p>\n Use a descrição longa para apresentar a comunidade para novas/os integrantes ou partilhe <a href=\"foo\">links</a> importantes.\n</p>\n<p>\n Você pode até mesmo usar tags 'img' do HTML\n</p>\n",
|
"<h1>HTML for your community's page</h1>\n<p>\n Use the long description to introduce new members to the community, or distribute\n some important <a href=\"foo\">links</a>\n</p>\n<p>\n You can even use 'img' tags\n</p>\n": "<h1>HTML para a página da sua comunidade</h1>\n<p>\n Use a descrição longa para apresentar a comunidade para novas/os participantes, ou compartilhe <a href=\"foo\">links</a> importantes.\n</p>\n<p>\n Você pode até mesmo usar tags 'img' em HTML\n</p>\n",
|
||||||
"Add rooms to the community summary": "Adicionar salas para o índice da comunidade",
|
"Add rooms to the community summary": "Adicionar salas para o índice da comunidade",
|
||||||
"Which rooms would you like to add to this summary?": "Quais salas você gostaria de adicionar a este índice?",
|
"Which rooms would you like to add to this summary?": "Quais salas você gostaria de adicionar a este índice?",
|
||||||
"Add to summary": "Adicionar ao índice",
|
"Add to summary": "Adicionar ao índice",
|
||||||
|
@ -603,12 +603,12 @@
|
||||||
"Leave %(groupName)s?": "Quer sair da comunidade %(groupName)s?",
|
"Leave %(groupName)s?": "Quer sair da comunidade %(groupName)s?",
|
||||||
"Leave": "Sair",
|
"Leave": "Sair",
|
||||||
"Community Settings": "Configurações da comunidade",
|
"Community Settings": "Configurações da comunidade",
|
||||||
"These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Essas salas são exibidas para os membros da comunidade na página da comunidade. Os membros da comunidade entram nas salas clicando nelas.",
|
"These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Essas salas são exibidas para os participantes da comunidade na página da comunidade. Os paraticipantes da comunidade entram nas salas clicando nelas.",
|
||||||
"Featured Rooms:": "Salas em destaque:",
|
"Featured Rooms:": "Salas em destaque:",
|
||||||
"Featured Users:": "Pessoas em destaque:",
|
"Featured Users:": "Pessoas em destaque:",
|
||||||
"%(inviter)s has invited you to join this community": "%(inviter)s convidou você para entrar nesta comunidade",
|
"%(inviter)s has invited you to join this community": "%(inviter)s convidou você para entrar nesta comunidade",
|
||||||
"You are an administrator of this community": "Você é administrador(a) desta comunidade",
|
"You are an administrator of this community": "Você é administrador(a) desta comunidade",
|
||||||
"You are a member of this community": "Você é um/a integrante desta comunidade",
|
"You are a member of this community": "Você é um/a participante desta comunidade",
|
||||||
"Your community hasn't got a Long Description, a HTML page to show to community members.<br />Click here to open settings and give it one!": "Sua comunidade não tem uma descrição longa, ou seja, uma página HTML para ser exibida às pessoas que fazem parte da comunidade.<br />Clique aqui para abrir as configurações e criar uma!",
|
"Your community hasn't got a Long Description, a HTML page to show to community members.<br />Click here to open settings and give it one!": "Sua comunidade não tem uma descrição longa, ou seja, uma página HTML para ser exibida às pessoas que fazem parte da comunidade.<br />Clique aqui para abrir as configurações e criar uma!",
|
||||||
"Long Description (HTML)": "Descrição longa (HTML)",
|
"Long Description (HTML)": "Descrição longa (HTML)",
|
||||||
"Description": "Descrição",
|
"Description": "Descrição",
|
||||||
|
@ -668,7 +668,7 @@
|
||||||
"Resend": "Reenviar",
|
"Resend": "Reenviar",
|
||||||
"Error saving email notification preferences": "Erro ao salvar a configuração de notificações por e-mail",
|
"Error saving email notification preferences": "Erro ao salvar a configuração de notificações por e-mail",
|
||||||
"Messages containing my display name": "Mensagens contendo meu nome e sobrenome",
|
"Messages containing my display name": "Mensagens contendo meu nome e sobrenome",
|
||||||
"Messages in one-to-one chats": "Mensagens em conversas pessoais",
|
"Messages in one-to-one chats": "Mensagens em conversas individuais",
|
||||||
"Unavailable": "Indisponível",
|
"Unavailable": "Indisponível",
|
||||||
"View Decrypted Source": "Ver código-fonte descriptografado",
|
"View Decrypted Source": "Ver código-fonte descriptografado",
|
||||||
"Failed to update keywords": "Falha ao alterar as palavras-chave",
|
"Failed to update keywords": "Falha ao alterar as palavras-chave",
|
||||||
|
@ -681,7 +681,7 @@
|
||||||
"Source URL": "Link do código-fonte",
|
"Source URL": "Link do código-fonte",
|
||||||
"Messages sent by bot": "Mensagens enviadas por bots",
|
"Messages sent by bot": "Mensagens enviadas por bots",
|
||||||
"Filter results": "Filtrar resultados",
|
"Filter results": "Filtrar resultados",
|
||||||
"Members": "Membros",
|
"Members": "Participantes",
|
||||||
"No update available.": "Nenhuma atualização disponível.",
|
"No update available.": "Nenhuma atualização disponível.",
|
||||||
"Noisy": "Ativado com som",
|
"Noisy": "Ativado com som",
|
||||||
"Files": "Arquivos",
|
"Files": "Arquivos",
|
||||||
|
@ -716,13 +716,13 @@
|
||||||
"Invite to this room": "Convidar para esta sala",
|
"Invite to this room": "Convidar para esta sala",
|
||||||
"Send logs": "Enviar registros",
|
"Send logs": "Enviar registros",
|
||||||
"All messages": "Todas as mensagens novas",
|
"All messages": "Todas as mensagens novas",
|
||||||
"Call invitation": "Convite para chamada",
|
"Call invitation": "Recebendo chamada",
|
||||||
"Downloading update...": "Baixando atualização...",
|
"Downloading update...": "Baixando atualização...",
|
||||||
"State Key": "Chave do Estado",
|
"State Key": "Chave do Estado",
|
||||||
"Failed to send custom event.": "Falha ao enviar evento personalizado.",
|
"Failed to send custom event.": "Falha ao enviar evento personalizado.",
|
||||||
"What's new?": "O que há de novidades?",
|
"What's new?": "O que há de novidades?",
|
||||||
"Notify me for anything else": "Notificar-me sobre qualquer outro evento",
|
"Notify me for anything else": "Notificar-me sobre qualquer outro evento",
|
||||||
"When I'm invited to a room": "Quando sou convidada(o) a uma sala",
|
"When I'm invited to a room": "Quando eu for convidada(o) a uma sala",
|
||||||
"Can't update user notification settings": "Não foi possível atualizar a configuração das notificações",
|
"Can't update user notification settings": "Não foi possível atualizar a configuração das notificações",
|
||||||
"Notify for all other messages/rooms": "Notificar para todas as outras mensagens e salas",
|
"Notify for all other messages/rooms": "Notificar para todas as outras mensagens e salas",
|
||||||
"Unable to look up room ID from server": "Não foi possível buscar identificação da sala no servidor",
|
"Unable to look up room ID from server": "Não foi possível buscar identificação da sala no servidor",
|
||||||
|
@ -819,8 +819,8 @@
|
||||||
"Enable widget screenshots on supported widgets": "Ativar capturas de tela do widget em widgets suportados",
|
"Enable widget screenshots on supported widgets": "Ativar capturas de tela do widget em widgets suportados",
|
||||||
"Show developer tools": "Mostrar ferramentas de desenvolvedor",
|
"Show developer tools": "Mostrar ferramentas de desenvolvedor",
|
||||||
"Messages containing @room": "Mensagens contendo @room",
|
"Messages containing @room": "Mensagens contendo @room",
|
||||||
"Encrypted messages in one-to-one chats": "Mensagens criptografadas em bate-papos individuais",
|
"Encrypted messages in one-to-one chats": "Mensagens criptografadas em conversas individuais",
|
||||||
"Encrypted messages in group chats": "Mensagens criptografadas em conversas em grupo",
|
"Encrypted messages in group chats": "Mensagens criptografadas em salas",
|
||||||
"Delete Backup": "Deletar Backup",
|
"Delete Backup": "Deletar Backup",
|
||||||
"Unable to load key backup status": "Não é possível carregar o status da chave de backup",
|
"Unable to load key backup status": "Não é possível carregar o status da chave de backup",
|
||||||
"Backup version: ": "Versão do Backup: ",
|
"Backup version: ": "Versão do Backup: ",
|
||||||
|
@ -855,7 +855,7 @@
|
||||||
"The email field must not be blank.": "O campo de e-mail não pode estar em branco.",
|
"The email field must not be blank.": "O campo de e-mail não pode estar em branco.",
|
||||||
"The phone number field must not be blank.": "O campo do número de telefone não pode estar em branco.",
|
"The phone number field must not be blank.": "O campo do número de telefone não pode estar em branco.",
|
||||||
"The password field must not be blank.": "O campo da senha não pode ficar em branco.",
|
"The password field must not be blank.": "O campo da senha não pode ficar em branco.",
|
||||||
"Failed to load group members": "Falha ao carregar membros da comunidade",
|
"Failed to load group members": "Falha ao carregar participantes da comunidade",
|
||||||
"Failed to remove widget": "Falha ao remover o widget",
|
"Failed to remove widget": "Falha ao remover o widget",
|
||||||
"An error ocurred whilst trying to remove the widget from the room": "Ocorreu um erro ao tentar remover o widget da sala",
|
"An error ocurred whilst trying to remove the widget from the room": "Ocorreu um erro ao tentar remover o widget da sala",
|
||||||
"Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Não é possível carregar o evento que foi respondido, ele não existe ou você não tem permissão para visualizá-lo.",
|
"Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Não é possível carregar o evento que foi respondido, ele não existe ou você não tem permissão para visualizá-lo.",
|
||||||
|
@ -886,7 +886,7 @@
|
||||||
"Create a new room with the same name, description and avatar": "Criar uma nova sala com o mesmo nome, descrição e foto",
|
"Create a new room with the same name, description and avatar": "Criar uma nova sala com o mesmo nome, descrição e foto",
|
||||||
"Stop users from speaking in the old version of the room, and post a message advising users to move to the new room": "Impeça os usuários de conversarem na versão antiga da sala. Além disso, digite uma mensagem aconselhando os usuários a migrarem para a nova sala",
|
"Stop users from speaking in the old version of the room, and post a message advising users to move to the new room": "Impeça os usuários de conversarem na versão antiga da sala. Além disso, digite uma mensagem aconselhando os usuários a migrarem para a nova sala",
|
||||||
"Put a link back to the old room at the start of the new room so people can see old messages": "Colocar um link para a sala antiga no começo da sala nova de modo que as pessoas possam ver mensagens antigas",
|
"Put a link back to the old room at the start of the new room so people can see old messages": "Colocar um link para a sala antiga no começo da sala nova de modo que as pessoas possam ver mensagens antigas",
|
||||||
"You've previously used %(brand)s 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, %(brand)s needs to resync your account.": "Você já usou o %(brand)s em %(host)s com o carregamento Lazy de membros ativado. Nesta versão, o carregamento Lazy está desativado. Como o cache local não é compatível entre essas duas configurações, o %(brand)s precisa ressincronizar sua conta.",
|
"You've previously used %(brand)s 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, %(brand)s needs to resync your account.": "Você já usou o %(brand)s em %(host)s com o carregamento Lazy de participantes ativado. Nesta versão, o carregamento Lazy está desativado. Como o cache local não é compatível entre essas duas configurações, o %(brand)s precisa ressincronizar sua conta.",
|
||||||
"If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Se a outra versão do %(brand)s ainda estiver aberta em outra aba, por favor, feche-a pois usar o %(brand)s no mesmo host com o carregamento Lazy ativado e desativado simultaneamente causará problemas.",
|
"If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Se a outra versão do %(brand)s ainda estiver aberta em outra aba, por favor, feche-a pois usar o %(brand)s no mesmo host com o carregamento Lazy ativado e desativado simultaneamente causará problemas.",
|
||||||
"Update any local room aliases to point to the new room": "Atualize todos os aliases da sala local para apontar para a nova sala",
|
"Update any local room aliases to point to the new room": "Atualize todos os aliases da sala local para apontar para a nova sala",
|
||||||
"Clear Storage and Sign Out": "Limpar armazenamento e sair",
|
"Clear Storage and Sign Out": "Limpar armazenamento e sair",
|
||||||
|
@ -894,12 +894,12 @@
|
||||||
"We encountered an error trying to restore your previous session.": "Encontramos um erro ao tentar restaurar sua sessão anterior.",
|
"We encountered an error trying to restore your previous session.": "Encontramos um erro ao tentar restaurar sua sessão anterior.",
|
||||||
"Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Limpar o armazenamento do seu navegador pode resolver o problema, mas você será deslogado e isso fará que qualquer histórico de bate-papo criptografado fique ilegível.",
|
"Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Limpar o armazenamento do seu navegador pode resolver o problema, mas você será deslogado e isso fará que qualquer histórico de bate-papo criptografado fique ilegível.",
|
||||||
"Checking...": "Checando...",
|
"Checking...": "Checando...",
|
||||||
"Share Room": "Compartilhar Sala",
|
"Share Room": "Compartilhar sala",
|
||||||
"Link to most recent message": "Link para a mensagem mais recente",
|
"Link to most recent message": "Link da mensagem mais recente",
|
||||||
"Share User": "Compartilhar usuário",
|
"Share User": "Compartilhar usuário",
|
||||||
"Share Community": "Compartilhar Comunidade",
|
"Share Community": "Compartilhar Comunidade",
|
||||||
"Share Room Message": "Compartilhar Mensagem da Sala",
|
"Share Room Message": "Compartilhar Mensagem da Sala",
|
||||||
"Link to selected message": "Link para a mensagem selecionada",
|
"Link to selected message": "Link da mensagem selecionada",
|
||||||
"COPY": "COPIAR",
|
"COPY": "COPIAR",
|
||||||
"Unable to load backup status": "Não é possível carregar o status do backup",
|
"Unable to load backup status": "Não é possível carregar o status do backup",
|
||||||
"Unable to restore backup": "Não é possível restaurar o backup",
|
"Unable to restore backup": "Não é possível restaurar o backup",
|
||||||
|
@ -933,7 +933,7 @@
|
||||||
"You can't send any messages until you review and agree to <consentLink>our terms and conditions</consentLink>.": "Você não pode enviar nenhuma mensagem até revisar e concordar com <consentLink>nossos termos e condições</consentLink>.",
|
"You can't send any messages until you review and agree to <consentLink>our terms and conditions</consentLink>.": "Você não pode enviar nenhuma mensagem até revisar e concordar com <consentLink>nossos termos e condições</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.": "Sua mensagem não foi enviada porque este homeserver atingiu seu Limite de usuário ativo mensal. Por favor, <a>entre em contato com o seu administrador de serviços</a> para continuar usando o serviço.",
|
"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.": "Sua mensagem não foi enviada porque este homeserver atingiu seu Limite de usuário ativo mensal. Por favor, <a>entre em contato com o seu administrador de serviços</a> para continuar usando o serviço.",
|
||||||
"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.": "Sua mensagem não foi enviada porque este servidor local excedeu o limite de recursos. Por favor, <a>entre em contato com o seu administrador de serviços</a> para continuar usando o serviço.",
|
"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.": "Sua mensagem não foi enviada porque este servidor local excedeu o limite de recursos. Por favor, <a>entre em contato com o seu administrador de serviços</a> para continuar usando o serviço.",
|
||||||
"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.": "Se você enviou um bug por meio do GitHub, os logs de depuração podem nos ajudar a rastrear o problema. Os logs de depuração contêm dados de uso do aplicativo, incluindo seu nome de usuário, os IDs ou apelidos das salas ou comunidades que você visitou e os nomes de usuários de outros usuários. Eles não contêm mensagens.",
|
"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.": "Se você enviou um bug por meio do GitHub, os registros de depuração podem nos ajudar a rastrear o problema. Os registros de depuração contêm dados de uso do aplicativo, incluindo seu nome de usuário, os IDs ou apelidos das salas ou comunidades que você visitou e os nomes de usuários de outros usuários. Eles não contêm mensagens.",
|
||||||
"Legal": "Legal",
|
"Legal": "Legal",
|
||||||
"No Audio Outputs detected": "Nenhuma caixa de som detectada",
|
"No Audio Outputs detected": "Nenhuma caixa de som detectada",
|
||||||
"Audio Output": "Caixa de som",
|
"Audio Output": "Caixa de som",
|
||||||
|
@ -993,7 +993,7 @@
|
||||||
"%(names)s and %(count)s others are typing …|other": "%(names)s e %(count)s outras pessoas estão digitando…",
|
"%(names)s and %(count)s others are typing …|other": "%(names)s e %(count)s outras pessoas estão digitando…",
|
||||||
"%(names)s and %(count)s others are typing …|one": "%(names)s e outra pessoa estão digitando…",
|
"%(names)s and %(count)s others are typing …|one": "%(names)s e outra pessoa estão digitando…",
|
||||||
"%(names)s and %(lastPerson)s are typing …": "%(names)s e %(lastPerson)s estão digitando…",
|
"%(names)s and %(lastPerson)s are typing …": "%(names)s e %(lastPerson)s estão digitando…",
|
||||||
"Show read receipts sent by other users": "Mostrar confirmações de leitura enviadas por outros usuários",
|
"Show read receipts sent by other users": "Mostrar confirmações de leitura dos outros usuários",
|
||||||
"Show avatars in user and room mentions": "Mostrar fotos de perfil em menções de usuários e de salas",
|
"Show avatars in user and room mentions": "Mostrar fotos de perfil em menções de usuários e de salas",
|
||||||
"Enable big emoji in chat": "Ativar emojis grandes no bate-papo",
|
"Enable big emoji in chat": "Ativar emojis grandes no bate-papo",
|
||||||
"Send typing notifications": "Permitir que saibam quando eu estiver digitando",
|
"Send typing notifications": "Permitir que saibam quando eu estiver digitando",
|
||||||
|
@ -1005,7 +1005,7 @@
|
||||||
"You've successfully verified this user.": "Você confirmou este usuário com sucesso.",
|
"You've successfully verified this user.": "Você confirmou este usuário com sucesso.",
|
||||||
"Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "As mensagens com este usuário estão protegidas com a criptografia de ponta a ponta e não podem ser lidas por terceiros.",
|
"Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "As mensagens com este usuário estão protegidas com a criptografia de ponta a ponta e não podem ser lidas por terceiros.",
|
||||||
"Got It": "Ok, entendi",
|
"Got It": "Ok, entendi",
|
||||||
"Unable to find a supported verification method.": "Não há um método de confirmação suportado.",
|
"Unable to find a supported verification method.": "Nenhum método de confirmação é suportado.",
|
||||||
"Dog": "Cachorro",
|
"Dog": "Cachorro",
|
||||||
"Cat": "Gato",
|
"Cat": "Gato",
|
||||||
"Lion": "Leão",
|
"Lion": "Leão",
|
||||||
|
@ -1100,7 +1100,7 @@
|
||||||
"Account management": "Gerenciamento da Conta",
|
"Account management": "Gerenciamento da Conta",
|
||||||
"Deactivating your account is a permanent action - be careful!": "Desativar sua conta é uma ação permanente - tenha cuidado!",
|
"Deactivating your account is a permanent action - be careful!": "Desativar sua conta é uma ação permanente - tenha cuidado!",
|
||||||
"General": "Geral",
|
"General": "Geral",
|
||||||
"Credits": "Créditos",
|
"Credits": "Licenças",
|
||||||
"For help with using %(brand)s, click <a>here</a>.": "Para obter ajuda com o uso do %(brand)s, clique <a>aqui</a>.",
|
"For help with using %(brand)s, click <a>here</a>.": "Para obter ajuda com o uso do %(brand)s, clique <a>aqui</a>.",
|
||||||
"For help with using %(brand)s, click <a>here</a> or start a chat with our bot using the button below.": "Para obter ajuda com o uso do %(brand)s, clique <a>aqui</a> ou inicie um bate-papo com nosso bot usando o botão abaixo.",
|
"For help with using %(brand)s, click <a>here</a> or start a chat with our bot using the button below.": "Para obter ajuda com o uso do %(brand)s, clique <a>aqui</a> ou inicie um bate-papo com nosso bot usando o botão abaixo.",
|
||||||
"Chat with %(brand)s Bot": "Converse com o bot do %(brand)s",
|
"Chat with %(brand)s Bot": "Converse com o bot do %(brand)s",
|
||||||
|
@ -1109,8 +1109,8 @@
|
||||||
"FAQ": "FAQ",
|
"FAQ": "FAQ",
|
||||||
"Versions": "Versões",
|
"Versions": "Versões",
|
||||||
"Preferences": "Preferências",
|
"Preferences": "Preferências",
|
||||||
"Composer": "Compositor",
|
"Composer": "Campo de texto",
|
||||||
"Timeline": "Linha do Tempo",
|
"Timeline": "Conversas",
|
||||||
"Room list": "Lista de Salas",
|
"Room list": "Lista de Salas",
|
||||||
"Autocomplete delay (ms)": "Atraso no preenchimento automático (ms)",
|
"Autocomplete delay (ms)": "Atraso no preenchimento automático (ms)",
|
||||||
"Ignored users": "Usuários bloqueados",
|
"Ignored users": "Usuários bloqueados",
|
||||||
|
@ -1181,8 +1181,8 @@
|
||||||
"Messages": "Mensagens",
|
"Messages": "Mensagens",
|
||||||
"Actions": "Ações",
|
"Actions": "Ações",
|
||||||
"Other": "Outros",
|
"Other": "Outros",
|
||||||
"Sends a message as plain text, without interpreting it as markdown": "Envia uma mensagem como texto puro, sem interpretá-la como markdown",
|
"Sends a message as plain text, without interpreting it as markdown": "Envia uma mensagem como texto simples, sem formatar o texto",
|
||||||
"Sends a message as html, without interpreting it as markdown": "Envia uma mensagem como HTML, sem interpretá-la como markdown",
|
"Sends a message as html, without interpreting it as markdown": "Envia uma mensagem como HTML, sem formatar o texto",
|
||||||
"You do not have the required permissions to use this command.": "Você não tem as permissões necessárias para usar este comando.",
|
"You do not have the required permissions to use this command.": "Você não tem as permissões necessárias para usar este comando.",
|
||||||
"Error upgrading room": "Erro atualizando a sala",
|
"Error upgrading room": "Erro atualizando a sala",
|
||||||
"Double check that your server supports the room version chosen and try again.": "Verifique se seu servidor suporta a versão de sala escolhida e tente novamente.",
|
"Double check that your server supports the room version chosen and try again.": "Verifique se seu servidor suporta a versão de sala escolhida e tente novamente.",
|
||||||
|
@ -1341,7 +1341,7 @@
|
||||||
"Order rooms by name": "Ordenar salas por nome",
|
"Order rooms by name": "Ordenar salas por nome",
|
||||||
"Show rooms with unread notifications first": "Mostrar primeiro as salas com notificações não lidas",
|
"Show rooms with unread notifications first": "Mostrar primeiro as salas com notificações não lidas",
|
||||||
"Show shortcuts to recently viewed rooms above the room list": "Mostrar atalhos para salas recentemente visualizadas acima da lista de salas",
|
"Show shortcuts to recently viewed rooms above the room list": "Mostrar atalhos para salas recentemente visualizadas acima da lista de salas",
|
||||||
"Show hidden events in timeline": "Mostrar eventos ocultos na timeline",
|
"Show hidden events in timeline": "Mostrar eventos ocultos nas conversas",
|
||||||
"Low bandwidth mode": "Modo de baixo uso de dados",
|
"Low bandwidth mode": "Modo de baixo uso de dados",
|
||||||
"Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Permitir a assistência do servidor de chamadas reserva turn.matrix.org quando seu servidor não oferecer este serviço (seu endereço IP será transmitido quando você ligar)",
|
"Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Permitir a assistência do servidor de chamadas reserva turn.matrix.org quando seu servidor não oferecer este serviço (seu endereço IP será transmitido quando você ligar)",
|
||||||
"Send read receipts for messages (requires compatible homeserver to disable)": "Enviar confirmação de leitura para mensagens (necessita um servidor compatível para desativar)",
|
"Send read receipts for messages (requires compatible homeserver to disable)": "Enviar confirmação de leitura para mensagens (necessita um servidor compatível para desativar)",
|
||||||
|
@ -1351,7 +1351,7 @@
|
||||||
"Manually verify all remote sessions": "Verificar manualmente todas as sessões remotas",
|
"Manually verify all remote sessions": "Verificar manualmente todas as sessões remotas",
|
||||||
"IRC display name width": "Largura do nome e sobrenome nas mensagens",
|
"IRC display name width": "Largura do nome e sobrenome nas mensagens",
|
||||||
"Enable experimental, compact IRC style layout": "Ativar o layout compacto experimental nas mensagens",
|
"Enable experimental, compact IRC style layout": "Ativar o layout compacto experimental nas mensagens",
|
||||||
"When rooms are upgraded": "Quando salas são atualizadas",
|
"When rooms are upgraded": "Quando a versão da sala é atualizada",
|
||||||
"My Ban List": "Minha lista de banidos",
|
"My Ban List": "Minha lista de banidos",
|
||||||
"This is your list of users/servers you have blocked - don't leave the room!": "Esta é a sua lista de usuárias(os)/servidores que você bloqueou - não saia da sala!",
|
"This is your list of users/servers you have blocked - don't leave the room!": "Esta é a sua lista de usuárias(os)/servidores que você bloqueou - não saia da sala!",
|
||||||
"Unknown caller": "Pessoa desconhecida ligando",
|
"Unknown caller": "Pessoa desconhecida ligando",
|
||||||
|
@ -1610,7 +1610,7 @@
|
||||||
"If disabled, messages from encrypted rooms won't appear in search results.": "Se desativado, as mensagens de salas criptografadas não aparecerão em resultados de buscas.",
|
"If disabled, messages from encrypted rooms won't appear in search results.": "Se desativado, as mensagens de salas criptografadas não aparecerão em resultados de buscas.",
|
||||||
"%(brand)s is securely caching encrypted messages locally for them to appear in search results:": "%(brand)s está armazenando de forma segura as mensagens criptografadas localmente, para que possam aparecer nos resultados das buscas:",
|
"%(brand)s is securely caching encrypted messages locally for them to appear in search results:": "%(brand)s está armazenando de forma segura as mensagens criptografadas localmente, para que possam aparecer nos resultados das buscas:",
|
||||||
"%(doneRooms)s out of %(totalRooms)s": "%(doneRooms)s de %(totalRooms)s",
|
"%(doneRooms)s out of %(totalRooms)s": "%(doneRooms)s de %(totalRooms)s",
|
||||||
"Jump to start/end of the composer": "Pule para o início/fim do compositor",
|
"Jump to start/end of the composer": "Pule para o início/fim do campo de texto",
|
||||||
"Click the button below to confirm adding this phone number.": "Clique no botão abaixo para confirmar a adição deste número de telefone.",
|
"Click the button below to confirm adding this phone number.": "Clique no botão abaixo para confirmar a adição deste número de telefone.",
|
||||||
"Clear notifications": "Limpar notificações",
|
"Clear notifications": "Limpar notificações",
|
||||||
"There are advanced notifications which are not shown here.": "Existem notificações avançadas que não são mostradas aqui.",
|
"There are advanced notifications which are not shown here.": "Existem notificações avançadas que não são mostradas aqui.",
|
||||||
|
@ -1700,7 +1700,7 @@
|
||||||
"Verification Requests": "Solicitações de confirmação",
|
"Verification Requests": "Solicitações de confirmação",
|
||||||
"Integrations are disabled": "As integrações estão desativadas",
|
"Integrations are disabled": "As integrações estão desativadas",
|
||||||
"Integrations not allowed": "As integrações não estão permitidas",
|
"Integrations not allowed": "As integrações não estão permitidas",
|
||||||
"End": "Fim",
|
"End": "End",
|
||||||
"List options": "Opções da Lista",
|
"List options": "Opções da Lista",
|
||||||
"Jump to first unread room.": "Ir para a primeira sala não lida.",
|
"Jump to first unread room.": "Ir para a primeira sala não lida.",
|
||||||
"Jump to first invite.": "Ir para o primeiro convite.",
|
"Jump to first invite.": "Ir para o primeiro convite.",
|
||||||
|
@ -1832,7 +1832,7 @@
|
||||||
"Select the roles required to change various parts of the room": "Selecione as permissões necessárias para alterar várias partes da sala",
|
"Select the roles required to change various parts of the room": "Selecione as permissões necessárias para alterar várias partes da sala",
|
||||||
"Emoji picker": "Enviar emoji",
|
"Emoji picker": "Enviar emoji",
|
||||||
"Room %(name)s": "Sala %(name)s",
|
"Room %(name)s": "Sala %(name)s",
|
||||||
"No recently visited rooms": "Não há salas visitadas recentemente",
|
"No recently visited rooms": "Nenhuma sala foi visitada recentemente",
|
||||||
"Custom Tag": "Etiqueta personalizada",
|
"Custom Tag": "Etiqueta personalizada",
|
||||||
"Joining room …": "Entrando na sala…",
|
"Joining room …": "Entrando na sala…",
|
||||||
"Loading …": "Carregando…",
|
"Loading …": "Carregando…",
|
||||||
|
@ -1870,7 +1870,7 @@
|
||||||
"Appearance": "Aparência",
|
"Appearance": "Aparência",
|
||||||
"Show rooms with unread messages first": "Mostrar salas não lidas em primeiro",
|
"Show rooms with unread messages first": "Mostrar salas não lidas em primeiro",
|
||||||
"Show previews of messages": "Mostrar pré-visualizações de mensagens",
|
"Show previews of messages": "Mostrar pré-visualizações de mensagens",
|
||||||
"Sort by": "Ordenar por",
|
"Sort by": "Classificar por",
|
||||||
"Activity": "Atividade recente",
|
"Activity": "Atividade recente",
|
||||||
"A-Z": "A-Z",
|
"A-Z": "A-Z",
|
||||||
"Unknown Command": "Comando desconhecido",
|
"Unknown Command": "Comando desconhecido",
|
||||||
|
@ -1908,7 +1908,7 @@
|
||||||
"Cancel replying to a message": "Cancelar resposta à mensagem",
|
"Cancel replying to a message": "Cancelar resposta à mensagem",
|
||||||
"Toggle microphone mute": "Ativar/desativar som do microfone",
|
"Toggle microphone mute": "Ativar/desativar som do microfone",
|
||||||
"Toggle video on/off": "Ativar/desativar o vídeo",
|
"Toggle video on/off": "Ativar/desativar o vídeo",
|
||||||
"Scroll up/down in the timeline": "Rolar para cima/baixo na linha do tempo",
|
"Scroll up/down in the timeline": "Rolar para cima/baixo na conversa",
|
||||||
"Dismiss read marker and jump to bottom": "Ignorar o marcador de leitura e ir para o final",
|
"Dismiss read marker and jump to bottom": "Ignorar o marcador de leitura e ir para o final",
|
||||||
"Jump to oldest unread message": "Ir para a mensagem não lida mais antiga",
|
"Jump to oldest unread message": "Ir para a mensagem não lida mais antiga",
|
||||||
"Upload a file": "Enviar um arquivo",
|
"Upload a file": "Enviar um arquivo",
|
||||||
|
@ -2225,7 +2225,7 @@
|
||||||
"This homeserver does not support login using email address.": "Este servidor local não suporta login usando endereço de e-mail.",
|
"This homeserver does not support login using email address.": "Este servidor local não suporta login usando endereço de e-mail.",
|
||||||
"or another cross-signing capable Matrix client": "ou outro cliente Matrix com capacidade de autoverificação",
|
"or another cross-signing capable Matrix client": "ou outro cliente Matrix com capacidade de autoverificação",
|
||||||
"For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "Quando há muitas mensagens, isso pode levar algum tempo. Por favor, não recarregue o seu cliente enquanto isso.",
|
"For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "Quando há muitas mensagens, isso pode levar algum tempo. Por favor, não recarregue o seu cliente enquanto isso.",
|
||||||
"<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>Atenção</b>: ao atualizar uma sala, <i>os membros da sala não são migrados automaticamente para a versão atualizada da sala.</i> Publicaremos um link da nova sala na versão antiga da sala - os membros da sala terão que clicar neste link para entrar na nova sala.",
|
"<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>Atenção</b>: ao atualizar uma sala, <i>os participantes da sala não são migrados automaticamente para a versão atualizada da sala.</i> Publicaremos um link da nova sala na versão antiga da sala - os participantes da sala terão que clicar neste link para entrar na nova sala.",
|
||||||
"Upgrade this room to the recommended room version": "Atualizar a versão desta sala",
|
"Upgrade this room to the recommended room version": "Atualizar a versão desta sala",
|
||||||
"this room": "esta sala",
|
"this room": "esta sala",
|
||||||
"View older messages in %(roomName)s.": "Ler mensagens antigas em %(roomName)s.",
|
"View older messages in %(roomName)s.": "Ler mensagens antigas em %(roomName)s.",
|
||||||
|
@ -2261,9 +2261,9 @@
|
||||||
"Send report": "Enviar relatório",
|
"Send report": "Enviar relatório",
|
||||||
"A browser extension is preventing the request.": "Uma extensão do navegador está impedindo a solicitação.",
|
"A browser extension is preventing the request.": "Uma extensão do navegador está impedindo a solicitação.",
|
||||||
"The server has denied your request.": "O servidor recusou a sua solicitação.",
|
"The server has denied your request.": "O servidor recusou a sua solicitação.",
|
||||||
"No files visible in this room": "Não há arquivos nesta sala",
|
"No files visible in this room": "Nenhum arquivo nesta sala",
|
||||||
"Attach files from chat or just drag and drop them anywhere in a room.": "Anexe arquivos na conversa, ou simplesmente arraste e solte arquivos em qualquer lugar na sala.",
|
"Attach files from chat or just drag and drop them anywhere in a room.": "Anexe arquivos na conversa, ou simplesmente arraste e solte arquivos em qualquer lugar na sala.",
|
||||||
"You have no visible notifications in this room.": "Não há notificações nesta sala.",
|
"You have no visible notifications in this room.": "Nenhuma notificação nesta sala",
|
||||||
"Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).": "Sua nova conta (%(newAccountId)s) foi registrada, mas você já está conectado a uma conta diferente (%(loggedInUserId)s).",
|
"Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).": "Sua nova conta (%(newAccountId)s) foi registrada, mas você já está conectado a uma conta diferente (%(loggedInUserId)s).",
|
||||||
"%(brand)s Desktop": "%(brand)s para Computador",
|
"%(brand)s Desktop": "%(brand)s para Computador",
|
||||||
"%(brand)s iOS": "%(brand)s para iOS",
|
"%(brand)s iOS": "%(brand)s para iOS",
|
||||||
|
@ -2283,5 +2283,17 @@
|
||||||
"Page Down": "Page Down",
|
"Page Down": "Page Down",
|
||||||
"You've successfully verified %(deviceName)s (%(deviceId)s)!": "Você confirmou %(deviceName)s (%(deviceId)s) com êxito!",
|
"You've successfully verified %(deviceName)s (%(deviceId)s)!": "Você confirmou %(deviceName)s (%(deviceId)s) com êxito!",
|
||||||
"Verified": "Confirmado",
|
"Verified": "Confirmado",
|
||||||
"Close dialog or context menu": "Fechar caixa de diálogo ou menu"
|
"Close dialog or context menu": "Fechar caixa de diálogo ou menu",
|
||||||
|
"Try scrolling up in the timeline to see if there are any earlier ones.": "Tente rolar para cima na conversa para ver se há mensagens anteriores.",
|
||||||
|
"Navigate composer history": "Ver o histórico de mensagens enviadas no campo de texto",
|
||||||
|
"Unexpected server error trying to leave the room": "Erro inesperado no servidor, ao tentar sair da sala",
|
||||||
|
"Error leaving room": "Erro ao sair da sala",
|
||||||
|
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Protótipo da segunda versão das Comunidades. Requer servidor principal compatível. Altamente experimental - use com cautela.",
|
||||||
|
"Space": "Barra de espaço",
|
||||||
|
"People you know on %(brand)s": "Pessoas que você conhece em %(brand)s",
|
||||||
|
"Show": "Mostrar",
|
||||||
|
"Send %(count)s invites|other": "Enviar %(count)s convites",
|
||||||
|
"Send %(count)s invites|one": "Enviar %(count)s convite",
|
||||||
|
"Community ID: +<localpart />:%(domain)s": "ID da comunidade: +<localpart />:%(domain)s",
|
||||||
|
"Enter name": "Digitar nome"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2420,5 +2420,40 @@
|
||||||
"Error leaving room": "Ошибка при выходе из комнаты",
|
"Error leaving room": "Ошибка при выходе из комнаты",
|
||||||
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Прототипы сообщества v2. Требуется совместимый домашний сервер. Очень экспериментально - используйте с осторожностью.",
|
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Прототипы сообщества v2. Требуется совместимый домашний сервер. Очень экспериментально - используйте с осторожностью.",
|
||||||
"Explore rooms in %(communityName)s": "Посмотреть комнаты в %(communityName)s",
|
"Explore rooms in %(communityName)s": "Посмотреть комнаты в %(communityName)s",
|
||||||
"Set up Secure Backup": "Настроить безопасное резервное копирование"
|
"Set up Secure Backup": "Настроить безопасное резервное копирование",
|
||||||
|
"Explore community rooms": "Просмотреть комнаты сообщества",
|
||||||
|
"Information": "Информация",
|
||||||
|
"Add another email": "Добавить еще один адрес электронной почты",
|
||||||
|
"People you know on %(brand)s": "Люди, которых вы знаете в %(brand)s",
|
||||||
|
"Show": "Показать",
|
||||||
|
"Send %(count)s invites|other": "Отправить %(count)s приглашений",
|
||||||
|
"Send %(count)s invites|one": "Отправить %(count)s приглашение",
|
||||||
|
"Invite people to join %(communityName)s": "Пригласите людей вступить в %(communityName)s",
|
||||||
|
"There was an error creating your community. The name may be taken or the server is unable to process your request.": "При создании сообщества произошла ошибка. Имя может быть занято или сервер не может обработать ваш запрос.",
|
||||||
|
"Community ID: +<localpart />:%(domain)s": "ID сообщества: +<localpart />:%(domain)s",
|
||||||
|
"Use this when referencing your community to others. The community ID cannot be changed.": "Используйте это при обращении к другим людям. ID сообщества не может быть изменён.",
|
||||||
|
"You can change this later if needed.": "При необходимости вы можете изменить это позже.",
|
||||||
|
"What's the name of your community or team?": "Как называется ваше сообщество или команда?",
|
||||||
|
"Enter name": "Введите имя",
|
||||||
|
"Add image (optional)": "Добавить изображение (необязательно)",
|
||||||
|
"An image will help people identify your community.": "Изображение поможет людям идентифицировать ваше сообщество.",
|
||||||
|
"Create a room in %(communityName)s": "Создать комнату в %(communityName)s",
|
||||||
|
"Create community": "Создать сообщество",
|
||||||
|
"Cross-signing and secret storage are ready for use.": "Кросс-подпись и секретное хранилище готовы к использованию.",
|
||||||
|
"Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.": "Кросс-подпись готова к использованию, но секретное хранилище в настоящее время не используется для резервного копирования ваших ключей.",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Приватные комнаты можно найти и присоединиться только по приглашению. Публичные комнаты может найти и присоединиться к ним кто угодно.",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Приватные комнаты можно найти и присоединиться только по приглашению. Публичные комнаты могут находить и присоединяться к ним любые участники этого сообщества.",
|
||||||
|
"You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Вы можете включить это, если комната будет использоваться только для совместной работы с внутренними командами на вашем домашнем сервере. Это не может быть изменено позже.",
|
||||||
|
"You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "Вы можете отключить это, если комната будет использоваться для совместной работы с внешними командами, у которых есть собственный домашний сервер. Это не может быть изменено позже.",
|
||||||
|
"Block anyone not part of %(serverName)s from ever joining this room.": "Запретить кому-либо, не входящему в %(serverName)s, когда-либо присоединяться к этой комнате.",
|
||||||
|
"There was an error updating your community. The server is unable to process your request.": "Произошла ошибка в обновлении вашего сообщества. Сервер не может обработать ваш запрос.",
|
||||||
|
"Update community": "Обновить сообщество",
|
||||||
|
"May include members not in %(communityName)s": "Может включать участников, не входящих в %(communityName)s",
|
||||||
|
"Start a conversation with someone using their name, username (like <userId/>) or email address. This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>.": "Начните разговор с кем-нибудь, используя имя, имя пользователя (например, <userId/>) или адрес электронной почты. Это не пригласит их в %(communityName)s. Чтобы пригласить кого-нибудь в %(communityName)s, нажмите <a>здесь</a>.",
|
||||||
|
"Failed to find the general chat for this community": "Не удалось найти общий чат для этого сообщества",
|
||||||
|
"Community settings": "Настройки сообщества",
|
||||||
|
"User settings": "Пользовательские настройки",
|
||||||
|
"Community and user menu": "Сообщество и меню пользователя",
|
||||||
|
"Privacy": "Конфиденциальность",
|
||||||
|
"Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "Добавляет ( ͡° ͜ʖ ͡°) к текстовому сообщению"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1798,5 +1798,18 @@
|
||||||
"Security & privacy": "Bezpečnosť & súkromie",
|
"Security & privacy": "Bezpečnosť & súkromie",
|
||||||
"All settings": "Všetky nastavenia",
|
"All settings": "Všetky nastavenia",
|
||||||
"Feedback": "Spätná väzba",
|
"Feedback": "Spätná väzba",
|
||||||
"Indexed rooms:": "Indexované miestnosti:"
|
"Indexed rooms:": "Indexované miestnosti:",
|
||||||
|
"Unexpected server error trying to leave the room": "Neočakávaná chyba servera pri pokuse opustiť miestnosť",
|
||||||
|
"Emoji picker": "Vybrať emoji",
|
||||||
|
"Send a reply…": "Odoslať odpoveď…",
|
||||||
|
"Send a message…": "Odoslať správu…",
|
||||||
|
"Bold": "Tučné",
|
||||||
|
"Italics": "Kurzíva",
|
||||||
|
"Strikethrough": "Preškrtnuté",
|
||||||
|
"Leave Room": "Opustiť miestnosť",
|
||||||
|
"Direct message": "Priama správa",
|
||||||
|
"Security": "Zabezpečenie",
|
||||||
|
"Send a Direct Message": "Poslať priamu správu",
|
||||||
|
"User menu": "Používateľské menu",
|
||||||
|
"Toggle Italics": "Prepnúť kurzíva"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2428,5 +2428,39 @@
|
||||||
"Error leaving room": "離開聊天室時發生錯誤",
|
"Error leaving room": "離開聊天室時發生錯誤",
|
||||||
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "社群 v2 原型。需要相容的家伺服器。高度實驗性,小心使用。",
|
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "社群 v2 原型。需要相容的家伺服器。高度實驗性,小心使用。",
|
||||||
"Explore rooms in %(communityName)s": "在 %(communityName)s 中探索聊天室",
|
"Explore rooms in %(communityName)s": "在 %(communityName)s 中探索聊天室",
|
||||||
"Set up Secure Backup": "設定安全備份"
|
"Set up Secure Backup": "設定安全備份",
|
||||||
|
"Information": "資訊",
|
||||||
|
"Add another email": "新增其他電子郵件",
|
||||||
|
"People you know on %(brand)s": "在 %(brand)s 上您認識的人們",
|
||||||
|
"Send %(count)s invites|other": "傳送 %(count)s 個邀請",
|
||||||
|
"Send %(count)s invites|one": "傳送 %(count)s 個邀請",
|
||||||
|
"Invite people to join %(communityName)s": "邀請夥伴加入 %(communityName)s",
|
||||||
|
"There was an error creating your community. The name may be taken or the server is unable to process your request.": "建立您的社群時發生錯誤。名稱已被使用或伺服器無法處理您的請求。",
|
||||||
|
"Community ID: +<localpart />:%(domain)s": "社群 ID:+<localpart />:%(domain)s",
|
||||||
|
"Use this when referencing your community to others. The community ID cannot be changed.": "在將您的社群推薦給其他人時使用此功能。社群 ID 無法變更。",
|
||||||
|
"You can change this later if needed.": "若需要,您可以在稍後變更這個。",
|
||||||
|
"What's the name of your community or team?": "您的社群或團隊的名稱是什麼?",
|
||||||
|
"Enter name": "輸入名稱",
|
||||||
|
"Add image (optional)": "新增圖片(選擇性)",
|
||||||
|
"An image will help people identify your community.": "圖片可以協助人們辨識您的社群。",
|
||||||
|
"Create community": "建立社群",
|
||||||
|
"Explore community rooms": "探索社群聊天室",
|
||||||
|
"Create a room in %(communityName)s": "在 %(communityName)s 中建立聊天室",
|
||||||
|
"Cross-signing and secret storage are ready for use.": "交叉簽章與秘密儲存空間已可使用。",
|
||||||
|
"Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.": "交叉簽章已準備好使用,但目前未使用秘密儲存空間備份您的金鑰。",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "私人聊天室僅能透過邀請找到與加入。公開聊天室則任何人都可以找到並加入。",
|
||||||
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "私人聊天室僅能透過邀請找到與加入。公開聊天室則任何在此社群的人都可以找到並加入。",
|
||||||
|
"You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "如果聊天室僅用於與在您的家伺服器上的內部團隊協作的話,可以啟用此功能。這無法在稍後變更。",
|
||||||
|
"You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "如果聊天室會用於與有自己的家伺服器的外部團隊協作的話,可以停用此功能。這無法在稍後變更。",
|
||||||
|
"Block anyone not part of %(serverName)s from ever joining this room.": "阻止任何不屬於 %(serverName)s 的人加入此聊天室。",
|
||||||
|
"There was an error updating your community. The server is unable to process your request.": "更新您的社群時發生錯誤。伺服器無法處理您的請求。",
|
||||||
|
"Update community": "更新社群",
|
||||||
|
"May include members not in %(communityName)s": "可能包含不在 %(communityName)s 中的成員",
|
||||||
|
"Start a conversation with someone using their name, username (like <userId/>) or email address. This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>.": "使用某人的名稱、使用者名稱(如 <userId/>)或電子郵件地址開始與他們對話。這不會邀請他們加入 %(communityName)s。要邀請某人加入 %(communityName)s,請點擊<a>此處</a>。",
|
||||||
|
"Failed to find the general chat for this community": "找不到此社群的一般聊天紀錄",
|
||||||
|
"Community settings": "社群設定",
|
||||||
|
"User settings": "使用者設定",
|
||||||
|
"Community and user menu": "社群與使用者選單",
|
||||||
|
"Privacy": "隱私",
|
||||||
|
"Prepends ( ͡° ͜ʖ ͡°) to a plain-text message": "把 ( ͡° ͜ʖ ͡°) 加在純文字訊息前"
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,6 +105,9 @@ export default class Resizer {
|
||||||
if (this.classNames.resizing) {
|
if (this.classNames.resizing) {
|
||||||
this.container.classList.add(this.classNames.resizing);
|
this.container.classList.add(this.classNames.resizing);
|
||||||
}
|
}
|
||||||
|
if (this.config.onResizeStart) {
|
||||||
|
this.config.onResizeStart();
|
||||||
|
}
|
||||||
|
|
||||||
const {sizer, distributor} = this._createSizerAndDistributor(resizeHandle);
|
const {sizer, distributor} = this._createSizerAndDistributor(resizeHandle);
|
||||||
distributor.start();
|
distributor.start();
|
||||||
|
@ -119,6 +122,9 @@ export default class Resizer {
|
||||||
if (this.classNames.resizing) {
|
if (this.classNames.resizing) {
|
||||||
this.container.classList.remove(this.classNames.resizing);
|
this.container.classList.remove(this.classNames.resizing);
|
||||||
}
|
}
|
||||||
|
if (this.config.onResizeStop) {
|
||||||
|
this.config.onResizeStop();
|
||||||
|
}
|
||||||
distributor.finish();
|
distributor.finish();
|
||||||
body.removeEventListener("mouseup", finishResize, false);
|
body.removeEventListener("mouseup", finishResize, false);
|
||||||
document.removeEventListener("mouseleave", finishResize, false);
|
document.removeEventListener("mouseleave", finishResize, false);
|
||||||
|
|
|
@ -56,6 +56,18 @@ export default class Sizer {
|
||||||
return this.vertical ? this.container.offsetTop : this.container.offsetLeft;
|
return this.vertical ? this.container.offsetTop : this.container.offsetLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return {number} container offset to document */
|
||||||
|
_getPageOffset() {
|
||||||
|
let element = this.container;
|
||||||
|
let offset = 0;
|
||||||
|
while (element) {
|
||||||
|
const pos = this.vertical ? element.offsetTop : element.offsetLeft;
|
||||||
|
offset = offset + pos;
|
||||||
|
element = element.offsetParent;
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
setItemSize(item, size) {
|
setItemSize(item, size) {
|
||||||
if (this.vertical) {
|
if (this.vertical) {
|
||||||
item.style.height = `${Math.round(size)}px`;
|
item.style.height = `${Math.round(size)}px`;
|
||||||
|
@ -80,9 +92,9 @@ export default class Sizer {
|
||||||
offsetFromEvent(event) {
|
offsetFromEvent(event) {
|
||||||
const pos = this.vertical ? event.pageY : event.pageX;
|
const pos = this.vertical ? event.pageY : event.pageX;
|
||||||
if (this.reverse) {
|
if (this.reverse) {
|
||||||
return (this._getOffset() + this.getTotalSize()) - pos;
|
return (this._getPageOffset() + this.getTotalSize()) - pos;
|
||||||
} else {
|
} else {
|
||||||
return pos - this._getOffset();
|
return pos - this._getPageOffset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -566,7 +566,7 @@ export const SETTINGS: {[setting: string]: ISetting} = {
|
||||||
},
|
},
|
||||||
"lastRightPanelPhaseForRoom": {
|
"lastRightPanelPhaseForRoom": {
|
||||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
default: RightPanelPhases.RoomMemberInfo,
|
default: RightPanelPhases.RoomSummary,
|
||||||
},
|
},
|
||||||
"lastRightPanelPhaseForGroup": {
|
"lastRightPanelPhaseForGroup": {
|
||||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
|
@ -607,4 +607,8 @@ export const SETTINGS: {[setting: string]: ISetting} = {
|
||||||
displayName: _td("Enable experimental, compact IRC style layout"),
|
displayName: _td("Enable experimental, compact IRC style layout"),
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
"Widgets.pinned": {
|
||||||
|
supportedLevels: LEVELS_ROOM_OR_ACCOUNT,
|
||||||
|
default: {},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,11 +18,10 @@ import { SettingLevel } from "./SettingLevel";
|
||||||
|
|
||||||
export type CallbackFn = (changedInRoomId: string, atLevel: SettingLevel, newValAtLevel: any) => void;
|
export type CallbackFn = (changedInRoomId: string, atLevel: SettingLevel, newValAtLevel: any) => void;
|
||||||
|
|
||||||
const IRRELEVANT_ROOM = Symbol("any room");
|
const IRRELEVANT_ROOM: string = null;
|
||||||
|
|
||||||
interface RoomWatcherMap {
|
interface RoomWatcherMap {
|
||||||
// @ts-ignore - TS wants string-only keys but we know better - https://github.com/Microsoft/TypeScript/issues/1863
|
[roomId: string]: CallbackFn[];
|
||||||
[roomId: string | symbol]: CallbackFn[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,7 +68,7 @@ export class WatchManager {
|
||||||
if (!inRoomId) {
|
if (!inRoomId) {
|
||||||
// Fire updates to all the individual room watchers too, as they probably
|
// Fire updates to all the individual room watchers too, as they probably
|
||||||
// care about the change higher up.
|
// care about the change higher up.
|
||||||
callbacks.push(...Object.values(roomWatchers).reduce((r, a) => [...r, ...a], []));
|
callbacks.push(...Object.values(roomWatchers).flat(1));
|
||||||
} else if (roomWatchers[IRRELEVANT_ROOM]) {
|
} else if (roomWatchers[IRRELEVANT_ROOM]) {
|
||||||
callbacks.push(...roomWatchers[IRRELEVANT_ROOM]);
|
callbacks.push(...roomWatchers[IRRELEVANT_ROOM]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,8 @@ interface RightPanelStoreState {
|
||||||
lastRoomPhase: RightPanelPhases;
|
lastRoomPhase: RightPanelPhases;
|
||||||
lastGroupPhase: RightPanelPhases;
|
lastGroupPhase: RightPanelPhases;
|
||||||
|
|
||||||
|
previousPhase?: RightPanelPhases;
|
||||||
|
|
||||||
// Extra information about the last phase
|
// Extra information about the last phase
|
||||||
lastRoomPhaseParams: {[key: string]: any};
|
lastRoomPhaseParams: {[key: string]: any};
|
||||||
}
|
}
|
||||||
|
@ -89,6 +91,10 @@ export default class RightPanelStore extends Store<ActionPayload> {
|
||||||
return this.state.lastGroupPhase;
|
return this.state.lastGroupPhase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get previousPhase(): RightPanelPhases | null {
|
||||||
|
return RIGHT_PANEL_PHASES_NO_ARGS.includes(this.state.previousPhase) ? this.state.previousPhase : null;
|
||||||
|
}
|
||||||
|
|
||||||
get visibleRoomPanelPhase(): RightPanelPhases {
|
get visibleRoomPanelPhase(): RightPanelPhases {
|
||||||
return this.isOpenForRoom ? this.roomPanelPhase : null;
|
return this.isOpenForRoom ? this.roomPanelPhase : null;
|
||||||
}
|
}
|
||||||
|
@ -176,23 +182,27 @@ export default class RightPanelStore extends Store<ActionPayload> {
|
||||||
if (targetPhase === this.state.lastGroupPhase) {
|
if (targetPhase === this.state.lastGroupPhase) {
|
||||||
this.setState({
|
this.setState({
|
||||||
showGroupPanel: !this.state.showGroupPanel,
|
showGroupPanel: !this.state.showGroupPanel,
|
||||||
|
previousPhase: null,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
lastGroupPhase: targetPhase,
|
lastGroupPhase: targetPhase,
|
||||||
showGroupPanel: true,
|
showGroupPanel: true,
|
||||||
|
previousPhase: this.state.lastGroupPhase,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (targetPhase === this.state.lastRoomPhase && !refireParams) {
|
if (targetPhase === this.state.lastRoomPhase && !refireParams) {
|
||||||
this.setState({
|
this.setState({
|
||||||
showRoomPanel: !this.state.showRoomPanel,
|
showRoomPanel: !this.state.showRoomPanel,
|
||||||
|
previousPhase: null,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
lastRoomPhase: targetPhase,
|
lastRoomPhase: targetPhase,
|
||||||
showRoomPanel: true,
|
showRoomPanel: true,
|
||||||
lastRoomPhaseParams: refireParams || {},
|
lastRoomPhaseParams: refireParams || {},
|
||||||
|
previousPhase: this.state.lastRoomPhase,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ export enum RightPanelPhases {
|
||||||
NotificationPanel = 'NotificationPanel',
|
NotificationPanel = 'NotificationPanel',
|
||||||
RoomMemberInfo = 'RoomMemberInfo',
|
RoomMemberInfo = 'RoomMemberInfo',
|
||||||
EncryptionPanel = 'EncryptionPanel',
|
EncryptionPanel = 'EncryptionPanel',
|
||||||
|
RoomSummary = 'RoomSummary',
|
||||||
|
Widget = 'Widget',
|
||||||
|
|
||||||
Room3pidMemberInfo = 'Room3pidMemberInfo',
|
Room3pidMemberInfo = 'Room3pidMemberInfo',
|
||||||
// Group stuff
|
// Group stuff
|
||||||
|
@ -34,6 +36,7 @@ export enum RightPanelPhases {
|
||||||
// These are the phases that are safe to persist (the ones that don't require additional
|
// These are the phases that are safe to persist (the ones that don't require additional
|
||||||
// arguments).
|
// arguments).
|
||||||
export const RIGHT_PANEL_PHASES_NO_ARGS = [
|
export const RIGHT_PANEL_PHASES_NO_ARGS = [
|
||||||
|
RightPanelPhases.RoomSummary,
|
||||||
RightPanelPhases.NotificationPanel,
|
RightPanelPhases.NotificationPanel,
|
||||||
RightPanelPhases.FilePanel,
|
RightPanelPhases.FilePanel,
|
||||||
RightPanelPhases.RoomMemberList,
|
RightPanelPhases.RoomMemberList,
|
||||||
|
|
|
@ -93,13 +93,13 @@ class WidgetEchoStore extends EventEmitter {
|
||||||
if (this._roomWidgetEcho[roomId] === undefined) this._roomWidgetEcho[roomId] = {};
|
if (this._roomWidgetEcho[roomId] === undefined) this._roomWidgetEcho[roomId] = {};
|
||||||
|
|
||||||
this._roomWidgetEcho[roomId][widgetId] = state;
|
this._roomWidgetEcho[roomId][widgetId] = state;
|
||||||
this.emit('update');
|
this.emit('update', roomId, widgetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeRoomWidgetEcho(roomId, widgetId) {
|
removeRoomWidgetEcho(roomId, widgetId) {
|
||||||
delete this._roomWidgetEcho[roomId][widgetId];
|
delete this._roomWidgetEcho[roomId][widgetId];
|
||||||
if (Object.keys(this._roomWidgetEcho[roomId]).length === 0) delete this._roomWidgetEcho[roomId];
|
if (Object.keys(this._roomWidgetEcho[roomId]).length === 0) delete this._roomWidgetEcho[roomId];
|
||||||
this.emit('update');
|
this.emit('update', roomId, widgetId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
209
src/stores/WidgetStore.ts
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
/*
|
||||||
|
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 { Room } from "matrix-js-sdk/src/models/room";
|
||||||
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
|
|
||||||
|
import { ActionPayload } from "../dispatcher/payloads";
|
||||||
|
import { AsyncStoreWithClient } from "./AsyncStoreWithClient";
|
||||||
|
import defaultDispatcher from "../dispatcher/dispatcher";
|
||||||
|
import SettingsStore from "../settings/SettingsStore";
|
||||||
|
import WidgetEchoStore from "../stores/WidgetEchoStore";
|
||||||
|
import WidgetUtils from "../utils/WidgetUtils";
|
||||||
|
import {SettingLevel} from "../settings/SettingLevel";
|
||||||
|
import {WidgetType} from "../widgets/WidgetType";
|
||||||
|
import {UPDATE_EVENT} from "./AsyncStore";
|
||||||
|
|
||||||
|
interface IState {}
|
||||||
|
|
||||||
|
export interface IApp {
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
roomId: string;
|
||||||
|
eventId: string;
|
||||||
|
creatorUserId: string;
|
||||||
|
waitForIframeLoad?: boolean;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
avatar_url: string; // MSC2765 https://github.com/matrix-org/matrix-doc/pull/2765
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IRoomWidgets {
|
||||||
|
widgets: IApp[];
|
||||||
|
pinned: Record<string, boolean>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO consolidate WidgetEchoStore into this
|
||||||
|
// TODO consolidate ActiveWidgetStore into this
|
||||||
|
export default class WidgetStore extends AsyncStoreWithClient<IState> {
|
||||||
|
private static internalInstance = new WidgetStore();
|
||||||
|
|
||||||
|
private widgetMap = new Map<string, IApp>();
|
||||||
|
private roomMap = new Map<string, IRoomWidgets>();
|
||||||
|
|
||||||
|
private constructor() {
|
||||||
|
super(defaultDispatcher, {});
|
||||||
|
|
||||||
|
SettingsStore.watchSetting("Widgets.pinned", null, this.onPinnedWidgetsChange);
|
||||||
|
WidgetEchoStore.on("update", this.onWidgetEchoStoreUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static get instance(): WidgetStore {
|
||||||
|
return WidgetStore.internalInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private initRoom(roomId: string) {
|
||||||
|
if (!this.roomMap.has(roomId)) {
|
||||||
|
this.roomMap.set(roomId, {
|
||||||
|
pinned: {},
|
||||||
|
widgets: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async onReady(): Promise<any> {
|
||||||
|
this.matrixClient.on("RoomState.events", this.onRoomStateEvents);
|
||||||
|
this.matrixClient.getRooms().forEach((room: Room) => {
|
||||||
|
const pinned = SettingsStore.getValue("Widgets.pinned", room.roomId);
|
||||||
|
|
||||||
|
if (pinned || WidgetUtils.getRoomWidgets(room).length) {
|
||||||
|
this.initRoom(room.roomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pinned) {
|
||||||
|
this.getRoom(room.roomId).pinned = pinned;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadRoomWidgets(room);
|
||||||
|
});
|
||||||
|
this.emit(UPDATE_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async onNotReady(): Promise<any> {
|
||||||
|
this.matrixClient.off("RoomState.events", this.onRoomStateEvents);
|
||||||
|
this.widgetMap = new Map();
|
||||||
|
this.roomMap = new Map();
|
||||||
|
await this.reset({});
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't need this, but our contract says we do.
|
||||||
|
protected async onAction(payload: ActionPayload) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private onWidgetEchoStoreUpdate = (roomId: string, widgetId: string) => {
|
||||||
|
this.initRoom(roomId);
|
||||||
|
this.loadRoomWidgets(this.matrixClient.getRoom(roomId));
|
||||||
|
this.emit(UPDATE_EVENT);
|
||||||
|
};
|
||||||
|
|
||||||
|
private generateApps(room: Room): IApp[] {
|
||||||
|
return WidgetEchoStore.getEchoedRoomWidgets(room.roomId, WidgetUtils.getRoomWidgets(room)).map((ev) => {
|
||||||
|
return WidgetUtils.makeAppConfig(
|
||||||
|
ev.getStateKey(), ev.getContent(), ev.getSender(), ev.getRoomId(), ev.getId(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadRoomWidgets(room: Room) {
|
||||||
|
const roomInfo = this.roomMap.get(room.roomId);
|
||||||
|
roomInfo.widgets = [];
|
||||||
|
this.generateApps(room).forEach(app => {
|
||||||
|
this.widgetMap.set(app.id, app);
|
||||||
|
roomInfo.widgets.push(app);
|
||||||
|
});
|
||||||
|
this.emit(room.roomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private onRoomStateEvents = (ev: MatrixEvent) => {
|
||||||
|
if (ev.getType() !== "im.vector.modular.widgets") return;
|
||||||
|
const roomId = ev.getRoomId();
|
||||||
|
this.initRoom(roomId);
|
||||||
|
this.loadRoomWidgets(this.matrixClient.getRoom(roomId));
|
||||||
|
this.emit(UPDATE_EVENT);
|
||||||
|
};
|
||||||
|
|
||||||
|
public getRoomId = (widgetId: string) => {
|
||||||
|
const app = this.widgetMap.get(widgetId);
|
||||||
|
if (!app) return null;
|
||||||
|
return app.roomId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getRoom = (roomId: string) => {
|
||||||
|
return this.roomMap.get(roomId);
|
||||||
|
};
|
||||||
|
|
||||||
|
private onPinnedWidgetsChange = (settingName: string, roomId: string) => {
|
||||||
|
this.initRoom(roomId);
|
||||||
|
this.getRoom(roomId).pinned = SettingsStore.getValue(settingName, roomId);
|
||||||
|
this.emit(roomId);
|
||||||
|
this.emit(UPDATE_EVENT);
|
||||||
|
};
|
||||||
|
|
||||||
|
public isPinned(widgetId: string) {
|
||||||
|
const roomId = this.getRoomId(widgetId);
|
||||||
|
const roomInfo = this.getRoom(roomId);
|
||||||
|
|
||||||
|
let pinned = roomInfo && roomInfo.pinned[widgetId];
|
||||||
|
// Jitsi widgets should be pinned by default
|
||||||
|
if (pinned === undefined && WidgetType.JITSI.matches(this.widgetMap.get(widgetId).type)) pinned = true;
|
||||||
|
return pinned;
|
||||||
|
}
|
||||||
|
|
||||||
|
public canPin(widgetId: string) {
|
||||||
|
// only allow pinning up to a max of two as we do not yet have grid splits
|
||||||
|
// the only case it will go to three is if you have two and then a Jitsi gets added
|
||||||
|
const roomId = this.getRoomId(widgetId);
|
||||||
|
const roomInfo = this.getRoom(roomId);
|
||||||
|
return roomInfo && Object.keys(roomInfo.pinned).length < 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public pinWidget(widgetId: string) {
|
||||||
|
this.setPinned(widgetId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public unpinWidget(widgetId: string) {
|
||||||
|
this.setPinned(widgetId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private setPinned(widgetId: string, value: boolean) {
|
||||||
|
const roomId = this.getRoomId(widgetId);
|
||||||
|
const roomInfo = this.getRoom(roomId);
|
||||||
|
if (!roomInfo) return;
|
||||||
|
roomInfo.pinned[widgetId] = value;
|
||||||
|
|
||||||
|
// Clean up the pinned record
|
||||||
|
Object.keys(roomInfo).forEach(wId => {
|
||||||
|
if (!roomInfo.widgets.some(w => w.id === wId)) {
|
||||||
|
delete roomInfo.pinned[wId];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
SettingsStore.setValue("Widgets.pinned", roomId, SettingLevel.ROOM_ACCOUNT, roomInfo.pinned);
|
||||||
|
this.emit(roomId);
|
||||||
|
this.emit(UPDATE_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getApps(room: Room, pinned?: boolean): IApp[] {
|
||||||
|
const roomInfo = this.getRoom(room.roomId);
|
||||||
|
if (!roomInfo) return [];
|
||||||
|
if (pinned) {
|
||||||
|
return roomInfo.widgets.filter(app => this.isPinned(app.id));
|
||||||
|
}
|
||||||
|
return roomInfo.widgets;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.mxWidgetStore = WidgetStore.instance;
|
|
@ -31,6 +31,19 @@ export default class ResizeNotifier extends EventEmitter {
|
||||||
// with default options, will call fn once at first call, and then every x ms
|
// with default options, will call fn once at first call, and then every x ms
|
||||||
// if there was another call in that timespan
|
// if there was another call in that timespan
|
||||||
this._throttledMiddlePanel = throttle(() => this.emit("middlePanelResized"), 200);
|
this._throttledMiddlePanel = throttle(() => this.emit("middlePanelResized"), 200);
|
||||||
|
this._isResizing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isResizing() {
|
||||||
|
return this._isResizing;
|
||||||
|
}
|
||||||
|
|
||||||
|
startResizing() {
|
||||||
|
this._isResizing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
stopResizing() {
|
||||||
|
this._isResizing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_noisyMiddlePanel() {
|
_noisyMiddlePanel() {
|
||||||
|
|
|
@ -18,7 +18,13 @@ interface Room {
|
||||||
roomId: string;
|
roomId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function shieldStatusForRoom(client: Client, room: Room): Promise<string> {
|
export enum E2EStatus {
|
||||||
|
Warning = "warning",
|
||||||
|
Verified = "verified",
|
||||||
|
Normal = "normal"
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function shieldStatusForRoom(client: Client, room: Room): Promise<E2EStatus> {
|
||||||
const members = (await room.getEncryptionTargetMembers()).map(({userId}) => userId);
|
const members = (await room.getEncryptionTargetMembers()).map(({userId}) => userId);
|
||||||
const inDMMap = !!DMRoomMap.shared().getUserIdForRoomId(room.roomId);
|
const inDMMap = !!DMRoomMap.shared().getUserIdForRoomId(room.roomId);
|
||||||
|
|
||||||
|
@ -33,7 +39,7 @@ export async function shieldStatusForRoom(client: Client, room: Room): Promise<s
|
||||||
/* Alarm if any unverified users were verified before. */
|
/* Alarm if any unverified users were verified before. */
|
||||||
for (const userId of unverified) {
|
for (const userId of unverified) {
|
||||||
if (client.checkUserTrust(userId).wasCrossSigningVerified()) {
|
if (client.checkUserTrust(userId).wasCrossSigningVerified()) {
|
||||||
return "warning";
|
return E2EStatus.Warning;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,9 +56,9 @@ export async function shieldStatusForRoom(client: Client, room: Room): Promise<s
|
||||||
return !client.checkDeviceTrust(userId, deviceId).isVerified();
|
return !client.checkDeviceTrust(userId, deviceId).isVerified();
|
||||||
});
|
});
|
||||||
if (anyDeviceNotVerified) {
|
if (anyDeviceNotVerified) {
|
||||||
return "warning";
|
return E2EStatus.Warning;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return unverified.length === 0 ? "verified" : "normal";
|
return unverified.length === 0 ? E2EStatus.Verified : E2EStatus.Normal;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import {Capability} from "../widgets/WidgetApi";
|
||||||
import {Room} from "matrix-js-sdk/src/models/room";
|
import {Room} from "matrix-js-sdk/src/models/room";
|
||||||
import {WidgetType} from "../widgets/WidgetType";
|
import {WidgetType} from "../widgets/WidgetType";
|
||||||
import {objectClone} from "./objects";
|
import {objectClone} from "./objects";
|
||||||
|
import {_t} from "../languageHandler";
|
||||||
|
|
||||||
export default class WidgetUtils {
|
export default class WidgetUtils {
|
||||||
/* Returns true if user is able to send state events to modify widgets in this room
|
/* Returns true if user is able to send state events to modify widgets in this room
|
||||||
|
@ -405,6 +406,7 @@ export default class WidgetUtils {
|
||||||
app.creatorUserId = senderUserId;
|
app.creatorUserId = senderUserId;
|
||||||
|
|
||||||
app.id = appId;
|
app.id = appId;
|
||||||
|
app.roomId = roomId;
|
||||||
app.eventId = eventId;
|
app.eventId = eventId;
|
||||||
app.name = app.name || app.type;
|
app.name = app.name || app.type;
|
||||||
|
|
||||||
|
@ -448,16 +450,21 @@ export default class WidgetUtils {
|
||||||
return encodeURIComponent(`${widgetLocation}::${widgetUrl}`);
|
return encodeURIComponent(`${widgetLocation}::${widgetUrl}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getLocalJitsiWrapperUrl(opts: {forLocalRender?: boolean}={}) {
|
static getLocalJitsiWrapperUrl(opts: {forLocalRender?: boolean, auth?: string}={}) {
|
||||||
// NB. we can't just encodeURIComponent all of these because the $ signs need to be there
|
// NB. we can't just encodeURIComponent all of these because the $ signs need to be there
|
||||||
const queryString = [
|
const queryStringParts = [
|
||||||
'conferenceDomain=$domain',
|
'conferenceDomain=$domain',
|
||||||
'conferenceId=$conferenceId',
|
'conferenceId=$conferenceId',
|
||||||
'isAudioOnly=$isAudioOnly',
|
'isAudioOnly=$isAudioOnly',
|
||||||
'displayName=$matrix_display_name',
|
'displayName=$matrix_display_name',
|
||||||
'avatarUrl=$matrix_avatar_url',
|
'avatarUrl=$matrix_avatar_url',
|
||||||
'userId=$matrix_user_id',
|
'userId=$matrix_user_id',
|
||||||
].join('&');
|
'roomId=$matrix_room_id',
|
||||||
|
];
|
||||||
|
if (opts.auth) {
|
||||||
|
queryStringParts.push(`auth=${opts.auth}`);
|
||||||
|
}
|
||||||
|
const queryString = queryStringParts.join('&');
|
||||||
|
|
||||||
let baseUrl = window.location;
|
let baseUrl = window.location;
|
||||||
if (window.location.protocol !== "https:" && !opts.forLocalRender) {
|
if (window.location.protocol !== "https:" && !opts.forLocalRender) {
|
||||||
|
@ -471,4 +478,33 @@ export default class WidgetUtils {
|
||||||
const url = new URL("jitsi.html#" + queryString, baseUrl); // this strips hash fragment from baseUrl
|
const url = new URL("jitsi.html#" + queryString, baseUrl); // this strips hash fragment from baseUrl
|
||||||
return url.href;
|
return url.href;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getWidgetName(app) {
|
||||||
|
return app?.name?.trim() || _t("Unknown App");
|
||||||
|
}
|
||||||
|
|
||||||
|
static getWidgetDataTitle(app) {
|
||||||
|
return app?.data?.title?.trim() || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static editWidget(room, app) {
|
||||||
|
// TODO: Open the right manager for the widget
|
||||||
|
if (SettingsStore.getValue("feature_many_integration_managers")) {
|
||||||
|
IntegrationManagers.sharedInstance().openAll(room, 'type_' + app.type, app.id);
|
||||||
|
} else {
|
||||||
|
IntegrationManagers.sharedInstance().getPrimaryManager().open(room, 'type_' + app.type, app.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static snapshotWidget(app) {
|
||||||
|
console.log("Requesting widget snapshot");
|
||||||
|
ActiveWidgetStore.getWidgetMessaging(app.id).getScreenshot().catch((err) => {
|
||||||
|
console.error("Failed to get screenshot", err);
|
||||||
|
}).then((screenshot) => {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'picture_snapshot',
|
||||||
|
file: screenshot,
|
||||||
|
}, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -332,6 +332,9 @@ export function tryTransformPermalinkToLocalHref(permalink: string): string {
|
||||||
if (permalinkParts.roomIdOrAlias) {
|
if (permalinkParts.roomIdOrAlias) {
|
||||||
const eventIdPart = permalinkParts.eventId ? `/${permalinkParts.eventId}` : '';
|
const eventIdPart = permalinkParts.eventId ? `/${permalinkParts.eventId}` : '';
|
||||||
permalink = `#/room/${permalinkParts.roomIdOrAlias}${eventIdPart}`;
|
permalink = `#/room/${permalinkParts.roomIdOrAlias}${eventIdPart}`;
|
||||||
|
if (permalinkParts.viaServers.length > 0) {
|
||||||
|
permalink += new SpecPermalinkConstructor().encodeServerCandidates(permalinkParts.viaServers);
|
||||||
|
}
|
||||||
} else if (permalinkParts.groupId) {
|
} else if (permalinkParts.groupId) {
|
||||||
permalink = `#/group/${permalinkParts.groupId}`;
|
permalink = `#/group/${permalinkParts.groupId}`;
|
||||||
} else if (permalinkParts.userId) {
|
} else if (permalinkParts.userId) {
|
||||||
|
|
|
@ -34,6 +34,30 @@ export class Jitsi {
|
||||||
return this.domain || 'jitsi.riot.im';
|
return this.domain || 'jitsi.riot.im';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for auth needed by looking up a well-known file
|
||||||
|
*
|
||||||
|
* If the file does not exist, we assume no auth.
|
||||||
|
*
|
||||||
|
* See https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification
|
||||||
|
*/
|
||||||
|
public async getJitsiAuth(): Promise<string|null> {
|
||||||
|
if (!this.preferredDomain) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let data;
|
||||||
|
try {
|
||||||
|
const response = await fetch(`https://${this.preferredDomain}/.well-known/element/jitsi`);
|
||||||
|
data = await response.json();
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (data.auth) {
|
||||||
|
return data.auth;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public start() {
|
public start() {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
cli.on("WellKnown.client", this.update);
|
cli.on("WellKnown.client", this.update);
|
||||||
|
|
|
@ -34,6 +34,7 @@ export enum KnownWidgetActions {
|
||||||
GetCapabilities = "capabilities",
|
GetCapabilities = "capabilities",
|
||||||
SendEvent = "send_event",
|
SendEvent = "send_event",
|
||||||
UpdateVisibility = "visibility",
|
UpdateVisibility = "visibility",
|
||||||
|
GetOpenIDCredentials = "get_openid",
|
||||||
ReceiveOpenIDCredentials = "openid_credentials",
|
ReceiveOpenIDCredentials = "openid_credentials",
|
||||||
SetAlwaysOnScreen = "set_always_on_screen",
|
SetAlwaysOnScreen = "set_always_on_screen",
|
||||||
ClientReady = "im.vector.ready",
|
ClientReady = "im.vector.ready",
|
||||||
|
@ -64,6 +65,13 @@ export interface FromWidgetRequest extends WidgetRequest {
|
||||||
response: any;
|
response: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface OpenIDCredentials {
|
||||||
|
accessToken: string;
|
||||||
|
tokenType: string;
|
||||||
|
matrixServerName: string;
|
||||||
|
expiresIn: number;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles Element <--> Widget interactions for embedded/standalone widgets.
|
* Handles Element <--> Widget interactions for embedded/standalone widgets.
|
||||||
*
|
*
|
||||||
|
@ -73,10 +81,12 @@ export interface FromWidgetRequest extends WidgetRequest {
|
||||||
* the given promise resolves.
|
* the given promise resolves.
|
||||||
*/
|
*/
|
||||||
export class WidgetApi extends EventEmitter {
|
export class WidgetApi extends EventEmitter {
|
||||||
private origin: string;
|
private readonly origin: string;
|
||||||
private inFlightRequests: { [requestId: string]: (reply: FromWidgetRequest) => void } = {};
|
private inFlightRequests: { [requestId: string]: (reply: FromWidgetRequest) => void } = {};
|
||||||
private readyPromise: Promise<any>;
|
private readonly readyPromise: Promise<any>;
|
||||||
private readyPromiseResolve: () => void;
|
private readyPromiseResolve: () => void;
|
||||||
|
private openIDCredentialsCallback: () => void;
|
||||||
|
public openIDCredentials: OpenIDCredentials;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set this to true if your widget is expecting a ready message from the client. False otherwise (default).
|
* Set this to true if your widget is expecting a ready message from the client. False otherwise (default).
|
||||||
|
@ -120,6 +130,10 @@ export class WidgetApi extends EventEmitter {
|
||||||
// Acknowledge that we're shut down now
|
// Acknowledge that we're shut down now
|
||||||
this.replyToRequest(<ToWidgetRequest>payload, {});
|
this.replyToRequest(<ToWidgetRequest>payload, {});
|
||||||
});
|
});
|
||||||
|
} else if (payload.action === KnownWidgetActions.ReceiveOpenIDCredentials) {
|
||||||
|
// Save OpenID credentials
|
||||||
|
this.setOpenIDCredentials(<ToWidgetRequest>payload);
|
||||||
|
this.replyToRequest(<ToWidgetRequest>payload, {});
|
||||||
} else {
|
} else {
|
||||||
console.warn(`[WidgetAPI] Got unexpected action: ${payload.action}`);
|
console.warn(`[WidgetAPI] Got unexpected action: ${payload.action}`);
|
||||||
}
|
}
|
||||||
|
@ -134,6 +148,32 @@ export class WidgetApi extends EventEmitter {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setOpenIDCredentials(value: WidgetRequest) {
|
||||||
|
const data = value.data;
|
||||||
|
if (data.state === 'allowed') {
|
||||||
|
this.openIDCredentials = {
|
||||||
|
accessToken: data.access_token,
|
||||||
|
tokenType: data.token_type,
|
||||||
|
matrixServerName: data.matrix_server_name,
|
||||||
|
expiresIn: data.expires_in,
|
||||||
|
}
|
||||||
|
} else if (data.state === 'blocked') {
|
||||||
|
this.openIDCredentials = null;
|
||||||
|
}
|
||||||
|
if (['allowed', 'blocked'].includes(data.state) && this.openIDCredentialsCallback) {
|
||||||
|
this.openIDCredentialsCallback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public requestOpenIDCredentials(credentialsResponseCallback: () => void) {
|
||||||
|
this.openIDCredentialsCallback = credentialsResponseCallback;
|
||||||
|
this.callAction(
|
||||||
|
KnownWidgetActions.GetOpenIDCredentials,
|
||||||
|
{},
|
||||||
|
this.setOpenIDCredentials,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public waitReady(): Promise<any> {
|
public waitReady(): Promise<any> {
|
||||||
return this.readyPromise;
|
return this.readyPromise;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
|
const {openRoomSummaryCard} = require("./rightpanel");
|
||||||
|
|
||||||
async function openMemberInfo(session, name) {
|
async function openMemberInfo(session, name) {
|
||||||
const membersAndNames = await getMembersInMemberlist(session);
|
const membersAndNames = await getMembersInMemberlist(session);
|
||||||
|
@ -63,17 +64,11 @@ module.exports.verifyDeviceForUser = async function(session, name, expectedDevic
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getMembersInMemberlist(session) {
|
async function getMembersInMemberlist(session) {
|
||||||
const memberPanelButton = await session.query(".mx_RightPanel_membersButton");
|
await openRoomSummaryCard(session);
|
||||||
try {
|
const memberPanelButton = await session.query(".mx_RoomSummaryCard_icon_people");
|
||||||
await session.query(".mx_RightPanel_headerButton_highlight", 500);
|
// We are back at the room summary card
|
||||||
// Right panel is open - toggle it to ensure it's the member list
|
await memberPanelButton.click();
|
||||||
// Sometimes our tests have this opened to MemberInfo
|
|
||||||
await memberPanelButton.click();
|
|
||||||
await memberPanelButton.click();
|
|
||||||
} catch (e) {
|
|
||||||
// Member list is closed - open it
|
|
||||||
await memberPanelButton.click();
|
|
||||||
}
|
|
||||||
const memberNameElements = await session.queryAll(".mx_MemberList .mx_EntityTile_name");
|
const memberNameElements = await session.queryAll(".mx_MemberList .mx_EntityTile_name");
|
||||||
return Promise.all(memberNameElements.map(async (el) => {
|
return Promise.all(memberNameElements.map(async (el) => {
|
||||||
return {label: el, displayName: await session.innerText(el)};
|
return {label: el, displayName: await session.innerText(el)};
|
||||||
|
|
43
test/end-to-end-tests/src/usecases/rightpanel.js
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports.openRoomRightPanel = async function(session) {
|
||||||
|
try {
|
||||||
|
await session.query('.mx_RoomHeader .mx_RightPanel_headerButton_highlight[aria-label="Room Info"]');
|
||||||
|
} catch (e) {
|
||||||
|
// If the room summary is not yet open, open it
|
||||||
|
const roomSummaryButton = await session.query('.mx_RoomHeader .mx_AccessibleButton[aria-label="Room Info"]');
|
||||||
|
await roomSummaryButton.click();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.goBackToRoomSummaryCard = async function(session) {
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
try {
|
||||||
|
const backButton = await session.query(".mx_BaseCard_back", 500);
|
||||||
|
// Right panel is open to the wrong thing - go back up to the Room Summary Card
|
||||||
|
// Sometimes our tests have this opened to MemberInfo
|
||||||
|
await backButton.click();
|
||||||
|
} catch (e) {
|
||||||
|
break; // stop trying to go further back
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.openRoomSummaryCard = async function(session) {
|
||||||
|
await module.exports.openRoomRightPanel(session);
|
||||||
|
await module.exports.goBackToRoomSummaryCard(session);
|
||||||
|
};
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
|
const {openRoomSummaryCard} = require("./rightpanel");
|
||||||
const {acceptDialog} = require('./dialog');
|
const {acceptDialog} = require('./dialog');
|
||||||
|
|
||||||
async function setSettingsToggle(session, toggle, enabled) {
|
async function setSettingsToggle(session, toggle, enabled) {
|
||||||
|
@ -45,7 +46,10 @@ async function findTabs(session) {
|
||||||
/// XXX delay is needed here, possibly because the header is being rerendered
|
/// XXX delay is needed here, possibly because the header is being rerendered
|
||||||
/// click doesn't do anything otherwise
|
/// click doesn't do anything otherwise
|
||||||
await session.delay(1000);
|
await session.delay(1000);
|
||||||
const settingsButton = await session.query(".mx_RoomHeader .mx_AccessibleButton[aria-label=Settings]");
|
|
||||||
|
await openRoomSummaryCard(session);
|
||||||
|
|
||||||
|
const settingsButton = await session.query(".mx_RoomSummaryCard_icon_settings");
|
||||||
await settingsButton.click();
|
await settingsButton.click();
|
||||||
|
|
||||||
//find tabs
|
//find tabs
|
||||||
|
|
|
@ -7557,6 +7557,11 @@ retry@^0.10.0:
|
||||||
resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4"
|
resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4"
|
||||||
integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=
|
integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=
|
||||||
|
|
||||||
|
rfc4648@^1.4.0:
|
||||||
|
version "1.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/rfc4648/-/rfc4648-1.4.0.tgz#c75b2856ad2e2d588b6ddb985d556f1f7f2a2abd"
|
||||||
|
integrity sha512-3qIzGhHlMHA6PoT6+cdPKZ+ZqtxkIvg8DZGKA5z6PQ33/uuhoJ+Ws/D/J9rXW6gXodgH8QYlz2UCl+sdUDmNIg==
|
||||||
|
|
||||||
rimraf@2.6.3:
|
rimraf@2.6.3:
|
||||||
version "2.6.3"
|
version "2.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
|
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
|
||||||
|
|