Merge remote-tracking branch 'upstream/develop' into compact-reply-rendering
This commit is contained in:
commit
c31967dc97
111 changed files with 6271 additions and 2212 deletions
|
@ -21,14 +21,14 @@ caret nodes (more on that later).
|
||||||
For these reasons it doesn't use `innerText`, `textContent` or anything similar.
|
For these reasons it doesn't use `innerText`, `textContent` or anything similar.
|
||||||
The model addresses any content in the editor within as an offset within this string.
|
The model addresses any content in the editor within as an offset within this string.
|
||||||
The caret position is thus also converted from a position in the DOM tree
|
The caret position is thus also converted from a position in the DOM tree
|
||||||
to an offset in the content string. This happens in `getCaretOffsetAndText` in `dom.js`.
|
to an offset in the content string. This happens in `getCaretOffsetAndText` in `dom.ts`.
|
||||||
|
|
||||||
Once the content string and caret offset is calculated, it is passed to the `update()`
|
Once the content string and caret offset is calculated, it is passed to the `update()`
|
||||||
method of the model. The model first calculates the same content string of its current parts,
|
method of the model. The model first calculates the same content string of its current parts,
|
||||||
basically just concatenating their text. It then looks for differences between
|
basically just concatenating their text. It then looks for differences between
|
||||||
the current and the new content string. The diffing algorithm is very basic,
|
the current and the new content string. The diffing algorithm is very basic,
|
||||||
and assumes there is only one change around the caret offset,
|
and assumes there is only one change around the caret offset,
|
||||||
so this should be very inexpensive. See `diff.js` for details.
|
so this should be very inexpensive. See `diff.ts` for details.
|
||||||
|
|
||||||
The result of the diffing is the strings that were added and/or removed from
|
The result of the diffing is the strings that were added and/or removed from
|
||||||
the current content. These differences are then applied to the parts,
|
the current content. These differences are then applied to the parts,
|
||||||
|
@ -51,7 +51,7 @@ which relate poorly to text input or changes, and don't need the `beforeinput` e
|
||||||
which isn't broadly supported yet.
|
which isn't broadly supported yet.
|
||||||
|
|
||||||
Once the parts of the model are updated, the DOM of the editor is then reconciled
|
Once the parts of the model are updated, the DOM of the editor is then reconciled
|
||||||
with the new model state, see `renderModel` in `render.js` for this.
|
with the new model state, see `renderModel` in `render.ts` for this.
|
||||||
If the model didn't reject the input and didn't make any additional changes,
|
If the model didn't reject the input and didn't make any additional changes,
|
||||||
this won't make any changes to the DOM at all, and should thus be fairly efficient.
|
this won't make any changes to the DOM at all, and should thus be fairly efficient.
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,7 @@
|
||||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
||||||
"matrix-widget-api": "^0.1.0-beta.13",
|
"matrix-widget-api": "^0.1.0-beta.13",
|
||||||
"minimist": "^1.2.5",
|
"minimist": "^1.2.5",
|
||||||
|
"opus-recorder": "^8.0.3",
|
||||||
"pako": "^2.0.3",
|
"pako": "^2.0.3",
|
||||||
"parse5": "^6.0.1",
|
"parse5": "^6.0.1",
|
||||||
"png-chunks-extract": "^1.0.0",
|
"png-chunks-extract": "^1.0.0",
|
||||||
|
|
|
@ -395,6 +395,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
||||||
border: 1px solid $accent-color;
|
border: 1px solid $accent-color;
|
||||||
color: $accent-color;
|
color: $accent-color;
|
||||||
background-color: $button-secondary-bg-color;
|
background-color: $button-secondary-bg-color;
|
||||||
|
font-family: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Dialog button:last-child {
|
.mx_Dialog button:last-child {
|
||||||
|
|
|
@ -111,12 +111,13 @@
|
||||||
@import "./views/elements/_AddressSelector.scss";
|
@import "./views/elements/_AddressSelector.scss";
|
||||||
@import "./views/elements/_AddressTile.scss";
|
@import "./views/elements/_AddressTile.scss";
|
||||||
@import "./views/elements/_DesktopBuildsNotice.scss";
|
@import "./views/elements/_DesktopBuildsNotice.scss";
|
||||||
@import "./views/elements/_DirectorySearchBox.scss";
|
|
||||||
@import "./views/elements/_DesktopCapturerSourcePicker.scss";
|
@import "./views/elements/_DesktopCapturerSourcePicker.scss";
|
||||||
|
@import "./views/elements/_DirectorySearchBox.scss";
|
||||||
@import "./views/elements/_Dropdown.scss";
|
@import "./views/elements/_Dropdown.scss";
|
||||||
@import "./views/elements/_EditableItemList.scss";
|
@import "./views/elements/_EditableItemList.scss";
|
||||||
@import "./views/elements/_ErrorBoundary.scss";
|
@import "./views/elements/_ErrorBoundary.scss";
|
||||||
@import "./views/elements/_EventListSummary.scss";
|
@import "./views/elements/_EventListSummary.scss";
|
||||||
|
@import "./views/elements/_FacePile.scss";
|
||||||
@import "./views/elements/_Field.scss";
|
@import "./views/elements/_Field.scss";
|
||||||
@import "./views/elements/_FormButton.scss";
|
@import "./views/elements/_FormButton.scss";
|
||||||
@import "./views/elements/_ImageView.scss";
|
@import "./views/elements/_ImageView.scss";
|
||||||
|
@ -213,13 +214,13 @@
|
||||||
@import "./views/rooms/_SendMessageComposer.scss";
|
@import "./views/rooms/_SendMessageComposer.scss";
|
||||||
@import "./views/rooms/_Stickers.scss";
|
@import "./views/rooms/_Stickers.scss";
|
||||||
@import "./views/rooms/_TopUnreadMessagesBar.scss";
|
@import "./views/rooms/_TopUnreadMessagesBar.scss";
|
||||||
|
@import "./views/rooms/_VoiceRecordComposerTile.scss";
|
||||||
@import "./views/rooms/_WhoIsTypingTile.scss";
|
@import "./views/rooms/_WhoIsTypingTile.scss";
|
||||||
@import "./views/settings/_AvatarSetting.scss";
|
@import "./views/settings/_AvatarSetting.scss";
|
||||||
@import "./views/settings/_CrossSigningPanel.scss";
|
@import "./views/settings/_CrossSigningPanel.scss";
|
||||||
@import "./views/settings/_DevicesPanel.scss";
|
@import "./views/settings/_DevicesPanel.scss";
|
||||||
@import "./views/settings/_E2eAdvancedPanel.scss";
|
@import "./views/settings/_E2eAdvancedPanel.scss";
|
||||||
@import "./views/settings/_EmailAddresses.scss";
|
@import "./views/settings/_EmailAddresses.scss";
|
||||||
@import "./views/settings/_SpellCheckLanguages.scss";
|
|
||||||
@import "./views/settings/_IntegrationManager.scss";
|
@import "./views/settings/_IntegrationManager.scss";
|
||||||
@import "./views/settings/_Notifications.scss";
|
@import "./views/settings/_Notifications.scss";
|
||||||
@import "./views/settings/_PhoneNumbers.scss";
|
@import "./views/settings/_PhoneNumbers.scss";
|
||||||
|
@ -227,6 +228,7 @@
|
||||||
@import "./views/settings/_SecureBackupPanel.scss";
|
@import "./views/settings/_SecureBackupPanel.scss";
|
||||||
@import "./views/settings/_SetIdServer.scss";
|
@import "./views/settings/_SetIdServer.scss";
|
||||||
@import "./views/settings/_SetIntegrationManager.scss";
|
@import "./views/settings/_SetIntegrationManager.scss";
|
||||||
|
@import "./views/settings/_SpellCheckLanguages.scss";
|
||||||
@import "./views/settings/_UpdateCheckButton.scss";
|
@import "./views/settings/_UpdateCheckButton.scss";
|
||||||
@import "./views/settings/tabs/_SettingsTab.scss";
|
@import "./views/settings/tabs/_SettingsTab.scss";
|
||||||
@import "./views/settings/tabs/room/_GeneralRoomSettingsTab.scss";
|
@import "./views/settings/tabs/room/_GeneralRoomSettingsTab.scss";
|
||||||
|
|
|
@ -130,6 +130,10 @@ $roomListCollapsedWidth: 68px;
|
||||||
mask-repeat: no-repeat;
|
mask-repeat: no-repeat;
|
||||||
background: $secondary-fg-color;
|
background: $secondary-fg-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.mx_LeftPanel_exploreButton_space::before {
|
||||||
|
mask-image: url('$(res)/img/element-icons/roomlist/browse.svg');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ limitations under the License.
|
||||||
// keep border thickness consistent to prevent movement
|
// keep border thickness consistent to prevent movement
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
padding: 2px;
|
padding: 1px;
|
||||||
|
|
||||||
// Create a flexbox for the icons (easier to manage)
|
// Create a flexbox for the icons (easier to manage)
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -63,7 +63,7 @@ $activeBorderColor: $secondary-fg-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AutoHideScrollbar {
|
.mx_AutoHideScrollbar {
|
||||||
padding: 16px 0;
|
padding: 8px 0 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceButton_toggleCollapse {
|
.mx_SpaceButton_toggleCollapse {
|
||||||
|
@ -99,7 +99,6 @@ $activeBorderColor: $secondary-fg-color;
|
||||||
|
|
||||||
.mx_SpaceButton {
|
.mx_SpaceButton {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
margin-bottom: 2px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 4px 4px 4px 0;
|
padding: 4px 4px 4px 0;
|
||||||
|
@ -147,9 +146,6 @@ $activeBorderColor: $secondary-fg-color;
|
||||||
|
|
||||||
.mx_SpaceButton_toggleCollapse {
|
.mx_SpaceButton_toggleCollapse {
|
||||||
width: $gutterSize;
|
width: $gutterSize;
|
||||||
// negative margin to place it correctly even with the complex
|
|
||||||
// 4px selection border each space button has when active
|
|
||||||
margin-right: -4px;
|
|
||||||
height: 20px;
|
height: 20px;
|
||||||
mask-position: center;
|
mask-position: center;
|
||||||
mask-size: 20px;
|
mask-size: 20px;
|
||||||
|
@ -334,20 +330,20 @@ $activeBorderColor: $secondary-fg-color;
|
||||||
mask-image: url('$(res)/img/element-icons/leave.svg');
|
mask-image: url('$(res)/img/element-icons/leave.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpacePanel_iconHome::before {
|
|
||||||
mask-image: url('$(res)/img/element-icons/roomlist/home.svg');
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SpacePanel_iconMembers::before {
|
.mx_SpacePanel_iconMembers::before {
|
||||||
mask-image: url('$(res)/img/element-icons/room/members.svg');
|
mask-image: url('$(res)/img/element-icons/room/members.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpacePanel_iconPlus::before {
|
.mx_SpacePanel_iconPlus::before {
|
||||||
mask-image: url('$(res)/img/element-icons/plus.svg');
|
mask-image: url('$(res)/img/element-icons/roomlist/plus-circle.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SpacePanel_iconHash::before {
|
||||||
|
mask-image: url('$(res)/img/element-icons/roomlist/hash-circle.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpacePanel_iconExplore::before {
|
.mx_SpacePanel_iconExplore::before {
|
||||||
mask-image: url('$(res)/img/element-icons/roomlist/explore.svg');
|
mask-image: url('$(res)/img/element-icons/roomlist/browse.svg');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,8 @@ limitations under the License.
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
.mx_BaseAvatar {
|
.mx_BaseAvatar {
|
||||||
margin-right: 16px;
|
margin-right: 12px;
|
||||||
|
align-self: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_BaseAvatar_image {
|
.mx_BaseAvatar_image {
|
||||||
|
@ -47,6 +48,7 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
|
font-weight: 400;
|
||||||
color: $secondary-fg-color;
|
color: $secondary-fg-color;
|
||||||
font-size: $font-15px;
|
font-size: $font-15px;
|
||||||
line-height: $font-24px;
|
line-height: $font-24px;
|
||||||
|
@ -55,38 +57,71 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_Dialog_content {
|
.mx_Dialog_content {
|
||||||
// TODO fix scrollbar
|
|
||||||
//display: flex;
|
|
||||||
//flex-direction: column;
|
|
||||||
//height: calc(100% - 80px);
|
|
||||||
|
|
||||||
.mx_AccessibleButton_kind_link {
|
.mx_AccessibleButton_kind_link {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SearchBox {
|
.mx_SearchBox {
|
||||||
margin: 24px 0 28px;
|
margin: 24px 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SpaceRoomDirectory_noResults {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
font-size: $font-15px;
|
||||||
|
line-height: $font-24px;
|
||||||
|
color: $secondary-fg-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_listHeader {
|
.mx_SpaceRoomDirectory_listHeader {
|
||||||
display: flex;
|
display: flex;
|
||||||
font-size: $font-12px;
|
min-height: 32px;
|
||||||
line-height: $font-15px;
|
align-items: center;
|
||||||
color: $secondary-fg-color;
|
font-size: $font-15px;
|
||||||
|
line-height: $font-24px;
|
||||||
|
color: $primary-fg-color;
|
||||||
|
|
||||||
.mx_FormButton {
|
.mx_AccessibleButton {
|
||||||
margin-bottom: 8px;
|
padding: 2px 8px;
|
||||||
|
font-weight: normal;
|
||||||
|
|
||||||
|
& + .mx_AccessibleButton {
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> span {
|
> span {
|
||||||
margin: auto 0 0 auto;
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SpaceRoomDirectory_error {
|
||||||
|
position: relative;
|
||||||
|
font-weight: $font-semi-bold;
|
||||||
|
color: $notice-primary-color;
|
||||||
|
font-size: $font-15px;
|
||||||
|
line-height: $font-18px;
|
||||||
|
margin: 20px auto 12px;
|
||||||
|
padding-left: 24px;
|
||||||
|
width: max-content;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
left: 0;
|
||||||
|
background-image: url("$(res)/img/element-icons/warning-badge.svg");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_list {
|
.mx_SpaceRoomDirectory_list {
|
||||||
margin-top: 8px;
|
margin-top: 16px;
|
||||||
|
padding-bottom: 40px;
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_roomCount {
|
.mx_SpaceRoomDirectory_roomCount {
|
||||||
> h3 {
|
> h3 {
|
||||||
|
@ -106,115 +141,141 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_subspace {
|
.mx_SpaceRoomDirectory_subspace {
|
||||||
margin-top: 8px;
|
.mx_BaseAvatar_image {
|
||||||
|
border-radius: 8px;
|
||||||
.mx_SpaceRoomDirectory_subspace_info {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
color: $secondary-fg-color;
|
|
||||||
font-weight: $font-semi-bold;
|
|
||||||
font-size: $font-12px;
|
|
||||||
line-height: $font-15px;
|
|
||||||
|
|
||||||
.mx_BaseAvatar {
|
|
||||||
margin-right: 12px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_BaseAvatar_image {
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_actions {
|
|
||||||
text-align: right;
|
|
||||||
height: min-content;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: 16px;
|
|
||||||
display: inline-flex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_subspace_children {
|
|
||||||
margin-left: 12px;
|
|
||||||
border-left: 2px solid $space-button-outline-color;
|
|
||||||
padding-left: 24px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_roomTile {
|
.mx_SpaceRoomDirectory_subspace_toggle {
|
||||||
padding: 16px;
|
position: absolute;
|
||||||
border-radius: 8px;
|
left: -1px;
|
||||||
border: 1px solid $space-button-outline-color;
|
top: 10px;
|
||||||
margin: 8px 0 16px;
|
height: 16px;
|
||||||
display: flex;
|
width: 16px;
|
||||||
min-height: 76px;
|
border-radius: 4px;
|
||||||
box-sizing: border-box;
|
background-color: $primary-bg-color;
|
||||||
|
|
||||||
&.mx_AccessibleButton:hover {
|
&::before {
|
||||||
background-color: rgba(141, 151, 165, 0.1);
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center;
|
||||||
|
background-color: $tertiary-fg-color;
|
||||||
|
mask-size: 16px;
|
||||||
|
transform: rotate(270deg);
|
||||||
|
mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.mx_SpaceRoomDirectory_subspace_toggle_shown::before {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SpaceRoomDirectory_subspace_children {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SpaceRoomDirectory_roomTile {
|
||||||
|
position: relative;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
min-height: 56px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 20px auto max-content;
|
||||||
|
grid-column-gap: 8px;
|
||||||
|
grid-row-gap: 6px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
.mx_BaseAvatar {
|
.mx_BaseAvatar {
|
||||||
margin-right: 16px;
|
grid-row: 1;
|
||||||
margin-top: 6px;
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SpaceRoomDirectory_roomTile_name {
|
||||||
|
font-weight: $font-semi-bold;
|
||||||
|
font-size: $font-15px;
|
||||||
|
line-height: $font-18px;
|
||||||
|
grid-row: 1;
|
||||||
|
grid-column: 2;
|
||||||
|
|
||||||
|
.mx_InfoTooltip {
|
||||||
|
display: inline;
|
||||||
|
margin-left: 12px;
|
||||||
|
color: $tertiary-fg-color;
|
||||||
|
font-size: $font-12px;
|
||||||
|
line-height: $font-15px;
|
||||||
|
|
||||||
|
.mx_InfoTooltip_icon {
|
||||||
|
margin-right: 4px;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: text-top;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_roomTile_info {
|
.mx_SpaceRoomDirectory_roomTile_info {
|
||||||
display: inline-block;
|
font-size: $font-14px;
|
||||||
font-size: $font-15px;
|
line-height: $font-18px;
|
||||||
flex-grow: 1;
|
color: $secondary-fg-color;
|
||||||
height: min-content;
|
grid-row: 2;
|
||||||
margin: auto 0;
|
grid-column: 1/3;
|
||||||
|
display: -webkit-box;
|
||||||
.mx_SpaceRoomDirectory_roomTile_name {
|
-webkit-box-orient: vertical;
|
||||||
font-weight: $font-semi-bold;
|
-webkit-line-clamp: 2;
|
||||||
line-height: $font-18px;
|
overflow: hidden;
|
||||||
}
|
|
||||||
.mx_SpaceRoomDirectory_roomTile_topic {
|
|
||||||
line-height: $font-24px;
|
|
||||||
color: $secondary-fg-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_roomTile_memberCount {
|
|
||||||
position: relative;
|
|
||||||
margin: auto 0 auto 24px;
|
|
||||||
padding: 0 0 0 28px;
|
|
||||||
line-height: $font-24px;
|
|
||||||
display: inline-block;
|
|
||||||
width: 32px;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
position: absolute;
|
|
||||||
content: '';
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
mask-position: center;
|
|
||||||
mask-repeat: no-repeat;
|
|
||||||
mask-size: contain;
|
|
||||||
background-color: $secondary-fg-color;
|
|
||||||
mask-image: url('$(res)/img/element-icons/community-members.svg');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_actions {
|
.mx_SpaceRoomDirectory_actions {
|
||||||
width: 180px;
|
|
||||||
text-align: right;
|
text-align: right;
|
||||||
margin-left: 28px;
|
margin-left: 20px;
|
||||||
display: inline-flex;
|
grid-column: 3;
|
||||||
align-items: center;
|
grid-row: 1/3;
|
||||||
|
|
||||||
.mx_AccessibleButton {
|
.mx_AccessibleButton {
|
||||||
vertical-align: middle;
|
padding: 8px 18px;
|
||||||
|
display: inline-block;
|
||||||
& + .mx_AccessibleButton {
|
visibility: hidden;
|
||||||
margin-left: 24px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_Checkbox {
|
||||||
|
display: inline-flex;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $groupFilterPanel-bg-color;
|
||||||
|
|
||||||
|
.mx_AccessibleButton {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SpaceRoomDirectory_roomTile,
|
||||||
|
.mx_SpaceRoomDirectory_subspace_children {
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
background-color: $groupFilterPanel-bg-color;
|
||||||
|
width: 1px;
|
||||||
|
height: 100%;
|
||||||
|
left: 6px;
|
||||||
|
top: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,4 +287,17 @@ limitations under the License.
|
||||||
color: $secondary-fg-color;
|
color: $secondary-fg-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> hr {
|
||||||
|
border: none;
|
||||||
|
height: 1px;
|
||||||
|
background-color: rgba(141, 151, 165, 0.2);
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SpaceRoomDirectory_createRoom {
|
||||||
|
display: block;
|
||||||
|
margin: 16px auto 0;
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,51 @@ limitations under the License.
|
||||||
|
|
||||||
$SpaceRoomViewInnerWidth: 428px;
|
$SpaceRoomViewInnerWidth: 428px;
|
||||||
|
|
||||||
|
@define-mixin SpacePillButton {
|
||||||
|
position: relative;
|
||||||
|
padding: 16px 32px 16px 72px;
|
||||||
|
width: 432px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid $input-border-color;
|
||||||
|
font-size: $font-15px;
|
||||||
|
margin: 20px 0;
|
||||||
|
|
||||||
|
> h3 {
|
||||||
|
font-weight: $font-semi-bold;
|
||||||
|
margin: 0 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> span {
|
||||||
|
color: $secondary-fg-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
top: 24px;
|
||||||
|
left: 20px;
|
||||||
|
mask-position: center;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-size: 24px;
|
||||||
|
background-color: $tertiary-fg-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: $accent-color;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
background-color: $accent-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
> span {
|
||||||
|
color: $primary-fg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomView {
|
.mx_SpaceRoomView {
|
||||||
.mx_MainSplit > div:first-child {
|
.mx_MainSplit > div:first-child {
|
||||||
padding: 80px 60px;
|
padding: 80px 60px;
|
||||||
|
@ -44,7 +89,7 @@ $SpaceRoomViewInnerWidth: 428px;
|
||||||
width: $SpaceRoomViewInnerWidth;
|
width: $SpaceRoomViewInnerWidth;
|
||||||
text-align: right; // button alignment right
|
text-align: right; // button alignment right
|
||||||
|
|
||||||
.mx_FormButton {
|
.mx_AccessibleButton_hasKind {
|
||||||
padding: 8px 22px;
|
padding: 8px 22px;
|
||||||
margin-left: 16px;
|
margin-left: 16px;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +122,6 @@ $SpaceRoomViewInnerWidth: 428px;
|
||||||
max-width: 480px;
|
max-width: 480px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
box-shadow: 2px 15px 30px $dialog-shadow-color;
|
box-shadow: 2px 15px 30px $dialog-shadow-color;
|
||||||
border: 1px solid $input-border-color;
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|
||||||
.mx_SpaceRoomView_preview_inviter {
|
.mx_SpaceRoomView_preview_inviter {
|
||||||
|
@ -109,53 +153,6 @@ $SpaceRoomViewInnerWidth: 428px;
|
||||||
margin: 20px 0 !important; // override default margin from above
|
margin: 20px 0 !important; // override default margin from above
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomView_preview_info {
|
|
||||||
color: $tertiary-fg-color;
|
|
||||||
font-size: $font-15px;
|
|
||||||
line-height: $font-24px;
|
|
||||||
margin: 20px 0;
|
|
||||||
|
|
||||||
.mx_SpaceRoomView_preview_info_public,
|
|
||||||
.mx_SpaceRoomView_preview_info_private {
|
|
||||||
padding-left: 20px;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
position: absolute;
|
|
||||||
content: "";
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
top: 0;
|
|
||||||
left: -2px;
|
|
||||||
mask-position: center;
|
|
||||||
mask-repeat: no-repeat;
|
|
||||||
background-color: $tertiary-fg-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SpaceRoomView_preview_info_public::before {
|
|
||||||
mask-size: 12px;
|
|
||||||
mask-image: url("$(res)/img/globe.svg");
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SpaceRoomView_preview_info_private::before {
|
|
||||||
mask-size: 14px;
|
|
||||||
mask-image: url("$(res)/img/element-icons/lock.svg");
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_AccessibleButton_kind_link {
|
|
||||||
color: inherit;
|
|
||||||
position: relative;
|
|
||||||
padding-left: 16px;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: "·"; // visual separator
|
|
||||||
position: absolute;
|
|
||||||
left: 6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_SpaceRoomView_preview_topic {
|
.mx_SpaceRoomView_preview_topic {
|
||||||
font-size: $font-14px;
|
font-size: $font-14px;
|
||||||
line-height: $font-22px;
|
line-height: $font-22px;
|
||||||
|
@ -209,36 +206,90 @@ $SpaceRoomViewInnerWidth: 428px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomView_landing_memberCount {
|
.mx_SpaceRoomView_landing_info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.mx_SpaceRoomView_info {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_FacePile {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: 12px;
|
||||||
|
|
||||||
|
.mx_FacePile_faces {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
> span:hover {
|
||||||
|
.mx_BaseAvatar {
|
||||||
|
filter: brightness(0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> span:first-child {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.mx_BaseAvatar {
|
||||||
|
filter: brightness(0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
z-index: 1;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
background: #ffffff; // white icon fill
|
||||||
|
mask-position: center;
|
||||||
|
mask-size: 24px;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-image: url('$(res)/img/element-icons/room/ellipsis.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SpaceRoomView_landing_inviteButton {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-left: 24px;
|
padding-left: 40px;
|
||||||
padding: 0 0 0 28px;
|
height: min-content;
|
||||||
line-height: $font-24px;
|
|
||||||
vertical-align: text-bottom;
|
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
content: '';
|
content: "";
|
||||||
width: 24px;
|
left: 8px;
|
||||||
height: 24px;
|
height: 16px;
|
||||||
top: 0;
|
width: 16px;
|
||||||
left: 0;
|
background: #ffffff; // white icon fill
|
||||||
mask-position: center;
|
mask-position: center;
|
||||||
|
mask-size: 16px;
|
||||||
mask-repeat: no-repeat;
|
mask-repeat: no-repeat;
|
||||||
mask-size: contain;
|
mask-image: url('$(res)/img/element-icons/room/invite.svg');
|
||||||
background-color: $accent-color;
|
|
||||||
mask-image: url('$(res)/img/element-icons/community-members.svg');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomView_landing_topic {
|
.mx_SpaceRoomView_landing_topic {
|
||||||
font-size: $font-15px;
|
font-size: $font-15px;
|
||||||
|
margin-top: 12px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> hr {
|
||||||
|
border: none;
|
||||||
|
height: 1px;
|
||||||
|
background-color: $groupFilterPanel-bg-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomView_landing_adminButtons {
|
.mx_SpaceRoomView_landing_adminButtons {
|
||||||
margin-top: 32px;
|
margin-top: 24px;
|
||||||
|
|
||||||
.mx_AccessibleButton {
|
.mx_AccessibleButton {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -247,9 +298,9 @@ $SpaceRoomViewInnerWidth: 428px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 72px 16px 0;
|
padding: 72px 16px 0;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
border: 1px solid $space-button-outline-color;
|
border: 1px solid $input-border-color;
|
||||||
margin-right: 28px;
|
margin-right: 28px;
|
||||||
margin-bottom: 28px;
|
margin-bottom: 20px;
|
||||||
font-size: $font-14px;
|
font-size: $font-14px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
|
@ -279,16 +330,6 @@ $SpaceRoomViewInnerWidth: 428px;
|
||||||
background: #ffffff; // white icon fill
|
background: #ffffff; // white icon fill
|
||||||
}
|
}
|
||||||
|
|
||||||
&.mx_SpaceRoomView_landing_inviteButton {
|
|
||||||
&::before {
|
|
||||||
background-color: $accent-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
mask-image: url('$(res)/img/element-icons/room/invite.svg');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.mx_SpaceRoomView_landing_addButton {
|
&.mx_SpaceRoomView_landing_addButton {
|
||||||
&::before {
|
&::before {
|
||||||
background-color: #ac3ba8;
|
background-color: #ac3ba8;
|
||||||
|
@ -321,74 +362,14 @@ $SpaceRoomViewInnerWidth: 428px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_list {
|
.mx_SearchBox {
|
||||||
max-width: 600px;
|
margin: 0 0 20px;
|
||||||
|
|
||||||
.mx_SpaceRoomDirectory_roomTile_actions {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomView_privateScope {
|
.mx_SpaceRoomView_privateScope {
|
||||||
.mx_RadioButton {
|
.mx_AccessibleButton {
|
||||||
width: $SpaceRoomViewInnerWidth;
|
@mixin SpacePillButton;
|
||||||
border-radius: 8px;
|
|
||||||
border: 1px solid $space-button-outline-color;
|
|
||||||
padding: 16px 16px 16px 72px;
|
|
||||||
margin-top: 36px;
|
|
||||||
cursor: pointer;
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
> div:first-of-type {
|
|
||||||
// hide radio dot
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RadioButton_content {
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
> h3 {
|
|
||||||
margin: 0 0 4px;
|
|
||||||
font-size: $font-15px;
|
|
||||||
font-weight: $font-semi-bold;
|
|
||||||
line-height: $font-18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> div {
|
|
||||||
color: $secondary-fg-color;
|
|
||||||
font-size: $font-15px;
|
|
||||||
line-height: $font-24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
height: 32px;
|
|
||||||
width: 32px;
|
|
||||||
top: 24px;
|
|
||||||
left: 20px;
|
|
||||||
background-color: $secondary-fg-color;
|
|
||||||
mask-repeat: no-repeat;
|
|
||||||
mask-position: center;
|
|
||||||
mask-size: contain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RadioButton_checked {
|
|
||||||
border-color: $accent-color;
|
|
||||||
|
|
||||||
.mx_RadioButton_content {
|
|
||||||
> div {
|
|
||||||
color: $primary-fg-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
background-color: $accent-color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceRoomView_privateScope_justMeButton::before {
|
.mx_SpaceRoomView_privateScope_justMeButton::before {
|
||||||
|
@ -435,3 +416,50 @@ $SpaceRoomViewInnerWidth: 428px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_SpaceRoomView_info {
|
||||||
|
color: $secondary-fg-color;
|
||||||
|
font-size: $font-15px;
|
||||||
|
line-height: $font-24px;
|
||||||
|
margin: 20px 0;
|
||||||
|
|
||||||
|
.mx_SpaceRoomView_info_public,
|
||||||
|
.mx_SpaceRoomView_info_private {
|
||||||
|
padding-left: 20px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
top: 0;
|
||||||
|
left: -2px;
|
||||||
|
mask-position: center;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
background-color: $tertiary-fg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SpaceRoomView_info_public::before {
|
||||||
|
mask-size: 12px;
|
||||||
|
mask-image: url("$(res)/img/globe.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_SpaceRoomView_info_private::before {
|
||||||
|
mask-size: 14px;
|
||||||
|
mask-image: url("$(res)/img/element-icons/lock.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_AccessibleButton_kind_link {
|
||||||
|
color: inherit;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "·"; // visual separator
|
||||||
|
position: absolute;
|
||||||
|
left: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
Copyright 2019-2021 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.
|
||||||
|
@ -158,6 +158,10 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_Toast_detail {
|
||||||
|
color: $secondary-fg-color;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_Toast_deviceID {
|
.mx_Toast_deviceID {
|
||||||
font-size: $font-10px;
|
font-size: $font-10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,6 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_ViewSource_label_left {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_ViewSource_label_right {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_ViewSource_separator {
|
.mx_ViewSource_separator {
|
||||||
clear: both;
|
clear: both;
|
||||||
border-bottom: 1px solid #e5e5e5;
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
|
|
@ -28,22 +28,23 @@ limitations under the License.
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
height: 80vh;
|
||||||
|
|
||||||
.mx_Dialog_title {
|
.mx_Dialog_title {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
.mx_BaseAvatar {
|
|
||||||
display: inline-flex;
|
|
||||||
margin: 5px 16px 5px 5px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_BaseAvatar_image {
|
.mx_BaseAvatar_image {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
vertical-align: unset;
|
vertical-align: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_BaseAvatar {
|
||||||
|
display: inline-flex;
|
||||||
|
margin: 5px 16px 5px 5px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
> h1 {
|
> h1 {
|
||||||
font-weight: $font-semi-bold;
|
font-weight: $font-semi-bold;
|
||||||
|
@ -101,6 +102,7 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_SearchBox {
|
.mx_SearchBox {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
flex-grow: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AddExistingToSpaceDialog_errorText {
|
.mx_AddExistingToSpaceDialog_errorText {
|
||||||
|
@ -112,7 +114,10 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AddExistingToSpaceDialog_content {
|
.mx_AddExistingToSpaceDialog_content {
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
.mx_AddExistingToSpaceDialog_noResults {
|
.mx_AddExistingToSpaceDialog_noResults {
|
||||||
|
display: block;
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -162,8 +167,14 @@ limitations under the License.
|
||||||
|
|
||||||
> span {
|
> span {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
font-size: $font-12px;
|
font-size: $font-14px;
|
||||||
line-height: $font-15px;
|
line-height: $font-15px;
|
||||||
|
font-weight: $font-semi-bold;
|
||||||
|
|
||||||
|
.mx_AccessibleButton {
|
||||||
|
font-size: inherit;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|
|
@ -49,7 +49,7 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_FormButton {
|
.mx_AccessibleButton_hasKind {
|
||||||
padding: 8px 22px;
|
padding: 8px 22px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
42
res/css/views/elements/_FacePile.scss
Normal file
42
res/css/views/elements/_FacePile.scss
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 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_FacePile {
|
||||||
|
.mx_FacePile_faces {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
> span + span {
|
||||||
|
margin-right: -8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_BaseAvatar_image {
|
||||||
|
border: 1px solid $primary-bg-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_BaseAvatar_initial {
|
||||||
|
margin: 1px; // to offset the border on the image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> span {
|
||||||
|
margin-left: 12px;
|
||||||
|
font-size: $font-14px;
|
||||||
|
line-height: $font-24px;
|
||||||
|
color: $tertiary-fg-color;
|
||||||
|
}
|
||||||
|
}
|
|
@ -66,6 +66,11 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.mx_BasicMessageComposer_input_disabled {
|
||||||
|
pointer-events: none;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_BasicMessageComposer_AutoCompleteWrapper {
|
.mx_BasicMessageComposer_AutoCompleteWrapper {
|
||||||
|
|
|
@ -227,6 +227,10 @@ limitations under the License.
|
||||||
mask-image: url('$(res)/img/element-icons/room/composer/attach.svg');
|
mask-image: url('$(res)/img/element-icons/room/composer/attach.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_MessageComposer_voiceMessage::before {
|
||||||
|
mask-image: url('$(res)/img/voip/mic-on-mask.svg');
|
||||||
|
}
|
||||||
|
|
||||||
.mx_MessageComposer_emoji::before {
|
.mx_MessageComposer_emoji::before {
|
||||||
mask-image: url('$(res)/img/element-icons/room/composer/emoji.svg');
|
mask-image: url('$(res)/img/element-icons/room/composer/emoji.svg');
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,8 @@ limitations under the License.
|
||||||
width: 27px;
|
width: 27px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
background: none;
|
||||||
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MessageComposerFormatBar_button::after {
|
.mx_MessageComposerFormatBar_button::after {
|
||||||
|
|
|
@ -33,8 +33,13 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_AccessibleButton {
|
.mx_AccessibleButton {
|
||||||
line-height: $font-24px;
|
line-height: $font-24px;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
&::before {
|
& + .mx_AccessibleButton {
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.mx_AccessibleButton_kind_primary_outline)::before {
|
||||||
content: '';
|
content: '';
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-color: $button-fg-color;
|
background-color: $button-fg-color;
|
||||||
|
|
|
@ -27,6 +27,9 @@ limitations under the License.
|
||||||
.mx_RoomList_iconExplore::before {
|
.mx_RoomList_iconExplore::before {
|
||||||
mask-image: url('$(res)/img/element-icons/roomlist/explore.svg');
|
mask-image: url('$(res)/img/element-icons/roomlist/explore.svg');
|
||||||
}
|
}
|
||||||
|
.mx_RoomList_iconBrowse::before {
|
||||||
|
mask-image: url('$(res)/img/element-icons/roomlist/browse.svg');
|
||||||
|
}
|
||||||
.mx_RoomList_iconDialpad::before {
|
.mx_RoomList_iconDialpad::before {
|
||||||
mask-image: url('$(res)/img/element-icons/roomlist/dialpad.svg');
|
mask-image: url('$(res)/img/element-icons/roomlist/dialpad.svg');
|
||||||
}
|
}
|
||||||
|
@ -34,29 +37,33 @@ limitations under the License.
|
||||||
.mx_RoomList_explorePrompt {
|
.mx_RoomList_explorePrompt {
|
||||||
margin: 4px 12px 4px;
|
margin: 4px 12px 4px;
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
border-top: 1px solid $tertiary-fg-color;
|
border-top: 1px solid $input-border-color;
|
||||||
font-size: $font-13px;
|
font-size: $font-14px;
|
||||||
|
|
||||||
div:first-child {
|
div:first-child {
|
||||||
font-weight: $font-semi-bold;
|
font-weight: $font-semi-bold;
|
||||||
|
line-height: $font-18px;
|
||||||
|
color: $primary-fg-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AccessibleButton {
|
.mx_AccessibleButton {
|
||||||
color: $secondary-fg-color;
|
color: $primary-fg-color;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0 0 0 24px;
|
padding: 8px 8px 8px 32px;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
margin-top: 8px;
|
margin-top: 12px;
|
||||||
display: block;
|
display: block;
|
||||||
text-align: start;
|
text-align: start;
|
||||||
|
background-color: $roomlist-button-bg-color;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
content: '';
|
content: '';
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 8px;
|
||||||
left: 0;
|
left: 8px;
|
||||||
background: $secondary-fg-color;
|
background: $secondary-fg-color;
|
||||||
mask-position: center;
|
mask-position: center;
|
||||||
mask-size: contain;
|
mask-size: contain;
|
||||||
|
@ -70,5 +77,13 @@ limitations under the License.
|
||||||
&.mx_RoomList_explorePrompt_explore::before {
|
&.mx_RoomList_explorePrompt_explore::before {
|
||||||
mask-image: url('$(res)/img/element-icons/roomlist/explore.svg');
|
mask-image: url('$(res)/img/element-icons/roomlist/explore.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.mx_RoomList_explorePrompt_spaceInvite::before {
|
||||||
|
mask-image: url('$(res)/img/element-icons/room/invite.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.mx_RoomList_explorePrompt_spaceExplore::before {
|
||||||
|
mask-image: url('$(res)/img/element-icons/roomlist/browse.svg');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
36
res/css/views/rooms/_VoiceRecordComposerTile.scss
Normal file
36
res/css/views/rooms/_VoiceRecordComposerTile.scss
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 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_VoiceRecordComposerTile_stop {
|
||||||
|
// 28px plus a 2px border makes this a 32px square (as intended)
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
border: 2px solid $voice-record-stop-border-color;
|
||||||
|
border-radius: 32px;
|
||||||
|
margin-right: 16px; // between us and the send button
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
position: absolute;
|
||||||
|
top: 7px;
|
||||||
|
left: 7px;
|
||||||
|
border-radius: 2px;
|
||||||
|
background-color: $voice-record-stop-symbol-color;
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,10 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: the space panel currently does not have a fixed width,
|
$spacePanelWidth: 71px;
|
||||||
// just the headers at each level have a max-width of 150px
|
|
||||||
// so this will look slightly off for now. We should probably use css grid for the whole main layout...
|
|
||||||
$spacePanelWidth: 200px;
|
|
||||||
|
|
||||||
.mx_SpaceCreateMenu_wrapper {
|
.mx_SpaceCreateMenu_wrapper {
|
||||||
// background blur everything except SpacePanel
|
// background blur everything except SpacePanel
|
||||||
|
@ -48,53 +45,11 @@ $spacePanelWidth: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceCreateMenuType {
|
.mx_SpaceCreateMenuType {
|
||||||
position: relative;
|
@mixin SpacePillButton;
|
||||||
padding: 16px 32px 16px 72px;
|
|
||||||
width: 432px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
border-radius: 8px;
|
|
||||||
border: 1px solid $input-darker-bg-color;
|
|
||||||
font-size: $font-15px;
|
|
||||||
margin: 20px 0;
|
|
||||||
|
|
||||||
> h3 {
|
|
||||||
font-weight: $font-semi-bold;
|
|
||||||
margin: 0 0 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> span {
|
|
||||||
color: $secondary-fg-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
position: absolute;
|
|
||||||
content: '';
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
top: 24px;
|
|
||||||
left: 20px;
|
|
||||||
mask-position: center;
|
|
||||||
mask-repeat: no-repeat;
|
|
||||||
mask-size: 32px;
|
|
||||||
background-color: $tertiary-fg-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-color: $accent-color;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
background-color: $accent-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
> span {
|
|
||||||
color: $primary-fg-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_SpaceCreateMenuType_public::before {
|
.mx_SpaceCreateMenuType_public::before {
|
||||||
mask-image: url('$(res)/img/globe.svg');
|
mask-image: url('$(res)/img/globe.svg');
|
||||||
mask-size: 26px;
|
|
||||||
}
|
}
|
||||||
.mx_SpaceCreateMenuType_private::before {
|
.mx_SpaceCreateMenuType_private::before {
|
||||||
mask-image: url('$(res)/img/element-icons/lock.svg');
|
mask-image: url('$(res)/img/element-icons/lock.svg');
|
||||||
|
@ -124,7 +79,7 @@ $spacePanelWidth: 200px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_FormButton {
|
.mx_AccessibleButton_kind_primary {
|
||||||
padding: 8px 22px;
|
padding: 8px 22px;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
@ -16,38 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
.mx_SpacePublicShare {
|
.mx_SpacePublicShare {
|
||||||
.mx_AccessibleButton {
|
.mx_AccessibleButton {
|
||||||
border: 1px solid $space-button-outline-color;
|
@mixin SpacePillButton;
|
||||||
box-sizing: border-box;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 12px 24px 12px 52px;
|
|
||||||
margin-top: 16px;
|
|
||||||
width: $SpaceRoomViewInnerWidth;
|
|
||||||
font-size: $font-15px;
|
|
||||||
line-height: $font-24px;
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
> span {
|
|
||||||
color: #368bd6;
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(141, 151, 165, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
mask-repeat: no-repeat;
|
|
||||||
mask-size: contain;
|
|
||||||
mask-position: center;
|
|
||||||
background: $muted-fg-color;
|
|
||||||
left: 12px;
|
|
||||||
top: 9px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.mx_SpacePublicShare_shareButton::before {
|
&.mx_SpacePublicShare_shareButton::before {
|
||||||
mask-image: url('$(res)/img/element-icons/link.svg');
|
mask-image: url('$(res)/img/element-icons/link.svg');
|
||||||
|
|
4
res/img/element-icons/roomlist/browse.svg
Normal file
4
res/img/element-icons/roomlist/browse.svg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="18" height="17" viewBox="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.00262 5.60945C7.02444 6.31867 7.18204 6.99371 7.45029 7.60945H5.83106L5.49798 11.0235H8.60274L8.757 9.44233C9.29964 9.94168 9.94406 10.3321 10.6556 10.579L10.6122 11.0235H12.7966C13.3489 11.0235 13.7966 11.4712 13.7966 12.0235C13.7966 12.5758 13.3489 13.0235 12.7966 13.0235H10.4171L10.1823 15.4305C10.1287 15.9802 9.63959 16.3823 9.08991 16.3287C8.54024 16.2751 8.13811 15.786 8.19174 15.2363L8.40762 13.0235H5.30286L5.06803 15.4305C5.0144 15.9802 4.52533 16.3823 3.97565 16.3287C3.42598 16.2751 3.02385 15.786 3.07748 15.2363L3.29336 13.0235H1.6665C1.11422 13.0235 0.666504 12.5758 0.666504 12.0235C0.666504 11.4712 1.11422 11.0235 1.6665 11.0235H3.48848L3.82156 7.60945H2.26807C1.71578 7.60945 1.26807 7.16173 1.26807 6.60945C1.26807 6.05716 1.71578 5.60945 2.26807 5.60945H4.01668L4.28073 2.90297C4.33436 2.3533 4.82343 1.95117 5.37311 2.0048C5.92278 2.05842 6.32491 2.5475 6.27128 3.09717L6.02618 5.60945H7.00262Z" fill="#8D99A5"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.4224 5.37843C14.4224 6.50754 13.5071 7.42287 12.3779 7.42287C11.2488 7.42287 10.3335 6.50754 10.3335 5.37843C10.3335 4.24931 11.2488 3.33398 12.3779 3.33398C13.5071 3.33398 14.4224 4.24931 14.4224 5.37843ZM15.8496 7.45454C16.2133 6.84764 16.4224 6.13745 16.4224 5.37843C16.4224 3.14474 14.6116 1.33398 12.3779 1.33398C10.1443 1.33398 8.3335 3.14474 8.3335 5.37843C8.3335 7.61211 10.1443 9.42287 12.3779 9.42287C13.1369 9.42287 13.8471 9.21381 14.454 8.85013C14.4853 8.89368 14.5205 8.93528 14.5597 8.97444L16.293 10.7078C16.6835 11.0983 17.3167 11.0983 17.7072 10.7078C18.0977 10.3172 18.0977 9.68408 17.7072 9.29356L15.9739 7.56023C15.9347 7.52107 15.8931 7.48584 15.8496 7.45454Z" fill="#8D99A5"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -1,5 +1,5 @@
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<circle cx="8" cy="8" r="8" fill="#737D8C" style="mix-blend-mode:multiply"/>
|
<circle cx="8" cy="8" r="8" fill="#FF4B55"/>
|
||||||
<rect x="7" y="3" width="2" height="6" rx="1" fill="white"/>
|
<rect x="7" y="3" width="2" height="6" rx="1" fill="white"/>
|
||||||
<rect x="7" y="11" width="2" height="2" rx="1" fill="white"/>
|
<rect x="7" y="11" width="2" height="2" rx="1" fill="white"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 303 B After Width: | Height: | Size: 283 B |
3
res/img/voip/mic-on-mask.svg
Normal file
3
res/img/voip/mic-on-mask.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.09999 4.15C6.09999 1.99609 7.84608 0.25 9.99999 0.25C12.1539 0.25 13.9 1.99609 13.9 4.15V9.98254C13.9 12.1365 12.1539 13.8825 9.99999 13.8825C7.84608 13.8825 6.09999 12.1365 6.09999 9.98254V4.15ZM3.1748 8.73755C3.86516 8.73755 4.4248 9.29719 4.4248 9.98755C4.4248 13.0574 6.91483 15.5493 9.9915 15.5538C9.99433 15.5538 9.99717 15.5538 10 15.5538C10.0028 15.5538 10.0056 15.5538 10.0084 15.5538C13.085 15.5492 15.5748 13.0573 15.5748 9.98755C15.5748 9.29719 16.1344 8.73755 16.8248 8.73755C17.5152 8.73755 18.0748 9.29719 18.0748 9.98755C18.0748 14.0189 15.115 17.3576 11.25 17.9577V18.7513C11.25 19.4416 10.6904 20.0013 10 20.0013C9.30964 20.0013 8.75 19.4416 8.75 18.7513V17.9578C4.88483 17.3578 1.9248 14.0191 1.9248 9.98755C1.9248 9.29719 2.48445 8.73755 3.1748 8.73755Z" fill="#C1C6CD"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 951 B |
|
@ -123,7 +123,6 @@ $roomsublist-divider-color: $primary-fg-color;
|
||||||
$roomsublist-skeleton-ui-bg: linear-gradient(180deg, #3e444c 0%, #3e444c00 100%);
|
$roomsublist-skeleton-ui-bg: linear-gradient(180deg, #3e444c 0%, #3e444c00 100%);
|
||||||
|
|
||||||
$groupFilterPanel-divider-color: $roomlist-header-color;
|
$groupFilterPanel-divider-color: $roomlist-header-color;
|
||||||
$space-button-outline-color: rgba(141, 151, 165, 0.2);
|
|
||||||
|
|
||||||
$roomtile-preview-color: $secondary-fg-color;
|
$roomtile-preview-color: $secondary-fg-color;
|
||||||
$roomtile-default-badge-bg-color: #61708b;
|
$roomtile-default-badge-bg-color: #61708b;
|
||||||
|
|
|
@ -120,7 +120,6 @@ $roomsublist-divider-color: $primary-fg-color;
|
||||||
$roomsublist-skeleton-ui-bg: linear-gradient(180deg, #3e444c 0%, #3e444c00 100%);
|
$roomsublist-skeleton-ui-bg: linear-gradient(180deg, #3e444c 0%, #3e444c00 100%);
|
||||||
|
|
||||||
$groupFilterPanel-divider-color: $roomlist-header-color;
|
$groupFilterPanel-divider-color: $roomlist-header-color;
|
||||||
$space-button-outline-color: rgba(141, 151, 165, 0.2);
|
|
||||||
|
|
||||||
$roomtile-preview-color: #9e9e9e;
|
$roomtile-preview-color: #9e9e9e;
|
||||||
$roomtile-default-badge-bg-color: #61708b;
|
$roomtile-default-badge-bg-color: #61708b;
|
||||||
|
|
|
@ -187,7 +187,9 @@ $roomsublist-divider-color: $primary-fg-color;
|
||||||
$roomsublist-skeleton-ui-bg: linear-gradient(180deg, #ffffff 0%, #ffffff00 100%);
|
$roomsublist-skeleton-ui-bg: linear-gradient(180deg, #ffffff 0%, #ffffff00 100%);
|
||||||
|
|
||||||
$groupFilterPanel-divider-color: $roomlist-header-color;
|
$groupFilterPanel-divider-color: $roomlist-header-color;
|
||||||
$space-button-outline-color: #E3E8F0;
|
|
||||||
|
$voice-record-stop-border-color: #E3E8F0;
|
||||||
|
$voice-record-stop-symbol-color: $warning-color;
|
||||||
|
|
||||||
$roomtile-preview-color: #9e9e9e;
|
$roomtile-preview-color: #9e9e9e;
|
||||||
$roomtile-default-badge-bg-color: #61708b;
|
$roomtile-default-badge-bg-color: #61708b;
|
||||||
|
|
|
@ -178,7 +178,9 @@ $roomsublist-divider-color: $primary-fg-color;
|
||||||
$roomsublist-skeleton-ui-bg: linear-gradient(180deg, #ffffff 0%, #ffffff00 100%);
|
$roomsublist-skeleton-ui-bg: linear-gradient(180deg, #ffffff 0%, #ffffff00 100%);
|
||||||
|
|
||||||
$groupFilterPanel-divider-color: $roomlist-header-color;
|
$groupFilterPanel-divider-color: $roomlist-header-color;
|
||||||
$space-button-outline-color: #E3E8F0;
|
|
||||||
|
$voice-record-stop-border-color: #E3E8F0;
|
||||||
|
$voice-record-stop-symbol-color: $warning-color;
|
||||||
|
|
||||||
$roomtile-preview-color: $secondary-fg-color;
|
$roomtile-preview-color: $secondary-fg-color;
|
||||||
$roomtile-default-badge-bg-color: #61708b;
|
$roomtile-default-badge-bg-color: #61708b;
|
||||||
|
|
2
src/@types/global.d.ts
vendored
2
src/@types/global.d.ts
vendored
|
@ -39,6 +39,7 @@ import {ModalWidgetStore} from "../stores/ModalWidgetStore";
|
||||||
import { WidgetLayoutStore } from "../stores/widgets/WidgetLayoutStore";
|
import { WidgetLayoutStore } from "../stores/widgets/WidgetLayoutStore";
|
||||||
import VoipUserMapper from "../VoipUserMapper";
|
import VoipUserMapper from "../VoipUserMapper";
|
||||||
import {SpaceStoreClass} from "../stores/SpaceStore";
|
import {SpaceStoreClass} from "../stores/SpaceStore";
|
||||||
|
import {VoiceRecorder} from "../voice/VoiceRecorder";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -70,6 +71,7 @@ declare global {
|
||||||
mxModalWidgetStore: ModalWidgetStore;
|
mxModalWidgetStore: ModalWidgetStore;
|
||||||
mxVoipUserMapper: VoipUserMapper;
|
mxVoipUserMapper: VoipUserMapper;
|
||||||
mxSpaceStore: SpaceStoreClass;
|
mxSpaceStore: SpaceStoreClass;
|
||||||
|
mxVoiceRecorder: typeof VoiceRecorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Document {
|
interface Document {
|
||||||
|
|
407
src/KeyBindingsDefaults.ts
Normal file
407
src/KeyBindingsDefaults.ts
Normal file
|
@ -0,0 +1,407 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 Clemens Zeidler
|
||||||
|
|
||||||
|
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 { AutocompleteAction, IKeyBindingsProvider, KeyBinding, MessageComposerAction, NavigationAction, RoomAction,
|
||||||
|
RoomListAction } from "./KeyBindingsManager";
|
||||||
|
import { isMac, Key } from "./Keyboard";
|
||||||
|
import SettingsStore from "./settings/SettingsStore";
|
||||||
|
|
||||||
|
const messageComposerBindings = (): KeyBinding<MessageComposerAction>[] => {
|
||||||
|
const bindings: KeyBinding<MessageComposerAction>[] = [
|
||||||
|
{
|
||||||
|
action: MessageComposerAction.SelectPrevSendHistory,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_UP,
|
||||||
|
altKey: true,
|
||||||
|
ctrlKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: MessageComposerAction.SelectNextSendHistory,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_DOWN,
|
||||||
|
altKey: true,
|
||||||
|
ctrlKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: MessageComposerAction.EditPrevMessage,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_UP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: MessageComposerAction.EditNextMessage,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_DOWN,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: MessageComposerAction.CancelEditing,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ESCAPE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: MessageComposerAction.FormatBold,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.B,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: MessageComposerAction.FormatItalics,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.I,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: MessageComposerAction.FormatQuote,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.GREATER_THAN,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
shiftKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: MessageComposerAction.EditUndo,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.Z,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: MessageComposerAction.MoveCursorToStart,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.HOME,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: MessageComposerAction.MoveCursorToEnd,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.END,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
if (isMac) {
|
||||||
|
bindings.push({
|
||||||
|
action: MessageComposerAction.EditRedo,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.Z,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
shiftKey: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
bindings.push({
|
||||||
|
action: MessageComposerAction.EditRedo,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.Y,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (SettingsStore.getValue('MessageComposerInput.ctrlEnterToSend')) {
|
||||||
|
bindings.push({
|
||||||
|
action: MessageComposerAction.Send,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ENTER,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
bindings.push({
|
||||||
|
action: MessageComposerAction.NewLine,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ENTER,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
bindings.push({
|
||||||
|
action: MessageComposerAction.Send,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ENTER,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
bindings.push({
|
||||||
|
action: MessageComposerAction.NewLine,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ENTER,
|
||||||
|
shiftKey: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (isMac) {
|
||||||
|
bindings.push({
|
||||||
|
action: MessageComposerAction.NewLine,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ENTER,
|
||||||
|
altKey: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
const autocompleteBindings = (): KeyBinding<AutocompleteAction>[] => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
action: AutocompleteAction.ApplySelection,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.TAB,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: AutocompleteAction.ApplySelection,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.TAB,
|
||||||
|
ctrlKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: AutocompleteAction.ApplySelection,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.TAB,
|
||||||
|
shiftKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: AutocompleteAction.ApplySelection,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.TAB,
|
||||||
|
ctrlKey: true,
|
||||||
|
shiftKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: AutocompleteAction.Cancel,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ESCAPE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: AutocompleteAction.PrevSelection,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_UP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: AutocompleteAction.NextSelection,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_DOWN,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
const roomListBindings = (): KeyBinding<RoomListAction>[] => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
action: RoomListAction.ClearSearch,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ESCAPE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: RoomListAction.PrevRoom,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_UP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: RoomListAction.NextRoom,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_DOWN,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: RoomListAction.SelectRoom,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ENTER,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: RoomListAction.CollapseSection,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_LEFT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: RoomListAction.ExpandSection,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_RIGHT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
const roomBindings = (): KeyBinding<RoomAction>[] => {
|
||||||
|
const bindings: KeyBinding<RoomAction>[] = [
|
||||||
|
{
|
||||||
|
action: RoomAction.ScrollUp,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.PAGE_UP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: RoomAction.RoomScrollDown,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.PAGE_DOWN,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: RoomAction.DismissReadMarker,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ESCAPE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: RoomAction.JumpToOldestUnread,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.PAGE_UP,
|
||||||
|
shiftKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: RoomAction.UploadFile,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.U,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
shiftKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: RoomAction.JumpToFirstMessage,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.HOME,
|
||||||
|
ctrlKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: RoomAction.JumpToLatestMessage,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.END,
|
||||||
|
ctrlKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
if (SettingsStore.getValue('ctrlFForSearch')) {
|
||||||
|
bindings.push({
|
||||||
|
action: RoomAction.FocusSearch,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.F,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return bindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
const navigationBindings = (): KeyBinding<NavigationAction>[] => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
action: NavigationAction.FocusRoomSearch,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.K,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: NavigationAction.ToggleRoomSidePanel,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.PERIOD,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: NavigationAction.ToggleUserMenu,
|
||||||
|
// Ideally this would be CTRL+P for "Profile", but that's
|
||||||
|
// taken by the print dialog. CTRL+I for "Information"
|
||||||
|
// was previously chosen but conflicted with italics in
|
||||||
|
// composer, so CTRL+` it is
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.BACKTICK,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: NavigationAction.ToggleShortCutDialog,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.SLASH,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: NavigationAction.ToggleShortCutDialog,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.SLASH,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
shiftKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: NavigationAction.GoToHome,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.H,
|
||||||
|
ctrlOrCmd: true,
|
||||||
|
altKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
action: NavigationAction.SelectPrevRoom,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_UP,
|
||||||
|
altKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: NavigationAction.SelectNextRoom,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_DOWN,
|
||||||
|
altKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: NavigationAction.SelectPrevUnreadRoom,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_UP,
|
||||||
|
altKey: true,
|
||||||
|
shiftKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: NavigationAction.SelectNextUnreadRoom,
|
||||||
|
keyCombo: {
|
||||||
|
key: Key.ARROW_DOWN,
|
||||||
|
altKey: true,
|
||||||
|
shiftKey: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultBindingsProvider: IKeyBindingsProvider = {
|
||||||
|
getMessageComposerBindings: messageComposerBindings,
|
||||||
|
getAutocompleteBindings: autocompleteBindings,
|
||||||
|
getRoomListBindings: roomListBindings,
|
||||||
|
getRoomBindings: roomBindings,
|
||||||
|
getNavigationBindings: navigationBindings,
|
||||||
|
}
|
266
src/KeyBindingsManager.ts
Normal file
266
src/KeyBindingsManager.ts
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 Clemens Zeidler
|
||||||
|
|
||||||
|
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 { defaultBindingsProvider } from './KeyBindingsDefaults';
|
||||||
|
import { isMac } from './Keyboard';
|
||||||
|
|
||||||
|
/** Actions for the chat message composer component */
|
||||||
|
export enum MessageComposerAction {
|
||||||
|
/** Send a message */
|
||||||
|
Send = 'Send',
|
||||||
|
/** Go backwards through the send history and use the message in composer view */
|
||||||
|
SelectPrevSendHistory = 'SelectPrevSendHistory',
|
||||||
|
/** Go forwards through the send history */
|
||||||
|
SelectNextSendHistory = 'SelectNextSendHistory',
|
||||||
|
/** Start editing the user's last sent message */
|
||||||
|
EditPrevMessage = 'EditPrevMessage',
|
||||||
|
/** Start editing the user's next sent message */
|
||||||
|
EditNextMessage = 'EditNextMessage',
|
||||||
|
/** Cancel editing a message or cancel replying to a message */
|
||||||
|
CancelEditing = 'CancelEditing',
|
||||||
|
|
||||||
|
/** Set bold format the current selection */
|
||||||
|
FormatBold = 'FormatBold',
|
||||||
|
/** Set italics format the current selection */
|
||||||
|
FormatItalics = 'FormatItalics',
|
||||||
|
/** Format the current selection as quote */
|
||||||
|
FormatQuote = 'FormatQuote',
|
||||||
|
/** Undo the last editing */
|
||||||
|
EditUndo = 'EditUndo',
|
||||||
|
/** Redo editing */
|
||||||
|
EditRedo = 'EditRedo',
|
||||||
|
/** Insert new line */
|
||||||
|
NewLine = 'NewLine',
|
||||||
|
/** Move the cursor to the start of the message */
|
||||||
|
MoveCursorToStart = 'MoveCursorToStart',
|
||||||
|
/** Move the cursor to the end of the message */
|
||||||
|
MoveCursorToEnd = 'MoveCursorToEnd',
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Actions for text editing autocompletion */
|
||||||
|
export enum AutocompleteAction {
|
||||||
|
/** Apply the current autocomplete selection */
|
||||||
|
ApplySelection = 'ApplySelection',
|
||||||
|
/** Cancel autocompletion */
|
||||||
|
Cancel = 'Cancel',
|
||||||
|
/** Move to the previous autocomplete selection */
|
||||||
|
PrevSelection = 'PrevSelection',
|
||||||
|
/** Move to the next autocomplete selection */
|
||||||
|
NextSelection = 'NextSelection',
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Actions for the room list sidebar */
|
||||||
|
export enum RoomListAction {
|
||||||
|
/** Clear room list filter field */
|
||||||
|
ClearSearch = 'ClearSearch',
|
||||||
|
/** Navigate up/down in the room list */
|
||||||
|
PrevRoom = 'PrevRoom',
|
||||||
|
/** Navigate down in the room list */
|
||||||
|
NextRoom = 'NextRoom',
|
||||||
|
/** Select room from the room list */
|
||||||
|
SelectRoom = 'SelectRoom',
|
||||||
|
/** Collapse room list section */
|
||||||
|
CollapseSection = 'CollapseSection',
|
||||||
|
/** Expand room list section, if already expanded, jump to first room in the selection */
|
||||||
|
ExpandSection = 'ExpandSection',
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Actions for the current room view */
|
||||||
|
export enum RoomAction {
|
||||||
|
/** Scroll up in the timeline */
|
||||||
|
ScrollUp = 'ScrollUp',
|
||||||
|
/** Scroll down in the timeline */
|
||||||
|
RoomScrollDown = 'RoomScrollDown',
|
||||||
|
/** Dismiss read marker and jump to bottom */
|
||||||
|
DismissReadMarker = 'DismissReadMarker',
|
||||||
|
/** Jump to oldest unread message */
|
||||||
|
JumpToOldestUnread = 'JumpToOldestUnread',
|
||||||
|
/** Upload a file */
|
||||||
|
UploadFile = 'UploadFile',
|
||||||
|
/** Focus search message in a room (must be enabled) */
|
||||||
|
FocusSearch = 'FocusSearch',
|
||||||
|
/** Jump to the first (downloaded) message in the room */
|
||||||
|
JumpToFirstMessage = 'JumpToFirstMessage',
|
||||||
|
/** Jump to the latest message in the room */
|
||||||
|
JumpToLatestMessage = 'JumpToLatestMessage',
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Actions for navigating do various menus, dialogs or screens */
|
||||||
|
export enum NavigationAction {
|
||||||
|
/** Jump to room search (search for a room) */
|
||||||
|
FocusRoomSearch = 'FocusRoomSearch',
|
||||||
|
/** Toggle the room side panel */
|
||||||
|
ToggleRoomSidePanel = 'ToggleRoomSidePanel',
|
||||||
|
/** Toggle the user menu */
|
||||||
|
ToggleUserMenu = 'ToggleUserMenu',
|
||||||
|
/** Toggle the short cut help dialog */
|
||||||
|
ToggleShortCutDialog = 'ToggleShortCutDialog',
|
||||||
|
/** Got to the Element home screen */
|
||||||
|
GoToHome = 'GoToHome',
|
||||||
|
/** Select prev room */
|
||||||
|
SelectPrevRoom = 'SelectPrevRoom',
|
||||||
|
/** Select next room */
|
||||||
|
SelectNextRoom = 'SelectNextRoom',
|
||||||
|
/** Select prev room with unread messages */
|
||||||
|
SelectPrevUnreadRoom = 'SelectPrevUnreadRoom',
|
||||||
|
/** Select next room with unread messages */
|
||||||
|
SelectNextUnreadRoom = 'SelectNextUnreadRoom',
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represent a key combination.
|
||||||
|
*
|
||||||
|
* The combo is evaluated strictly, i.e. the KeyboardEvent must match exactly what is specified in the KeyCombo.
|
||||||
|
*/
|
||||||
|
export type KeyCombo = {
|
||||||
|
key?: string;
|
||||||
|
|
||||||
|
/** On PC: ctrl is pressed; on Mac: meta is pressed */
|
||||||
|
ctrlOrCmd?: boolean;
|
||||||
|
|
||||||
|
altKey?: boolean;
|
||||||
|
ctrlKey?: boolean;
|
||||||
|
metaKey?: boolean;
|
||||||
|
shiftKey?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type KeyBinding<T extends string> = {
|
||||||
|
action: T;
|
||||||
|
keyCombo: KeyCombo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to check if a KeyboardEvent matches a KeyCombo
|
||||||
|
*
|
||||||
|
* Note, this method is only exported for testing.
|
||||||
|
*/
|
||||||
|
export function isKeyComboMatch(ev: KeyboardEvent | React.KeyboardEvent, combo: KeyCombo, onMac: boolean): boolean {
|
||||||
|
if (combo.key !== undefined) {
|
||||||
|
// When shift is pressed, letters are returned as upper case chars. In this case do a lower case comparison.
|
||||||
|
// This works for letter combos such as shift + U as well for none letter combos such as shift + Escape.
|
||||||
|
// If shift is not pressed, the toLowerCase conversion can be avoided.
|
||||||
|
if (ev.shiftKey) {
|
||||||
|
if (ev.key.toLowerCase() !== combo.key.toLowerCase()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (ev.key !== combo.key) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const comboCtrl = combo.ctrlKey ?? false;
|
||||||
|
const comboAlt = combo.altKey ?? false;
|
||||||
|
const comboShift = combo.shiftKey ?? false;
|
||||||
|
const comboMeta = combo.metaKey ?? false;
|
||||||
|
// Tests mock events may keep the modifiers undefined; convert them to booleans
|
||||||
|
const evCtrl = ev.ctrlKey ?? false;
|
||||||
|
const evAlt = ev.altKey ?? false;
|
||||||
|
const evShift = ev.shiftKey ?? false;
|
||||||
|
const evMeta = ev.metaKey ?? false;
|
||||||
|
// When ctrlOrCmd is set, the keys need do evaluated differently on PC and Mac
|
||||||
|
if (combo.ctrlOrCmd) {
|
||||||
|
if (onMac) {
|
||||||
|
if (!evMeta
|
||||||
|
|| evCtrl !== comboCtrl
|
||||||
|
|| evAlt !== comboAlt
|
||||||
|
|| evShift !== comboShift) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!evCtrl
|
||||||
|
|| evMeta !== comboMeta
|
||||||
|
|| evAlt !== comboAlt
|
||||||
|
|| evShift !== comboShift) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (evMeta !== comboMeta
|
||||||
|
|| evCtrl !== comboCtrl
|
||||||
|
|| evAlt !== comboAlt
|
||||||
|
|| evShift !== comboShift) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type KeyBindingGetter<T extends string> = () => KeyBinding<T>[];
|
||||||
|
|
||||||
|
export interface IKeyBindingsProvider {
|
||||||
|
getMessageComposerBindings: KeyBindingGetter<MessageComposerAction>;
|
||||||
|
getAutocompleteBindings: KeyBindingGetter<AutocompleteAction>;
|
||||||
|
getRoomListBindings: KeyBindingGetter<RoomListAction>;
|
||||||
|
getRoomBindings: KeyBindingGetter<RoomAction>;
|
||||||
|
getNavigationBindings: KeyBindingGetter<NavigationAction>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class KeyBindingsManager {
|
||||||
|
/**
|
||||||
|
* List of key bindings providers.
|
||||||
|
*
|
||||||
|
* Key bindings from the first provider(s) in the list will have precedence over key bindings from later providers.
|
||||||
|
*
|
||||||
|
* To overwrite the default key bindings add a new providers before the default provider, e.g. a provider for
|
||||||
|
* customized key bindings.
|
||||||
|
*/
|
||||||
|
bindingsProviders: IKeyBindingsProvider[] = [
|
||||||
|
defaultBindingsProvider,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a matching KeyAction for a given KeyboardEvent
|
||||||
|
*/
|
||||||
|
private getAction<T extends string>(getters: KeyBindingGetter<T>[], ev: KeyboardEvent | React.KeyboardEvent)
|
||||||
|
: T | undefined {
|
||||||
|
for (const getter of getters) {
|
||||||
|
const bindings = getter();
|
||||||
|
const binding = bindings.find(it => isKeyComboMatch(ev, it.keyCombo, isMac));
|
||||||
|
if (binding) {
|
||||||
|
return binding.action;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
getMessageComposerAction(ev: KeyboardEvent | React.KeyboardEvent): MessageComposerAction | undefined {
|
||||||
|
return this.getAction(this.bindingsProviders.map(it => it.getMessageComposerBindings), ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
getAutocompleteAction(ev: KeyboardEvent | React.KeyboardEvent): AutocompleteAction | undefined {
|
||||||
|
return this.getAction(this.bindingsProviders.map(it => it.getAutocompleteBindings), ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
getRoomListAction(ev: KeyboardEvent | React.KeyboardEvent): RoomListAction | undefined {
|
||||||
|
return this.getAction(this.bindingsProviders.map(it => it.getRoomListBindings), ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
getRoomAction(ev: KeyboardEvent | React.KeyboardEvent): RoomAction | undefined {
|
||||||
|
return this.getAction(this.bindingsProviders.map(it => it.getRoomBindings), ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
getNavigationAction(ev: KeyboardEvent | React.KeyboardEvent): NavigationAction | undefined {
|
||||||
|
return this.getAction(this.bindingsProviders.map(it => it.getNavigationBindings), ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const manager = new KeyBindingsManager();
|
||||||
|
|
||||||
|
export function getKeyBindingsManager(): KeyBindingsManager {
|
||||||
|
return manager;
|
||||||
|
}
|
|
@ -296,10 +296,11 @@ class _MatrixClientPeg implements IMatrixClientPeg {
|
||||||
// These are always installed regardless of the labs flag so that
|
// These are always installed regardless of the labs flag so that
|
||||||
// cross-signing features can toggle on without reloading and also be
|
// cross-signing features can toggle on without reloading and also be
|
||||||
// accessed immediately after login.
|
// accessed immediately after login.
|
||||||
const customisedCallbacks = {
|
Object.assign(opts.cryptoCallbacks, crossSigningCallbacks);
|
||||||
getDehydrationKey: SecurityCustomisations.getDehydrationKey,
|
if (SecurityCustomisations.getDehydrationKey) {
|
||||||
};
|
opts.cryptoCallbacks.getDehydrationKey =
|
||||||
Object.assign(opts.cryptoCallbacks, crossSigningCallbacks, customisedCallbacks);
|
SecurityCustomisations.getDehydrationKey;
|
||||||
|
}
|
||||||
|
|
||||||
this.matrixClient = createMatrixClient(opts);
|
this.matrixClient = createMatrixClient(opts);
|
||||||
|
|
||||||
|
|
|
@ -49,11 +49,12 @@ export function showStartChatInviteDialog(initialText) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showRoomInviteDialog(roomId) {
|
export function showRoomInviteDialog(roomId, initialText = "") {
|
||||||
// This dialog handles the room creation internally - we don't need to worry about it.
|
// This dialog handles the room creation internally - we don't need to worry about it.
|
||||||
Modal.createTrackedDialog(
|
Modal.createTrackedDialog(
|
||||||
"Invite Users", "", InviteDialog, {
|
"Invite Users", "", InviteDialog, {
|
||||||
kind: KIND_INVITE,
|
kind: KIND_INVITE,
|
||||||
|
initialText,
|
||||||
roomId,
|
roomId,
|
||||||
},
|
},
|
||||||
/*className=*/null, /*isPriority=*/false, /*isStatic=*/true,
|
/*className=*/null, /*isPriority=*/false, /*isStatic=*/true,
|
||||||
|
|
|
@ -20,6 +20,7 @@ limitations under the License.
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import { ContentHelpers } from 'matrix-js-sdk';
|
||||||
import {MatrixClientPeg} from './MatrixClientPeg';
|
import {MatrixClientPeg} from './MatrixClientPeg';
|
||||||
import dis from './dispatcher/dispatcher';
|
import dis from './dispatcher/dispatcher';
|
||||||
import * as sdk from './index';
|
import * as sdk from './index';
|
||||||
|
@ -126,10 +127,10 @@ export class Command {
|
||||||
return this.getCommand() + " " + this.args;
|
return this.getCommand() + " " + this.args;
|
||||||
}
|
}
|
||||||
|
|
||||||
run(roomId: string, args: string, cmd: string) {
|
run(roomId: string, args: string) {
|
||||||
// if it has no runFn then its an ignored/nop command (autocomplete only) e.g `/me`
|
// if it has no runFn then its an ignored/nop command (autocomplete only) e.g `/me`
|
||||||
if (!this.runFn) return reject(_t("Command error"));
|
if (!this.runFn) return reject(_t("Command error"));
|
||||||
return this.runFn.bind(this)(roomId, args, cmd);
|
return this.runFn.bind(this)(roomId, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
getUsage() {
|
getUsage() {
|
||||||
|
@ -163,7 +164,7 @@ export const Commands = [
|
||||||
if (args) {
|
if (args) {
|
||||||
message = message + ' ' + args;
|
message = message + ' ' + args;
|
||||||
}
|
}
|
||||||
return success(MatrixClientPeg.get().sendTextMessage(roomId, message));
|
return success(ContentHelpers.makeTextMessage(message));
|
||||||
},
|
},
|
||||||
category: CommandCategories.messages,
|
category: CommandCategories.messages,
|
||||||
}),
|
}),
|
||||||
|
@ -176,7 +177,7 @@ export const Commands = [
|
||||||
if (args) {
|
if (args) {
|
||||||
message = message + ' ' + args;
|
message = message + ' ' + args;
|
||||||
}
|
}
|
||||||
return success(MatrixClientPeg.get().sendTextMessage(roomId, message));
|
return success(ContentHelpers.makeTextMessage(message));
|
||||||
},
|
},
|
||||||
category: CommandCategories.messages,
|
category: CommandCategories.messages,
|
||||||
}),
|
}),
|
||||||
|
@ -189,7 +190,7 @@ export const Commands = [
|
||||||
if (args) {
|
if (args) {
|
||||||
message = message + ' ' + args;
|
message = message + ' ' + args;
|
||||||
}
|
}
|
||||||
return success(MatrixClientPeg.get().sendTextMessage(roomId, message));
|
return success(ContentHelpers.makeTextMessage(message));
|
||||||
},
|
},
|
||||||
category: CommandCategories.messages,
|
category: CommandCategories.messages,
|
||||||
}),
|
}),
|
||||||
|
@ -202,7 +203,7 @@ export const Commands = [
|
||||||
if (args) {
|
if (args) {
|
||||||
message = message + ' ' + args;
|
message = message + ' ' + args;
|
||||||
}
|
}
|
||||||
return success(MatrixClientPeg.get().sendTextMessage(roomId, message));
|
return success(ContentHelpers.makeTextMessage(message));
|
||||||
},
|
},
|
||||||
category: CommandCategories.messages,
|
category: CommandCategories.messages,
|
||||||
}),
|
}),
|
||||||
|
@ -211,7 +212,7 @@ export const Commands = [
|
||||||
args: '<message>',
|
args: '<message>',
|
||||||
description: _td('Sends a message as plain text, without interpreting it as markdown'),
|
description: _td('Sends a message as plain text, without interpreting it as markdown'),
|
||||||
runFn: function(roomId, messages) {
|
runFn: function(roomId, messages) {
|
||||||
return success(MatrixClientPeg.get().sendTextMessage(roomId, messages));
|
return success(ContentHelpers.makeTextMessage(messages));
|
||||||
},
|
},
|
||||||
category: CommandCategories.messages,
|
category: CommandCategories.messages,
|
||||||
}),
|
}),
|
||||||
|
@ -220,7 +221,7 @@ export const Commands = [
|
||||||
args: '<message>',
|
args: '<message>',
|
||||||
description: _td('Sends a message as html, without interpreting it as markdown'),
|
description: _td('Sends a message as html, without interpreting it as markdown'),
|
||||||
runFn: function(roomId, messages) {
|
runFn: function(roomId, messages) {
|
||||||
return success(MatrixClientPeg.get().sendHtmlMessage(roomId, messages, messages));
|
return success(ContentHelpers.makeHtmlMessage(messages, messages));
|
||||||
},
|
},
|
||||||
category: CommandCategories.messages,
|
category: CommandCategories.messages,
|
||||||
}),
|
}),
|
||||||
|
@ -965,7 +966,7 @@ export const Commands = [
|
||||||
args: '<message>',
|
args: '<message>',
|
||||||
runFn: function(roomId, args) {
|
runFn: function(roomId, args) {
|
||||||
if (!args) return reject(this.getUserId());
|
if (!args) return reject(this.getUserId());
|
||||||
return success(MatrixClientPeg.get().sendHtmlMessage(roomId, args, textToHtmlRainbow(args)));
|
return success(ContentHelpers.makeHtmlMessage(args, textToHtmlRainbow(args)));
|
||||||
},
|
},
|
||||||
category: CommandCategories.messages,
|
category: CommandCategories.messages,
|
||||||
}),
|
}),
|
||||||
|
@ -975,7 +976,7 @@ export const Commands = [
|
||||||
args: '<message>',
|
args: '<message>',
|
||||||
runFn: function(roomId, args) {
|
runFn: function(roomId, args) {
|
||||||
if (!args) return reject(this.getUserId());
|
if (!args) return reject(this.getUserId());
|
||||||
return success(MatrixClientPeg.get().sendHtmlEmote(roomId, args, textToHtmlRainbow(args)));
|
return success(ContentHelpers.makeHtmlEmote(args, textToHtmlRainbow(args)));
|
||||||
},
|
},
|
||||||
category: CommandCategories.messages,
|
category: CommandCategories.messages,
|
||||||
}),
|
}),
|
||||||
|
@ -1200,10 +1201,13 @@ export function parseCommandString(input: string) {
|
||||||
* processing the command, or 'promise' if a request was sent out.
|
* processing the command, or 'promise' if a request was sent out.
|
||||||
* Returns null if the input didn't match a command.
|
* Returns null if the input didn't match a command.
|
||||||
*/
|
*/
|
||||||
export function getCommand(roomId: string, input: string) {
|
export function getCommand(input: string) {
|
||||||
const {cmd, args} = parseCommandString(input);
|
const {cmd, args} = parseCommandString(input);
|
||||||
|
|
||||||
if (CommandMap.has(cmd) && CommandMap.get(cmd).isEnabled()) {
|
if (CommandMap.has(cmd) && CommandMap.get(cmd).isEnabled()) {
|
||||||
return () => CommandMap.get(cmd).run(roomId, args, cmd);
|
return {
|
||||||
|
cmd: CommandMap.get(cmd),
|
||||||
|
args,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,11 @@ limitations under the License.
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { createRef } from "react";
|
import { createRef } from "react";
|
||||||
|
import classNames from "classnames";
|
||||||
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
|
|
||||||
import GroupFilterPanel from "./GroupFilterPanel";
|
import GroupFilterPanel from "./GroupFilterPanel";
|
||||||
import CustomRoomTagPanel from "./CustomRoomTagPanel";
|
import CustomRoomTagPanel from "./CustomRoomTagPanel";
|
||||||
import classNames from "classnames";
|
|
||||||
import dis from "../../dispatcher/dispatcher";
|
import dis from "../../dispatcher/dispatcher";
|
||||||
import { _t } from "../../languageHandler";
|
import { _t } from "../../languageHandler";
|
||||||
import RoomList from "../views/rooms/RoomList";
|
import RoomList from "../views/rooms/RoomList";
|
||||||
|
@ -40,6 +42,7 @@ import RoomListNumResults from "../views/rooms/RoomListNumResults";
|
||||||
import LeftPanelWidget from "./LeftPanelWidget";
|
import LeftPanelWidget from "./LeftPanelWidget";
|
||||||
import {replaceableComponent} from "../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../utils/replaceableComponent";
|
||||||
import {mediaFromMxc} from "../../customisations/Media";
|
import {mediaFromMxc} from "../../customisations/Media";
|
||||||
|
import SpaceStore, {UPDATE_SELECTED_SPACE} from "../../stores/SpaceStore";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
isMinimized: boolean;
|
isMinimized: boolean;
|
||||||
|
@ -49,6 +52,7 @@ interface IProps {
|
||||||
interface IState {
|
interface IState {
|
||||||
showBreadcrumbs: boolean;
|
showBreadcrumbs: boolean;
|
||||||
showGroupFilterPanel: boolean;
|
showGroupFilterPanel: boolean;
|
||||||
|
activeSpace?: Room;
|
||||||
}
|
}
|
||||||
|
|
||||||
// List of CSS classes which should be included in keyboard navigation within the room list
|
// List of CSS classes which should be included in keyboard navigation within the room list
|
||||||
|
@ -74,11 +78,13 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
||||||
this.state = {
|
this.state = {
|
||||||
showBreadcrumbs: BreadcrumbsStore.instance.visible,
|
showBreadcrumbs: BreadcrumbsStore.instance.visible,
|
||||||
showGroupFilterPanel: SettingsStore.getValue('TagPanel.enableTagPanel'),
|
showGroupFilterPanel: SettingsStore.getValue('TagPanel.enableTagPanel'),
|
||||||
|
activeSpace: SpaceStore.instance.activeSpace,
|
||||||
};
|
};
|
||||||
|
|
||||||
BreadcrumbsStore.instance.on(UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
BreadcrumbsStore.instance.on(UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
||||||
RoomListStore.instance.on(LISTS_UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
RoomListStore.instance.on(LISTS_UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
||||||
OwnProfileStore.instance.on(UPDATE_EVENT, this.onBackgroundImageUpdate);
|
OwnProfileStore.instance.on(UPDATE_EVENT, this.onBackgroundImageUpdate);
|
||||||
|
SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.updateActiveSpace);
|
||||||
this.bgImageWatcherRef = SettingsStore.watchSetting(
|
this.bgImageWatcherRef = SettingsStore.watchSetting(
|
||||||
"RoomList.backgroundImage", null, this.onBackgroundImageUpdate);
|
"RoomList.backgroundImage", null, this.onBackgroundImageUpdate);
|
||||||
this.groupFilterPanelWatcherRef = SettingsStore.watchSetting("TagPanel.enableTagPanel", null, () => {
|
this.groupFilterPanelWatcherRef = SettingsStore.watchSetting("TagPanel.enableTagPanel", null, () => {
|
||||||
|
@ -96,9 +102,14 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
||||||
BreadcrumbsStore.instance.off(UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
BreadcrumbsStore.instance.off(UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
||||||
RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
||||||
OwnProfileStore.instance.off(UPDATE_EVENT, this.onBackgroundImageUpdate);
|
OwnProfileStore.instance.off(UPDATE_EVENT, this.onBackgroundImageUpdate);
|
||||||
|
SpaceStore.instance.off(UPDATE_SELECTED_SPACE, this.updateActiveSpace);
|
||||||
this.props.resizeNotifier.off("middlePanelResizedNoisy", this.onResize);
|
this.props.resizeNotifier.off("middlePanelResizedNoisy", this.onResize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private updateActiveSpace = (activeSpace: Room) => {
|
||||||
|
this.setState({ activeSpace });
|
||||||
|
};
|
||||||
|
|
||||||
private onExplore = () => {
|
private onExplore = () => {
|
||||||
dis.fire(Action.ViewRoomDirectory);
|
dis.fire(Action.ViewRoomDirectory);
|
||||||
};
|
};
|
||||||
|
@ -381,7 +392,9 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
||||||
onEnter={this.onEnter}
|
onEnter={this.onEnter}
|
||||||
/>
|
/>
|
||||||
<AccessibleTooltipButton
|
<AccessibleTooltipButton
|
||||||
className="mx_LeftPanel_exploreButton"
|
className={classNames("mx_LeftPanel_exploreButton", {
|
||||||
|
mx_LeftPanel_exploreButton_space: !!this.state.activeSpace,
|
||||||
|
})}
|
||||||
onClick={this.onExplore}
|
onClick={this.onExplore}
|
||||||
title={_t("Explore rooms")}
|
title={_t("Explore rooms")}
|
||||||
/>
|
/>
|
||||||
|
@ -407,6 +420,7 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
||||||
onBlur={this.onBlur}
|
onBlur={this.onBlur}
|
||||||
isMinimized={this.props.isMinimized}
|
isMinimized={this.props.isMinimized}
|
||||||
onResize={this.onResize}
|
onResize={this.onResize}
|
||||||
|
activeSpace={this.state.activeSpace}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
const containerClasses = classNames({
|
const containerClasses = classNames({
|
||||||
|
|
|
@ -21,7 +21,7 @@ import * as PropTypes from 'prop-types';
|
||||||
import { MatrixClient } from 'matrix-js-sdk/src/client';
|
import { MatrixClient } from 'matrix-js-sdk/src/client';
|
||||||
import { DragDropContext } from 'react-beautiful-dnd';
|
import { DragDropContext } from 'react-beautiful-dnd';
|
||||||
|
|
||||||
import {Key, isOnlyCtrlOrCmdKeyEvent, isOnlyCtrlOrCmdIgnoreShiftKeyEvent, isMac} from '../../Keyboard';
|
import {Key} from '../../Keyboard';
|
||||||
import PageTypes from '../../PageTypes';
|
import PageTypes from '../../PageTypes';
|
||||||
import CallMediaHandler from '../../CallMediaHandler';
|
import CallMediaHandler from '../../CallMediaHandler';
|
||||||
import { fixupColorFonts } from '../../utils/FontManager';
|
import { fixupColorFonts } from '../../utils/FontManager';
|
||||||
|
@ -55,6 +55,7 @@ import { IThreepidInvite } from "../../stores/ThreepidInviteStore";
|
||||||
import Modal from "../../Modal";
|
import Modal from "../../Modal";
|
||||||
import { ICollapseConfig } from "../../resizer/distributors/collapse";
|
import { ICollapseConfig } from "../../resizer/distributors/collapse";
|
||||||
import HostSignupContainer from '../views/host_signup/HostSignupContainer';
|
import HostSignupContainer from '../views/host_signup/HostSignupContainer';
|
||||||
|
import { getKeyBindingsManager, NavigationAction, RoomAction } from '../../KeyBindingsManager';
|
||||||
import { IOpts } from "../../createRoom";
|
import { IOpts } from "../../createRoom";
|
||||||
import SpacePanel from "../views/spaces/SpacePanel";
|
import SpacePanel from "../views/spaces/SpacePanel";
|
||||||
import {replaceableComponent} from "../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../utils/replaceableComponent";
|
||||||
|
@ -74,7 +75,6 @@ function canElementReceiveInput(el) {
|
||||||
interface IProps {
|
interface IProps {
|
||||||
matrixClient: MatrixClient;
|
matrixClient: MatrixClient;
|
||||||
onRegistered: (credentials: IMatrixClientCreds) => Promise<MatrixClient>;
|
onRegistered: (credentials: IMatrixClientCreds) => Promise<MatrixClient>;
|
||||||
viaServers?: string[];
|
|
||||||
hideToSRUsers: boolean;
|
hideToSRUsers: boolean;
|
||||||
resizeNotifier: ResizeNotifier;
|
resizeNotifier: ResizeNotifier;
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
|
@ -143,9 +143,6 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
// transitioned to PWLU)
|
// transitioned to PWLU)
|
||||||
onRegistered: PropTypes.func,
|
onRegistered: PropTypes.func,
|
||||||
|
|
||||||
// Used by the RoomView to handle joining rooms
|
|
||||||
viaServers: PropTypes.arrayOf(PropTypes.string),
|
|
||||||
|
|
||||||
// and lots and lots of other stuff.
|
// and lots and lots of other stuff.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -440,86 +437,54 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
_onKeyDown = (ev) => {
|
_onKeyDown = (ev) => {
|
||||||
let handled = false;
|
let handled = false;
|
||||||
const ctrlCmdOnly = isOnlyCtrlOrCmdKeyEvent(ev);
|
|
||||||
const hasModifier = ev.altKey || ev.ctrlKey || ev.metaKey || ev.shiftKey;
|
|
||||||
const isModifier = ev.key === Key.ALT || ev.key === Key.CONTROL || ev.key === Key.META || ev.key === Key.SHIFT;
|
|
||||||
const modKey = isMac ? ev.metaKey : ev.ctrlKey;
|
|
||||||
|
|
||||||
switch (ev.key) {
|
const roomAction = getKeyBindingsManager().getRoomAction(ev);
|
||||||
case Key.PAGE_UP:
|
switch (roomAction) {
|
||||||
case Key.PAGE_DOWN:
|
case RoomAction.ScrollUp:
|
||||||
if (!hasModifier && !isModifier) {
|
case RoomAction.RoomScrollDown:
|
||||||
this._onScrollKeyPressed(ev);
|
case RoomAction.JumpToFirstMessage:
|
||||||
handled = true;
|
case RoomAction.JumpToLatestMessage:
|
||||||
}
|
this._onScrollKeyPressed(ev);
|
||||||
|
handled = true;
|
||||||
break;
|
break;
|
||||||
|
case RoomAction.FocusSearch:
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'focus_search',
|
||||||
|
});
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (handled) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
ev.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case Key.HOME:
|
const navAction = getKeyBindingsManager().getNavigationAction(ev);
|
||||||
case Key.END:
|
switch (navAction) {
|
||||||
if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {
|
case NavigationAction.FocusRoomSearch:
|
||||||
this._onScrollKeyPressed(ev);
|
dis.dispatch({
|
||||||
handled = true;
|
action: 'focus_room_filter',
|
||||||
}
|
});
|
||||||
|
handled = true;
|
||||||
break;
|
break;
|
||||||
case Key.K:
|
case NavigationAction.ToggleUserMenu:
|
||||||
if (ctrlCmdOnly) {
|
dis.fire(Action.ToggleUserMenu);
|
||||||
dis.dispatch({
|
handled = true;
|
||||||
action: 'focus_room_filter',
|
|
||||||
});
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Key.F:
|
case NavigationAction.ToggleShortCutDialog:
|
||||||
if (ctrlCmdOnly && SettingsStore.getValue("ctrlFForSearch")) {
|
KeyboardShortcuts.toggleDialog();
|
||||||
dis.dispatch({
|
handled = true;
|
||||||
action: 'focus_search',
|
|
||||||
});
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Key.BACKTICK:
|
case NavigationAction.GoToHome:
|
||||||
// Ideally this would be CTRL+P for "Profile", but that's
|
dis.dispatch({
|
||||||
// taken by the print dialog. CTRL+I for "Information"
|
action: 'view_home_page',
|
||||||
// was previously chosen but conflicted with italics in
|
});
|
||||||
// composer, so CTRL+` it is
|
Modal.closeCurrentModal("homeKeyboardShortcut");
|
||||||
|
handled = true;
|
||||||
if (ctrlCmdOnly) {
|
|
||||||
dis.fire(Action.ToggleUserMenu);
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
case NavigationAction.ToggleRoomSidePanel:
|
||||||
case Key.SLASH:
|
if (this.props.page_type === "room_view" || this.props.page_type === "group_view") {
|
||||||
if (isOnlyCtrlOrCmdIgnoreShiftKeyEvent(ev)) {
|
|
||||||
KeyboardShortcuts.toggleDialog();
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Key.H:
|
|
||||||
if (ev.altKey && modKey) {
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'view_home_page',
|
|
||||||
});
|
|
||||||
Modal.closeCurrentModal("homeKeyboardShortcut");
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Key.ARROW_UP:
|
|
||||||
case Key.ARROW_DOWN:
|
|
||||||
if (ev.altKey && !ev.ctrlKey && !ev.metaKey) {
|
|
||||||
dis.dispatch<ViewRoomDeltaPayload>({
|
|
||||||
action: Action.ViewRoomDelta,
|
|
||||||
delta: ev.key === Key.ARROW_UP ? -1 : 1,
|
|
||||||
unread: ev.shiftKey,
|
|
||||||
});
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Key.PERIOD:
|
|
||||||
if (ctrlCmdOnly && (this.props.page_type === "room_view" || this.props.page_type === "group_view")) {
|
|
||||||
dis.dispatch<ToggleRightPanelPayload>({
|
dis.dispatch<ToggleRightPanelPayload>({
|
||||||
action: Action.ToggleRightPanel,
|
action: Action.ToggleRightPanel,
|
||||||
type: this.props.page_type === "room_view" ? "room" : "group",
|
type: this.props.page_type === "room_view" ? "room" : "group",
|
||||||
|
@ -527,16 +492,48 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case NavigationAction.SelectPrevRoom:
|
||||||
|
dis.dispatch<ViewRoomDeltaPayload>({
|
||||||
|
action: Action.ViewRoomDelta,
|
||||||
|
delta: -1,
|
||||||
|
unread: false,
|
||||||
|
});
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
case NavigationAction.SelectNextRoom:
|
||||||
|
dis.dispatch<ViewRoomDeltaPayload>({
|
||||||
|
action: Action.ViewRoomDelta,
|
||||||
|
delta: 1,
|
||||||
|
unread: false,
|
||||||
|
});
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
case NavigationAction.SelectPrevUnreadRoom:
|
||||||
|
dis.dispatch<ViewRoomDeltaPayload>({
|
||||||
|
action: Action.ViewRoomDelta,
|
||||||
|
delta: -1,
|
||||||
|
unread: true,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case NavigationAction.SelectNextUnreadRoom:
|
||||||
|
dis.dispatch<ViewRoomDeltaPayload>({
|
||||||
|
action: Action.ViewRoomDelta,
|
||||||
|
delta: 1,
|
||||||
|
unread: true,
|
||||||
|
});
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// if we do not have a handler for it, pass it to the platform which might
|
// if we do not have a handler for it, pass it to the platform which might
|
||||||
handled = PlatformPeg.get().onKeyDown(ev);
|
handled = PlatformPeg.get().onKeyDown(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handled) {
|
if (handled) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
} else if (!isModifier && !ev.altKey && !ev.ctrlKey && !ev.metaKey) {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isModifier = ev.key === Key.ALT || ev.key === Key.CONTROL || ev.key === Key.META || ev.key === Key.SHIFT;
|
||||||
|
if (!isModifier && !ev.altKey && !ev.ctrlKey && !ev.metaKey) {
|
||||||
// The above condition is crafted to _allow_ characters with Shift
|
// The above condition is crafted to _allow_ characters with Shift
|
||||||
// already pressed (but not the Shift key down itself).
|
// already pressed (but not the Shift key down itself).
|
||||||
|
|
||||||
|
@ -625,11 +622,9 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
case PageTypes.RoomView:
|
case PageTypes.RoomView:
|
||||||
pageElement = <RoomView
|
pageElement = <RoomView
|
||||||
ref={this._roomView}
|
ref={this._roomView}
|
||||||
autoJoin={this.props.autoJoin}
|
|
||||||
onRegistered={this.props.onRegistered}
|
onRegistered={this.props.onRegistered}
|
||||||
threepidInvite={this.props.threepidInvite}
|
threepidInvite={this.props.threepidInvite}
|
||||||
oobData={this.props.roomOobData}
|
oobData={this.props.roomOobData}
|
||||||
viaServers={this.props.viaServers}
|
|
||||||
key={this.props.currentRoomId || 'roomview'}
|
key={this.props.currentRoomId || 'roomview'}
|
||||||
resizeNotifier={this.props.resizeNotifier}
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
justCreatedOpts={this.props.roomJustCreatedOpts}
|
justCreatedOpts={this.props.roomJustCreatedOpts}
|
||||||
|
|
|
@ -80,10 +80,10 @@ import DialPadModal from "../views/voip/DialPadModal";
|
||||||
import { showToast as showMobileGuideToast } from '../../toasts/MobileGuideToast';
|
import { showToast as showMobileGuideToast } from '../../toasts/MobileGuideToast';
|
||||||
import { shouldUseLoginForWelcome } from "../../utils/pages";
|
import { shouldUseLoginForWelcome } from "../../utils/pages";
|
||||||
import SpaceStore from "../../stores/SpaceStore";
|
import SpaceStore from "../../stores/SpaceStore";
|
||||||
import SpaceRoomDirectory from "./SpaceRoomDirectory";
|
|
||||||
import {replaceableComponent} from "../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../utils/replaceableComponent";
|
||||||
import RoomListStore from "../../stores/room-list/RoomListStore";
|
import RoomListStore from "../../stores/room-list/RoomListStore";
|
||||||
import {RoomUpdateCause} from "../../stores/room-list/models";
|
import {RoomUpdateCause} from "../../stores/room-list/models";
|
||||||
|
import defaultDispatcher from "../../dispatcher/dispatcher";
|
||||||
|
|
||||||
/** constants for MatrixChat.state.view */
|
/** constants for MatrixChat.state.view */
|
||||||
export enum Views {
|
export enum Views {
|
||||||
|
@ -202,7 +202,6 @@ interface IState {
|
||||||
ready: boolean;
|
ready: boolean;
|
||||||
threepidInvite?: IThreepidInvite,
|
threepidInvite?: IThreepidInvite,
|
||||||
roomOobData?: object;
|
roomOobData?: object;
|
||||||
viaServers?: string[];
|
|
||||||
pendingInitialSync?: boolean;
|
pendingInitialSync?: boolean;
|
||||||
justRegistered?: boolean;
|
justRegistered?: boolean;
|
||||||
roomJustCreatedOpts?: IOpts;
|
roomJustCreatedOpts?: IOpts;
|
||||||
|
@ -691,10 +690,10 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
case Action.ViewRoomDirectory: {
|
case Action.ViewRoomDirectory: {
|
||||||
if (SpaceStore.instance.activeSpace) {
|
if (SpaceStore.instance.activeSpace) {
|
||||||
Modal.createTrackedDialog("Space room directory", "", SpaceRoomDirectory, {
|
defaultDispatcher.dispatch({
|
||||||
space: SpaceStore.instance.activeSpace,
|
action: "view_room",
|
||||||
initialText: payload.initialText,
|
room_id: SpaceStore.instance.activeSpace.roomId,
|
||||||
}, "mx_SpaceRoomDirectory_dialogWrapper", false, true);
|
});
|
||||||
} else {
|
} else {
|
||||||
const RoomDirectory = sdk.getComponent("structures.RoomDirectory");
|
const RoomDirectory = sdk.getComponent("structures.RoomDirectory");
|
||||||
Modal.createTrackedDialog('Room directory', '', RoomDirectory, {
|
Modal.createTrackedDialog('Room directory', '', RoomDirectory, {
|
||||||
|
@ -929,7 +928,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
page_type: PageTypes.RoomView,
|
page_type: PageTypes.RoomView,
|
||||||
threepidInvite: roomInfo.threepid_invite,
|
threepidInvite: roomInfo.threepid_invite,
|
||||||
roomOobData: roomInfo.oob_data,
|
roomOobData: roomInfo.oob_data,
|
||||||
viaServers: roomInfo.via_servers,
|
|
||||||
ready: true,
|
ready: true,
|
||||||
roomJustCreatedOpts: roomInfo.justCreatedOpts,
|
roomJustCreatedOpts: roomInfo.justCreatedOpts,
|
||||||
}, () => {
|
}, () => {
|
||||||
|
@ -1556,7 +1554,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
} else if (request.pending) {
|
} else if (request.pending) {
|
||||||
ToastStore.sharedInstance().addOrReplaceToast({
|
ToastStore.sharedInstance().addOrReplaceToast({
|
||||||
key: 'verifreq_' + request.channel.transactionId,
|
key: 'verifreq_' + request.channel.transactionId,
|
||||||
title: request.isSelfVerification ? _t("Self-verification request") : _t("Verification Request"),
|
title: _t("Verification requested"),
|
||||||
icon: "verification",
|
icon: "verification",
|
||||||
props: {request},
|
props: {request},
|
||||||
component: sdk.getComponent("toasts.VerificationRequestToast"),
|
component: sdk.getComponent("toasts.VerificationRequestToast"),
|
||||||
|
|
|
@ -46,6 +46,9 @@ function shouldFormContinuation(prevEvent, mxEvent) {
|
||||||
// check if within the max continuation period
|
// check if within the max continuation period
|
||||||
if (mxEvent.getTs() - prevEvent.getTs() > CONTINUATION_MAX_INTERVAL) return false;
|
if (mxEvent.getTs() - prevEvent.getTs() > CONTINUATION_MAX_INTERVAL) return false;
|
||||||
|
|
||||||
|
// As we summarise redactions, do not continue a redacted event onto a non-redacted one and vice-versa
|
||||||
|
if (mxEvent.isRedacted() !== prevEvent.isRedacted()) return false;
|
||||||
|
|
||||||
// Some events should appear as continuations from previous events of different types.
|
// Some events should appear as continuations from previous events of different types.
|
||||||
if (mxEvent.getType() !== prevEvent.getType() &&
|
if (mxEvent.getType() !== prevEvent.getType() &&
|
||||||
(!continuedTypes.includes(mxEvent.getType()) ||
|
(!continuedTypes.includes(mxEvent.getType()) ||
|
||||||
|
@ -452,6 +455,20 @@ export default class MessagePanel extends React.Component {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_getNextEventInfo(arr, i) {
|
||||||
|
const nextEvent = i < arr.length - 1
|
||||||
|
? arr[i + 1]
|
||||||
|
: null;
|
||||||
|
|
||||||
|
// The next event with tile is used to to determine the 'last successful' flag
|
||||||
|
// when rendering the tile. The shouldShowEvent function is pretty quick at what
|
||||||
|
// it does, so this should have no significant cost even when a room is used for
|
||||||
|
// not-chat purposes.
|
||||||
|
const nextTile = arr.slice(i + 1).find(e => this._shouldShowEvent(e));
|
||||||
|
|
||||||
|
return {nextEvent, nextTile};
|
||||||
|
}
|
||||||
|
|
||||||
_getEventTiles() {
|
_getEventTiles() {
|
||||||
this.eventNodes = {};
|
this.eventNodes = {};
|
||||||
|
|
||||||
|
@ -503,6 +520,7 @@ export default class MessagePanel extends React.Component {
|
||||||
const mxEv = this.props.events[i];
|
const mxEv = this.props.events[i];
|
||||||
const eventId = mxEv.getId();
|
const eventId = mxEv.getId();
|
||||||
const last = (mxEv === lastShownEvent);
|
const last = (mxEv === lastShownEvent);
|
||||||
|
const {nextEvent, nextTile} = this._getNextEventInfo(this.props.events, i);
|
||||||
|
|
||||||
if (grouper) {
|
if (grouper) {
|
||||||
if (grouper.shouldGroup(mxEv)) {
|
if (grouper.shouldGroup(mxEv)) {
|
||||||
|
@ -519,22 +537,12 @@ export default class MessagePanel extends React.Component {
|
||||||
|
|
||||||
for (const Grouper of groupers) {
|
for (const Grouper of groupers) {
|
||||||
if (Grouper.canStartGroup(this, mxEv)) {
|
if (Grouper.canStartGroup(this, mxEv)) {
|
||||||
grouper = new Grouper(this, mxEv, prevEvent, lastShownEvent);
|
grouper = new Grouper(this, mxEv, prevEvent, lastShownEvent, nextEvent, nextTile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!grouper) {
|
if (!grouper) {
|
||||||
const wantTile = this._shouldShowEvent(mxEv);
|
const wantTile = this._shouldShowEvent(mxEv);
|
||||||
if (wantTile) {
|
if (wantTile) {
|
||||||
const nextEvent = i < this.props.events.length - 1
|
|
||||||
? this.props.events[i + 1]
|
|
||||||
: null;
|
|
||||||
|
|
||||||
// The next event with tile is used to to determine the 'last successful' flag
|
|
||||||
// when rendering the tile. The shouldShowEvent function is pretty quick at what
|
|
||||||
// it does, so this should have no significant cost even when a room is used for
|
|
||||||
// not-chat purposes.
|
|
||||||
const nextTile = this.props.events.slice(i + 1).find(e => this._shouldShowEvent(e));
|
|
||||||
|
|
||||||
// make sure we unpack the array returned by _getTilesForEvent,
|
// make sure we unpack the array returned by _getTilesForEvent,
|
||||||
// otherwise react will auto-generate keys and we will end up
|
// otherwise react will auto-generate keys and we will end up
|
||||||
// replacing all of the DOM elements every time we paginate.
|
// replacing all of the DOM elements every time we paginate.
|
||||||
|
@ -1032,7 +1040,7 @@ class RedactionGrouper {
|
||||||
return panel._shouldShowEvent(ev) && ev.isRedacted();
|
return panel._shouldShowEvent(ev) && ev.isRedacted();
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(panel, ev, prevEvent, lastShownEvent) {
|
constructor(panel, ev, prevEvent, lastShownEvent, nextEvent, nextEventTile) {
|
||||||
this.panel = panel;
|
this.panel = panel;
|
||||||
this.readMarker = panel._readMarkerForEvent(
|
this.readMarker = panel._readMarkerForEvent(
|
||||||
ev.getId(),
|
ev.getId(),
|
||||||
|
@ -1041,9 +1049,15 @@ class RedactionGrouper {
|
||||||
this.events = [ev];
|
this.events = [ev];
|
||||||
this.prevEvent = prevEvent;
|
this.prevEvent = prevEvent;
|
||||||
this.lastShownEvent = lastShownEvent;
|
this.lastShownEvent = lastShownEvent;
|
||||||
|
this.nextEvent = nextEvent;
|
||||||
|
this.nextEventTile = nextEventTile;
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldGroup(ev) {
|
shouldGroup(ev) {
|
||||||
|
// absorb hidden events so that they do not break up streams of messages & redaction events being grouped
|
||||||
|
if (!this.panel._shouldShowEvent(ev)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (this.panel._wantsDateSeparator(this.events[0], ev.getDate())) {
|
if (this.panel._wantsDateSeparator(this.events[0], ev.getDate())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1055,6 +1069,9 @@ class RedactionGrouper {
|
||||||
ev.getId(),
|
ev.getId(),
|
||||||
ev === this.lastShownEvent,
|
ev === this.lastShownEvent,
|
||||||
);
|
);
|
||||||
|
if (!this.panel._shouldShowEvent(ev)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.events.push(ev);
|
this.events.push(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1080,13 +1097,10 @@ class RedactionGrouper {
|
||||||
);
|
);
|
||||||
|
|
||||||
const senders = new Set();
|
const senders = new Set();
|
||||||
let eventTiles = this.events.map((e) => {
|
let eventTiles = this.events.map((e, i) => {
|
||||||
senders.add(e.sender);
|
senders.add(e.sender);
|
||||||
// In order to prevent DateSeparators from appearing in the expanded form,
|
const prevEvent = i === 0 ? this.prevEvent : this.events[i - 1];
|
||||||
// render each member event as if the previous one was itself.
|
return panel._getTilesForEvent(prevEvent, e, e === lastShownEvent, this.nextEvent, this.nextEventTile);
|
||||||
// This way, the timestamp of the previous event === the
|
|
||||||
// timestamp of the current event, and no DateSeparator is inserted.
|
|
||||||
return panel._getTilesForEvent(e, e, e === lastShownEvent);
|
|
||||||
}).reduce((a, b) => a.concat(b), []);
|
}).reduce((a, b) => a.concat(b), []);
|
||||||
|
|
||||||
if (eventTiles.length === 0) {
|
if (eventTiles.length === 0) {
|
||||||
|
@ -1114,7 +1128,7 @@ class RedactionGrouper {
|
||||||
}
|
}
|
||||||
|
|
||||||
getNewPrevEvent() {
|
getNewPrevEvent() {
|
||||||
return this.events[0];
|
return this.events[this.events.length - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
Copyright 2020, 2021 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.
|
||||||
|
@ -20,12 +20,13 @@ import classNames from "classnames";
|
||||||
import defaultDispatcher from "../../dispatcher/dispatcher";
|
import defaultDispatcher from "../../dispatcher/dispatcher";
|
||||||
import { _t } from "../../languageHandler";
|
import { _t } from "../../languageHandler";
|
||||||
import { ActionPayload } from "../../dispatcher/payloads";
|
import { ActionPayload } from "../../dispatcher/payloads";
|
||||||
import { Key } from "../../Keyboard";
|
|
||||||
import AccessibleButton from "../views/elements/AccessibleButton";
|
import AccessibleButton from "../views/elements/AccessibleButton";
|
||||||
import { Action } from "../../dispatcher/actions";
|
import { Action } from "../../dispatcher/actions";
|
||||||
import RoomListStore from "../../stores/room-list/RoomListStore";
|
import RoomListStore from "../../stores/room-list/RoomListStore";
|
||||||
import { NameFilterCondition } from "../../stores/room-list/filters/NameFilterCondition";
|
import { NameFilterCondition } from "../../stores/room-list/filters/NameFilterCondition";
|
||||||
|
import { getKeyBindingsManager, RoomListAction } from "../../KeyBindingsManager";
|
||||||
import {replaceableComponent} from "../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../utils/replaceableComponent";
|
||||||
|
import SpaceStore, {UPDATE_SELECTED_SPACE} from "../../stores/SpaceStore";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
isMinimized: boolean;
|
isMinimized: boolean;
|
||||||
|
@ -53,6 +54,8 @@ export default class RoomSearch extends React.PureComponent<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.dispatcherRef = defaultDispatcher.register(this.onAction);
|
this.dispatcherRef = defaultDispatcher.register(this.onAction);
|
||||||
|
// clear filter when changing spaces, in future we may wish to maintain a filter per-space
|
||||||
|
SpaceStore.instance.on(UPDATE_SELECTED_SPACE, this.clearInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidUpdate(prevProps: Readonly<IProps>, prevState: Readonly<IState>): void {
|
public componentDidUpdate(prevProps: Readonly<IProps>, prevState: Readonly<IState>): void {
|
||||||
|
@ -72,6 +75,7 @@ export default class RoomSearch extends React.PureComponent<IProps, IState> {
|
||||||
|
|
||||||
public componentWillUnmount() {
|
public componentWillUnmount() {
|
||||||
defaultDispatcher.unregister(this.dispatcherRef);
|
defaultDispatcher.unregister(this.dispatcherRef);
|
||||||
|
SpaceStore.instance.off(UPDATE_SELECTED_SPACE, this.clearInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onAction = (payload: ActionPayload) => {
|
private onAction = (payload: ActionPayload) => {
|
||||||
|
@ -108,18 +112,25 @@ export default class RoomSearch extends React.PureComponent<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private onKeyDown = (ev: React.KeyboardEvent) => {
|
private onKeyDown = (ev: React.KeyboardEvent) => {
|
||||||
if (ev.key === Key.ESCAPE) {
|
const action = getKeyBindingsManager().getRoomListAction(ev);
|
||||||
this.clearInput();
|
switch (action) {
|
||||||
defaultDispatcher.fire(Action.FocusComposer);
|
case RoomListAction.ClearSearch:
|
||||||
} else if (ev.key === Key.ARROW_UP || ev.key === Key.ARROW_DOWN) {
|
this.clearInput();
|
||||||
this.props.onVerticalArrow(ev);
|
defaultDispatcher.fire(Action.FocusComposer);
|
||||||
} else if (ev.key === Key.ENTER) {
|
break;
|
||||||
const shouldClear = this.props.onEnter(ev);
|
case RoomListAction.NextRoom:
|
||||||
if (shouldClear) {
|
case RoomListAction.PrevRoom:
|
||||||
// wrap in set immediate to delay it so that we don't clear the filter & then change room
|
this.props.onVerticalArrow(ev);
|
||||||
setImmediate(() => {
|
break;
|
||||||
this.clearInput();
|
case RoomListAction.SelectRoom: {
|
||||||
});
|
const shouldClear = this.props.onEnter(ev);
|
||||||
|
if (shouldClear) {
|
||||||
|
// wrap in set immediate to delay it so that we don't clear the filter & then change room
|
||||||
|
setImmediate(() => {
|
||||||
|
this.clearInput();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,7 +40,6 @@ import Tinter from '../../Tinter';
|
||||||
import rateLimitedFunc from '../../ratelimitedfunc';
|
import rateLimitedFunc from '../../ratelimitedfunc';
|
||||||
import * as Rooms from '../../Rooms';
|
import * as Rooms from '../../Rooms';
|
||||||
import eventSearch, { searchPagination } from '../../Searching';
|
import eventSearch, { searchPagination } from '../../Searching';
|
||||||
import { isOnlyCtrlOrCmdIgnoreShiftKeyEvent, Key } from '../../Keyboard';
|
|
||||||
import MainSplit from './MainSplit';
|
import MainSplit from './MainSplit';
|
||||||
import RightPanel from './RightPanel';
|
import RightPanel from './RightPanel';
|
||||||
import RoomViewStore from '../../stores/RoomViewStore';
|
import RoomViewStore from '../../stores/RoomViewStore';
|
||||||
|
@ -79,6 +78,7 @@ import Notifier from "../../Notifier";
|
||||||
import { showToast as showNotificationsToast } from "../../toasts/DesktopNotificationsToast";
|
import { showToast as showNotificationsToast } from "../../toasts/DesktopNotificationsToast";
|
||||||
import { RoomNotificationStateStore } from "../../stores/notifications/RoomNotificationStateStore";
|
import { RoomNotificationStateStore } from "../../stores/notifications/RoomNotificationStateStore";
|
||||||
import { Container, WidgetLayoutStore } from "../../stores/widgets/WidgetLayoutStore";
|
import { Container, WidgetLayoutStore } from "../../stores/widgets/WidgetLayoutStore";
|
||||||
|
import { getKeyBindingsManager, RoomAction } from '../../KeyBindingsManager';
|
||||||
import { objectHasDiff } from "../../utils/objects";
|
import { objectHasDiff } from "../../utils/objects";
|
||||||
import SpaceRoomView from "./SpaceRoomView";
|
import SpaceRoomView from "./SpaceRoomView";
|
||||||
import { IOpts } from "../../createRoom";
|
import { IOpts } from "../../createRoom";
|
||||||
|
@ -112,10 +112,6 @@ interface IProps {
|
||||||
inviterName?: string;
|
inviterName?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Servers the RoomView can use to try and assist joins
|
|
||||||
viaServers?: string[];
|
|
||||||
|
|
||||||
autoJoin?: boolean;
|
|
||||||
resizeNotifier: ResizeNotifier;
|
resizeNotifier: ResizeNotifier;
|
||||||
justCreatedOpts?: IOpts;
|
justCreatedOpts?: IOpts;
|
||||||
|
|
||||||
|
@ -450,9 +446,7 @@ export default class RoomView extends React.Component<IProps, IState> {
|
||||||
// now not joined because the js-sdk peeking API will clobber our historical room,
|
// now not joined because the js-sdk peeking API will clobber our historical room,
|
||||||
// making it impossible to indicate a newly joined room.
|
// making it impossible to indicate a newly joined room.
|
||||||
if (!joining && roomId) {
|
if (!joining && roomId) {
|
||||||
if (this.props.autoJoin) {
|
if (!room && shouldPeek) {
|
||||||
this.onJoinButtonClicked();
|
|
||||||
} else if (!room && shouldPeek) {
|
|
||||||
console.info("Attempting to peek into room %s", roomId);
|
console.info("Attempting to peek into room %s", roomId);
|
||||||
this.setState({
|
this.setState({
|
||||||
peekLoading: true,
|
peekLoading: true,
|
||||||
|
@ -668,26 +662,20 @@ export default class RoomView extends React.Component<IProps, IState> {
|
||||||
private onReactKeyDown = ev => {
|
private onReactKeyDown = ev => {
|
||||||
let handled = false;
|
let handled = false;
|
||||||
|
|
||||||
switch (ev.key) {
|
const action = getKeyBindingsManager().getRoomAction(ev);
|
||||||
case Key.ESCAPE:
|
switch (action) {
|
||||||
if (!ev.altKey && !ev.ctrlKey && !ev.shiftKey && !ev.metaKey) {
|
case RoomAction.DismissReadMarker:
|
||||||
this.messagePanel.forgetReadMarker();
|
this.messagePanel.forgetReadMarker();
|
||||||
this.jumpToLiveTimeline();
|
this.jumpToLiveTimeline();
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Key.PAGE_UP:
|
case RoomAction.JumpToOldestUnread:
|
||||||
if (!ev.altKey && !ev.ctrlKey && ev.shiftKey && !ev.metaKey) {
|
this.jumpToReadMarker();
|
||||||
this.jumpToReadMarker();
|
handled = true;
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Key.U: // Mac returns lowercase
|
case RoomAction.UploadFile:
|
||||||
case Key.U.toUpperCase():
|
dis.dispatch({ action: "upload_file" }, true);
|
||||||
if (isOnlyCtrlOrCmdIgnoreShiftKeyEvent(ev) && ev.shiftKey) {
|
handled = true;
|
||||||
dis.dispatch({ action: "upload_file" }, true);
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1123,7 +1111,7 @@ export default class RoomView extends React.Component<IProps, IState> {
|
||||||
const signUrl = this.props.threepidInvite?.signUrl;
|
const signUrl = this.props.threepidInvite?.signUrl;
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'join_room',
|
action: 'join_room',
|
||||||
opts: { inviteSignUrl: signUrl, viaServers: this.props.viaServers },
|
opts: { inviteSignUrl: signUrl },
|
||||||
_type: "unknown", // TODO: instrumentation
|
_type: "unknown", // TODO: instrumentation
|
||||||
});
|
});
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
|
|
|
@ -32,6 +32,8 @@ export default class SearchBox extends React.Component {
|
||||||
onKeyDown: PropTypes.func,
|
onKeyDown: PropTypes.func,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
placeholder: PropTypes.string.isRequired,
|
placeholder: PropTypes.string.isRequired,
|
||||||
|
autoFocus: PropTypes.bool,
|
||||||
|
initialValue: PropTypes.string,
|
||||||
|
|
||||||
// If true, the search box will focus and clear itself
|
// If true, the search box will focus and clear itself
|
||||||
// on room search focus action (it would be nicer to take
|
// on room search focus action (it would be nicer to take
|
||||||
|
@ -49,7 +51,7 @@ export default class SearchBox extends React.Component {
|
||||||
this._search = createRef();
|
this._search = createRef();
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
searchTerm: "",
|
searchTerm: this.props.initialValue || "",
|
||||||
blurred: true,
|
blurred: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -158,6 +160,7 @@ export default class SearchBox extends React.Component {
|
||||||
onBlur={this._onBlur}
|
onBlur={this._onBlur}
|
||||||
placeholder={ placeholder }
|
placeholder={ placeholder }
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
|
autoFocus={this.props.autoFocus}
|
||||||
/>
|
/>
|
||||||
{ clearButton }
|
{ clearButton }
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,32 +14,37 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {useMemo, useRef, useState} from "react";
|
import React, {useMemo, useState} from "react";
|
||||||
import Room from "matrix-js-sdk/src/models/room";
|
import {Room} from "matrix-js-sdk/src/models/room";
|
||||||
import MatrixEvent from "matrix-js-sdk/src/models/event";
|
import {MatrixClient} from "matrix-js-sdk/src/client";
|
||||||
import {EventType, RoomType} from "matrix-js-sdk/src/@types/event";
|
import {EventType, RoomType} from "matrix-js-sdk/src/@types/event";
|
||||||
|
import classNames from "classnames";
|
||||||
|
import {sortBy} from "lodash";
|
||||||
|
|
||||||
import {MatrixClientPeg} from "../../MatrixClientPeg";
|
import {MatrixClientPeg} from "../../MatrixClientPeg";
|
||||||
import dis from "../../dispatcher/dispatcher";
|
import dis from "../../dispatcher/dispatcher";
|
||||||
import {_t} from "../../languageHandler";
|
import {_t} from "../../languageHandler";
|
||||||
import AccessibleButton from "../views/elements/AccessibleButton";
|
import AccessibleButton from "../views/elements/AccessibleButton";
|
||||||
import BaseDialog from "../views/dialogs/BaseDialog";
|
import BaseDialog from "../views/dialogs/BaseDialog";
|
||||||
import FormButton from "../views/elements/FormButton";
|
import Spinner from "../views/elements/Spinner";
|
||||||
import SearchBox from "./SearchBox";
|
import SearchBox from "./SearchBox";
|
||||||
import RoomAvatar from "../views/avatars/RoomAvatar";
|
import RoomAvatar from "../views/avatars/RoomAvatar";
|
||||||
import RoomName from "../views/elements/RoomName";
|
import RoomName from "../views/elements/RoomName";
|
||||||
import {useAsyncMemo} from "../../hooks/useAsyncMemo";
|
import {useAsyncMemo} from "../../hooks/useAsyncMemo";
|
||||||
import {shouldShowSpaceSettings} from "../../utils/space";
|
|
||||||
import {EnhancedMap} from "../../utils/maps";
|
import {EnhancedMap} from "../../utils/maps";
|
||||||
import StyledCheckbox from "../views/elements/StyledCheckbox";
|
import StyledCheckbox from "../views/elements/StyledCheckbox";
|
||||||
import AutoHideScrollbar from "./AutoHideScrollbar";
|
import AutoHideScrollbar from "./AutoHideScrollbar";
|
||||||
import BaseAvatar from "../views/avatars/BaseAvatar";
|
import BaseAvatar from "../views/avatars/BaseAvatar";
|
||||||
import {mediaFromMxc} from "../../customisations/Media";
|
import {mediaFromMxc} from "../../customisations/Media";
|
||||||
|
import InfoTooltip from "../views/elements/InfoTooltip";
|
||||||
|
import TextWithTooltip from "../views/elements/TextWithTooltip";
|
||||||
|
import {useStateToggle} from "../../hooks/useStateToggle";
|
||||||
|
|
||||||
interface IProps {
|
interface IHierarchyProps {
|
||||||
space: Room;
|
space: Room;
|
||||||
initialText?: string;
|
initialText?: string;
|
||||||
onFinished(): void;
|
refreshToken?: any;
|
||||||
|
showRoom(room: ISpaceSummaryRoom, viaServers?: string[], autoJoin?: boolean): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
|
@ -72,227 +77,131 @@ export interface ISpaceSummaryEvent {
|
||||||
}
|
}
|
||||||
/* eslint-enable camelcase */
|
/* eslint-enable camelcase */
|
||||||
|
|
||||||
interface ISubspaceProps {
|
interface ITileProps {
|
||||||
space: ISpaceSummaryRoom;
|
room: ISpaceSummaryRoom;
|
||||||
event?: MatrixEvent;
|
suggested?: boolean;
|
||||||
editing?: boolean;
|
selected?: boolean;
|
||||||
onPreviewClick?(): void;
|
numChildRooms?: number;
|
||||||
queueAction?(action: IAction): void;
|
hasPermissions?: boolean;
|
||||||
onJoinClick?(): void;
|
onViewRoomClick(autoJoin: boolean): void;
|
||||||
|
onToggleClick?(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SubSpace: React.FC<ISubspaceProps> = ({
|
const Tile: React.FC<ITileProps> = ({
|
||||||
space,
|
room,
|
||||||
editing,
|
suggested,
|
||||||
event,
|
selected,
|
||||||
queueAction,
|
hasPermissions,
|
||||||
onJoinClick,
|
onToggleClick,
|
||||||
onPreviewClick,
|
onViewRoomClick,
|
||||||
|
numChildRooms,
|
||||||
children,
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
const name = space.name || space.canonical_alias || space.aliases?.[0] || _t("Unnamed Space");
|
const name = room.name || room.canonical_alias || room.aliases?.[0]
|
||||||
|
|| (room.room_type === RoomType.Space ? _t("Unnamed Space") : _t("Unnamed Room"));
|
||||||
|
|
||||||
const evContent = event?.getContent();
|
const [showChildren, toggleShowChildren] = useStateToggle(true);
|
||||||
const [suggested, _setSuggested] = useState(evContent?.suggested);
|
|
||||||
const [removed, _setRemoved] = useState(!evContent?.via);
|
|
||||||
|
|
||||||
const cli = MatrixClientPeg.get();
|
|
||||||
const cliRoom = cli.getRoom(space.room_id);
|
|
||||||
const myMembership = cliRoom?.getMyMembership();
|
|
||||||
|
|
||||||
// TODO DRY code
|
|
||||||
let actions;
|
|
||||||
if (editing && queueAction) {
|
|
||||||
if (event && cli.getRoom(event.getRoomId())?.currentState.maySendStateEvent(event.getType(), cli.getUserId())) {
|
|
||||||
const setSuggested = () => {
|
|
||||||
_setSuggested(v => {
|
|
||||||
queueAction({
|
|
||||||
event,
|
|
||||||
removed,
|
|
||||||
suggested: !v,
|
|
||||||
});
|
|
||||||
return !v;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const setRemoved = () => {
|
|
||||||
_setRemoved(v => {
|
|
||||||
queueAction({
|
|
||||||
event,
|
|
||||||
removed: !v,
|
|
||||||
suggested,
|
|
||||||
});
|
|
||||||
return !v;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
if (removed) {
|
|
||||||
actions = <React.Fragment>
|
|
||||||
<FormButton kind="danger" onClick={setRemoved} label={_t("Undo")} />
|
|
||||||
</React.Fragment>;
|
|
||||||
} else {
|
|
||||||
actions = <React.Fragment>
|
|
||||||
<FormButton kind="danger" onClick={setRemoved} label={_t("Remove from Space")} />
|
|
||||||
<StyledCheckbox checked={suggested} onChange={setSuggested} />
|
|
||||||
</React.Fragment>;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
actions = <span className="mx_SpaceRoomDirectory_actionsText">
|
|
||||||
{ _t("No permissions")}
|
|
||||||
</span>;
|
|
||||||
}
|
|
||||||
// TODO confirm remove from space click behaviour here
|
|
||||||
} else {
|
|
||||||
if (myMembership === "join") {
|
|
||||||
actions = <span className="mx_SpaceRoomDirectory_actionsText">
|
|
||||||
{ _t("You're in this space")}
|
|
||||||
</span>;
|
|
||||||
} else if (onJoinClick) {
|
|
||||||
actions = <React.Fragment>
|
|
||||||
<AccessibleButton onClick={onPreviewClick} kind="link">
|
|
||||||
{ _t("Preview") }
|
|
||||||
</AccessibleButton>
|
|
||||||
<FormButton onClick={onJoinClick} label={_t("Join")} />
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let url: string;
|
|
||||||
if (space.avatar_url) {
|
|
||||||
url = mediaFromMxc(space.avatar_url).getSquareThumbnailHttp(Math.floor(24 * window.devicePixelRatio));
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div className="mx_SpaceRoomDirectory_subspace">
|
|
||||||
<div className="mx_SpaceRoomDirectory_subspace_info">
|
|
||||||
<BaseAvatar name={name} idName={space.room_id} url={url} width={24} height={24} />
|
|
||||||
{ name }
|
|
||||||
|
|
||||||
<div className="mx_SpaceRoomDirectory_actions">
|
|
||||||
{ actions }
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="mx_SpaceRoomDirectory_subspace_children">
|
|
||||||
{ children }
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
};
|
|
||||||
|
|
||||||
interface IAction {
|
|
||||||
event: MatrixEvent;
|
|
||||||
suggested: boolean;
|
|
||||||
removed: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IRoomTileProps {
|
|
||||||
room: ISpaceSummaryRoom;
|
|
||||||
event?: MatrixEvent;
|
|
||||||
editing?: boolean;
|
|
||||||
onPreviewClick(): void;
|
|
||||||
queueAction?(action: IAction): void;
|
|
||||||
onJoinClick?(): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const RoomTile = ({ room, event, editing, queueAction, onPreviewClick, onJoinClick }: IRoomTileProps) => {
|
|
||||||
const name = room.name || room.canonical_alias || room.aliases?.[0] || _t("Unnamed Room");
|
|
||||||
|
|
||||||
const evContent = event?.getContent();
|
|
||||||
const [suggested, _setSuggested] = useState(evContent?.suggested);
|
|
||||||
const [removed, _setRemoved] = useState(!evContent?.via);
|
|
||||||
|
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const cliRoom = cli.getRoom(room.room_id);
|
const cliRoom = cli.getRoom(room.room_id);
|
||||||
const myMembership = cliRoom?.getMyMembership();
|
const myMembership = cliRoom?.getMyMembership();
|
||||||
|
|
||||||
let actions;
|
const onPreviewClick = () => onViewRoomClick(false);
|
||||||
if (editing && queueAction) {
|
const onJoinClick = () => onViewRoomClick(true);
|
||||||
if (event && cli.getRoom(event.getRoomId())?.currentState.maySendStateEvent(event.getType(), cli.getUserId())) {
|
|
||||||
const setSuggested = () => {
|
|
||||||
_setSuggested(v => {
|
|
||||||
queueAction({
|
|
||||||
event,
|
|
||||||
removed,
|
|
||||||
suggested: !v,
|
|
||||||
});
|
|
||||||
return !v;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const setRemoved = () => {
|
let button;
|
||||||
_setRemoved(v => {
|
if (myMembership === "join") {
|
||||||
queueAction({
|
button = <AccessibleButton onClick={onPreviewClick} kind="primary_outline">
|
||||||
event,
|
{ _t("View") }
|
||||||
removed: !v,
|
</AccessibleButton>;
|
||||||
suggested,
|
} else if (onJoinClick) {
|
||||||
});
|
button = <AccessibleButton onClick={onJoinClick} kind="primary">
|
||||||
return !v;
|
{ _t("Join") }
|
||||||
});
|
</AccessibleButton>;
|
||||||
};
|
}
|
||||||
|
|
||||||
if (removed) {
|
let checkbox;
|
||||||
actions = <React.Fragment>
|
if (onToggleClick) {
|
||||||
<FormButton kind="danger" onClick={setRemoved} label={_t("Undo")} />
|
if (hasPermissions) {
|
||||||
</React.Fragment>;
|
checkbox = <StyledCheckbox checked={!!selected} onChange={onToggleClick} />;
|
||||||
} else {
|
|
||||||
actions = <React.Fragment>
|
|
||||||
<FormButton kind="danger" onClick={setRemoved} label={_t("Remove from Space")} />
|
|
||||||
<StyledCheckbox checked={suggested} onChange={setSuggested} />
|
|
||||||
</React.Fragment>;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
actions = <span className="mx_SpaceRoomDirectory_actionsText">
|
checkbox = <TextWithTooltip
|
||||||
{ _t("No permissions")}
|
tooltip={_t("You don't have permission")}
|
||||||
</span>;
|
onClick={ev => { ev.stopPropagation() }}
|
||||||
}
|
>
|
||||||
// TODO confirm remove from space click behaviour here
|
<StyledCheckbox disabled={true} />
|
||||||
} else {
|
</TextWithTooltip>;
|
||||||
if (myMembership === "join") {
|
|
||||||
actions = <span className="mx_SpaceRoomDirectory_actionsText">
|
|
||||||
{ _t("You're in this room")}
|
|
||||||
</span>;
|
|
||||||
} else if (onJoinClick) {
|
|
||||||
actions = <React.Fragment>
|
|
||||||
<AccessibleButton onClick={onPreviewClick} kind="link">
|
|
||||||
{ _t("Preview") }
|
|
||||||
</AccessibleButton>
|
|
||||||
<FormButton onClick={onJoinClick} label={_t("Join")} />
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let url: string;
|
let url: string;
|
||||||
if (room.avatar_url) {
|
if (room.avatar_url) {
|
||||||
url = mediaFromMxc(room.avatar_url).getSquareThumbnailHttp(Math.floor(32 * window.devicePixelRatio));
|
url = mediaFromMxc(room.avatar_url).getSquareThumbnailHttp(Math.floor(20 * window.devicePixelRatio));
|
||||||
|
}
|
||||||
|
|
||||||
|
let description = _t("%(count)s members", { count: room.num_joined_members });
|
||||||
|
if (numChildRooms) {
|
||||||
|
description += " · " + _t("%(count)s rooms", { count: numChildRooms });
|
||||||
|
}
|
||||||
|
if (room.topic) {
|
||||||
|
description += " · " + room.topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
let suggestedSection;
|
||||||
|
if (suggested) {
|
||||||
|
suggestedSection = <InfoTooltip tooltip={_t("This room is suggested as a good one to join")}>
|
||||||
|
{ _t("Suggested") }
|
||||||
|
</InfoTooltip>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const content = <React.Fragment>
|
const content = <React.Fragment>
|
||||||
<BaseAvatar name={name} idName={room.room_id} url={url} width={32} height={32} />
|
<BaseAvatar name={name} idName={room.room_id} url={url} width={20} height={20} />
|
||||||
|
<div className="mx_SpaceRoomDirectory_roomTile_name">
|
||||||
|
{ name }
|
||||||
|
{ suggestedSection }
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="mx_SpaceRoomDirectory_roomTile_info">
|
<div className="mx_SpaceRoomDirectory_roomTile_info">
|
||||||
<div className="mx_SpaceRoomDirectory_roomTile_name">
|
{ description }
|
||||||
{ name }
|
|
||||||
</div>
|
|
||||||
<div className="mx_SpaceRoomDirectory_roomTile_topic">
|
|
||||||
{ room.topic }
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_SpaceRoomDirectory_roomTile_memberCount">
|
|
||||||
{ room.num_joined_members }
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mx_SpaceRoomDirectory_actions">
|
<div className="mx_SpaceRoomDirectory_actions">
|
||||||
{ actions }
|
{ button }
|
||||||
|
{ checkbox }
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
|
|
||||||
if (editing) {
|
let childToggle;
|
||||||
return <div className="mx_SpaceRoomDirectory_roomTile">
|
let childSection;
|
||||||
{ content }
|
if (children) {
|
||||||
</div>
|
// the chevron is purposefully a div rather than a button as it should be ignored for a11y
|
||||||
|
childToggle = <div
|
||||||
|
className={classNames("mx_SpaceRoomDirectory_subspace_toggle", {
|
||||||
|
mx_SpaceRoomDirectory_subspace_toggle_shown: showChildren,
|
||||||
|
})}
|
||||||
|
onClick={ev => {
|
||||||
|
ev.stopPropagation();
|
||||||
|
toggleShowChildren();
|
||||||
|
}}
|
||||||
|
/>;
|
||||||
|
if (showChildren) {
|
||||||
|
childSection = <div className="mx_SpaceRoomDirectory_subspace_children">
|
||||||
|
{ children }
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return <AccessibleButton className="mx_SpaceRoomDirectory_roomTile" onClick={onPreviewClick}>
|
return <>
|
||||||
{ content }
|
<AccessibleButton
|
||||||
</AccessibleButton>;
|
className={classNames("mx_SpaceRoomDirectory_roomTile", {
|
||||||
|
mx_SpaceRoomDirectory_subspace: room.room_type === RoomType.Space,
|
||||||
|
})}
|
||||||
|
onClick={(hasPermissions && onToggleClick) ? onToggleClick : onPreviewClick}
|
||||||
|
>
|
||||||
|
{ content }
|
||||||
|
{ childToggle }
|
||||||
|
</AccessibleButton>
|
||||||
|
{ childSection }
|
||||||
|
</>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const showRoom = (room: ISpaceSummaryRoom, viaServers?: string[], autoJoin = false) => {
|
export const showRoom = (room: ISpaceSummaryRoom, viaServers?: string[], autoJoin = false) => {
|
||||||
|
@ -325,99 +234,337 @@ export const showRoom = (room: ISpaceSummaryRoom, viaServers?: string[], autoJoi
|
||||||
interface IHierarchyLevelProps {
|
interface IHierarchyLevelProps {
|
||||||
spaceId: string;
|
spaceId: string;
|
||||||
rooms: Map<string, ISpaceSummaryRoom>;
|
rooms: Map<string, ISpaceSummaryRoom>;
|
||||||
editing?: boolean;
|
relations: Map<string, Map<string, ISpaceSummaryEvent>>;
|
||||||
relations: EnhancedMap<string, string[]>;
|
|
||||||
parents: Set<string>;
|
parents: Set<string>;
|
||||||
queueAction?(action: IAction): void;
|
selectedMap?: Map<string, Set<string>>;
|
||||||
onPreviewClick(roomId: string): void;
|
onViewRoomClick(roomId: string, autoJoin: boolean): void;
|
||||||
onRemoveFromSpaceClick?(roomId: string): void;
|
onToggleClick?(parentId: string, childId: string): void;
|
||||||
onJoinClick?(roomId: string): void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const HierarchyLevel = ({
|
export const HierarchyLevel = ({
|
||||||
spaceId,
|
spaceId,
|
||||||
rooms,
|
rooms,
|
||||||
editing,
|
|
||||||
relations,
|
relations,
|
||||||
parents,
|
parents,
|
||||||
onPreviewClick,
|
selectedMap,
|
||||||
onJoinClick,
|
onViewRoomClick,
|
||||||
queueAction,
|
onToggleClick,
|
||||||
}: IHierarchyLevelProps) => {
|
}: IHierarchyLevelProps) => {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const space = cli.getRoom(spaceId);
|
const space = cli.getRoom(spaceId);
|
||||||
// TODO respect order
|
const hasPermissions = space?.currentState.maySendStateEvent(EventType.SpaceChild, cli.getUserId());
|
||||||
const [subspaces, childRooms] = relations.get(spaceId)?.reduce((result, roomId: string) => {
|
|
||||||
if (!rooms.has(roomId)) return result; // TODO wat
|
const sortedChildren = sortBy([...(relations.get(spaceId)?.values() || [])], ev => ev.content.order || null);
|
||||||
|
const [subspaces, childRooms] = sortedChildren.reduce((result, ev: ISpaceSummaryEvent) => {
|
||||||
|
const roomId = ev.state_key;
|
||||||
|
if (!rooms.has(roomId)) return result;
|
||||||
result[rooms.get(roomId).room_type === RoomType.Space ? 0 : 1].push(roomId);
|
result[rooms.get(roomId).room_type === RoomType.Space ? 0 : 1].push(roomId);
|
||||||
return result;
|
return result;
|
||||||
}, [[], []]) || [[], []];
|
}, [[], []]) || [[], []];
|
||||||
|
|
||||||
// Don't render this subspace if it has no rooms we can show
|
|
||||||
// TODO this is broken - as a space may have subspaces we still need to show
|
|
||||||
// if (!childRooms.length) return null;
|
|
||||||
|
|
||||||
const userId = cli.getUserId();
|
|
||||||
|
|
||||||
const newParents = new Set(parents).add(spaceId);
|
const newParents = new Set(parents).add(spaceId);
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
{
|
{
|
||||||
childRooms.map(roomId => (
|
childRooms.map(roomId => (
|
||||||
<RoomTile
|
<Tile
|
||||||
key={roomId}
|
key={roomId}
|
||||||
room={rooms.get(roomId)}
|
room={rooms.get(roomId)}
|
||||||
event={space?.currentState.maySendStateEvent(EventType.SpaceChild, userId)
|
suggested={relations.get(spaceId)?.get(roomId)?.content.suggested}
|
||||||
? space?.currentState.getStateEvents(EventType.SpaceChild, roomId)
|
selected={selectedMap?.get(spaceId)?.has(roomId)}
|
||||||
: undefined}
|
onViewRoomClick={(autoJoin) => {
|
||||||
editing={editing}
|
onViewRoomClick(roomId, autoJoin);
|
||||||
queueAction={queueAction}
|
|
||||||
onPreviewClick={() => {
|
|
||||||
onPreviewClick(roomId);
|
|
||||||
}}
|
}}
|
||||||
onJoinClick={onJoinClick ? () => {
|
hasPermissions={hasPermissions}
|
||||||
onJoinClick(roomId);
|
onToggleClick={onToggleClick ? () => onToggleClick(spaceId, roomId) : undefined}
|
||||||
} : undefined}
|
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
subspaces.filter(roomId => !newParents.has(roomId)).map(roomId => (
|
subspaces.filter(roomId => !newParents.has(roomId)).map(roomId => (
|
||||||
<SubSpace
|
<Tile
|
||||||
key={roomId}
|
key={roomId}
|
||||||
space={rooms.get(roomId)}
|
room={rooms.get(roomId)}
|
||||||
event={space?.currentState.getStateEvents(EventType.SpaceChild, roomId)}
|
numChildRooms={Array.from(relations.get(roomId)?.values() || [])
|
||||||
editing={editing}
|
.filter(ev => rooms.get(ev.state_key)?.room_type !== RoomType.Space).length}
|
||||||
queueAction={queueAction}
|
suggested={relations.get(spaceId)?.get(roomId)?.content.suggested}
|
||||||
onPreviewClick={() => {
|
selected={selectedMap?.get(spaceId)?.has(roomId)}
|
||||||
onPreviewClick(roomId);
|
onViewRoomClick={(autoJoin) => {
|
||||||
}}
|
onViewRoomClick(roomId, autoJoin);
|
||||||
onJoinClick={() => {
|
|
||||||
onJoinClick(roomId);
|
|
||||||
}}
|
}}
|
||||||
|
hasPermissions={hasPermissions}
|
||||||
|
onToggleClick={onToggleClick ? () => onToggleClick(spaceId, roomId) : undefined}
|
||||||
>
|
>
|
||||||
<HierarchyLevel
|
<HierarchyLevel
|
||||||
spaceId={roomId}
|
spaceId={roomId}
|
||||||
rooms={rooms}
|
rooms={rooms}
|
||||||
editing={editing}
|
|
||||||
relations={relations}
|
relations={relations}
|
||||||
parents={newParents}
|
parents={newParents}
|
||||||
onPreviewClick={onPreviewClick}
|
selectedMap={selectedMap}
|
||||||
onJoinClick={onJoinClick}
|
onViewRoomClick={onViewRoomClick}
|
||||||
queueAction={queueAction}
|
onToggleClick={onToggleClick}
|
||||||
/>
|
/>
|
||||||
</SubSpace>
|
</Tile>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
};
|
};
|
||||||
|
|
||||||
const SpaceRoomDirectory: React.FC<IProps> = ({ space, initialText = "", onFinished }) => {
|
// mutate argument refreshToken to force a reload
|
||||||
|
export const useSpaceSummary = (cli: MatrixClient, space: Room, refreshToken?: any): [
|
||||||
|
ISpaceSummaryRoom[],
|
||||||
|
Map<string, Map<string, ISpaceSummaryEvent>>,
|
||||||
|
Map<string, Set<string>>,
|
||||||
|
Map<string, Set<string>>,
|
||||||
|
] | [] => {
|
||||||
// TODO pagination
|
// TODO pagination
|
||||||
const cli = MatrixClientPeg.get();
|
return useAsyncMemo(async () => {
|
||||||
const [query, setQuery] = useState(initialText);
|
try {
|
||||||
const [isEditing, setIsEditing] = useState(false);
|
const data = await cli.getSpaceSummary(space.roomId);
|
||||||
|
|
||||||
|
const parentChildRelations = new EnhancedMap<string, Map<string, ISpaceSummaryEvent>>();
|
||||||
|
const childParentRelations = new EnhancedMap<string, Set<string>>();
|
||||||
|
const viaMap = new EnhancedMap<string, Set<string>>();
|
||||||
|
data.events.map((ev: ISpaceSummaryEvent) => {
|
||||||
|
if (ev.type === EventType.SpaceChild) {
|
||||||
|
parentChildRelations.getOrCreate(ev.room_id, new Map()).set(ev.state_key, ev);
|
||||||
|
childParentRelations.getOrCreate(ev.state_key, new Set()).add(ev.room_id);
|
||||||
|
}
|
||||||
|
if (Array.isArray(ev.content["via"])) {
|
||||||
|
const set = viaMap.getOrCreate(ev.state_key, new Set());
|
||||||
|
ev.content["via"].forEach(via => set.add(via));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return [data.rooms as ISpaceSummaryRoom[], parentChildRelations, viaMap, childParentRelations];
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}, [space, refreshToken], []);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SpaceHierarchy: React.FC<IHierarchyProps> = ({
|
||||||
|
space,
|
||||||
|
initialText = "",
|
||||||
|
showRoom,
|
||||||
|
refreshToken,
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const cli = MatrixClientPeg.get();
|
||||||
|
const userId = cli.getUserId();
|
||||||
|
const [query, setQuery] = useState(initialText);
|
||||||
|
|
||||||
|
const [selected, setSelected] = useState(new Map<string, Set<string>>()); // Map<parentId, Set<childId>>
|
||||||
|
|
||||||
|
const [rooms, parentChildMap, viaMap, childParentMap] = useSpaceSummary(cli, space, refreshToken);
|
||||||
|
|
||||||
|
const roomsMap = useMemo(() => {
|
||||||
|
if (!rooms) return null;
|
||||||
|
const lcQuery = query.toLowerCase().trim();
|
||||||
|
|
||||||
|
const roomsMap = new Map<string, ISpaceSummaryRoom>(rooms.map(r => [r.room_id, r]));
|
||||||
|
if (!lcQuery) return roomsMap;
|
||||||
|
|
||||||
|
const directMatches = rooms.filter(r => {
|
||||||
|
return r.name?.toLowerCase().includes(lcQuery) || r.topic?.toLowerCase().includes(lcQuery);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Walk back up the tree to find all parents of the direct matches to show their place in the hierarchy
|
||||||
|
const visited = new Set<string>();
|
||||||
|
const queue = [...directMatches.map(r => r.room_id)];
|
||||||
|
while (queue.length) {
|
||||||
|
const roomId = queue.pop();
|
||||||
|
visited.add(roomId);
|
||||||
|
childParentMap.get(roomId)?.forEach(parentId => {
|
||||||
|
if (!visited.has(parentId)) {
|
||||||
|
queue.push(parentId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove any mappings for rooms which were not visited in the walk
|
||||||
|
Array.from(roomsMap.keys()).forEach(roomId => {
|
||||||
|
if (!visited.has(roomId)) {
|
||||||
|
roomsMap.delete(roomId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return roomsMap;
|
||||||
|
}, [rooms, childParentMap, query]);
|
||||||
|
|
||||||
|
const [error, setError] = useState("");
|
||||||
|
const [removing, setRemoving] = useState(false);
|
||||||
|
const [saving, setSaving] = useState(false);
|
||||||
|
|
||||||
|
let content;
|
||||||
|
if (roomsMap) {
|
||||||
|
const numRooms = Array.from(roomsMap.values()).filter(r => r.room_type !== RoomType.Space).length;
|
||||||
|
const numSpaces = roomsMap.size - numRooms - 1; // -1 at the end to exclude the space we are looking at
|
||||||
|
|
||||||
|
let countsStr;
|
||||||
|
if (numSpaces > 1) {
|
||||||
|
countsStr = _t("%(count)s rooms and %(numSpaces)s spaces", { count: numRooms, numSpaces });
|
||||||
|
} else if (numSpaces > 0) {
|
||||||
|
countsStr = _t("%(count)s rooms and 1 space", { count: numRooms, numSpaces });
|
||||||
|
} else {
|
||||||
|
countsStr = _t("%(count)s rooms", { count: numRooms, numSpaces });
|
||||||
|
}
|
||||||
|
|
||||||
|
let editSection;
|
||||||
|
if (space.getMyMembership() === "join" && space.currentState.maySendStateEvent(EventType.SpaceChild, userId)) {
|
||||||
|
const selectedRelations = Array.from(selected.keys()).flatMap(parentId => {
|
||||||
|
return [...selected.get(parentId).values()].map(childId => [parentId, childId]) as [string, string][];
|
||||||
|
});
|
||||||
|
|
||||||
|
let buttons;
|
||||||
|
if (selectedRelations.length) {
|
||||||
|
const selectionAllSuggested = selectedRelations.every(([parentId, childId]) => {
|
||||||
|
return parentChildMap.get(parentId)?.get(childId)?.content.suggested;
|
||||||
|
});
|
||||||
|
|
||||||
|
const disabled = removing || saving;
|
||||||
|
|
||||||
|
buttons = <>
|
||||||
|
<AccessibleButton
|
||||||
|
onClick={async () => {
|
||||||
|
setRemoving(true);
|
||||||
|
try {
|
||||||
|
for (const [parentId, childId] of selectedRelations) {
|
||||||
|
await cli.sendStateEvent(parentId, EventType.SpaceChild, {}, childId);
|
||||||
|
parentChildMap.get(parentId).get(childId).content = {};
|
||||||
|
parentChildMap.set(parentId, new Map(parentChildMap.get(parentId)));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
setError(_t("Failed to remove some rooms. Try again later"));
|
||||||
|
}
|
||||||
|
setRemoving(false);
|
||||||
|
}}
|
||||||
|
kind="danger_outline"
|
||||||
|
disabled={disabled}
|
||||||
|
>
|
||||||
|
{ removing ? _t("Removing...") : _t("Remove") }
|
||||||
|
</AccessibleButton>
|
||||||
|
<AccessibleButton
|
||||||
|
onClick={async () => {
|
||||||
|
setSaving(true);
|
||||||
|
try {
|
||||||
|
for (const [parentId, childId] of selectedRelations) {
|
||||||
|
const suggested = !selectionAllSuggested;
|
||||||
|
const existingContent = parentChildMap.get(parentId)?.get(childId)?.content;
|
||||||
|
if (!existingContent || existingContent.suggested === suggested) continue;
|
||||||
|
|
||||||
|
const content = {
|
||||||
|
...existingContent,
|
||||||
|
suggested: !selectionAllSuggested,
|
||||||
|
};
|
||||||
|
|
||||||
|
await cli.sendStateEvent(parentId, EventType.SpaceChild, content, childId);
|
||||||
|
|
||||||
|
parentChildMap.get(parentId).get(childId).content = content;
|
||||||
|
parentChildMap.set(parentId, new Map(parentChildMap.get(parentId)));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
setError("Failed to update some suggestions. Try again later");
|
||||||
|
}
|
||||||
|
setSaving(false);
|
||||||
|
}}
|
||||||
|
kind="primary_outline"
|
||||||
|
disabled={disabled}
|
||||||
|
>
|
||||||
|
{ saving
|
||||||
|
? _t("Saving...")
|
||||||
|
: (selectionAllSuggested ? _t("Mark as not suggested") : _t("Mark as suggested"))
|
||||||
|
}
|
||||||
|
</AccessibleButton>
|
||||||
|
</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
editSection = <span>
|
||||||
|
{ buttons }
|
||||||
|
</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
let results;
|
||||||
|
if (roomsMap.size) {
|
||||||
|
const hasPermissions = space?.currentState.maySendStateEvent(EventType.SpaceChild, cli.getUserId());
|
||||||
|
|
||||||
|
results = <>
|
||||||
|
<HierarchyLevel
|
||||||
|
spaceId={space.roomId}
|
||||||
|
rooms={roomsMap}
|
||||||
|
relations={parentChildMap}
|
||||||
|
parents={new Set()}
|
||||||
|
selectedMap={selected}
|
||||||
|
onToggleClick={hasPermissions ? (parentId, childId) => {
|
||||||
|
setError("");
|
||||||
|
if (!selected.has(parentId)) {
|
||||||
|
setSelected(new Map(selected.set(parentId, new Set([childId]))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentSet = selected.get(parentId);
|
||||||
|
if (!parentSet.has(childId)) {
|
||||||
|
setSelected(new Map(selected.set(parentId, new Set([...parentSet, childId]))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parentSet.delete(childId);
|
||||||
|
setSelected(new Map(selected.set(parentId, new Set(parentSet))));
|
||||||
|
} : undefined}
|
||||||
|
onViewRoomClick={(roomId, autoJoin) => {
|
||||||
|
showRoom(roomsMap.get(roomId), Array.from(viaMap.get(roomId) || []), autoJoin);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{ children && <hr /> }
|
||||||
|
</>;
|
||||||
|
} else {
|
||||||
|
results = <div className="mx_SpaceRoomDirectory_noResults">
|
||||||
|
<h3>{ _t("No results found") }</h3>
|
||||||
|
<div>{ _t("You may want to try a different search or check for typos.") }</div>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
content = <>
|
||||||
|
<div className="mx_SpaceRoomDirectory_listHeader">
|
||||||
|
{ countsStr }
|
||||||
|
{ editSection }
|
||||||
|
</div>
|
||||||
|
{ error && <div className="mx_SpaceRoomDirectory_error">
|
||||||
|
{ error }
|
||||||
|
</div> }
|
||||||
|
<AutoHideScrollbar className="mx_SpaceRoomDirectory_list">
|
||||||
|
{ results }
|
||||||
|
{ children }
|
||||||
|
</AutoHideScrollbar>
|
||||||
|
</>;
|
||||||
|
} else if (!rooms) {
|
||||||
|
content = <Spinner />;
|
||||||
|
} else {
|
||||||
|
content = <p>{_t("Your server does not support showing space hierarchies.")}</p>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO loading state/error state
|
||||||
|
return <>
|
||||||
|
<SearchBox
|
||||||
|
className="mx_textinput_icon mx_textinput_search"
|
||||||
|
placeholder={ _t("Search names and description") }
|
||||||
|
onSearch={setQuery}
|
||||||
|
autoFocus={true}
|
||||||
|
initialValue={initialText}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{ content }
|
||||||
|
</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
space: Room;
|
||||||
|
initialText?: string;
|
||||||
|
onFinished(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SpaceRoomDirectory: React.FC<IProps> = ({ space, onFinished, initialText }) => {
|
||||||
const onCreateRoomClick = () => {
|
const onCreateRoomClick = () => {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'view_create_room',
|
action: 'view_create_room',
|
||||||
|
@ -426,134 +573,40 @@ const SpaceRoomDirectory: React.FC<IProps> = ({ space, initialText = "", onFinis
|
||||||
onFinished();
|
onFinished();
|
||||||
};
|
};
|
||||||
|
|
||||||
// stored within a ref as we don't need to re-render when it changes
|
|
||||||
const pendingActions = useRef(new Map<string, IAction>());
|
|
||||||
|
|
||||||
let adminButton;
|
|
||||||
if (shouldShowSpaceSettings(cli, space)) { // TODO this is an imperfect test
|
|
||||||
const onManageButtonClicked = () => {
|
|
||||||
setIsEditing(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSaveButtonClicked = () => {
|
|
||||||
// TODO setBusy
|
|
||||||
pendingActions.current.forEach(({event, suggested, removed}) => {
|
|
||||||
const content = {
|
|
||||||
...event.getContent(),
|
|
||||||
suggested,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (removed) {
|
|
||||||
delete content["via"];
|
|
||||||
}
|
|
||||||
|
|
||||||
cli.sendStateEvent(event.getRoomId(), event.getType(), content, event.getStateKey());
|
|
||||||
});
|
|
||||||
setIsEditing(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isEditing) {
|
|
||||||
adminButton = <React.Fragment>
|
|
||||||
<FormButton label={_t("Save changes")} onClick={onSaveButtonClicked} />
|
|
||||||
<span>{ _t("Promoted to users") }</span>
|
|
||||||
</React.Fragment>;
|
|
||||||
} else {
|
|
||||||
adminButton = <FormButton label={_t("Manage rooms")} onClick={onManageButtonClicked} />;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const [rooms, relations, viaMap] = useAsyncMemo(async () => {
|
|
||||||
try {
|
|
||||||
const data = await cli.getSpaceSummary(space.roomId);
|
|
||||||
|
|
||||||
const parentChildRelations = new EnhancedMap<string, string[]>();
|
|
||||||
const viaMap = new EnhancedMap<string, Set<string>>();
|
|
||||||
data.events.map((ev: ISpaceSummaryEvent) => {
|
|
||||||
if (ev.type === EventType.SpaceChild) {
|
|
||||||
parentChildRelations.getOrCreate(ev.room_id, []).push(ev.state_key);
|
|
||||||
}
|
|
||||||
if (Array.isArray(ev.content["via"])) {
|
|
||||||
const set = viaMap.getOrCreate(ev.state_key, new Set());
|
|
||||||
ev.content["via"].forEach(via => set.add(via));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return [data.rooms, parentChildRelations, viaMap];
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
}, [space], []);
|
|
||||||
|
|
||||||
const roomsMap = useMemo(() => {
|
|
||||||
if (!rooms) return null;
|
|
||||||
const lcQuery = query.toLowerCase();
|
|
||||||
|
|
||||||
const filteredRooms = rooms.filter(r => {
|
|
||||||
return r.room_type === RoomType.Space // always include spaces to allow filtering of sub-space rooms
|
|
||||||
|| r.name?.toLowerCase().includes(lcQuery)
|
|
||||||
|| r.topic?.toLowerCase().includes(lcQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
return new Map<string, ISpaceSummaryRoom>(filteredRooms.map(r => [r.room_id, r]));
|
|
||||||
// const root = rooms.get(space.roomId);
|
|
||||||
}, [rooms, query]);
|
|
||||||
|
|
||||||
const title = <React.Fragment>
|
const title = <React.Fragment>
|
||||||
<RoomAvatar room={space} height={40} width={40} />
|
<RoomAvatar room={space} height={32} width={32} />
|
||||||
<div>
|
<div>
|
||||||
<h1>{ _t("Explore rooms") }</h1>
|
<h1>{ _t("Explore rooms") }</h1>
|
||||||
<div><RoomName room={space} /></div>
|
<div><RoomName room={space} /></div>
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
const explanation =
|
|
||||||
_t("If you can't find the room you're looking for, ask for an invite or <a>Create a new room</a>.", null,
|
|
||||||
{a: sub => {
|
|
||||||
return <AccessibleButton kind="link" onClick={onCreateRoomClick}>{sub}</AccessibleButton>;
|
|
||||||
}},
|
|
||||||
);
|
|
||||||
|
|
||||||
let content;
|
|
||||||
if (roomsMap) {
|
|
||||||
content = <AutoHideScrollbar className="mx_SpaceRoomDirectory_list">
|
|
||||||
<HierarchyLevel
|
|
||||||
spaceId={space.roomId}
|
|
||||||
rooms={roomsMap}
|
|
||||||
editing={isEditing}
|
|
||||||
relations={relations}
|
|
||||||
parents={new Set()}
|
|
||||||
queueAction={action => {
|
|
||||||
pendingActions.current.set(action.event.room_id, action);
|
|
||||||
}}
|
|
||||||
onPreviewClick={roomId => {
|
|
||||||
showRoom(roomsMap.get(roomId), Array.from(viaMap.get(roomId) || []), false);
|
|
||||||
onFinished();
|
|
||||||
}}
|
|
||||||
onJoinClick={(roomId) => {
|
|
||||||
showRoom(roomsMap.get(roomId), Array.from(viaMap.get(roomId) || []), true);
|
|
||||||
onFinished();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</AutoHideScrollbar>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO loading state/error state
|
|
||||||
return (
|
return (
|
||||||
<BaseDialog className="mx_SpaceRoomDirectory" hasCancel={true} onFinished={onFinished} title={title}>
|
<BaseDialog className="mx_SpaceRoomDirectory" hasCancel={true} onFinished={onFinished} title={title}>
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content">
|
||||||
{ explanation }
|
{ _t("If you can't find the room you're looking for, ask for an invite or <a>create a new room</a>.",
|
||||||
|
null,
|
||||||
|
{a: sub => {
|
||||||
|
return <AccessibleButton kind="link" onClick={onCreateRoomClick}>{sub}</AccessibleButton>;
|
||||||
|
}},
|
||||||
|
) }
|
||||||
|
|
||||||
<SearchBox
|
<SpaceHierarchy
|
||||||
className="mx_textinput_icon mx_textinput_search"
|
space={space}
|
||||||
placeholder={ _t("Find a room...") }
|
showRoom={(room: ISpaceSummaryRoom, viaServers?: string[], autoJoin = false) => {
|
||||||
onSearch={setQuery}
|
showRoom(room, viaServers, autoJoin);
|
||||||
/>
|
onFinished();
|
||||||
|
}}
|
||||||
<div className="mx_SpaceRoomDirectory_listHeader">
|
initialText={initialText}
|
||||||
{ adminButton }
|
>
|
||||||
</div>
|
<AccessibleButton
|
||||||
{ content }
|
onClick={onCreateRoomClick}
|
||||||
|
kind="primary"
|
||||||
|
className="mx_SpaceRoomDirectory_createRoom"
|
||||||
|
>
|
||||||
|
{ _t("Create room") }
|
||||||
|
</AccessibleButton>
|
||||||
|
</SpaceHierarchy>
|
||||||
</div>
|
</div>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
);
|
);
|
||||||
|
|
|
@ -15,8 +15,9 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {RefObject, useContext, useRef, useState} from "react";
|
import React, {RefObject, useContext, useRef, useState} from "react";
|
||||||
import {EventType, RoomType} from "matrix-js-sdk/src/@types/event";
|
import {EventType} from "matrix-js-sdk/src/@types/event";
|
||||||
import {Room} from "matrix-js-sdk/src/models/room";
|
import {Room} from "matrix-js-sdk/src/models/room";
|
||||||
|
import {EventSubscription} from "fbemitter";
|
||||||
|
|
||||||
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
||||||
import RoomAvatar from "../views/avatars/RoomAvatar";
|
import RoomAvatar from "../views/avatars/RoomAvatar";
|
||||||
|
@ -25,13 +26,11 @@ import AccessibleButton from "../views/elements/AccessibleButton";
|
||||||
import RoomName from "../views/elements/RoomName";
|
import RoomName from "../views/elements/RoomName";
|
||||||
import RoomTopic from "../views/elements/RoomTopic";
|
import RoomTopic from "../views/elements/RoomTopic";
|
||||||
import InlineSpinner from "../views/elements/InlineSpinner";
|
import InlineSpinner from "../views/elements/InlineSpinner";
|
||||||
import FormButton from "../views/elements/FormButton";
|
|
||||||
import {inviteMultipleToRoom, showRoomInviteDialog} from "../../RoomInvite";
|
import {inviteMultipleToRoom, showRoomInviteDialog} from "../../RoomInvite";
|
||||||
import {useRoomMembers} from "../../hooks/useRoomMembers";
|
import {useRoomMembers} from "../../hooks/useRoomMembers";
|
||||||
import createRoom, {IOpts, Preset} from "../../createRoom";
|
import createRoom, {IOpts, Preset} from "../../createRoom";
|
||||||
import Field from "../views/elements/Field";
|
import Field from "../views/elements/Field";
|
||||||
import {useEventEmitter} from "../../hooks/useEventEmitter";
|
import {useEventEmitter} from "../../hooks/useEventEmitter";
|
||||||
import StyledRadioGroup from "../views/elements/StyledRadioGroup";
|
|
||||||
import withValidation from "../views/elements/Validation";
|
import withValidation from "../views/elements/Validation";
|
||||||
import * as Email from "../../email";
|
import * as Email from "../../email";
|
||||||
import defaultDispatcher from "../../dispatcher/dispatcher";
|
import defaultDispatcher from "../../dispatcher/dispatcher";
|
||||||
|
@ -42,18 +41,16 @@ import ErrorBoundary from "../views/elements/ErrorBoundary";
|
||||||
import {ActionPayload} from "../../dispatcher/payloads";
|
import {ActionPayload} from "../../dispatcher/payloads";
|
||||||
import RightPanel from "./RightPanel";
|
import RightPanel from "./RightPanel";
|
||||||
import RightPanelStore from "../../stores/RightPanelStore";
|
import RightPanelStore from "../../stores/RightPanelStore";
|
||||||
import {EventSubscription} from "fbemitter";
|
|
||||||
import {RightPanelPhases} from "../../stores/RightPanelStorePhases";
|
import {RightPanelPhases} from "../../stores/RightPanelStorePhases";
|
||||||
import {SetRightPanelPhasePayload} from "../../dispatcher/payloads/SetRightPanelPhasePayload";
|
import {SetRightPanelPhasePayload} from "../../dispatcher/payloads/SetRightPanelPhasePayload";
|
||||||
import {useStateArray} from "../../hooks/useStateArray";
|
import {useStateArray} from "../../hooks/useStateArray";
|
||||||
import SpacePublicShare from "../views/spaces/SpacePublicShare";
|
import SpacePublicShare from "../views/spaces/SpacePublicShare";
|
||||||
import {showAddExistingRooms, showCreateNewRoom, shouldShowSpaceSettings, showSpaceSettings} from "../../utils/space";
|
import {showAddExistingRooms, showCreateNewRoom, shouldShowSpaceSettings, showSpaceSettings} from "../../utils/space";
|
||||||
import {HierarchyLevel, ISpaceSummaryEvent, ISpaceSummaryRoom, showRoom} from "./SpaceRoomDirectory";
|
import {showRoom, SpaceHierarchy} from "./SpaceRoomDirectory";
|
||||||
import {useAsyncMemo} from "../../hooks/useAsyncMemo";
|
|
||||||
import {EnhancedMap} from "../../utils/maps";
|
|
||||||
import AutoHideScrollbar from "./AutoHideScrollbar";
|
|
||||||
import MemberAvatar from "../views/avatars/MemberAvatar";
|
import MemberAvatar from "../views/avatars/MemberAvatar";
|
||||||
import {useStateToggle} from "../../hooks/useStateToggle";
|
import {useStateToggle} from "../../hooks/useStateToggle";
|
||||||
|
import SpaceStore from "../../stores/SpaceStore";
|
||||||
|
import FacePile from "../views/elements/FacePile";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
space: Room;
|
space: Room;
|
||||||
|
@ -66,6 +63,7 @@ interface IProps {
|
||||||
interface IState {
|
interface IState {
|
||||||
phase: Phase;
|
phase: Phase;
|
||||||
showRightPanel: boolean;
|
showRightPanel: boolean;
|
||||||
|
myMembership: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Phase {
|
enum Phase {
|
||||||
|
@ -94,10 +92,47 @@ const useMyRoomMembership = (room: Room) => {
|
||||||
return membership;
|
return membership;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SpaceInfo = ({ space }) => {
|
||||||
|
const joinRule = space.getJoinRule();
|
||||||
|
|
||||||
|
let visibilitySection;
|
||||||
|
if (joinRule === "public") {
|
||||||
|
visibilitySection = <span className="mx_SpaceRoomView_info_public">
|
||||||
|
{ _t("Public space") }
|
||||||
|
</span>;
|
||||||
|
} else {
|
||||||
|
visibilitySection = <span className="mx_SpaceRoomView_info_private">
|
||||||
|
{ _t("Private space") }
|
||||||
|
</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div className="mx_SpaceRoomView_info">
|
||||||
|
{ visibilitySection }
|
||||||
|
{ joinRule === "public" && <RoomMemberCount room={space}>
|
||||||
|
{(count) => count > 0 ? (
|
||||||
|
<AccessibleButton
|
||||||
|
kind="link"
|
||||||
|
onClick={() => {
|
||||||
|
defaultDispatcher.dispatch<SetRightPanelPhasePayload>({
|
||||||
|
action: Action.SetRightPanelPhase,
|
||||||
|
phase: RightPanelPhases.RoomMemberList,
|
||||||
|
refireParams: { space },
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ _t("%(count)s members", { count }) }
|
||||||
|
</AccessibleButton>
|
||||||
|
) : null}
|
||||||
|
</RoomMemberCount> }
|
||||||
|
</div>
|
||||||
|
};
|
||||||
|
|
||||||
const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) => {
|
const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) => {
|
||||||
const cli = useContext(MatrixClientContext);
|
const cli = useContext(MatrixClientContext);
|
||||||
const myMembership = useMyRoomMembership(space);
|
const myMembership = useMyRoomMembership(space);
|
||||||
|
|
||||||
|
const [busy, setBusy] = useState(false);
|
||||||
|
|
||||||
let inviterSection;
|
let inviterSection;
|
||||||
let joinButtons;
|
let joinButtons;
|
||||||
if (myMembership === "invite") {
|
if (myMembership === "invite") {
|
||||||
|
@ -121,22 +156,41 @@ const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
|
||||||
}
|
}
|
||||||
|
|
||||||
joinButtons = <>
|
joinButtons = <>
|
||||||
<FormButton label={_t("Reject")} kind="secondary" onClick={onRejectButtonClicked} />
|
<AccessibleButton
|
||||||
<FormButton label={_t("Accept")} onClick={onJoinButtonClicked} />
|
kind="secondary"
|
||||||
|
onClick={() => {
|
||||||
|
setBusy(true);
|
||||||
|
onRejectButtonClicked();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ _t("Reject") }
|
||||||
|
</AccessibleButton>
|
||||||
|
<AccessibleButton
|
||||||
|
kind="primary"
|
||||||
|
onClick={() => {
|
||||||
|
setBusy(true);
|
||||||
|
onJoinButtonClicked();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ _t("Accept") }
|
||||||
|
</AccessibleButton>
|
||||||
</>;
|
</>;
|
||||||
} else {
|
} else {
|
||||||
joinButtons = <FormButton label={_t("Join")} onClick={onJoinButtonClicked} />
|
joinButtons = (
|
||||||
|
<AccessibleButton
|
||||||
|
kind="primary"
|
||||||
|
onClick={() => {
|
||||||
|
setBusy(true);
|
||||||
|
onJoinButtonClicked();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ _t("Join") }
|
||||||
|
</AccessibleButton>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let visibilitySection;
|
if (busy) {
|
||||||
if (space.getJoinRule() === "public") {
|
joinButtons = <InlineSpinner />;
|
||||||
visibilitySection = <span className="mx_SpaceRoomView_preview_info_public">
|
|
||||||
{ _t("Public space") }
|
|
||||||
</span>;
|
|
||||||
} else {
|
|
||||||
visibilitySection = <span className="mx_SpaceRoomView_preview_info_private">
|
|
||||||
{ _t("Private space") }
|
|
||||||
</span>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div className="mx_SpaceRoomView_preview">
|
return <div className="mx_SpaceRoomView_preview">
|
||||||
|
@ -145,26 +199,7 @@ const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
|
||||||
<h1 className="mx_SpaceRoomView_preview_name">
|
<h1 className="mx_SpaceRoomView_preview_name">
|
||||||
<RoomName room={space} />
|
<RoomName room={space} />
|
||||||
</h1>
|
</h1>
|
||||||
<div className="mx_SpaceRoomView_preview_info">
|
<SpaceInfo space={space} />
|
||||||
{ visibilitySection }
|
|
||||||
<RoomMemberCount room={space}>
|
|
||||||
{(count) => count > 0 ? (
|
|
||||||
<AccessibleButton
|
|
||||||
className="mx_SpaceRoomView_preview_memberCount"
|
|
||||||
kind="link"
|
|
||||||
onClick={() => {
|
|
||||||
defaultDispatcher.dispatch<SetRightPanelPhasePayload>({
|
|
||||||
action: Action.SetRightPanelPhase,
|
|
||||||
phase: RightPanelPhases.RoomMemberList,
|
|
||||||
refireParams: { space },
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{ _t("%(count)s members", { count }) }
|
|
||||||
</AccessibleButton>
|
|
||||||
) : null}
|
|
||||||
</RoomMemberCount>
|
|
||||||
</div>
|
|
||||||
<RoomTopic room={space}>
|
<RoomTopic room={space}>
|
||||||
{(topic, ref) =>
|
{(topic, ref) =>
|
||||||
<div className="mx_SpaceRoomView_preview_topic" ref={ref}>
|
<div className="mx_SpaceRoomView_preview_topic" ref={ref}>
|
||||||
|
@ -172,6 +207,7 @@ const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</RoomTopic>
|
</RoomTopic>
|
||||||
|
{ space.getJoinRule() === "public" && <FacePile room={space} /> }
|
||||||
<div className="mx_SpaceRoomView_preview_joinButtons">
|
<div className="mx_SpaceRoomView_preview_joinButtons">
|
||||||
{ joinButtons }
|
{ joinButtons }
|
||||||
</div>
|
</div>
|
||||||
|
@ -186,17 +222,21 @@ const SpaceLanding = ({ space }) => {
|
||||||
let inviteButton;
|
let inviteButton;
|
||||||
if (myMembership === "join" && space.canInvite(userId)) {
|
if (myMembership === "join" && space.canInvite(userId)) {
|
||||||
inviteButton = (
|
inviteButton = (
|
||||||
<AccessibleButton className="mx_SpaceRoomView_landing_inviteButton" onClick={() => {
|
<AccessibleButton
|
||||||
showRoomInviteDialog(space.roomId);
|
kind="primary"
|
||||||
}}>
|
className="mx_SpaceRoomView_landing_inviteButton"
|
||||||
{ _t("Invite people") }
|
onClick={() => {
|
||||||
|
showRoomInviteDialog(space.roomId);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ _t("Invite") }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const canAddRooms = myMembership === "join" && space.currentState.maySendStateEvent(EventType.SpaceChild, userId);
|
const canAddRooms = myMembership === "join" && space.currentState.maySendStateEvent(EventType.SpaceChild, userId);
|
||||||
|
|
||||||
const [_, forceUpdate] = useStateToggle(false); // TODO
|
const [refreshToken, forceUpdate] = useStateToggle(false);
|
||||||
|
|
||||||
let addRoomButtons;
|
let addRoomButtons;
|
||||||
if (canAddRooms) {
|
if (canAddRooms) {
|
||||||
|
@ -226,50 +266,13 @@ const SpaceLanding = ({ space }) => {
|
||||||
</AccessibleButton>;
|
</AccessibleButton>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [loading, roomsMap, relations, numRooms] = useAsyncMemo(async () => {
|
const onMembersClick = () => {
|
||||||
try {
|
defaultDispatcher.dispatch<SetRightPanelPhasePayload>({
|
||||||
const data = await cli.getSpaceSummary(space.roomId, undefined, myMembership !== "join");
|
action: Action.SetRightPanelPhase,
|
||||||
|
phase: RightPanelPhases.RoomMemberList,
|
||||||
const parentChildRelations = new EnhancedMap<string, string[]>();
|
refireParams: { space },
|
||||||
data.events.map((ev: ISpaceSummaryEvent) => {
|
});
|
||||||
if (ev.type === EventType.SpaceChild) {
|
};
|
||||||
parentChildRelations.getOrCreate(ev.room_id, []).push(ev.state_key);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const roomsMap = new Map<string, ISpaceSummaryRoom>(data.rooms.map(r => [r.room_id, r]));
|
|
||||||
const numRooms = data.rooms.filter(r => r.room_type !== RoomType.Space).length;
|
|
||||||
return [false, roomsMap, parentChildRelations, numRooms];
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
return [false];
|
|
||||||
}, [space, _], [true]);
|
|
||||||
|
|
||||||
let previewRooms;
|
|
||||||
if (roomsMap) {
|
|
||||||
previewRooms = <AutoHideScrollbar className="mx_SpaceRoomDirectory_list">
|
|
||||||
<div className="mx_SpaceRoomDirectory_roomCount">
|
|
||||||
<h3>{ myMembership === "join" ? _t("Rooms") : _t("Default Rooms")}</h3>
|
|
||||||
<span>{ numRooms }</span>
|
|
||||||
</div>
|
|
||||||
<HierarchyLevel
|
|
||||||
spaceId={space.roomId}
|
|
||||||
rooms={roomsMap}
|
|
||||||
editing={false}
|
|
||||||
relations={relations}
|
|
||||||
parents={new Set()}
|
|
||||||
onPreviewClick={roomId => {
|
|
||||||
showRoom(roomsMap.get(roomId), [], false); // TODO
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</AutoHideScrollbar>;
|
|
||||||
} else if (loading) {
|
|
||||||
previewRooms = <InlineSpinner />;
|
|
||||||
} else {
|
|
||||||
previewRooms = <p>{_t("Your server does not support showing space hierarchies.")}</p>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div className="mx_SpaceRoomView_landing">
|
return <div className="mx_SpaceRoomView_landing">
|
||||||
<RoomAvatar room={space} height={80} width={80} viewAvatarOnClick={true} />
|
<RoomAvatar room={space} height={80} width={80} viewAvatarOnClick={true} />
|
||||||
|
@ -278,45 +281,26 @@ const SpaceLanding = ({ space }) => {
|
||||||
{(name) => {
|
{(name) => {
|
||||||
const tags = { name: () => <div className="mx_SpaceRoomView_landing_nameRow">
|
const tags = { name: () => <div className="mx_SpaceRoomView_landing_nameRow">
|
||||||
<h1>{ name }</h1>
|
<h1>{ name }</h1>
|
||||||
<RoomMemberCount room={space}>
|
|
||||||
{(count) => count > 0 ? (
|
|
||||||
<AccessibleButton
|
|
||||||
className="mx_SpaceRoomView_landing_memberCount"
|
|
||||||
kind="link"
|
|
||||||
onClick={() => {
|
|
||||||
defaultDispatcher.dispatch<SetRightPanelPhasePayload>({
|
|
||||||
action: Action.SetRightPanelPhase,
|
|
||||||
phase: RightPanelPhases.RoomMemberList,
|
|
||||||
refireParams: { space },
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{ _t("%(count)s members", { count }) }
|
|
||||||
</AccessibleButton>
|
|
||||||
) : null}
|
|
||||||
</RoomMemberCount>
|
|
||||||
</div> };
|
</div> };
|
||||||
if (shouldShowSpaceSettings(cli, space)) {
|
|
||||||
if (space.getJoinRule() === "public") {
|
|
||||||
return _t("Your public space <name/>", {}, tags) as JSX.Element;
|
|
||||||
} else {
|
|
||||||
return _t("Your private space <name/>", {}, tags) as JSX.Element;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _t("Welcome to <name/>", {}, tags) as JSX.Element;
|
return _t("Welcome to <name/>", {}, tags) as JSX.Element;
|
||||||
}}
|
}}
|
||||||
</RoomName>
|
</RoomName>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mx_SpaceRoomView_landing_info">
|
||||||
|
<SpaceInfo space={space} />
|
||||||
|
<FacePile room={space} onlyKnownUsers={false} numShown={7} onClick={onMembersClick} />
|
||||||
|
{ inviteButton }
|
||||||
|
</div>
|
||||||
<div className="mx_SpaceRoomView_landing_topic">
|
<div className="mx_SpaceRoomView_landing_topic">
|
||||||
<RoomTopic room={space} />
|
<RoomTopic room={space} />
|
||||||
</div>
|
</div>
|
||||||
|
<hr />
|
||||||
<div className="mx_SpaceRoomView_landing_adminButtons">
|
<div className="mx_SpaceRoomView_landing_adminButtons">
|
||||||
{ inviteButton }
|
|
||||||
{ addRoomButtons }
|
{ addRoomButtons }
|
||||||
{ settingsButton }
|
{ settingsButton }
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ previewRooms }
|
<SpaceHierarchy space={space} showRoom={showRoom} refreshToken={refreshToken} />
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -337,6 +321,7 @@ const SpaceSetupFirstRooms = ({ space, title, description, onFinished }) => {
|
||||||
placeholder={placeholders[i]}
|
placeholder={placeholders[i]}
|
||||||
value={roomNames[i]}
|
value={roomNames[i]}
|
||||||
onChange={ev => setRoomName(i, ev.target.value)}
|
onChange={ev => setRoomName(i, ev.target.value)}
|
||||||
|
autoFocus={i === 2}
|
||||||
/>;
|
/>;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -369,7 +354,7 @@ const SpaceSetupFirstRooms = ({ space, title, description, onFinished }) => {
|
||||||
let buttonLabel = _t("Skip for now");
|
let buttonLabel = _t("Skip for now");
|
||||||
if (roomNames.some(name => name.trim())) {
|
if (roomNames.some(name => name.trim())) {
|
||||||
onClick = onNextClick;
|
onClick = onNextClick;
|
||||||
buttonLabel = busy ? _t("Creating rooms...") : _t("Next")
|
buttonLabel = busy ? _t("Creating rooms...") : _t("Continue")
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
|
@ -380,61 +365,55 @@ const SpaceSetupFirstRooms = ({ space, title, description, onFinished }) => {
|
||||||
{ fields }
|
{ fields }
|
||||||
|
|
||||||
<div className="mx_SpaceRoomView_buttons">
|
<div className="mx_SpaceRoomView_buttons">
|
||||||
<FormButton
|
<AccessibleButton
|
||||||
label={buttonLabel}
|
kind="primary"
|
||||||
disabled={busy}
|
disabled={busy}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
/>
|
>
|
||||||
|
{ buttonLabel }
|
||||||
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SpaceSetupPublicShare = ({ space, onFinished }) => {
|
const SpaceSetupPublicShare = ({ space, onFinished }) => {
|
||||||
return <div className="mx_SpaceRoomView_publicShare">
|
return <div className="mx_SpaceRoomView_publicShare">
|
||||||
<h1>{ _t("Share your public space") }</h1>
|
<h1>{ _t("Share %(name)s", { name: space.name }) }</h1>
|
||||||
<div className="mx_SpacePublicShare_description">{ _t("At the moment only you can see it.") }</div>
|
<div className="mx_SpaceRoomView_description">
|
||||||
|
{ _t("It's just you at the moment, it will be even better with others.") }
|
||||||
|
</div>
|
||||||
|
|
||||||
<SpacePublicShare space={space} onFinished={onFinished} />
|
<SpacePublicShare space={space} />
|
||||||
|
|
||||||
<div className="mx_SpaceRoomView_buttons">
|
<div className="mx_SpaceRoomView_buttons">
|
||||||
<FormButton label={_t("Finish")} onClick={onFinished} />
|
<AccessibleButton kind="primary" onClick={onFinished}>
|
||||||
|
{ _t("Go to my first room") }
|
||||||
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SpaceSetupPrivateScope = ({ onFinished }) => {
|
const SpaceSetupPrivateScope = ({ space, onFinished }) => {
|
||||||
const [option, setOption] = useState<string>(null);
|
|
||||||
|
|
||||||
return <div className="mx_SpaceRoomView_privateScope">
|
return <div className="mx_SpaceRoomView_privateScope">
|
||||||
<h1>{ _t("Who are you working with?") }</h1>
|
<h1>{ _t("Who are you working with?") }</h1>
|
||||||
<div className="mx_SpaceRoomView_description">{ _t("Ensure the right people have access to the space.") }</div>
|
<div className="mx_SpaceRoomView_description">
|
||||||
|
{ _t("Make sure the right people have access to %(name)s", { name: space.name }) }
|
||||||
<StyledRadioGroup
|
|
||||||
name="privateSpaceScope"
|
|
||||||
value={option}
|
|
||||||
onChange={setOption}
|
|
||||||
definitions={[
|
|
||||||
{
|
|
||||||
value: "justMe",
|
|
||||||
className: "mx_SpaceRoomView_privateScope_justMeButton",
|
|
||||||
label: <React.Fragment>
|
|
||||||
<h3>{ _t("Just Me") }</h3>
|
|
||||||
<div>{ _t("A private space just for you") }</div>
|
|
||||||
</React.Fragment>,
|
|
||||||
}, {
|
|
||||||
value: "meAndMyTeammates",
|
|
||||||
className: "mx_SpaceRoomView_privateScope_meAndMyTeammatesButton",
|
|
||||||
label: <React.Fragment>
|
|
||||||
<h3>{ _t("Me and my teammates") }</h3>
|
|
||||||
<div>{ _t("A private space for you and your teammates") }</div>
|
|
||||||
</React.Fragment>,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="mx_SpaceRoomView_buttons">
|
|
||||||
<FormButton label={_t("Next")} disabled={!option} onClick={() => onFinished(option !== "justMe")} />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<AccessibleButton
|
||||||
|
className="mx_SpaceRoomView_privateScope_justMeButton"
|
||||||
|
onClick={() => { onFinished(false) }}
|
||||||
|
>
|
||||||
|
<h3>{ _t("Just me") }</h3>
|
||||||
|
<div>{ _t("A private space to organise your rooms") }</div>
|
||||||
|
</AccessibleButton>
|
||||||
|
<AccessibleButton
|
||||||
|
className="mx_SpaceRoomView_privateScope_meAndMyTeammatesButton"
|
||||||
|
onClick={() => { onFinished(true) }}
|
||||||
|
>
|
||||||
|
<h3>{ _t("Me and my teammates") }</h3>
|
||||||
|
<div>{ _t("A private space for you and your teammates") }</div>
|
||||||
|
</AccessibleButton>
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -464,6 +443,7 @@ const SpaceSetupPrivateInvite = ({ space, onFinished }) => {
|
||||||
onChange={ev => setEmailAddress(i, ev.target.value)}
|
onChange={ev => setEmailAddress(i, ev.target.value)}
|
||||||
ref={fieldRefs[i]}
|
ref={fieldRefs[i]}
|
||||||
onValidate={validateEmailRules}
|
onValidate={validateEmailRules}
|
||||||
|
autoFocus={i === 0}
|
||||||
/>;
|
/>;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -501,9 +481,18 @@ const SpaceSetupPrivateInvite = ({ space, onFinished }) => {
|
||||||
setBusy(false);
|
setBusy(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let onClick = onFinished;
|
||||||
|
let buttonLabel = _t("Skip for now");
|
||||||
|
if (emailAddresses.some(name => name.trim())) {
|
||||||
|
onClick = onNextClick;
|
||||||
|
buttonLabel = busy ? _t("Inviting...") : _t("Continue")
|
||||||
|
}
|
||||||
|
|
||||||
return <div className="mx_SpaceRoomView_inviteTeammates">
|
return <div className="mx_SpaceRoomView_inviteTeammates">
|
||||||
<h1>{ _t("Invite your teammates") }</h1>
|
<h1>{ _t("Invite your teammates") }</h1>
|
||||||
<div className="mx_SpaceRoomView_description">{ _t("Ensure the right people have access to the space.") }</div>
|
<div className="mx_SpaceRoomView_description">
|
||||||
|
{ _t("Make sure the right people have access. You can invite more later.") }
|
||||||
|
</div>
|
||||||
|
|
||||||
{ error && <div className="mx_SpaceRoomView_errorText">{ error }</div> }
|
{ error && <div className="mx_SpaceRoomView_errorText">{ error }</div> }
|
||||||
{ fields }
|
{ fields }
|
||||||
|
@ -518,8 +507,9 @@ const SpaceSetupPrivateInvite = ({ space, onFinished }) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mx_SpaceRoomView_buttons">
|
<div className="mx_SpaceRoomView_buttons">
|
||||||
<AccessibleButton onClick={onFinished} kind="link">{_t("Skip for now")}</AccessibleButton>
|
<AccessibleButton kind="primary" disabled={busy} onClick={onClick}>
|
||||||
<FormButton label={busy ? _t("Inviting...") : _t("Next")} disabled={busy} onClick={onNextClick} />
|
{ buttonLabel }
|
||||||
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
@ -547,17 +537,26 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
|
||||||
this.state = {
|
this.state = {
|
||||||
phase,
|
phase,
|
||||||
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
|
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
|
||||||
|
myMembership: this.props.space.getMyMembership(),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.dispatcherRef = defaultDispatcher.register(this.onAction);
|
this.dispatcherRef = defaultDispatcher.register(this.onAction);
|
||||||
this.rightPanelStoreToken = RightPanelStore.getSharedInstance().addListener(this.onRightPanelStoreUpdate);
|
this.rightPanelStoreToken = RightPanelStore.getSharedInstance().addListener(this.onRightPanelStoreUpdate);
|
||||||
|
this.context.on("Room.myMembership", this.onMyMembership);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
defaultDispatcher.unregister(this.dispatcherRef);
|
defaultDispatcher.unregister(this.dispatcherRef);
|
||||||
this.rightPanelStoreToken.remove();
|
this.rightPanelStoreToken.remove();
|
||||||
|
this.context.off("Room.myMembership", this.onMyMembership);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onMyMembership = (room: Room, myMembership: string) => {
|
||||||
|
if (room.roomId === this.props.space.roomId) {
|
||||||
|
this.setState({ myMembership });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private onRightPanelStoreUpdate = () => {
|
private onRightPanelStoreUpdate = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
|
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
|
||||||
|
@ -594,10 +593,45 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private goToFirstRoom = async () => {
|
||||||
|
// TODO actually go to the first room
|
||||||
|
|
||||||
|
const childRooms = SpaceStore.instance.getChildRooms(this.props.space.roomId);
|
||||||
|
if (childRooms.length) {
|
||||||
|
const room = childRooms[0];
|
||||||
|
defaultDispatcher.dispatch({
|
||||||
|
action: "view_room",
|
||||||
|
room_id: room.roomId,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let suggestedRooms = SpaceStore.instance.suggestedRooms;
|
||||||
|
if (SpaceStore.instance.activeSpace !== this.props.space) {
|
||||||
|
// the space store has the suggested rooms loaded for a different space, fetch the right ones
|
||||||
|
suggestedRooms = (await SpaceStore.instance.fetchSuggestedRooms(this.props.space, 1)).rooms;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (suggestedRooms.length) {
|
||||||
|
const room = suggestedRooms[0];
|
||||||
|
defaultDispatcher.dispatch({
|
||||||
|
action: "view_room",
|
||||||
|
room_id: room.room_id,
|
||||||
|
oobData: {
|
||||||
|
avatarUrl: room.avatar_url,
|
||||||
|
name: room.name || room.canonical_alias || room.aliases.pop() || _t("Empty room"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ phase: Phase.Landing });
|
||||||
|
};
|
||||||
|
|
||||||
private renderBody() {
|
private renderBody() {
|
||||||
switch (this.state.phase) {
|
switch (this.state.phase) {
|
||||||
case Phase.Landing:
|
case Phase.Landing:
|
||||||
if (this.props.space.getMyMembership() === "join") {
|
if (this.state.myMembership === "join") {
|
||||||
return <SpaceLanding space={this.props.space} />;
|
return <SpaceLanding space={this.props.space} />;
|
||||||
} else {
|
} else {
|
||||||
return <SpacePreview
|
return <SpacePreview
|
||||||
|
@ -609,18 +643,21 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
|
||||||
case Phase.PublicCreateRooms:
|
case Phase.PublicCreateRooms:
|
||||||
return <SpaceSetupFirstRooms
|
return <SpaceSetupFirstRooms
|
||||||
space={this.props.space}
|
space={this.props.space}
|
||||||
title={_t("What are some things you want to discuss?")}
|
title={_t("What are some things you want to discuss in %(spaceName)s?", {
|
||||||
description={_t("We'll create rooms for each topic.")}
|
spaceName: this.props.space.name,
|
||||||
|
})}
|
||||||
|
description={
|
||||||
|
_t("Let's create a room for each of them.") + "\n" +
|
||||||
|
_t("You can add more later too, including already existing ones.")
|
||||||
|
}
|
||||||
onFinished={() => this.setState({ phase: Phase.PublicShare })}
|
onFinished={() => this.setState({ phase: Phase.PublicShare })}
|
||||||
/>;
|
/>;
|
||||||
case Phase.PublicShare:
|
case Phase.PublicShare:
|
||||||
return <SpaceSetupPublicShare
|
return <SpaceSetupPublicShare space={this.props.space} onFinished={this.goToFirstRoom} />;
|
||||||
space={this.props.space}
|
|
||||||
onFinished={() => this.setState({ phase: Phase.Landing })}
|
|
||||||
/>;
|
|
||||||
|
|
||||||
case Phase.PrivateScope:
|
case Phase.PrivateScope:
|
||||||
return <SpaceSetupPrivateScope
|
return <SpaceSetupPrivateScope
|
||||||
|
space={this.props.space}
|
||||||
onFinished={(invite: boolean) => {
|
onFinished={(invite: boolean) => {
|
||||||
this.setState({ phase: invite ? Phase.PrivateInvite : Phase.PrivateCreateRooms });
|
this.setState({ phase: invite ? Phase.PrivateInvite : Phase.PrivateCreateRooms });
|
||||||
}}
|
}}
|
||||||
|
@ -634,7 +671,8 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
|
||||||
return <SpaceSetupFirstRooms
|
return <SpaceSetupFirstRooms
|
||||||
space={this.props.space}
|
space={this.props.space}
|
||||||
title={_t("What projects are you working on?")}
|
title={_t("What projects are you working on?")}
|
||||||
description={_t("We'll create rooms for each of them. You can add existing rooms after setup.")}
|
description={_t("We'll create rooms for each of them. " +
|
||||||
|
"You can add more later too, including already existing ones.")}
|
||||||
onFinished={() => this.setState({ phase: Phase.Landing })}
|
onFinished={() => this.setState({ phase: Phase.Landing })}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,11 @@ export default class UploadBar extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {uploadsHere: []};
|
|
||||||
|
// Set initial state to any available upload in this room - we might be mounting
|
||||||
|
// earlier than the first progress event, so should show something relevant.
|
||||||
|
const uploadsHere = this.getUploadsInRoom();
|
||||||
|
this.state = {currentUpload: uploadsHere[0], uploadsHere};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -56,6 +60,11 @@ export default class UploadBar extends React.Component<IProps, IState> {
|
||||||
dis.unregister(this.dispatcherRef);
|
dis.unregister(this.dispatcherRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getUploadsInRoom(): IUpload[] {
|
||||||
|
const uploads = ContentMessages.sharedInstance().getCurrentUploads();
|
||||||
|
return uploads.filter(u => u.roomId === this.props.room.roomId);
|
||||||
|
}
|
||||||
|
|
||||||
private onAction = (payload: ActionPayload) => {
|
private onAction = (payload: ActionPayload) => {
|
||||||
switch (payload.action) {
|
switch (payload.action) {
|
||||||
case Action.UploadStarted:
|
case Action.UploadStarted:
|
||||||
|
@ -64,8 +73,7 @@ export default class UploadBar extends React.Component<IProps, IState> {
|
||||||
case Action.UploadCanceled:
|
case Action.UploadCanceled:
|
||||||
case Action.UploadFailed: {
|
case Action.UploadFailed: {
|
||||||
if (!this.mounted) return;
|
if (!this.mounted) return;
|
||||||
const uploads = ContentMessages.sharedInstance().getCurrentUploads();
|
const uploadsHere = this.getUploadsInRoom();
|
||||||
const uploadsHere = uploads.filter(u => u.roomId === this.props.room.roomId);
|
|
||||||
this.setState({currentUpload: uploadsHere[0], uploadsHere});
|
this.setState({currentUpload: uploadsHere[0], uploadsHere});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,8 +176,8 @@ export default class ViewSource extends React.Component {
|
||||||
return (
|
return (
|
||||||
<BaseDialog className="mx_ViewSource" onFinished={this.props.onFinished} title={_t("View Source")}>
|
<BaseDialog className="mx_ViewSource" onFinished={this.props.onFinished} title={_t("View Source")}>
|
||||||
<div>
|
<div>
|
||||||
<div className="mx_ViewSource_label_left">Room ID: {roomId}</div>
|
<div>Room ID: {roomId}</div>
|
||||||
<div className="mx_ViewSource_label_left">Event ID: {eventId}</div>
|
<div>Event ID: {eventId}</div>
|
||||||
<div className="mx_ViewSource_separator" />
|
<div className="mx_ViewSource_separator" />
|
||||||
{isEditing ? this.editSourceContent() : this.viewSourceContent()}
|
{isEditing ? this.editSourceContent() : this.viewSourceContent()}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -155,15 +155,14 @@ export default class SetupEncryptionBody extends React.Component {
|
||||||
let verifyButton;
|
let verifyButton;
|
||||||
if (store.hasDevicesToVerifyAgainst) {
|
if (store.hasDevicesToVerifyAgainst) {
|
||||||
verifyButton = <AccessibleButton kind="primary" onClick={this._onVerifyClick}>
|
verifyButton = <AccessibleButton kind="primary" onClick={this._onVerifyClick}>
|
||||||
{ _t("Verify with another session") }
|
{ _t("Use another login") }
|
||||||
</AccessibleButton>;
|
</AccessibleButton>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>{_t(
|
<p>{_t(
|
||||||
"Verify this login to access your encrypted messages and " +
|
"Verify your identity to access encrypted messages and prove your identity to others.",
|
||||||
"prove to others that this login is really you.",
|
|
||||||
)}</p>
|
)}</p>
|
||||||
|
|
||||||
<div className="mx_CompleteSecurity_actionRow">
|
<div className="mx_CompleteSecurity_actionRow">
|
||||||
|
@ -205,8 +204,8 @@ export default class SetupEncryptionBody extends React.Component {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>{_t(
|
<p>{_t(
|
||||||
"Without completing security on this session, it won’t have " +
|
"Without verifying, you won’t have access to all your messages " +
|
||||||
"access to encrypted messages.",
|
"and may appear as untrusted to others.",
|
||||||
)}</p>
|
)}</p>
|
||||||
<div className="mx_CompleteSecurity_actionRow">
|
<div className="mx_CompleteSecurity_actionRow">
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
|
|
|
@ -22,7 +22,6 @@ import {MatrixClient} from "matrix-js-sdk/src/client";
|
||||||
import {_t} from '../../../languageHandler';
|
import {_t} from '../../../languageHandler';
|
||||||
import {IDialogProps} from "./IDialogProps";
|
import {IDialogProps} from "./IDialogProps";
|
||||||
import BaseDialog from "./BaseDialog";
|
import BaseDialog from "./BaseDialog";
|
||||||
import FormButton from "../elements/FormButton";
|
|
||||||
import Dropdown from "../elements/Dropdown";
|
import Dropdown from "../elements/Dropdown";
|
||||||
import SearchBox from "../../structures/SearchBox";
|
import SearchBox from "../../structures/SearchBox";
|
||||||
import SpaceStore from "../../../stores/SpaceStore";
|
import SpaceStore from "../../../stores/SpaceStore";
|
||||||
|
@ -69,6 +68,7 @@ const AddExistingToSpaceDialog: React.FC<IProps> = ({ matrixClient: cli, space,
|
||||||
const existingRoomsSet = new Set(existingRooms);
|
const existingRoomsSet = new Set(existingRooms);
|
||||||
const rooms = cli.getVisibleRooms().filter(room => {
|
const rooms = cli.getVisibleRooms().filter(room => {
|
||||||
return !existingRoomsSet.has(room) // not already in space
|
return !existingRoomsSet.has(room) // not already in space
|
||||||
|
&& !room.isSpaceRoom() // not a space itself
|
||||||
&& room.name.toLowerCase().includes(lcQuery) // contains query
|
&& room.name.toLowerCase().includes(lcQuery) // contains query
|
||||||
&& !DMRoomMap.shared().getUserIdForRoomId(room.roomId); // not a DM
|
&& !DMRoomMap.shared().getUserIdForRoomId(room.roomId); // not a DM
|
||||||
});
|
});
|
||||||
|
@ -109,7 +109,7 @@ const AddExistingToSpaceDialog: React.FC<IProps> = ({ matrixClient: cli, space,
|
||||||
const title = <React.Fragment>
|
const title = <React.Fragment>
|
||||||
<RoomAvatar room={selectedSpace} height={40} width={40} />
|
<RoomAvatar room={selectedSpace} height={40} width={40} />
|
||||||
<div>
|
<div>
|
||||||
<h1>{ _t("Add existing spaces/rooms") }</h1>
|
<h1>{ _t("Add existing rooms") }</h1>
|
||||||
{ spaceOptionSection }
|
{ spaceOptionSection }
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
|
@ -127,29 +127,9 @@ const AddExistingToSpaceDialog: React.FC<IProps> = ({ matrixClient: cli, space,
|
||||||
className="mx_textinput_icon mx_textinput_search"
|
className="mx_textinput_icon mx_textinput_search"
|
||||||
placeholder={ _t("Filter your rooms and spaces") }
|
placeholder={ _t("Filter your rooms and spaces") }
|
||||||
onSearch={setQuery}
|
onSearch={setQuery}
|
||||||
|
autoComplete={true}
|
||||||
/>
|
/>
|
||||||
<AutoHideScrollbar className="mx_AddExistingToSpaceDialog_content" id="mx_AddExistingToSpaceDialog">
|
<AutoHideScrollbar className="mx_AddExistingToSpaceDialog_content" id="mx_AddExistingToSpaceDialog">
|
||||||
{ spaces.length > 0 ? (
|
|
||||||
<div className="mx_AddExistingToSpaceDialog_section mx_AddExistingToSpaceDialog_section_spaces">
|
|
||||||
<h3>{ _t("Spaces") }</h3>
|
|
||||||
{ spaces.map(space => {
|
|
||||||
return <Entry
|
|
||||||
key={space.roomId}
|
|
||||||
room={space}
|
|
||||||
checked={selectedToAdd.has(space)}
|
|
||||||
onChange={(checked) => {
|
|
||||||
if (checked) {
|
|
||||||
selectedToAdd.add(space);
|
|
||||||
} else {
|
|
||||||
selectedToAdd.delete(space);
|
|
||||||
}
|
|
||||||
setSelectedToAdd(new Set(selectedToAdd));
|
|
||||||
}}
|
|
||||||
/>;
|
|
||||||
}) }
|
|
||||||
</div>
|
|
||||||
) : null }
|
|
||||||
|
|
||||||
{ rooms.length > 0 ? (
|
{ rooms.length > 0 ? (
|
||||||
<div className="mx_AddExistingToSpaceDialog_section">
|
<div className="mx_AddExistingToSpaceDialog_section">
|
||||||
<h3>{ _t("Rooms") }</h3>
|
<h3>{ _t("Rooms") }</h3>
|
||||||
|
@ -171,6 +151,27 @@ const AddExistingToSpaceDialog: React.FC<IProps> = ({ matrixClient: cli, space,
|
||||||
</div>
|
</div>
|
||||||
) : undefined }
|
) : undefined }
|
||||||
|
|
||||||
|
{ spaces.length > 0 ? (
|
||||||
|
<div className="mx_AddExistingToSpaceDialog_section mx_AddExistingToSpaceDialog_section_spaces">
|
||||||
|
<h3>{ _t("Spaces") }</h3>
|
||||||
|
{ spaces.map(space => {
|
||||||
|
return <Entry
|
||||||
|
key={space.roomId}
|
||||||
|
room={space}
|
||||||
|
checked={selectedToAdd.has(space)}
|
||||||
|
onChange={(checked) => {
|
||||||
|
if (checked) {
|
||||||
|
selectedToAdd.add(space);
|
||||||
|
} else {
|
||||||
|
selectedToAdd.delete(space);
|
||||||
|
}
|
||||||
|
setSelectedToAdd(new Set(selectedToAdd));
|
||||||
|
}}
|
||||||
|
/>;
|
||||||
|
}) }
|
||||||
|
</div>
|
||||||
|
) : null }
|
||||||
|
|
||||||
{ spaces.length + rooms.length < 1 ? <span className="mx_AddExistingToSpaceDialog_noResults">
|
{ spaces.length + rooms.length < 1 ? <span className="mx_AddExistingToSpaceDialog_noResults">
|
||||||
{ _t("No results") }
|
{ _t("No results") }
|
||||||
</span> : undefined }
|
</span> : undefined }
|
||||||
|
@ -184,8 +185,8 @@ const AddExistingToSpaceDialog: React.FC<IProps> = ({ matrixClient: cli, space,
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<FormButton
|
<AccessibleButton
|
||||||
label={busy ? _t("Applying...") : _t("Apply")}
|
kind="primary"
|
||||||
disabled={busy || selectedToAdd.size < 1}
|
disabled={busy || selectedToAdd.size < 1}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
|
@ -199,7 +200,9 @@ const AddExistingToSpaceDialog: React.FC<IProps> = ({ matrixClient: cli, space,
|
||||||
}
|
}
|
||||||
setBusy(false);
|
setBusy(false);
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
{ busy ? _t("Adding...") : _t("Add") }
|
||||||
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
</BaseDialog>;
|
</BaseDialog>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,6 +43,7 @@ import {Room} from "matrix-js-sdk/src/models/room";
|
||||||
import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
|
import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||||
import {mediaFromMxc} from "../../../customisations/Media";
|
import {mediaFromMxc} from "../../../customisations/Media";
|
||||||
|
import {getAddressType} from "../../../UserAddress";
|
||||||
|
|
||||||
// we have a number of types defined from the Matrix spec which can't reasonably be altered here.
|
// we have a number of types defined from the Matrix spec which can't reasonably be altered here.
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
|
@ -673,19 +674,20 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.setState({
|
this.setState({
|
||||||
busy: false,
|
busy: false,
|
||||||
errorText: _t("We couldn't create your DM. Please check the users you want to invite and try again."),
|
errorText: _t("We couldn't create your DM."),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
_inviteUsers = () => {
|
_inviteUsers = async () => {
|
||||||
const startTime = CountlyAnalytics.getTimestamp();
|
const startTime = CountlyAnalytics.getTimestamp();
|
||||||
this.setState({busy: true});
|
this.setState({busy: true});
|
||||||
this._convertFilter();
|
this._convertFilter();
|
||||||
const targets = this._convertFilter();
|
const targets = this._convertFilter();
|
||||||
const targetIds = targets.map(t => t.userId);
|
const targetIds = targets.map(t => t.userId);
|
||||||
|
|
||||||
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
const cli = MatrixClientPeg.get();
|
||||||
|
const room = cli.getRoom(this.props.roomId);
|
||||||
if (!room) {
|
if (!room) {
|
||||||
console.error("Failed to find the room to invite users to");
|
console.error("Failed to find the room to invite users to");
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -695,12 +697,34 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
inviteMultipleToRoom(this.props.roomId, targetIds).then(result => {
|
try {
|
||||||
|
const result = await inviteMultipleToRoom(this.props.roomId, targetIds)
|
||||||
CountlyAnalytics.instance.trackSendInvite(startTime, this.props.roomId, targetIds.length);
|
CountlyAnalytics.instance.trackSendInvite(startTime, this.props.roomId, targetIds.length);
|
||||||
if (!this._shouldAbortAfterInviteError(result)) { // handles setting error message too
|
if (!this._shouldAbortAfterInviteError(result)) { // handles setting error message too
|
||||||
this.props.onFinished();
|
this.props.onFinished();
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
|
||||||
|
if (cli.isRoomEncrypted(this.props.roomId) &&
|
||||||
|
SettingsStore.getValue("feature_room_history_key_sharing")) {
|
||||||
|
const visibilityEvent = room.currentState.getStateEvents(
|
||||||
|
"m.room.history_visibility", "",
|
||||||
|
);
|
||||||
|
const visibility = visibilityEvent && visibilityEvent.getContent() &&
|
||||||
|
visibilityEvent.getContent().history_visibility;
|
||||||
|
if (visibility == "world_readable" || visibility == "shared") {
|
||||||
|
const invitedUsers = [];
|
||||||
|
for (const [addr, state] of Object.entries(result.states)) {
|
||||||
|
if (state === "invited" && getAddressType(addr) === "mx-user-id") {
|
||||||
|
invitedUsers.push(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("Sharing history with", invitedUsers);
|
||||||
|
cli.sendSharedHistoryKeys(
|
||||||
|
this.props.roomId, invitedUsers,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.setState({
|
this.setState({
|
||||||
busy: false,
|
busy: false,
|
||||||
|
@ -708,7 +732,7 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
||||||
"We couldn't invite those users. Please check the users you want to invite and try again.",
|
"We couldn't invite those users. Please check the users you want to invite and try again.",
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_transferCall = async () => {
|
_transferCall = async () => {
|
||||||
|
@ -886,19 +910,21 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
||||||
};
|
};
|
||||||
|
|
||||||
_toggleMember = (member: Member) => {
|
_toggleMember = (member: Member) => {
|
||||||
let filterText = this.state.filterText;
|
if (!this.state.busy) {
|
||||||
const targets = this.state.targets.map(t => t); // cheap clone for mutation
|
let filterText = this.state.filterText;
|
||||||
const idx = targets.indexOf(member);
|
const targets = this.state.targets.map(t => t); // cheap clone for mutation
|
||||||
if (idx >= 0) {
|
const idx = targets.indexOf(member);
|
||||||
targets.splice(idx, 1);
|
if (idx >= 0) {
|
||||||
} else {
|
targets.splice(idx, 1);
|
||||||
targets.push(member);
|
} else {
|
||||||
filterText = ""; // clear the filter when the user accepts a suggestion
|
targets.push(member);
|
||||||
}
|
filterText = ""; // clear the filter when the user accepts a suggestion
|
||||||
this.setState({targets, filterText});
|
}
|
||||||
|
this.setState({targets, filterText});
|
||||||
|
|
||||||
if (this._editorRef && this._editorRef.current) {
|
if (this._editorRef && this._editorRef.current) {
|
||||||
this._editorRef.current.focus();
|
this._editorRef.current.focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1189,10 +1215,12 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
||||||
let helpText;
|
let helpText;
|
||||||
let buttonText;
|
let buttonText;
|
||||||
let goButtonFn;
|
let goButtonFn;
|
||||||
|
let keySharingWarning = <span />;
|
||||||
|
|
||||||
const identityServersEnabled = SettingsStore.getValue(UIFeature.IdentityServer);
|
const identityServersEnabled = SettingsStore.getValue(UIFeature.IdentityServer);
|
||||||
|
|
||||||
const userId = MatrixClientPeg.get().getUserId();
|
const cli = MatrixClientPeg.get();
|
||||||
|
const userId = cli.getUserId();
|
||||||
if (this.props.kind === KIND_DM) {
|
if (this.props.kind === KIND_DM) {
|
||||||
title = _t("Direct Messages");
|
title = _t("Direct Messages");
|
||||||
|
|
||||||
|
@ -1288,6 +1316,25 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
||||||
|
|
||||||
buttonText = _t("Invite");
|
buttonText = _t("Invite");
|
||||||
goButtonFn = this._inviteUsers;
|
goButtonFn = this._inviteUsers;
|
||||||
|
|
||||||
|
if (SettingsStore.getValue("feature_room_history_key_sharing") &&
|
||||||
|
cli.isRoomEncrypted(this.props.roomId)) {
|
||||||
|
const room = cli.getRoom(this.props.roomId);
|
||||||
|
const visibilityEvent = room.currentState.getStateEvents(
|
||||||
|
"m.room.history_visibility", "",
|
||||||
|
);
|
||||||
|
const visibility = visibilityEvent && visibilityEvent.getContent() &&
|
||||||
|
visibilityEvent.getContent().history_visibility;
|
||||||
|
if (visibility === "world_readable" || visibility === "shared") {
|
||||||
|
keySharingWarning =
|
||||||
|
<p className='mx_InviteDialog_helpText'>
|
||||||
|
<img
|
||||||
|
src={require("../../../../res/img/element-icons/info.svg")}
|
||||||
|
width={14} height={14} />
|
||||||
|
{" " + _t("Invited people will be able to read old messages.")}
|
||||||
|
</p>;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (this.props.kind === KIND_CALL_TRANSFER) {
|
} else if (this.props.kind === KIND_CALL_TRANSFER) {
|
||||||
title = _t("Transfer");
|
title = _t("Transfer");
|
||||||
buttonText = _t("Transfer");
|
buttonText = _t("Transfer");
|
||||||
|
@ -1321,6 +1368,7 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
||||||
{spinner}
|
{spinner}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{keySharingWarning}
|
||||||
{this._renderIdentityServerWarning()}
|
{this._renderIdentityServerWarning()}
|
||||||
<div className='error'>{this.state.errorText}</div>
|
<div className='error'>{this.state.errorText}</div>
|
||||||
<div className='mx_InviteDialog_userSections'>
|
<div className='mx_InviteDialog_userSections'>
|
||||||
|
|
|
@ -28,7 +28,6 @@ import {getTopic} from "../elements/RoomTopic";
|
||||||
import {avatarUrlForRoom} from "../../../Avatar";
|
import {avatarUrlForRoom} from "../../../Avatar";
|
||||||
import ToggleSwitch from "../elements/ToggleSwitch";
|
import ToggleSwitch from "../elements/ToggleSwitch";
|
||||||
import AccessibleButton from "../elements/AccessibleButton";
|
import AccessibleButton from "../elements/AccessibleButton";
|
||||||
import FormButton from "../elements/FormButton";
|
|
||||||
import Modal from "../../../Modal";
|
import Modal from "../../../Modal";
|
||||||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||||
import {allSettled} from "../../../utils/promise";
|
import {allSettled} from "../../../utils/promise";
|
||||||
|
@ -127,23 +126,24 @@ const SpaceSettingsDialog: React.FC<IProps> = ({ matrixClient: cli, space, onFin
|
||||||
<div>
|
<div>
|
||||||
{ _t("Make this space private") }
|
{ _t("Make this space private") }
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
checked={joinRule === "private"}
|
checked={joinRule !== "public"}
|
||||||
onChange={checked => setJoinRule(checked ? "private" : "invite")}
|
onChange={checked => setJoinRule(checked ? "invite" : "public")}
|
||||||
disabled={!canSetJoinRule}
|
disabled={!canSetJoinRule}
|
||||||
aria-label={_t("Make this space private")}
|
aria-label={_t("Make this space private")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<FormButton
|
<AccessibleButton
|
||||||
kind="danger"
|
kind="danger"
|
||||||
label={_t("Leave Space")}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
defaultDispatcher.dispatch({
|
defaultDispatcher.dispatch({
|
||||||
action: "leave_room",
|
action: "leave_room",
|
||||||
room_id: space.roomId,
|
room_id: space.roomId,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
{ _t("Leave Space") }
|
||||||
|
</AccessibleButton>
|
||||||
|
|
||||||
<div className="mx_SpaceSettingsDialog_buttons">
|
<div className="mx_SpaceSettingsDialog_buttons">
|
||||||
<AccessibleButton onClick={() => Modal.createDialog(DevtoolsDialog, {roomId: space.roomId})}>
|
<AccessibleButton onClick={() => Modal.createDialog(DevtoolsDialog, {roomId: space.roomId})}>
|
||||||
|
@ -152,7 +152,9 @@ const SpaceSettingsDialog: React.FC<IProps> = ({ matrixClient: cli, space, onFin
|
||||||
<AccessibleButton onClick={onFinished} disabled={busy} kind="link">
|
<AccessibleButton onClick={onFinished} disabled={busy} kind="link">
|
||||||
{ _t("Cancel") }
|
{ _t("Cancel") }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
<FormButton onClick={onSave} disabled={busy} label={busy ? _t("Saving...") : _t("Save Changes")} />
|
<AccessibleButton onClick={onSave} disabled={busy} kind="primary">
|
||||||
|
{ busy ? _t("Saving...") : _t("Save Changes") }
|
||||||
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</BaseDialog>;
|
</BaseDialog>;
|
||||||
|
|
|
@ -50,7 +50,7 @@ export default class VerificationRequestDialog extends React.Component {
|
||||||
const member = this.props.member ||
|
const member = this.props.member ||
|
||||||
otherUserId && MatrixClientPeg.get().getUser(otherUserId);
|
otherUserId && MatrixClientPeg.get().getUser(otherUserId);
|
||||||
const title = request && request.isSelfVerification ?
|
const title = request && request.isSelfVerification ?
|
||||||
_t("Verify other session") : _t("Verification Request");
|
_t("Verify other login") : _t("Verification Request");
|
||||||
|
|
||||||
return <BaseDialog className="mx_InfoDialog" onFinished={this.props.onFinished}
|
return <BaseDialog className="mx_InfoDialog" onFinished={this.props.onFinished}
|
||||||
contentId="mx_Dialog_content"
|
contentId="mx_Dialog_content"
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2018, 2019 New Vector Ltd
|
Copyright 2018-2021 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.
|
||||||
|
@ -17,14 +16,15 @@ limitations under the License.
|
||||||
|
|
||||||
import {debounce} from "lodash";
|
import {debounce} from "lodash";
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React from 'react';
|
import React, {ChangeEvent, FormEvent} from 'react';
|
||||||
import PropTypes from "prop-types";
|
import {ISecretStorageKeyInfo} from "matrix-js-sdk/src";
|
||||||
|
|
||||||
import * as sdk from '../../../../index';
|
import * as sdk from '../../../../index';
|
||||||
import {MatrixClientPeg} from '../../../../MatrixClientPeg';
|
import {MatrixClientPeg} from '../../../../MatrixClientPeg';
|
||||||
import Field from '../../elements/Field';
|
import Field from '../../elements/Field';
|
||||||
import AccessibleButton from '../../elements/AccessibleButton';
|
import AccessibleButton from '../../elements/AccessibleButton';
|
||||||
|
import {_t} from '../../../../languageHandler';
|
||||||
import { _t } from '../../../../languageHandler';
|
import {IDialogProps} from "../IDialogProps";
|
||||||
|
|
||||||
// Maximum acceptable size of a key file. It's 59 characters including the spaces we encode,
|
// Maximum acceptable size of a key file. It's 59 characters including the spaces we encode,
|
||||||
// so this should be plenty and allow for people putting extra whitespace in the file because
|
// so this should be plenty and allow for people putting extra whitespace in the file because
|
||||||
|
@ -34,22 +34,30 @@ const KEY_FILE_MAX_SIZE = 128;
|
||||||
// Don't shout at the user that their key is invalid every time they type a key: wait a short time
|
// Don't shout at the user that their key is invalid every time they type a key: wait a short time
|
||||||
const VALIDATION_THROTTLE_MS = 200;
|
const VALIDATION_THROTTLE_MS = 200;
|
||||||
|
|
||||||
|
interface IProps extends IDialogProps {
|
||||||
|
keyInfo: ISecretStorageKeyInfo;
|
||||||
|
checkPrivateKey: (k: {passphrase?: string, recoveryKey?: string}) => boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
recoveryKey: string;
|
||||||
|
recoveryKeyValid: boolean | null;
|
||||||
|
recoveryKeyCorrect: boolean | null;
|
||||||
|
recoveryKeyFileError: boolean | null;
|
||||||
|
forceRecoveryKey: boolean;
|
||||||
|
passPhrase: string;
|
||||||
|
keyMatches: boolean | null;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access Secure Secret Storage by requesting the user's passphrase.
|
* Access Secure Secret Storage by requesting the user's passphrase.
|
||||||
*/
|
*/
|
||||||
export default class AccessSecretStorageDialog extends React.PureComponent {
|
export default class AccessSecretStorageDialog extends React.PureComponent<IProps, IState> {
|
||||||
static propTypes = {
|
private fileUpload = React.createRef<HTMLInputElement>();
|
||||||
// { passphrase, pubkey }
|
|
||||||
keyInfo: PropTypes.object.isRequired,
|
|
||||||
// Function from one of { passphrase, recoveryKey } -> boolean
|
|
||||||
checkPrivateKey: PropTypes.func.isRequired,
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this._fileUpload = React.createRef();
|
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
recoveryKey: "",
|
recoveryKey: "",
|
||||||
recoveryKeyValid: null,
|
recoveryKeyValid: null,
|
||||||
|
@ -61,21 +69,21 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCancel = () => {
|
private onCancel = () => {
|
||||||
this.props.onFinished(false);
|
this.props.onFinished(false);
|
||||||
}
|
};
|
||||||
|
|
||||||
_onUseRecoveryKeyClick = () => {
|
private onUseRecoveryKeyClick = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
forceRecoveryKey: true,
|
forceRecoveryKey: true,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
_validateRecoveryKeyOnChange = debounce(() => {
|
private validateRecoveryKeyOnChange = debounce(async () => {
|
||||||
this._validateRecoveryKey();
|
await this.validateRecoveryKey();
|
||||||
}, VALIDATION_THROTTLE_MS);
|
}, VALIDATION_THROTTLE_MS);
|
||||||
|
|
||||||
async _validateRecoveryKey() {
|
private async validateRecoveryKey() {
|
||||||
if (this.state.recoveryKey === '') {
|
if (this.state.recoveryKey === '') {
|
||||||
this.setState({
|
this.setState({
|
||||||
recoveryKeyValid: null,
|
recoveryKeyValid: null,
|
||||||
|
@ -102,27 +110,27 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onRecoveryKeyChange = (e) => {
|
private onRecoveryKeyChange = (ev: ChangeEvent<HTMLInputElement>) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
recoveryKey: e.target.value,
|
recoveryKey: ev.target.value,
|
||||||
recoveryKeyFileError: null,
|
recoveryKeyFileError: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
// also clear the file upload control so that the user can upload the same file
|
// also clear the file upload control so that the user can upload the same file
|
||||||
// the did before (otherwise the onchange wouldn't fire)
|
// the did before (otherwise the onchange wouldn't fire)
|
||||||
if (this._fileUpload.current) this._fileUpload.current.value = null;
|
if (this.fileUpload.current) this.fileUpload.current.value = null;
|
||||||
|
|
||||||
// We don't use Field's validation here because a) we want it in a separate place rather
|
// We don't use Field's validation here because a) we want it in a separate place rather
|
||||||
// than in a tooltip and b) we want it to display feedback based on the uploaded file
|
// than in a tooltip and b) we want it to display feedback based on the uploaded file
|
||||||
// as well as the text box. Ideally we would refactor Field's validation logic so we could
|
// as well as the text box. Ideally we would refactor Field's validation logic so we could
|
||||||
// re-use some of it.
|
// re-use some of it.
|
||||||
this._validateRecoveryKeyOnChange();
|
this.validateRecoveryKeyOnChange();
|
||||||
}
|
};
|
||||||
|
|
||||||
_onRecoveryKeyFileChange = async e => {
|
private onRecoveryKeyFileChange = async (ev: ChangeEvent<HTMLInputElement>) => {
|
||||||
if (e.target.files.length === 0) return;
|
if (ev.target.files.length === 0) return;
|
||||||
|
|
||||||
const f = e.target.files[0];
|
const f = ev.target.files[0];
|
||||||
|
|
||||||
if (f.size > KEY_FILE_MAX_SIZE) {
|
if (f.size > KEY_FILE_MAX_SIZE) {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -140,7 +148,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
recoveryKeyFileError: null,
|
recoveryKeyFileError: null,
|
||||||
recoveryKey: contents.trim(),
|
recoveryKey: contents.trim(),
|
||||||
});
|
});
|
||||||
this._validateRecoveryKey();
|
await this.validateRecoveryKey();
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
recoveryKeyFileError: true,
|
recoveryKeyFileError: true,
|
||||||
|
@ -150,14 +158,14 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private onRecoveryKeyFileUploadClick = () => {
|
||||||
|
this.fileUpload.current.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onRecoveryKeyFileUploadClick = () => {
|
private onPassPhraseNext = async (ev: FormEvent<HTMLFormElement>) => {
|
||||||
this._fileUpload.current.click();
|
ev.preventDefault();
|
||||||
}
|
|
||||||
|
|
||||||
_onPassPhraseNext = async (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
if (this.state.passPhrase.length <= 0) return;
|
if (this.state.passPhrase.length <= 0) return;
|
||||||
|
|
||||||
|
@ -169,10 +177,10 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.setState({ keyMatches });
|
this.setState({ keyMatches });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
_onRecoveryKeyNext = async (e) => {
|
private onRecoveryKeyNext = async (ev: FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault();
|
ev.preventDefault();
|
||||||
|
|
||||||
if (!this.state.recoveryKeyValid) return;
|
if (!this.state.recoveryKeyValid) return;
|
||||||
|
|
||||||
|
@ -184,16 +192,16 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.setState({ keyMatches });
|
this.setState({ keyMatches });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
_onPassPhraseChange = (e) => {
|
private onPassPhraseChange = (ev: ChangeEvent<HTMLInputElement>) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
passPhrase: e.target.value,
|
passPhrase: ev.target.value,
|
||||||
keyMatches: null,
|
keyMatches: null,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
getKeyValidationText() {
|
private getKeyValidationText(): string {
|
||||||
if (this.state.recoveryKeyFileError) {
|
if (this.state.recoveryKeyFileError) {
|
||||||
return _t("Wrong file type");
|
return _t("Wrong file type");
|
||||||
} else if (this.state.recoveryKeyCorrect) {
|
} else if (this.state.recoveryKeyCorrect) {
|
||||||
|
@ -208,7 +216,8 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
// Caution: Making this an import will break tests.
|
||||||
|
const BaseDialog = sdk.getComponent("views.dialogs.BaseDialog");
|
||||||
|
|
||||||
const hasPassphrase = (
|
const hasPassphrase = (
|
||||||
this.props.keyInfo &&
|
this.props.keyInfo &&
|
||||||
|
@ -244,18 +253,18 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
{
|
{
|
||||||
button: s => <AccessibleButton className="mx_linkButton"
|
button: s => <AccessibleButton className="mx_linkButton"
|
||||||
element="span"
|
element="span"
|
||||||
onClick={this._onUseRecoveryKeyClick}
|
onClick={this.onUseRecoveryKeyClick}
|
||||||
>
|
>
|
||||||
{s}
|
{s}
|
||||||
</AccessibleButton>,
|
</AccessibleButton>,
|
||||||
},
|
},
|
||||||
)}</p>
|
)}</p>
|
||||||
|
|
||||||
<form className="mx_AccessSecretStorageDialog_primaryContainer" onSubmit={this._onPassPhraseNext}>
|
<form className="mx_AccessSecretStorageDialog_primaryContainer" onSubmit={this.onPassPhraseNext}>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
className="mx_AccessSecretStorageDialog_passPhraseInput"
|
className="mx_AccessSecretStorageDialog_passPhraseInput"
|
||||||
onChange={this._onPassPhraseChange}
|
onChange={this.onPassPhraseChange}
|
||||||
value={this.state.passPhrase}
|
value={this.state.passPhrase}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
autoComplete="new-password"
|
autoComplete="new-password"
|
||||||
|
@ -264,9 +273,9 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
{keyStatus}
|
{keyStatus}
|
||||||
<DialogButtons
|
<DialogButtons
|
||||||
primaryButton={_t('Continue')}
|
primaryButton={_t('Continue')}
|
||||||
onPrimaryButtonClick={this._onPassPhraseNext}
|
onPrimaryButtonClick={this.onPassPhraseNext}
|
||||||
hasCancel={true}
|
hasCancel={true}
|
||||||
onCancel={this._onCancel}
|
onCancel={this.onCancel}
|
||||||
focus={false}
|
focus={false}
|
||||||
primaryDisabled={this.state.passPhrase.length === 0}
|
primaryDisabled={this.state.passPhrase.length === 0}
|
||||||
/>
|
/>
|
||||||
|
@ -291,7 +300,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
|
|
||||||
<form
|
<form
|
||||||
className="mx_AccessSecretStorageDialog_primaryContainer"
|
className="mx_AccessSecretStorageDialog_primaryContainer"
|
||||||
onSubmit={this._onRecoveryKeyNext}
|
onSubmit={this.onRecoveryKeyNext}
|
||||||
spellCheck={false}
|
spellCheck={false}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
>
|
>
|
||||||
|
@ -301,7 +310,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
type="password"
|
type="password"
|
||||||
label={_t('Security Key')}
|
label={_t('Security Key')}
|
||||||
value={this.state.recoveryKey}
|
value={this.state.recoveryKey}
|
||||||
onChange={this._onRecoveryKeyChange}
|
onChange={this.onRecoveryKeyChange}
|
||||||
forceValidity={this.state.recoveryKeyCorrect}
|
forceValidity={this.state.recoveryKeyCorrect}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
/>
|
/>
|
||||||
|
@ -312,10 +321,10 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
<div>
|
<div>
|
||||||
<input type="file"
|
<input type="file"
|
||||||
className="mx_AccessSecretStorageDialog_recoveryKeyEntry_fileInput"
|
className="mx_AccessSecretStorageDialog_recoveryKeyEntry_fileInput"
|
||||||
ref={this._fileUpload}
|
ref={this.fileUpload}
|
||||||
onChange={this._onRecoveryKeyFileChange}
|
onChange={this.onRecoveryKeyFileChange}
|
||||||
/>
|
/>
|
||||||
<AccessibleButton kind="primary" onClick={this._onRecoveryKeyFileUploadClick}>
|
<AccessibleButton kind="primary" onClick={this.onRecoveryKeyFileUploadClick}>
|
||||||
{_t("Upload")}
|
{_t("Upload")}
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
|
@ -323,11 +332,11 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
{recoveryKeyFeedback}
|
{recoveryKeyFeedback}
|
||||||
<DialogButtons
|
<DialogButtons
|
||||||
primaryButton={_t('Continue')}
|
primaryButton={_t('Continue')}
|
||||||
onPrimaryButtonClick={this._onRecoveryKeyNext}
|
onPrimaryButtonClick={this.onRecoveryKeyNext}
|
||||||
hasCancel={true}
|
hasCancel={true}
|
||||||
cancelButton={_t("Go Back")}
|
cancelButton={_t("Go Back")}
|
||||||
cancelButtonClass='danger'
|
cancelButtonClass='danger'
|
||||||
onCancel={this._onCancel}
|
onCancel={this.onCancel}
|
||||||
focus={false}
|
focus={false}
|
||||||
primaryDisabled={!this.state.recoveryKeyValid}
|
primaryDisabled={!this.state.recoveryKeyValid}
|
||||||
/>
|
/>
|
||||||
|
@ -341,9 +350,9 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
||||||
title={title}
|
title={title}
|
||||||
titleClass={titleClass}
|
titleClass={titleClass}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
{content}
|
{content}
|
||||||
</div>
|
</div>
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
);
|
);
|
||||||
}
|
}
|
66
src/components/views/elements/FacePile.tsx
Normal file
66
src/components/views/elements/FacePile.tsx
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 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, { HTMLAttributes } from "react";
|
||||||
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
|
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||||
|
import { sortBy } from "lodash";
|
||||||
|
|
||||||
|
import MemberAvatar from "../avatars/MemberAvatar";
|
||||||
|
import { _t } from "../../../languageHandler";
|
||||||
|
import DMRoomMap from "../../../utils/DMRoomMap";
|
||||||
|
import TextWithTooltip from "../elements/TextWithTooltip";
|
||||||
|
import { useRoomMembers } from "../../../hooks/useRoomMembers";
|
||||||
|
|
||||||
|
const DEFAULT_NUM_FACES = 5;
|
||||||
|
|
||||||
|
interface IProps extends HTMLAttributes<HTMLSpanElement> {
|
||||||
|
room: Room;
|
||||||
|
onlyKnownUsers?: boolean;
|
||||||
|
numShown?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isKnownMember = (member: RoomMember) => !!DMRoomMap.shared().getDMRoomsForUserId(member.userId)?.length;
|
||||||
|
|
||||||
|
const FacePile = ({ room, onlyKnownUsers = true, numShown = DEFAULT_NUM_FACES, ...props }: IProps) => {
|
||||||
|
let members = useRoomMembers(room);
|
||||||
|
|
||||||
|
// sort users with an explicit avatar first
|
||||||
|
const iteratees = [member => !!member.getMxcAvatarUrl()];
|
||||||
|
if (onlyKnownUsers) {
|
||||||
|
members = members.filter(isKnownMember);
|
||||||
|
} else {
|
||||||
|
// sort known users first
|
||||||
|
iteratees.unshift(member => isKnownMember(member));
|
||||||
|
}
|
||||||
|
if (members.length < 1) return null;
|
||||||
|
|
||||||
|
const shownMembers = sortBy(members, iteratees).slice(0, numShown);
|
||||||
|
return <div {...props} className="mx_FacePile">
|
||||||
|
<div className="mx_FacePile_faces">
|
||||||
|
{ shownMembers.map(member => {
|
||||||
|
return <TextWithTooltip key={member.userId} tooltip={member.name}>
|
||||||
|
<MemberAvatar member={member} width={28} height={28} />
|
||||||
|
</TextWithTooltip>;
|
||||||
|
}) }
|
||||||
|
</div>
|
||||||
|
{ onlyKnownUsers && <span>
|
||||||
|
{ _t("%(count)s people you know have already joined", { count: members.length }) }
|
||||||
|
</span> }
|
||||||
|
</div>
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FacePile;
|
|
@ -73,7 +73,7 @@ const SSOButton: React.FC<ISSOButtonProps> = ({
|
||||||
brandClass = `mx_SSOButton_brand_${brandName}`;
|
brandClass = `mx_SSOButton_brand_${brandName}`;
|
||||||
icon = <img src={brandIcon} height="24" width="24" alt={brandName} />;
|
icon = <img src={brandIcon} height="24" width="24" alt={brandName} />;
|
||||||
} else if (typeof idp?.icon === "string" && idp.icon.startsWith("mxc://")) {
|
} else if (typeof idp?.icon === "string" && idp.icon.startsWith("mxc://")) {
|
||||||
const src = mediaFromMxc(idp.icon).getSquareThumbnailHttp(24);
|
const src = mediaFromMxc(idp.icon, matrixClient).getSquareThumbnailHttp(24);
|
||||||
icon = <img src={src} height="24" width="24" alt={idp.name} />;
|
icon = <img src={src} height="24" width="24" alt={idp.name} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,12 +46,14 @@ export default class TextWithTooltip extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const Tooltip = sdk.getComponent("elements.Tooltip");
|
const Tooltip = sdk.getComponent("elements.Tooltip");
|
||||||
|
|
||||||
|
const {class: className, children, tooltip, tooltipClass, ...props} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span onMouseOver={this.onMouseOver} onMouseLeave={this.onMouseLeave} className={this.props.class}>
|
<span {...props} onMouseOver={this.onMouseOver} onMouseLeave={this.onMouseLeave} className={className}>
|
||||||
{this.props.children}
|
{children}
|
||||||
{this.state.hover && <Tooltip
|
{this.state.hover && <Tooltip
|
||||||
label={this.props.tooltip}
|
label={tooltip}
|
||||||
tooltipClassName={this.props.tooltipClass}
|
tooltipClassName={tooltipClass}
|
||||||
className={"mx_TextWithTooltip_tooltip"} /> }
|
className={"mx_TextWithTooltip_tooltip"} /> }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|
|
@ -74,6 +74,11 @@ export default class MessageEvent extends React.Component {
|
||||||
'm.file': sdk.getComponent('messages.MFileBody'),
|
'm.file': sdk.getComponent('messages.MFileBody'),
|
||||||
'm.audio': sdk.getComponent('messages.MAudioBody'),
|
'm.audio': sdk.getComponent('messages.MAudioBody'),
|
||||||
'm.video': sdk.getComponent('messages.MVideoBody'),
|
'm.video': sdk.getComponent('messages.MVideoBody'),
|
||||||
|
|
||||||
|
// TODO: @@ TravisR: Use labs flag determination.
|
||||||
|
// MSC: https://github.com/matrix-org/matrix-doc/pull/2516
|
||||||
|
'org.matrix.msc2516.voice': sdk.getComponent('messages.MAudioBody'),
|
||||||
|
|
||||||
...(this.props.overrideBodyTypes || {}),
|
...(this.props.overrideBodyTypes || {}),
|
||||||
};
|
};
|
||||||
const evTypes = {
|
const evTypes = {
|
||||||
|
|
|
@ -216,12 +216,12 @@ export default class TextualBody extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
_addLineNumbers(pre) {
|
_addLineNumbers(pre) {
|
||||||
|
// Calculate number of lines in pre
|
||||||
|
const number = pre.innerHTML.replace(/\n(<\/code>)?$/, "").split(/\n/).length;
|
||||||
pre.innerHTML = '<span class="mx_EventTile_lineNumbers"></span>' + pre.innerHTML + '<span></span>';
|
pre.innerHTML = '<span class="mx_EventTile_lineNumbers"></span>' + pre.innerHTML + '<span></span>';
|
||||||
const lineNumbers = pre.getElementsByClassName("mx_EventTile_lineNumbers")[0];
|
const lineNumbers = pre.getElementsByClassName("mx_EventTile_lineNumbers")[0];
|
||||||
// Calculate number of lines in pre
|
|
||||||
const number = pre.innerHTML.split(/\n/).length;
|
|
||||||
// Iterate through lines starting with 1 (number of the first line is 1)
|
// Iterate through lines starting with 1 (number of the first line is 1)
|
||||||
for (let i = 1; i < number; i++) {
|
for (let i = 1; i <= number; i++) {
|
||||||
lineNumbers.innerHTML += '<span class="mx_EventTile_lineNumber">' + i + '</span>';
|
lineNumbers.innerHTML += '<span class="mx_EventTile_lineNumber">' + i + '</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ const EncryptionInfo: React.FC<IProps> = ({
|
||||||
let text: string;
|
let text: string;
|
||||||
if (waitingForOtherParty) {
|
if (waitingForOtherParty) {
|
||||||
if (isSelfVerification) {
|
if (isSelfVerification) {
|
||||||
text = _t("Waiting for you to accept on your other session…");
|
text = _t("Accept on your other login…");
|
||||||
} else {
|
} else {
|
||||||
text = _t("Waiting for %(displayName)s to accept…", {
|
text = _t("Waiting for %(displayName)s to accept…", {
|
||||||
displayName: member.displayName || member.name || member.userId,
|
displayName: member.displayName || member.name || member.userId,
|
||||||
|
|
|
@ -46,6 +46,7 @@ import {IDiff} from "../../../editor/diff";
|
||||||
import AutocompleteWrapperModel from "../../../editor/autocomplete";
|
import AutocompleteWrapperModel from "../../../editor/autocomplete";
|
||||||
import DocumentPosition from "../../../editor/position";
|
import DocumentPosition from "../../../editor/position";
|
||||||
import {ICompletion} from "../../../autocomplete/Autocompleter";
|
import {ICompletion} from "../../../autocomplete/Autocompleter";
|
||||||
|
import { AutocompleteAction, getKeyBindingsManager, MessageComposerAction } from '../../../KeyBindingsManager';
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||||
|
|
||||||
// matches emoticons which follow the start of a line or whitespace
|
// matches emoticons which follow the start of a line or whitespace
|
||||||
|
@ -93,6 +94,7 @@ interface IProps {
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
initialCaret?: DocumentOffset;
|
initialCaret?: DocumentOffset;
|
||||||
|
disabled?: boolean;
|
||||||
|
|
||||||
onChange?();
|
onChange?();
|
||||||
onPaste?(event: ClipboardEvent<HTMLDivElement>, model: EditorModel): boolean;
|
onPaste?(event: ClipboardEvent<HTMLDivElement>, model: EditorModel): boolean;
|
||||||
|
@ -421,98 +423,94 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
|
||||||
|
|
||||||
private onKeyDown = (event: React.KeyboardEvent) => {
|
private onKeyDown = (event: React.KeyboardEvent) => {
|
||||||
const model = this.props.model;
|
const model = this.props.model;
|
||||||
const modKey = IS_MAC ? event.metaKey : event.ctrlKey;
|
|
||||||
let handled = false;
|
let handled = false;
|
||||||
// format bold
|
const action = getKeyBindingsManager().getMessageComposerAction(event);
|
||||||
if (modKey && event.key === Key.B) {
|
switch (action) {
|
||||||
this.onFormatAction(Formatting.Bold);
|
case MessageComposerAction.FormatBold:
|
||||||
handled = true;
|
this.onFormatAction(Formatting.Bold);
|
||||||
// format italics
|
|
||||||
} else if (modKey && event.key === Key.I) {
|
|
||||||
this.onFormatAction(Formatting.Italics);
|
|
||||||
handled = true;
|
|
||||||
// format quote
|
|
||||||
} else if (modKey && event.key === Key.GREATER_THAN) {
|
|
||||||
this.onFormatAction(Formatting.Quote);
|
|
||||||
handled = true;
|
|
||||||
// redo
|
|
||||||
} else if ((!IS_MAC && modKey && event.key === Key.Y) ||
|
|
||||||
(IS_MAC && modKey && event.shiftKey && event.key === Key.Z)) {
|
|
||||||
if (this.historyManager.canRedo()) {
|
|
||||||
const {parts, caret} = this.historyManager.redo();
|
|
||||||
// pass matching inputType so historyManager doesn't push echo
|
|
||||||
// when invoked from rerender callback.
|
|
||||||
model.reset(parts, caret, "historyRedo");
|
|
||||||
}
|
|
||||||
handled = true;
|
|
||||||
// undo
|
|
||||||
} else if (modKey && event.key === Key.Z) {
|
|
||||||
if (this.historyManager.canUndo()) {
|
|
||||||
const {parts, caret} = this.historyManager.undo(this.props.model);
|
|
||||||
// pass matching inputType so historyManager doesn't push echo
|
|
||||||
// when invoked from rerender callback.
|
|
||||||
model.reset(parts, caret, "historyUndo");
|
|
||||||
}
|
|
||||||
handled = true;
|
|
||||||
// insert newline on Shift+Enter
|
|
||||||
} else if (event.key === Key.ENTER && (event.shiftKey || (IS_MAC && event.altKey))) {
|
|
||||||
this.insertText("\n");
|
|
||||||
handled = true;
|
|
||||||
// move selection to start of composer
|
|
||||||
} else if (modKey && event.key === Key.HOME && !event.shiftKey) {
|
|
||||||
setSelection(this.editorRef.current, model, {
|
|
||||||
index: 0,
|
|
||||||
offset: 0,
|
|
||||||
});
|
|
||||||
handled = true;
|
|
||||||
// move selection to end of composer
|
|
||||||
} else if (modKey && event.key === Key.END && !event.shiftKey) {
|
|
||||||
setSelection(this.editorRef.current, model, {
|
|
||||||
index: model.parts.length - 1,
|
|
||||||
offset: model.parts[model.parts.length - 1].text.length,
|
|
||||||
});
|
|
||||||
handled = true;
|
|
||||||
// autocomplete or enter to send below shouldn't have any modifier keys pressed.
|
|
||||||
} else {
|
|
||||||
const metaOrAltPressed = event.metaKey || event.altKey;
|
|
||||||
const modifierPressed = metaOrAltPressed || event.shiftKey;
|
|
||||||
if (model.autoComplete && model.autoComplete.hasCompletions()) {
|
|
||||||
const autoComplete = model.autoComplete;
|
|
||||||
switch (event.key) {
|
|
||||||
case Key.ARROW_UP:
|
|
||||||
if (!modifierPressed) {
|
|
||||||
autoComplete.onUpArrow(event);
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Key.ARROW_DOWN:
|
|
||||||
if (!modifierPressed) {
|
|
||||||
autoComplete.onDownArrow(event);
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Key.TAB:
|
|
||||||
if (!metaOrAltPressed) {
|
|
||||||
autoComplete.onTab(event);
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Key.ESCAPE:
|
|
||||||
if (!modifierPressed) {
|
|
||||||
autoComplete.onEscape(event);
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return; // don't preventDefault on anything else
|
|
||||||
}
|
|
||||||
} else if (event.key === Key.TAB) {
|
|
||||||
this.tabCompleteName(event);
|
|
||||||
handled = true;
|
handled = true;
|
||||||
} else if (event.key === Key.BACKSPACE || event.key === Key.DELETE) {
|
break;
|
||||||
this.formatBarRef.current.hide();
|
case MessageComposerAction.FormatItalics:
|
||||||
}
|
this.onFormatAction(Formatting.Italics);
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
case MessageComposerAction.FormatQuote:
|
||||||
|
this.onFormatAction(Formatting.Quote);
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
case MessageComposerAction.EditRedo:
|
||||||
|
if (this.historyManager.canRedo()) {
|
||||||
|
const {parts, caret} = this.historyManager.redo();
|
||||||
|
// pass matching inputType so historyManager doesn't push echo
|
||||||
|
// when invoked from rerender callback.
|
||||||
|
model.reset(parts, caret, "historyRedo");
|
||||||
|
}
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
case MessageComposerAction.EditUndo:
|
||||||
|
if (this.historyManager.canUndo()) {
|
||||||
|
const {parts, caret} = this.historyManager.undo(this.props.model);
|
||||||
|
// pass matching inputType so historyManager doesn't push echo
|
||||||
|
// when invoked from rerender callback.
|
||||||
|
model.reset(parts, caret, "historyUndo");
|
||||||
|
}
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
case MessageComposerAction.NewLine:
|
||||||
|
this.insertText("\n");
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
case MessageComposerAction.MoveCursorToStart:
|
||||||
|
setSelection(this.editorRef.current, model, {
|
||||||
|
index: 0,
|
||||||
|
offset: 0,
|
||||||
|
});
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
case MessageComposerAction.MoveCursorToEnd:
|
||||||
|
setSelection(this.editorRef.current, model, {
|
||||||
|
index: model.parts.length - 1,
|
||||||
|
offset: model.parts[model.parts.length - 1].text.length,
|
||||||
|
});
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (handled) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const autocompleteAction = getKeyBindingsManager().getAutocompleteAction(event);
|
||||||
|
if (model.autoComplete && model.autoComplete.hasCompletions()) {
|
||||||
|
const autoComplete = model.autoComplete;
|
||||||
|
switch (autocompleteAction) {
|
||||||
|
case AutocompleteAction.PrevSelection:
|
||||||
|
autoComplete.onUpArrow(event);
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
case AutocompleteAction.NextSelection:
|
||||||
|
autoComplete.onDownArrow(event);
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
case AutocompleteAction.ApplySelection:
|
||||||
|
autoComplete.onTab(event);
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
case AutocompleteAction.Cancel:
|
||||||
|
autoComplete.onEscape(event);
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return; // don't preventDefault on anything else
|
||||||
|
}
|
||||||
|
} else if (autocompleteAction === AutocompleteAction.ApplySelection) {
|
||||||
|
this.tabCompleteName(event);
|
||||||
|
handled = true;
|
||||||
|
} else if (event.key === Key.BACKSPACE || event.key === Key.DELETE) {
|
||||||
|
this.formatBarRef.current.hide();
|
||||||
|
}
|
||||||
|
|
||||||
if (handled) {
|
if (handled) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
@ -672,6 +670,9 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
|
||||||
});
|
});
|
||||||
const classes = classNames("mx_BasicMessageComposer_input", {
|
const classes = classNames("mx_BasicMessageComposer_input", {
|
||||||
"mx_BasicMessageComposer_input_shouldShowPillAvatar": this.state.showPillAvatar,
|
"mx_BasicMessageComposer_input_shouldShowPillAvatar": this.state.showPillAvatar,
|
||||||
|
|
||||||
|
// TODO: @@ TravisR: This doesn't work properly. The composer resets in a strange way.
|
||||||
|
"mx_BasicMessageComposer_input_disabled": this.props.disabled,
|
||||||
});
|
});
|
||||||
|
|
||||||
const shortcuts = {
|
const shortcuts = {
|
||||||
|
@ -704,6 +705,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
|
||||||
aria-expanded={Boolean(this.state.autoComplete)}
|
aria-expanded={Boolean(this.state.autoComplete)}
|
||||||
aria-activedescendant={completionIndex >= 0 ? generateCompletionDomId(completionIndex) : undefined}
|
aria-activedescendant={completionIndex >= 0 ? generateCompletionDomId(completionIndex) : undefined}
|
||||||
dir="auto"
|
dir="auto"
|
||||||
|
aria-disabled={this.props.disabled}
|
||||||
/>
|
/>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,10 @@ import EditorStateTransfer from '../../../utils/EditorStateTransfer';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import {EventStatus} from 'matrix-js-sdk/src/models/event';
|
import {EventStatus} from 'matrix-js-sdk/src/models/event';
|
||||||
import BasicMessageComposer from "./BasicMessageComposer";
|
import BasicMessageComposer from "./BasicMessageComposer";
|
||||||
import {Key, isOnlyCtrlOrCmdKeyEvent} from "../../../Keyboard";
|
|
||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
import {Action} from "../../../dispatcher/actions";
|
import {Action} from "../../../dispatcher/actions";
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
|
||||||
import CountlyAnalytics from "../../../CountlyAnalytics";
|
import CountlyAnalytics from "../../../CountlyAnalytics";
|
||||||
|
import {getKeyBindingsManager, MessageComposerAction} from '../../../KeyBindingsManager';
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||||
|
|
||||||
function _isReply(mxEvent) {
|
function _isReply(mxEvent) {
|
||||||
|
@ -136,38 +135,41 @@ export default class EditMessageComposer extends React.Component {
|
||||||
if (this._editorRef.isComposing(event)) {
|
if (this._editorRef.isComposing(event)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event.metaKey || event.altKey || event.shiftKey) {
|
const action = getKeyBindingsManager().getMessageComposerAction(event);
|
||||||
return;
|
switch (action) {
|
||||||
}
|
case MessageComposerAction.Send:
|
||||||
const ctrlEnterToSend = !!SettingsStore.getValue('MessageComposerInput.ctrlEnterToSend');
|
this._sendEdit();
|
||||||
const send = ctrlEnterToSend ? event.key === Key.ENTER && isOnlyCtrlOrCmdKeyEvent(event)
|
|
||||||
: event.key === Key.ENTER;
|
|
||||||
if (send) {
|
|
||||||
this._sendEdit();
|
|
||||||
event.preventDefault();
|
|
||||||
} else if (event.key === Key.ESCAPE) {
|
|
||||||
this._cancelEdit();
|
|
||||||
} else if (event.key === Key.ARROW_UP) {
|
|
||||||
if (this._editorRef.isModified() || !this._editorRef.isCaretAtStart()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const previousEvent = findEditableEvent(this._getRoom(), false, this.props.editState.getEvent().getId());
|
|
||||||
if (previousEvent) {
|
|
||||||
dis.dispatch({action: 'edit_event', event: previousEvent});
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
break;
|
||||||
|
case MessageComposerAction.CancelEditing:
|
||||||
|
this._cancelEdit();
|
||||||
|
break;
|
||||||
|
case MessageComposerAction.EditPrevMessage: {
|
||||||
|
if (this._editorRef.isModified() || !this._editorRef.isCaretAtStart()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const previousEvent = findEditableEvent(this._getRoom(), false,
|
||||||
|
this.props.editState.getEvent().getId());
|
||||||
|
if (previousEvent) {
|
||||||
|
dis.dispatch({action: 'edit_event', event: previousEvent});
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (event.key === Key.ARROW_DOWN) {
|
case MessageComposerAction.EditNextMessage: {
|
||||||
if (this._editorRef.isModified() || !this._editorRef.isCaretAtEnd()) {
|
if (this._editorRef.isModified() || !this._editorRef.isCaretAtEnd()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
const nextEvent = findEditableEvent(this._getRoom(), true, this.props.editState.getEvent().getId());
|
||||||
|
if (nextEvent) {
|
||||||
|
dis.dispatch({action: 'edit_event', event: nextEvent});
|
||||||
|
} else {
|
||||||
|
dis.dispatch({action: 'edit_event', event: null});
|
||||||
|
dis.fire(Action.FocusComposer);
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
const nextEvent = findEditableEvent(this._getRoom(), true, this.props.editState.getEvent().getId());
|
|
||||||
if (nextEvent) {
|
|
||||||
dis.dispatch({action: 'edit_event', event: nextEvent});
|
|
||||||
} else {
|
|
||||||
dis.dispatch({action: 'edit_event', event: null});
|
|
||||||
dis.fire(Action.FocusComposer);
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ import WidgetStore from "../../../stores/WidgetStore";
|
||||||
import {UPDATE_EVENT} from "../../../stores/AsyncStore";
|
import {UPDATE_EVENT} from "../../../stores/AsyncStore";
|
||||||
import ActiveWidgetStore from "../../../stores/ActiveWidgetStore";
|
import ActiveWidgetStore from "../../../stores/ActiveWidgetStore";
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||||
|
import VoiceRecordComposerTile from "./VoiceRecordComposerTile";
|
||||||
|
|
||||||
function ComposerAvatar(props) {
|
function ComposerAvatar(props) {
|
||||||
const MemberStatusMessageAvatar = sdk.getComponent('avatars.MemberStatusMessageAvatar');
|
const MemberStatusMessageAvatar = sdk.getComponent('avatars.MemberStatusMessageAvatar');
|
||||||
|
@ -187,6 +188,7 @@ export default class MessageComposer extends React.Component {
|
||||||
hasConference: WidgetStore.instance.doesRoomHaveConference(this.props.room),
|
hasConference: WidgetStore.instance.doesRoomHaveConference(this.props.room),
|
||||||
joinedConference: WidgetStore.instance.isJoinedToConferenceIn(this.props.room),
|
joinedConference: WidgetStore.instance.isJoinedToConferenceIn(this.props.room),
|
||||||
isComposerEmpty: true,
|
isComposerEmpty: true,
|
||||||
|
haveRecording: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,6 +327,10 @@ export default class MessageComposer extends React.Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onVoiceUpdate = (haveRecording: boolean) => {
|
||||||
|
this.setState({haveRecording});
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const controls = [
|
const controls = [
|
||||||
this.state.me ? <ComposerAvatar key="controls_avatar" me={this.state.me} /> : null,
|
this.state.me ? <ComposerAvatar key="controls_avatar" me={this.state.me} /> : null,
|
||||||
|
@ -346,17 +352,32 @@ export default class MessageComposer extends React.Component {
|
||||||
permalinkCreator={this.props.permalinkCreator}
|
permalinkCreator={this.props.permalinkCreator}
|
||||||
replyToEvent={this.props.replyToEvent}
|
replyToEvent={this.props.replyToEvent}
|
||||||
onChange={this.onChange}
|
onChange={this.onChange}
|
||||||
|
// TODO: @@ TravisR - Disabling the composer doesn't work
|
||||||
|
disabled={this.state.haveRecording}
|
||||||
/>,
|
/>,
|
||||||
<UploadButton key="controls_upload" roomId={this.props.room.roomId} />,
|
|
||||||
<EmojiButton key="emoji_button" addEmoji={this.addEmoji} />,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!this.state.haveRecording) {
|
||||||
|
controls.push(
|
||||||
|
<UploadButton key="controls_upload" roomId={this.props.room.roomId} />,
|
||||||
|
<EmojiButton key="emoji_button" addEmoji={this.addEmoji} />,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (SettingsStore.getValue(UIFeature.Widgets) &&
|
if (SettingsStore.getValue(UIFeature.Widgets) &&
|
||||||
SettingsStore.getValue("MessageComposerInput.showStickersButton")) {
|
SettingsStore.getValue("MessageComposerInput.showStickersButton") &&
|
||||||
|
!this.state.haveRecording) {
|
||||||
controls.push(<Stickerpicker key="stickerpicker_controls_button" room={this.props.room} />);
|
controls.push(<Stickerpicker key="stickerpicker_controls_button" room={this.props.room} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.state.isComposerEmpty) {
|
if (SettingsStore.getValue("feature_voice_messages")) {
|
||||||
|
controls.push(<VoiceRecordComposerTile
|
||||||
|
key="controls_voice_record"
|
||||||
|
room={this.props.room}
|
||||||
|
onRecording={this.onVoiceUpdate} />);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.state.isComposerEmpty || this.state.haveRecording) {
|
||||||
controls.push(
|
controls.push(
|
||||||
<SendButton key="controls_send" onClick={this.sendMessage} />,
|
<SendButton key="controls_send" onClick={this.sendMessage} />,
|
||||||
);
|
);
|
||||||
|
|
|
@ -85,8 +85,8 @@ class FormatButton extends React.PureComponent {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AccessibleTooltipButton
|
<AccessibleTooltipButton
|
||||||
as="span"
|
element="button"
|
||||||
role="button"
|
type="button"
|
||||||
onClick={this.props.onClick}
|
onClick={this.props.onClick}
|
||||||
title={this.props.label}
|
title={this.props.label}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
Copyright 2020, 2021 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.
|
||||||
|
@ -28,6 +28,8 @@ import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||||
import {ViewUserPayload} from "../../../dispatcher/payloads/ViewUserPayload";
|
import {ViewUserPayload} from "../../../dispatcher/payloads/ViewUserPayload";
|
||||||
import {Action} from "../../../dispatcher/actions";
|
import {Action} from "../../../dispatcher/actions";
|
||||||
import dis from "../../../dispatcher/dispatcher";
|
import dis from "../../../dispatcher/dispatcher";
|
||||||
|
import SpaceStore from "../../../stores/SpaceStore";
|
||||||
|
import {showSpaceInvite} from "../../../utils/space";
|
||||||
|
|
||||||
const NewRoomIntro = () => {
|
const NewRoomIntro = () => {
|
||||||
const cli = useContext(MatrixClientContext);
|
const cli = useContext(MatrixClientContext);
|
||||||
|
@ -100,17 +102,48 @@ const NewRoomIntro = () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let buttons;
|
let parentSpace;
|
||||||
if (room.canInvite(cli.getUserId())) {
|
if (
|
||||||
const onInviteClick = () => {
|
SpaceStore.instance.activeSpace?.canInvite(cli.getUserId()) &&
|
||||||
dis.dispatch({ action: "view_invite", roomId });
|
SpaceStore.instance.getSpaceFilteredRoomIds(SpaceStore.instance.activeSpace).has(room.roomId)
|
||||||
};
|
) {
|
||||||
|
parentSpace = SpaceStore.instance.activeSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
let buttons;
|
||||||
|
if (parentSpace) {
|
||||||
buttons = <div className="mx_NewRoomIntro_buttons">
|
buttons = <div className="mx_NewRoomIntro_buttons">
|
||||||
<AccessibleButton className="mx_NewRoomIntro_inviteButton" kind="primary" onClick={onInviteClick}>
|
<AccessibleButton
|
||||||
|
className="mx_NewRoomIntro_inviteButton"
|
||||||
|
kind="primary"
|
||||||
|
onClick={() => {
|
||||||
|
showSpaceInvite(parentSpace);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{_t("Invite to %(spaceName)s", { spaceName: parentSpace.name })}
|
||||||
|
</AccessibleButton>
|
||||||
|
{ room.canInvite(cli.getUserId()) && <AccessibleButton
|
||||||
|
className="mx_NewRoomIntro_inviteButton"
|
||||||
|
kind="primary_outline"
|
||||||
|
onClick={() => {
|
||||||
|
dis.dispatch({ action: "view_invite", roomId });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{_t("Invite to just this room")}
|
||||||
|
</AccessibleButton> }
|
||||||
|
</div>;
|
||||||
|
} else if (room.canInvite(cli.getUserId())) {
|
||||||
|
buttons = <div className="mx_NewRoomIntro_buttons">
|
||||||
|
<AccessibleButton
|
||||||
|
className="mx_NewRoomIntro_inviteButton"
|
||||||
|
kind="primary"
|
||||||
|
onClick={() => {
|
||||||
|
dis.dispatch({ action: "view_invite", roomId });
|
||||||
|
}}
|
||||||
|
>
|
||||||
{_t("Invite to this room")}
|
{_t("Invite to this room")}
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</div>
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const avatarUrl = room.currentState.getStateEvents(EventType.RoomAvatar, "")?.getContent()?.url;
|
const avatarUrl = room.currentState.getStateEvents(EventType.RoomAvatar, "")?.getContent()?.url;
|
||||||
|
|
|
@ -20,6 +20,7 @@ import React, { ReactComponentElement } from "react";
|
||||||
import { Dispatcher } from "flux";
|
import { Dispatcher } from "flux";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import * as fbEmitter from "fbemitter";
|
import * as fbEmitter from "fbemitter";
|
||||||
|
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||||
|
|
||||||
import { _t, _td } from "../../../languageHandler";
|
import { _t, _td } from "../../../languageHandler";
|
||||||
import { RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex";
|
import { RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex";
|
||||||
|
@ -48,9 +49,8 @@ import { IconizedContextMenuOption, IconizedContextMenuOptionList } from "../con
|
||||||
import AccessibleButton from "../elements/AccessibleButton";
|
import AccessibleButton from "../elements/AccessibleButton";
|
||||||
import { CommunityPrototypeStore } from "../../../stores/CommunityPrototypeStore";
|
import { CommunityPrototypeStore } from "../../../stores/CommunityPrototypeStore";
|
||||||
import CallHandler from "../../../CallHandler";
|
import CallHandler from "../../../CallHandler";
|
||||||
import SpaceStore, { SUGGESTED_ROOMS } from "../../../stores/SpaceStore";
|
import SpaceStore, {SUGGESTED_ROOMS} from "../../../stores/SpaceStore";
|
||||||
import { showAddExistingRooms, showCreateNewRoom } from "../../../utils/space";
|
import {showAddExistingRooms, showCreateNewRoom, showSpaceInvite} from "../../../utils/space";
|
||||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||||
import RoomAvatar from "../avatars/RoomAvatar";
|
import RoomAvatar from "../avatars/RoomAvatar";
|
||||||
import { ISpaceSummaryRoom } from "../../structures/SpaceRoomDirectory";
|
import { ISpaceSummaryRoom } from "../../structures/SpaceRoomDirectory";
|
||||||
|
@ -62,6 +62,7 @@ interface IProps {
|
||||||
onResize: () => void;
|
onResize: () => void;
|
||||||
resizeNotifier: ResizeNotifier;
|
resizeNotifier: ResizeNotifier;
|
||||||
isMinimized: boolean;
|
isMinimized: boolean;
|
||||||
|
activeSpace: Room;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
|
@ -194,8 +195,8 @@ const TAG_AESTHETICS: ITagAestheticsMap = {
|
||||||
: _t("You do not have permissions to add rooms to this space")}
|
: _t("You do not have permissions to add rooms to this space")}
|
||||||
/>
|
/>
|
||||||
<IconizedContextMenuOption
|
<IconizedContextMenuOption
|
||||||
label={_t("Explore space rooms")}
|
label={_t("Explore rooms")}
|
||||||
iconClassName="mx_RoomList_iconExplore"
|
iconClassName="mx_RoomList_iconBrowse"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
@ -424,6 +425,11 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
||||||
dis.dispatch({ action: Action.ViewRoomDirectory, initialText });
|
dis.dispatch({ action: Action.ViewRoomDirectory, initialText });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private onSpaceInviteClick = () => {
|
||||||
|
const initialText = RoomListStore.instance.getFirstNameFilterCondition()?.search;
|
||||||
|
showSpaceInvite(this.props.activeSpace, initialText);
|
||||||
|
};
|
||||||
|
|
||||||
private renderSuggestedRooms(): ReactComponentElement<typeof ExtraTile>[] {
|
private renderSuggestedRooms(): ReactComponentElement<typeof ExtraTile>[] {
|
||||||
return this.state.suggestedRooms.map(room => {
|
return this.state.suggestedRooms.map(room => {
|
||||||
const name = room.name || room.canonical_alias || room.aliases.pop() || _t("Empty room");
|
const name = room.name || room.canonical_alias || room.aliases.pop() || _t("Empty room");
|
||||||
|
@ -569,7 +575,23 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
||||||
kind="link"
|
kind="link"
|
||||||
onClick={this.onExplore}
|
onClick={this.onExplore}
|
||||||
>
|
>
|
||||||
{_t("Explore all public rooms")}
|
{ this.props.activeSpace ? _t("Explore rooms") : _t("Explore all public rooms") }
|
||||||
|
</AccessibleButton>
|
||||||
|
</div>;
|
||||||
|
} else if (this.props.activeSpace) {
|
||||||
|
explorePrompt = <div className="mx_RoomList_explorePrompt">
|
||||||
|
<div>{ _t("Quick actions") }</div>
|
||||||
|
{ this.props.activeSpace.canInvite(MatrixClientPeg.get().getUserId()) && <AccessibleButton
|
||||||
|
className="mx_RoomList_explorePrompt_spaceInvite"
|
||||||
|
onClick={this.onSpaceInviteClick}
|
||||||
|
>
|
||||||
|
{_t("Invite people")}
|
||||||
|
</AccessibleButton> }
|
||||||
|
<AccessibleButton
|
||||||
|
className="mx_RoomList_explorePrompt_spaceExplore"
|
||||||
|
onClick={this.onExplore}
|
||||||
|
>
|
||||||
|
{_t("Explore rooms")}
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</div>;
|
</div>;
|
||||||
} else if (Object.values(this.state.sublists).some(list => list.length > 0)) {
|
} else if (Object.values(this.state.sublists).some(list => list.length > 0)) {
|
||||||
|
|
|
@ -51,6 +51,7 @@ import { objectExcluding, objectHasDiff } from "../../../utils/objects";
|
||||||
import ExtraTile from "./ExtraTile";
|
import ExtraTile from "./ExtraTile";
|
||||||
import { ListNotificationState } from "../../../stores/notifications/ListNotificationState";
|
import { ListNotificationState } from "../../../stores/notifications/ListNotificationState";
|
||||||
import IconizedContextMenu from "../context_menus/IconizedContextMenu";
|
import IconizedContextMenu from "../context_menus/IconizedContextMenu";
|
||||||
|
import { getKeyBindingsManager, RoomListAction } from "../../../KeyBindingsManager";
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||||
|
|
||||||
const SHOW_N_BUTTON_HEIGHT = 28; // As defined by CSS
|
const SHOW_N_BUTTON_HEIGHT = 28; // As defined by CSS
|
||||||
|
@ -470,18 +471,19 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private onHeaderKeyDown = (ev: React.KeyboardEvent) => {
|
private onHeaderKeyDown = (ev: React.KeyboardEvent) => {
|
||||||
switch (ev.key) {
|
const action = getKeyBindingsManager().getRoomListAction(ev);
|
||||||
case Key.ARROW_LEFT:
|
switch (action) {
|
||||||
|
case RoomListAction.CollapseSection:
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
if (this.state.isExpanded) {
|
if (this.state.isExpanded) {
|
||||||
// On ARROW_LEFT collapse the room sublist if it isn't already
|
// Collapse the room sublist if it isn't already
|
||||||
this.toggleCollapsed();
|
this.toggleCollapsed();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Key.ARROW_RIGHT: {
|
case RoomListAction.ExpandSection: {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
if (!this.state.isExpanded) {
|
if (!this.state.isExpanded) {
|
||||||
// On ARROW_RIGHT expand the room sublist if it isn't already
|
// Expand the room sublist if it isn't already
|
||||||
this.toggleCollapsed();
|
this.toggleCollapsed();
|
||||||
} else if (this.sublistRef.current) {
|
} else if (this.sublistRef.current) {
|
||||||
// otherwise focus the first room
|
// otherwise focus the first room
|
||||||
|
|
|
@ -33,22 +33,22 @@ import ReplyThread from "../elements/ReplyThread";
|
||||||
import {parseEvent} from '../../../editor/deserialize';
|
import {parseEvent} from '../../../editor/deserialize';
|
||||||
import {findEditableEvent} from '../../../utils/EventUtils';
|
import {findEditableEvent} from '../../../utils/EventUtils';
|
||||||
import SendHistoryManager from "../../../SendHistoryManager";
|
import SendHistoryManager from "../../../SendHistoryManager";
|
||||||
import {getCommand} from '../../../SlashCommands';
|
import {CommandCategories, getCommand} from '../../../SlashCommands';
|
||||||
import * as sdk from '../../../index';
|
import * as sdk from '../../../index';
|
||||||
import Modal from '../../../Modal';
|
import Modal from '../../../Modal';
|
||||||
import {_t, _td} from '../../../languageHandler';
|
import {_t, _td} from '../../../languageHandler';
|
||||||
import ContentMessages from '../../../ContentMessages';
|
import ContentMessages from '../../../ContentMessages';
|
||||||
import {Key, isOnlyCtrlOrCmdKeyEvent} from "../../../Keyboard";
|
|
||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
import RateLimitedFunc from '../../../ratelimitedfunc';
|
import RateLimitedFunc from '../../../ratelimitedfunc';
|
||||||
import {Action} from "../../../dispatcher/actions";
|
import {Action} from "../../../dispatcher/actions";
|
||||||
import {containsEmoji} from "../../../effects/utils";
|
import {containsEmoji} from "../../../effects/utils";
|
||||||
import {CHAT_EFFECTS} from '../../../effects';
|
import {CHAT_EFFECTS} from '../../../effects';
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
|
||||||
import CountlyAnalytics from "../../../CountlyAnalytics";
|
import CountlyAnalytics from "../../../CountlyAnalytics";
|
||||||
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||||
import EMOJI_REGEX from 'emojibase-regex';
|
import EMOJI_REGEX from 'emojibase-regex';
|
||||||
|
import {getKeyBindingsManager, MessageComposerAction} from '../../../KeyBindingsManager';
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||||
|
import SettingsStore from '../../../settings/SettingsStore';
|
||||||
|
|
||||||
function addReplyToMessageContent(content, repliedToEvent, permalinkCreator) {
|
function addReplyToMessageContent(content, repliedToEvent, permalinkCreator) {
|
||||||
const replyContent = ReplyThread.makeReplyMixIn(repliedToEvent);
|
const replyContent = ReplyThread.makeReplyMixIn(repliedToEvent);
|
||||||
|
@ -120,6 +120,7 @@ export default class SendMessageComposer extends React.Component {
|
||||||
permalinkCreator: PropTypes.object.isRequired,
|
permalinkCreator: PropTypes.object.isRequired,
|
||||||
replyToEvent: PropTypes.object,
|
replyToEvent: PropTypes.object,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
static contextType = MatrixClientContext;
|
static contextType = MatrixClientContext;
|
||||||
|
@ -147,60 +148,50 @@ export default class SendMessageComposer extends React.Component {
|
||||||
if (this._editorRef.isComposing(event)) {
|
if (this._editorRef.isComposing(event)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const hasModifier = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
|
const action = getKeyBindingsManager().getMessageComposerAction(event);
|
||||||
const ctrlEnterToSend = !!SettingsStore.getValue('MessageComposerInput.ctrlEnterToSend');
|
switch (action) {
|
||||||
const send = ctrlEnterToSend
|
case MessageComposerAction.Send:
|
||||||
? event.key === Key.ENTER && isOnlyCtrlOrCmdKeyEvent(event)
|
this._sendMessage();
|
||||||
: event.key === Key.ENTER && !hasModifier;
|
event.preventDefault();
|
||||||
if (send) {
|
break;
|
||||||
this._sendMessage();
|
case MessageComposerAction.SelectPrevSendHistory:
|
||||||
event.preventDefault();
|
case MessageComposerAction.SelectNextSendHistory: {
|
||||||
} else if (event.key === Key.ARROW_UP) {
|
// Try select composer history
|
||||||
this.onVerticalArrow(event, true);
|
const selected = this.selectSendHistory(action === MessageComposerAction.SelectPrevSendHistory);
|
||||||
} else if (event.key === Key.ARROW_DOWN) {
|
if (selected) {
|
||||||
this.onVerticalArrow(event, false);
|
// We're selecting history, so prevent the key event from doing anything else
|
||||||
} else if (event.key === Key.ESCAPE) {
|
event.preventDefault();
|
||||||
dis.dispatch({
|
}
|
||||||
action: 'reply_to_event',
|
break;
|
||||||
event: null,
|
}
|
||||||
});
|
case MessageComposerAction.EditPrevMessage:
|
||||||
} else if (this._prepareToEncrypt) {
|
// selection must be collapsed and caret at start
|
||||||
// This needs to be last!
|
if (this._editorRef.isSelectionCollapsed() && this._editorRef.isCaretAtStart()) {
|
||||||
this._prepareToEncrypt();
|
const editEvent = findEditableEvent(this.props.room, false);
|
||||||
|
if (editEvent) {
|
||||||
|
// We're selecting history, so prevent the key event from doing anything else
|
||||||
|
event.preventDefault();
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'edit_event',
|
||||||
|
event: editEvent,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MessageComposerAction.CancelEditing:
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'reply_to_event',
|
||||||
|
event: null,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (this._prepareToEncrypt) {
|
||||||
|
// This needs to be last!
|
||||||
|
this._prepareToEncrypt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onVerticalArrow(e, up) {
|
|
||||||
// arrows from an initial-caret composer navigates recent messages to edit
|
|
||||||
// ctrl-alt-arrows navigate send history
|
|
||||||
if (e.shiftKey || e.metaKey) return;
|
|
||||||
|
|
||||||
const shouldSelectHistory = e.altKey && e.ctrlKey;
|
|
||||||
const shouldEditLastMessage = !e.altKey && !e.ctrlKey && up && !this.props.replyToEvent;
|
|
||||||
|
|
||||||
if (shouldSelectHistory) {
|
|
||||||
// Try select composer history
|
|
||||||
const selected = this.selectSendHistory(up);
|
|
||||||
if (selected) {
|
|
||||||
// We're selecting history, so prevent the key event from doing anything else
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
} else if (shouldEditLastMessage) {
|
|
||||||
// selection must be collapsed and caret at start
|
|
||||||
if (this._editorRef.isSelectionCollapsed() && this._editorRef.isCaretAtStart()) {
|
|
||||||
const editEvent = findEditableEvent(this.props.room, false);
|
|
||||||
if (editEvent) {
|
|
||||||
// We're selecting history, so prevent the key event from doing anything else
|
|
||||||
e.preventDefault();
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'edit_event',
|
|
||||||
event: editEvent,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we keep sent messages/commands in a separate history (separate from undo history)
|
// we keep sent messages/commands in a separate history (separate from undo history)
|
||||||
// so you can alt+up/down in them
|
// so you can alt+up/down in them
|
||||||
selectSendHistory(up) {
|
selectSendHistory(up) {
|
||||||
|
@ -265,7 +256,7 @@ export default class SendMessageComposer extends React.Component {
|
||||||
const myReactionKeys = [...myReactionEvents]
|
const myReactionKeys = [...myReactionEvents]
|
||||||
.filter(event => !event.isRedacted())
|
.filter(event => !event.isRedacted())
|
||||||
.map(event => event.getRelation().key);
|
.map(event => event.getRelation().key);
|
||||||
shouldReact = !myReactionKeys.includes(reaction);
|
shouldReact = !myReactionKeys.includes(reaction);
|
||||||
}
|
}
|
||||||
if (shouldReact) {
|
if (shouldReact) {
|
||||||
MatrixClientPeg.get().sendEvent(lastMessage.getRoomId(), "m.reaction", {
|
MatrixClientPeg.get().sendEvent(lastMessage.getRoomId(), "m.reaction", {
|
||||||
|
@ -290,15 +281,22 @@ export default class SendMessageComposer extends React.Component {
|
||||||
}
|
}
|
||||||
return text + part.text;
|
return text + part.text;
|
||||||
}, "");
|
}, "");
|
||||||
return [getCommand(this.props.room.roomId, commandText), commandText];
|
const {cmd, args} = getCommand(commandText);
|
||||||
|
return [cmd, args, commandText];
|
||||||
}
|
}
|
||||||
|
|
||||||
async _runSlashCommand(fn) {
|
async _runSlashCommand(cmd, args) {
|
||||||
const cmd = fn();
|
const result = cmd.run(this.props.room.roomId, args);
|
||||||
let error = cmd.error;
|
let messageContent;
|
||||||
if (cmd.promise) {
|
let error = result.error;
|
||||||
|
if (result.promise) {
|
||||||
try {
|
try {
|
||||||
await cmd.promise;
|
if (cmd.category === CommandCategories.messages) {
|
||||||
|
// The command returns a modified message that we need to pass on
|
||||||
|
messageContent = await result.promise;
|
||||||
|
} else {
|
||||||
|
await result.promise;
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
error = err;
|
error = err;
|
||||||
}
|
}
|
||||||
|
@ -307,7 +305,7 @@ export default class SendMessageComposer extends React.Component {
|
||||||
console.error("Command failure: %s", error);
|
console.error("Command failure: %s", error);
|
||||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
// assume the error is a server error when the command is async
|
// assume the error is a server error when the command is async
|
||||||
const isServerError = !!cmd.promise;
|
const isServerError = !!result.promise;
|
||||||
const title = isServerError ? _td("Server error") : _td("Command error");
|
const title = isServerError ? _td("Server error") : _td("Command error");
|
||||||
|
|
||||||
let errText;
|
let errText;
|
||||||
|
@ -325,6 +323,7 @@ export default class SendMessageComposer extends React.Component {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log("Command success.");
|
console.log("Command success.");
|
||||||
|
if (messageContent) return messageContent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,13 +332,22 @@ export default class SendMessageComposer extends React.Component {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const replyToEvent = this.props.replyToEvent;
|
||||||
let shouldSend = true;
|
let shouldSend = true;
|
||||||
|
let content;
|
||||||
|
|
||||||
if (!containsEmote(this.model) && this._isSlashCommand()) {
|
if (!containsEmote(this.model) && this._isSlashCommand()) {
|
||||||
const [cmd, commandText] = this._getSlashCommand();
|
const [cmd, args, commandText] = this._getSlashCommand();
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
shouldSend = false;
|
if (cmd.category === CommandCategories.messages) {
|
||||||
this._runSlashCommand(cmd);
|
content = await this._runSlashCommand(cmd, args);
|
||||||
|
if (replyToEvent) {
|
||||||
|
addReplyToMessageContent(content, replyToEvent, this.props.permalinkCreator);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._runSlashCommand(cmd, args);
|
||||||
|
shouldSend = false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// ask the user if their unknown command should be sent as a message
|
// ask the user if their unknown command should be sent as a message
|
||||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||||
|
@ -374,11 +382,12 @@ export default class SendMessageComposer extends React.Component {
|
||||||
this._sendQuickReaction();
|
this._sendQuickReaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
const replyToEvent = this.props.replyToEvent;
|
|
||||||
if (shouldSend) {
|
if (shouldSend) {
|
||||||
const startTime = CountlyAnalytics.getTimestamp();
|
const startTime = CountlyAnalytics.getTimestamp();
|
||||||
const {roomId} = this.props.room;
|
const {roomId} = this.props.room;
|
||||||
const content = createMessageContent(this.model, this.props.permalinkCreator, replyToEvent);
|
if (!content) {
|
||||||
|
content = createMessageContent(this.model, this.props.permalinkCreator, replyToEvent);
|
||||||
|
}
|
||||||
// don't bother sending an empty message
|
// don't bother sending an empty message
|
||||||
if (!content.body.trim()) return;
|
if (!content.body.trim()) return;
|
||||||
|
|
||||||
|
@ -453,12 +462,17 @@ export default class SendMessageComposer extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// should save state when editor has contents or reply is open
|
||||||
|
_shouldSaveStoredEditorState = () => {
|
||||||
|
return !this.model.isEmpty || this.props.replyToEvent;
|
||||||
|
}
|
||||||
|
|
||||||
_saveStoredEditorState = () => {
|
_saveStoredEditorState = () => {
|
||||||
if (this.model.isEmpty) {
|
if (this._shouldSaveStoredEditorState()) {
|
||||||
this._clearStoredEditorState();
|
|
||||||
} else {
|
|
||||||
const item = SendHistoryManager.createItem(this.model, this.props.replyToEvent);
|
const item = SendHistoryManager.createItem(this.model, this.props.replyToEvent);
|
||||||
localStorage.setItem(this._editorStateKey, JSON.stringify(item));
|
localStorage.setItem(this._editorStateKey, JSON.stringify(item));
|
||||||
|
} else {
|
||||||
|
this._clearStoredEditorState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,7 +516,7 @@ export default class SendMessageComposer extends React.Component {
|
||||||
_insertQuotedMessage(event) {
|
_insertQuotedMessage(event) {
|
||||||
const {model} = this;
|
const {model} = this;
|
||||||
const {partCreator} = model;
|
const {partCreator} = model;
|
||||||
const quoteParts = parseEvent(event, partCreator, { isQuotedMessage: true });
|
const quoteParts = parseEvent(event, partCreator, {isQuotedMessage: true});
|
||||||
// add two newlines
|
// add two newlines
|
||||||
quoteParts.push(partCreator.newline());
|
quoteParts.push(partCreator.newline());
|
||||||
quoteParts.push(partCreator.newline());
|
quoteParts.push(partCreator.newline());
|
||||||
|
@ -556,6 +570,7 @@ export default class SendMessageComposer extends React.Component {
|
||||||
label={this.props.placeholder}
|
label={this.props.placeholder}
|
||||||
placeholder={this.props.placeholder}
|
placeholder={this.props.placeholder}
|
||||||
onPaste={this._onPaste}
|
onPaste={this._onPaste}
|
||||||
|
disabled={this.props.disabled}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
88
src/components/views/rooms/VoiceRecordComposerTile.tsx
Normal file
88
src/components/views/rooms/VoiceRecordComposerTile.tsx
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 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 AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||||
|
import {_t} from "../../../languageHandler";
|
||||||
|
import React from "react";
|
||||||
|
import {VoiceRecorder} from "../../../voice/VoiceRecorder";
|
||||||
|
import {Room} from "matrix-js-sdk/src/models/room";
|
||||||
|
import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
room: Room;
|
||||||
|
onRecording: (haveRecording: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
recorder?: VoiceRecorder;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class VoiceRecordComposerTile extends React.PureComponent<IProps, IState> {
|
||||||
|
public constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
recorder: null, // not recording by default
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private onStartStopVoiceMessage = async () => {
|
||||||
|
// TODO: @@ TravisR: We do not want to auto-send on stop.
|
||||||
|
if (this.state.recorder) {
|
||||||
|
await this.state.recorder.stop();
|
||||||
|
const mxc = await this.state.recorder.upload();
|
||||||
|
MatrixClientPeg.get().sendMessage(this.props.room.roomId, {
|
||||||
|
body: "Voice message",
|
||||||
|
msgtype: "org.matrix.msc2516.voice",
|
||||||
|
url: mxc,
|
||||||
|
});
|
||||||
|
this.setState({recorder: null});
|
||||||
|
this.props.onRecording(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const recorder = new VoiceRecorder(MatrixClientPeg.get());
|
||||||
|
await recorder.start();
|
||||||
|
this.props.onRecording(true);
|
||||||
|
// TODO: @@ TravisR: Run through EQ component
|
||||||
|
// recorder.frequencyData.onUpdate((freq) => {
|
||||||
|
// console.log('@@ UPDATE', freq);
|
||||||
|
// });
|
||||||
|
this.setState({recorder});
|
||||||
|
};
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
const classes = classNames({
|
||||||
|
'mx_MessageComposer_button': !this.state.recorder,
|
||||||
|
'mx_MessageComposer_voiceMessage': !this.state.recorder,
|
||||||
|
'mx_VoiceRecordComposerTile_stop': !!this.state.recorder,
|
||||||
|
});
|
||||||
|
|
||||||
|
let tooltip = _t("Record a voice message");
|
||||||
|
if (!!this.state.recorder) {
|
||||||
|
// TODO: @@ TravisR: Change to match behaviour
|
||||||
|
tooltip = _t("Stop & send recording");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AccessibleTooltipButton
|
||||||
|
className={classes}
|
||||||
|
onClick={this.onStartStopVoiceMessage}
|
||||||
|
title={tooltip}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -190,7 +190,7 @@ export default class EventIndexPanel extends React.Component {
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else if (!EventIndexPeg.platformHasSupport()) {
|
||||||
eventIndexingSettings = (
|
eventIndexingSettings = (
|
||||||
<div className='mx_SettingsTab_subsectionText'>
|
<div className='mx_SettingsTab_subsectionText'>
|
||||||
{
|
{
|
||||||
|
@ -208,6 +208,23 @@ export default class EventIndexPanel extends React.Component {
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
eventIndexingSettings = (
|
||||||
|
<div className='mx_SettingsTab_subsectionText'>
|
||||||
|
<p>
|
||||||
|
{_t("Message search initilisation failed")}
|
||||||
|
</p>
|
||||||
|
{EventIndexPeg.error && (
|
||||||
|
<details>
|
||||||
|
<summary>{_t("Advanced")}</summary>
|
||||||
|
<code>
|
||||||
|
{EventIndexPeg.error.message}
|
||||||
|
</code>
|
||||||
|
</details>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return eventIndexingSettings;
|
return eventIndexingSettings;
|
||||||
|
|
|
@ -203,6 +203,7 @@ export class EmailAddress extends React.Component {
|
||||||
className="mx_ExistingEmailAddress_confirmBtn"
|
className="mx_ExistingEmailAddress_confirmBtn"
|
||||||
kind="primary_sm"
|
kind="primary_sm"
|
||||||
onClick={this.onContinueClick}
|
onClick={this.onContinueClick}
|
||||||
|
disabled={this.state.continueDisabled}
|
||||||
>
|
>
|
||||||
{_t("Complete")}
|
{_t("Complete")}
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
|
|
|
@ -206,10 +206,10 @@ export default class GeneralUserSettingsTab extends React.Component {
|
||||||
|
|
||||||
_onPasswordChangeError = (err) => {
|
_onPasswordChangeError = (err) => {
|
||||||
// TODO: Figure out a design that doesn't involve replacing the current dialog
|
// TODO: Figure out a design that doesn't involve replacing the current dialog
|
||||||
let errMsg = err.error || "";
|
let errMsg = err.error || err.message || "";
|
||||||
if (err.httpStatus === 403) {
|
if (err.httpStatus === 403) {
|
||||||
errMsg = _t("Failed to change password. Is your password correct?");
|
errMsg = _t("Failed to change password. Is your password correct?");
|
||||||
} else if (err.httpStatus) {
|
} else if (!errMsg) {
|
||||||
errMsg += ` (HTTP status ${err.httpStatus})`;
|
errMsg += ` (HTTP status ${err.httpStatus})`;
|
||||||
}
|
}
|
||||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
|
|
|
@ -21,7 +21,6 @@ import {EventType, RoomType, RoomCreateTypeField} from "matrix-js-sdk/src/@types
|
||||||
import {_t} from "../../../languageHandler";
|
import {_t} from "../../../languageHandler";
|
||||||
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||||
import {ChevronFace, ContextMenu} from "../../structures/ContextMenu";
|
import {ChevronFace, ContextMenu} from "../../structures/ContextMenu";
|
||||||
import FormButton from "../elements/FormButton";
|
|
||||||
import createRoom, {IStateEvent, Preset} from "../../../createRoom";
|
import createRoom, {IStateEvent, Preset} from "../../../createRoom";
|
||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
import SpaceBasicSettings from "./SpaceBasicSettings";
|
import SpaceBasicSettings from "./SpaceBasicSettings";
|
||||||
|
@ -89,6 +88,7 @@ const SpaceCreateMenu = ({ onFinished }) => {
|
||||||
power_level_content_override: {
|
power_level_content_override: {
|
||||||
// Only allow Admins to write to the timeline to prevent hidden sync spam
|
// Only allow Admins to write to the timeline to prevent hidden sync spam
|
||||||
events_default: 100,
|
events_default: 100,
|
||||||
|
...Visibility.Public ? { invite: 0 } : {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
spinner: false,
|
spinner: false,
|
||||||
|
@ -108,7 +108,7 @@ const SpaceCreateMenu = ({ onFinished }) => {
|
||||||
body = <React.Fragment>
|
body = <React.Fragment>
|
||||||
<h2>{ _t("Create a space") }</h2>
|
<h2>{ _t("Create a space") }</h2>
|
||||||
<p>{ _t("Spaces are new ways to group rooms and people. " +
|
<p>{ _t("Spaces are new ways to group rooms and people. " +
|
||||||
"To join an existing space you’ll need an invite") }</p>
|
"To join an existing space you'll need an invite.") }</p>
|
||||||
|
|
||||||
<SpaceCreateMenuType
|
<SpaceCreateMenuType
|
||||||
title={_t("Public")}
|
title={_t("Public")}
|
||||||
|
@ -140,19 +140,17 @@ const SpaceCreateMenu = ({ onFinished }) => {
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
{
|
{
|
||||||
_t("Give it a photo, name and description to help you identify it.")
|
_t("Add some details to help people recognise it.")
|
||||||
} {
|
} {
|
||||||
_t("You can change these at any point.")
|
_t("You can change these anytime.")
|
||||||
}
|
}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<SpaceBasicSettings setAvatar={setAvatar} name={name} setName={setName} topic={topic} setTopic={setTopic} />
|
<SpaceBasicSettings setAvatar={setAvatar} name={name} setName={setName} topic={topic} setTopic={setTopic} />
|
||||||
|
|
||||||
<FormButton
|
<AccessibleButton kind="primary" onClick={onSpaceCreateClick} disabled={!name || busy}>
|
||||||
label={busy ? _t("Creating...") : _t("Create")}
|
{ busy ? _t("Creating...") : _t("Create") }
|
||||||
onClick={onSpaceCreateClick}
|
</AccessibleButton>
|
||||||
disabled={!name && !busy}
|
|
||||||
/>
|
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,13 +220,19 @@ const SpacePanel = () => {
|
||||||
<SpaceButton
|
<SpaceButton
|
||||||
className={newClasses}
|
className={newClasses}
|
||||||
tooltip={menuDisplayed ? _t("Cancel") : _t("Create a space")}
|
tooltip={menuDisplayed ? _t("Cancel") : _t("Create a space")}
|
||||||
onClick={menuDisplayed ? closeMenu : openMenu}
|
onClick={menuDisplayed ? closeMenu : () => {
|
||||||
|
openMenu();
|
||||||
|
if (!isPanelCollapsed) setPanelCollapsed(true);
|
||||||
|
}}
|
||||||
isNarrow={isPanelCollapsed}
|
isNarrow={isPanelCollapsed}
|
||||||
/>
|
/>
|
||||||
</AutoHideScrollbar>
|
</AutoHideScrollbar>
|
||||||
<AccessibleTooltipButton
|
<AccessibleTooltipButton
|
||||||
className={classNames("mx_SpacePanel_toggleCollapse", {expanded: !isPanelCollapsed})}
|
className={classNames("mx_SpacePanel_toggleCollapse", {expanded: !isPanelCollapsed})}
|
||||||
onClick={evt => setPanelCollapsed(!isPanelCollapsed)}
|
onClick={() => {
|
||||||
|
setPanelCollapsed(!isPanelCollapsed);
|
||||||
|
if (menuDisplayed) closeMenu();
|
||||||
|
}}
|
||||||
title={expandCollapseButtonTitle}
|
title={expandCollapseButtonTitle}
|
||||||
/>
|
/>
|
||||||
{ contextMenu }
|
{ contextMenu }
|
||||||
|
|
|
@ -26,7 +26,7 @@ import {showRoomInviteDialog} from "../../../RoomInvite";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
space: Room;
|
space: Room;
|
||||||
onFinished(): void;
|
onFinished?(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SpacePublicShare = ({ space, onFinished }: IProps) => {
|
const SpacePublicShare = ({ space, onFinished }: IProps) => {
|
||||||
|
@ -41,23 +41,24 @@ const SpacePublicShare = ({ space, onFinished }: IProps) => {
|
||||||
const success = await copyPlaintext(permalinkCreator.forRoom());
|
const success = await copyPlaintext(permalinkCreator.forRoom());
|
||||||
const text = success ? _t("Copied!") : _t("Failed to copy");
|
const text = success ? _t("Copied!") : _t("Failed to copy");
|
||||||
setCopiedText(text);
|
setCopiedText(text);
|
||||||
await sleep(10);
|
await sleep(5000);
|
||||||
if (copiedText === text) { // if the text hasn't changed by another click then clear it after some time
|
if (copiedText === text) { // if the text hasn't changed by another click then clear it after some time
|
||||||
setCopiedText(_t("Click to copy"));
|
setCopiedText(_t("Click to copy"));
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{ _t("Share invite link") }
|
<h3>{ _t("Share invite link") }</h3>
|
||||||
<span>{ copiedText }</span>
|
<span>{ copiedText }</span>
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
className="mx_SpacePublicShare_inviteButton"
|
className="mx_SpacePublicShare_inviteButton"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
showRoomInviteDialog(space.roomId);
|
showRoomInviteDialog(space.roomId);
|
||||||
onFinished();
|
if (onFinished) onFinished();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{ _t("Invite by email or username") }
|
<h3>{ _t("Invite people") }</h3>
|
||||||
|
<span>{ _t("Invite with email or username") }</span>
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,20 +30,21 @@ import IconizedContextMenu, {
|
||||||
import {_t} from "../../../languageHandler";
|
import {_t} from "../../../languageHandler";
|
||||||
import {ContextMenuTooltipButton} from "../../../accessibility/context_menu/ContextMenuTooltipButton";
|
import {ContextMenuTooltipButton} from "../../../accessibility/context_menu/ContextMenuTooltipButton";
|
||||||
import {toRightOf} from "../../structures/ContextMenu";
|
import {toRightOf} from "../../structures/ContextMenu";
|
||||||
import {shouldShowSpaceSettings, showCreateNewRoom, showSpaceSettings} from "../../../utils/space";
|
import {
|
||||||
|
shouldShowSpaceSettings,
|
||||||
|
showAddExistingRooms,
|
||||||
|
showCreateNewRoom,
|
||||||
|
showSpaceInvite,
|
||||||
|
showSpaceSettings,
|
||||||
|
} from "../../../utils/space";
|
||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
import {ButtonEvent} from "../elements/AccessibleButton";
|
import AccessibleButton, {ButtonEvent} from "../elements/AccessibleButton";
|
||||||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||||
import Modal from "../../../Modal";
|
|
||||||
import SpacePublicShare from "./SpacePublicShare";
|
|
||||||
import {Action} from "../../../dispatcher/actions";
|
import {Action} from "../../../dispatcher/actions";
|
||||||
import RoomViewStore from "../../../stores/RoomViewStore";
|
import RoomViewStore from "../../../stores/RoomViewStore";
|
||||||
import {SetRightPanelPhasePayload} from "../../../dispatcher/payloads/SetRightPanelPhasePayload";
|
import {SetRightPanelPhasePayload} from "../../../dispatcher/payloads/SetRightPanelPhasePayload";
|
||||||
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
|
||||||
import {showRoomInviteDialog} from "../../../RoomInvite";
|
|
||||||
import InfoDialog from "../dialogs/InfoDialog";
|
|
||||||
import {EventType} from "matrix-js-sdk/src/@types/event";
|
import {EventType} from "matrix-js-sdk/src/@types/event";
|
||||||
import SpaceRoomDirectory from "../../structures/SpaceRoomDirectory";
|
|
||||||
|
|
||||||
interface IItemProps {
|
interface IItemProps {
|
||||||
space?: Room;
|
space?: Room;
|
||||||
|
@ -110,36 +111,11 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
||||||
this.setState({contextMenuPosition: null});
|
this.setState({contextMenuPosition: null});
|
||||||
};
|
};
|
||||||
|
|
||||||
private onHomeClick = (ev: ButtonEvent) => {
|
|
||||||
ev.preventDefault();
|
|
||||||
ev.stopPropagation();
|
|
||||||
|
|
||||||
defaultDispatcher.dispatch({
|
|
||||||
action: "view_room",
|
|
||||||
room_id: this.props.space.roomId,
|
|
||||||
});
|
|
||||||
this.setState({contextMenuPosition: null}); // also close the menu
|
|
||||||
};
|
|
||||||
|
|
||||||
private onInviteClick = (ev: ButtonEvent) => {
|
private onInviteClick = (ev: ButtonEvent) => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
|
|
||||||
if (this.props.space.getJoinRule() === "public") {
|
showSpaceInvite(this.props.space);
|
||||||
const modal = Modal.createTrackedDialog("Space Invite", "User Menu", InfoDialog, {
|
|
||||||
title: _t("Invite members"),
|
|
||||||
description: <React.Fragment>
|
|
||||||
<span>{ _t("Share your public space") }</span>
|
|
||||||
<SpacePublicShare space={this.props.space} onFinished={() => modal.close()} />
|
|
||||||
</React.Fragment>,
|
|
||||||
fixedWidth: false,
|
|
||||||
button: false,
|
|
||||||
className: "mx_SpacePanel_sharePublicSpace",
|
|
||||||
hasCloseButton: true,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
showRoomInviteDialog(this.props.space.roomId);
|
|
||||||
}
|
|
||||||
this.setState({contextMenuPosition: null}); // also close the menu
|
this.setState({contextMenuPosition: null}); // also close the menu
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -170,6 +146,14 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
||||||
this.setState({contextMenuPosition: null}); // also close the menu
|
this.setState({contextMenuPosition: null}); // also close the menu
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private onAddExistingRoomClick = (ev: ButtonEvent) => {
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
|
||||||
|
showAddExistingRooms(this.context, this.props.space);
|
||||||
|
this.setState({contextMenuPosition: null}); // also close the menu
|
||||||
|
};
|
||||||
|
|
||||||
private onMembersClick = (ev: ButtonEvent) => {
|
private onMembersClick = (ev: ButtonEvent) => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
|
@ -193,9 +177,10 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
|
|
||||||
Modal.createTrackedDialog("Space room directory", "Space panel", SpaceRoomDirectory, {
|
defaultDispatcher.dispatch({
|
||||||
space: this.props.space,
|
action: "view_room",
|
||||||
}, "mx_SpaceRoomDirectory_dialogWrapper", false, true);
|
room_id: this.props.space.roomId,
|
||||||
|
});
|
||||||
this.setState({contextMenuPosition: null}); // also close the menu
|
this.setState({contextMenuPosition: null}); // also close the menu
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -236,15 +221,22 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
||||||
</IconizedContextMenuOptionList>;
|
</IconizedContextMenuOptionList>;
|
||||||
}
|
}
|
||||||
|
|
||||||
let newRoomOption;
|
const canAddRooms = this.props.space.currentState.maySendStateEvent(EventType.SpaceChild, userId);
|
||||||
|
|
||||||
|
let newRoomSection;
|
||||||
if (this.props.space.currentState.maySendStateEvent(EventType.SpaceChild, userId)) {
|
if (this.props.space.currentState.maySendStateEvent(EventType.SpaceChild, userId)) {
|
||||||
newRoomOption = (
|
newRoomSection = <IconizedContextMenuOptionList first>
|
||||||
<IconizedContextMenuOption
|
<IconizedContextMenuOption
|
||||||
iconClassName="mx_SpacePanel_iconPlus"
|
iconClassName="mx_SpacePanel_iconPlus"
|
||||||
label={_t("New room")}
|
label={_t("Create new room")}
|
||||||
onClick={this.onNewRoomClick}
|
onClick={this.onNewRoomClick}
|
||||||
/>
|
/>
|
||||||
);
|
<IconizedContextMenuOption
|
||||||
|
iconClassName="mx_SpacePanel_iconHash"
|
||||||
|
label={_t("Add existing room")}
|
||||||
|
onClick={this.onAddExistingRoomClick}
|
||||||
|
/>
|
||||||
|
</IconizedContextMenuOptionList>;
|
||||||
}
|
}
|
||||||
|
|
||||||
contextMenu = <IconizedContextMenu
|
contextMenu = <IconizedContextMenu
|
||||||
|
@ -258,11 +250,6 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
||||||
</div>
|
</div>
|
||||||
<IconizedContextMenuOptionList first>
|
<IconizedContextMenuOptionList first>
|
||||||
{ inviteOption }
|
{ inviteOption }
|
||||||
<IconizedContextMenuOption
|
|
||||||
iconClassName="mx_SpacePanel_iconHome"
|
|
||||||
label={_t("Space Home")}
|
|
||||||
onClick={this.onHomeClick}
|
|
||||||
/>
|
|
||||||
<IconizedContextMenuOption
|
<IconizedContextMenuOption
|
||||||
iconClassName="mx_SpacePanel_iconMembers"
|
iconClassName="mx_SpacePanel_iconMembers"
|
||||||
label={_t("Members")}
|
label={_t("Members")}
|
||||||
|
@ -271,11 +258,11 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
||||||
{ settingsOption }
|
{ settingsOption }
|
||||||
<IconizedContextMenuOption
|
<IconizedContextMenuOption
|
||||||
iconClassName="mx_SpacePanel_iconExplore"
|
iconClassName="mx_SpacePanel_iconExplore"
|
||||||
label={_t("Explore rooms")}
|
label={canAddRooms ? _t("Manage & explore rooms") : _t("Explore rooms")}
|
||||||
onClick={this.onExploreRoomsClick}
|
onClick={this.onExploreRoomsClick}
|
||||||
/>
|
/>
|
||||||
{ newRoomOption }
|
|
||||||
</IconizedContextMenuOptionList>
|
</IconizedContextMenuOptionList>
|
||||||
|
{ newRoomSection }
|
||||||
{ leaveSection }
|
{ leaveSection }
|
||||||
</IconizedContextMenu>;
|
</IconizedContextMenu>;
|
||||||
}
|
}
|
||||||
|
@ -335,7 +322,7 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
||||||
const avatarSize = isNested ? 24 : 32;
|
const avatarSize = isNested ? 24 : 32;
|
||||||
|
|
||||||
const toggleCollapseButton = childSpaces && childSpaces.length ?
|
const toggleCollapseButton = childSpaces && childSpaces.length ?
|
||||||
<button
|
<AccessibleButton
|
||||||
className="mx_SpaceButton_toggleCollapse"
|
className="mx_SpaceButton_toggleCollapse"
|
||||||
onClick={evt => this.toggleCollapse(evt)}
|
onClick={evt => this.toggleCollapse(evt)}
|
||||||
/> : null;
|
/> : null;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
Copyright 2020-2021 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.
|
||||||
|
@ -21,6 +21,7 @@ import {XOR} from "../../../@types/common";
|
||||||
|
|
||||||
export interface IProps {
|
export interface IProps {
|
||||||
description: ReactNode;
|
description: ReactNode;
|
||||||
|
detail?: ReactNode;
|
||||||
acceptLabel: string;
|
acceptLabel: string;
|
||||||
|
|
||||||
onAccept();
|
onAccept();
|
||||||
|
@ -33,14 +34,20 @@ interface IPropsExtended extends IProps {
|
||||||
|
|
||||||
const GenericToast: React.FC<XOR<IPropsExtended, IProps>> = ({
|
const GenericToast: React.FC<XOR<IPropsExtended, IProps>> = ({
|
||||||
description,
|
description,
|
||||||
|
detail,
|
||||||
acceptLabel,
|
acceptLabel,
|
||||||
rejectLabel,
|
rejectLabel,
|
||||||
onAccept,
|
onAccept,
|
||||||
onReject,
|
onReject,
|
||||||
}) => {
|
}) => {
|
||||||
|
const detailContent = detail ? <div className="mx_Toast_detail">
|
||||||
|
{detail}
|
||||||
|
</div> : null;
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
<div className="mx_Toast_description">
|
<div className="mx_Toast_description">
|
||||||
{ description }
|
{description}
|
||||||
|
{detailContent}
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Toast_buttons" aria-live="off">
|
<div className="mx_Toast_buttons" aria-live="off">
|
||||||
{onReject && rejectLabel && <FormButton label={rejectLabel} kind="danger" onClick={onReject} /> }
|
{onReject && rejectLabel && <FormButton label={rejectLabel} kind="danger" onClick={onReject} /> }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
Copyright 2019-2021 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.
|
||||||
|
@ -140,11 +140,12 @@ export default class VerificationRequestToast extends React.PureComponent<IProps
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {request} = this.props;
|
const {request} = this.props;
|
||||||
let nameLabel;
|
let description;
|
||||||
|
let detail;
|
||||||
if (request.isSelfVerification) {
|
if (request.isSelfVerification) {
|
||||||
if (this.state.device) {
|
if (this.state.device) {
|
||||||
nameLabel = _t("From %(deviceName)s (%(deviceId)s) at %(ip)s", {
|
description = this.state.device.getDisplayName();
|
||||||
deviceName: this.state.device.getDisplayName(),
|
detail = _t("%(deviceId)s from %(ip)s", {
|
||||||
deviceId: this.state.device.deviceId,
|
deviceId: this.state.device.deviceId,
|
||||||
ip: this.state.ip,
|
ip: this.state.ip,
|
||||||
});
|
});
|
||||||
|
@ -152,13 +153,13 @@ export default class VerificationRequestToast extends React.PureComponent<IProps
|
||||||
} else {
|
} else {
|
||||||
const userId = request.otherUserId;
|
const userId = request.otherUserId;
|
||||||
const roomId = request.channel.roomId;
|
const roomId = request.channel.roomId;
|
||||||
nameLabel = roomId ? userLabelForEventRoom(userId, roomId) : userId;
|
description = roomId ? userLabelForEventRoom(userId, roomId) : userId;
|
||||||
// for legacy to_device verification requests
|
// for legacy to_device verification requests
|
||||||
if (nameLabel === userId) {
|
if (description === userId) {
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
const user = client.getUser(userId);
|
const user = client.getUser(userId);
|
||||||
if (user && user.displayName) {
|
if (user && user.displayName) {
|
||||||
nameLabel = _t("%(name)s (%(userId)s)", {name: user.displayName, userId});
|
description = _t("%(name)s (%(userId)s)", {name: user.displayName, userId});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,7 +168,8 @@ export default class VerificationRequestToast extends React.PureComponent<IProps
|
||||||
_t("Decline (%(counter)s)", {counter: this.state.counter});
|
_t("Decline (%(counter)s)", {counter: this.state.counter});
|
||||||
|
|
||||||
return <GenericToast
|
return <GenericToast
|
||||||
description={nameLabel}
|
description={description}
|
||||||
|
detail={detail}
|
||||||
acceptLabel={_t("Accept")}
|
acceptLabel={_t("Accept")}
|
||||||
onAccept={this.accept}
|
onAccept={this.accept}
|
||||||
rejectLabel={declineLabel}
|
rejectLabel={declineLabel}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
import {MatrixClientPeg} from "../MatrixClientPeg";
|
import {MatrixClientPeg} from "../MatrixClientPeg";
|
||||||
import {IMediaEventContent, IPreparedMedia, prepEventContentAsMedia} from "./models/IMediaEventContent";
|
import {IMediaEventContent, IPreparedMedia, prepEventContentAsMedia} from "./models/IMediaEventContent";
|
||||||
import {ResizeMethod} from "../Avatar";
|
import {ResizeMethod} from "../Avatar";
|
||||||
|
import {MatrixClient} from "matrix-js-sdk/src/client";
|
||||||
|
|
||||||
// Populate this class with the details of your customisations when copying it.
|
// Populate this class with the details of your customisations when copying it.
|
||||||
|
|
||||||
|
@ -30,8 +31,14 @@ import {ResizeMethod} from "../Avatar";
|
||||||
* "thumbnail media", derived from event contents or external sources.
|
* "thumbnail media", derived from event contents or external sources.
|
||||||
*/
|
*/
|
||||||
export class Media {
|
export class Media {
|
||||||
|
private client: MatrixClient;
|
||||||
|
|
||||||
// Per above, this constructor signature can be whatever is helpful for you.
|
// Per above, this constructor signature can be whatever is helpful for you.
|
||||||
constructor(private prepared: IPreparedMedia) {
|
constructor(private prepared: IPreparedMedia, client?: MatrixClient) {
|
||||||
|
this.client = client ?? MatrixClientPeg.get();
|
||||||
|
if (!this.client) {
|
||||||
|
throw new Error("No possible MatrixClient for media resolution. Please provide one or log in.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,7 +74,7 @@ export class Media {
|
||||||
* The HTTP URL for the source media.
|
* The HTTP URL for the source media.
|
||||||
*/
|
*/
|
||||||
public get srcHttp(): string {
|
public get srcHttp(): string {
|
||||||
return MatrixClientPeg.get().mxcUrlToHttp(this.srcMxc);
|
return this.client.mxcUrlToHttp(this.srcMxc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,7 +83,7 @@ export class Media {
|
||||||
*/
|
*/
|
||||||
public get thumbnailHttp(): string | undefined | null {
|
public get thumbnailHttp(): string | undefined | null {
|
||||||
if (!this.hasThumbnail) return null;
|
if (!this.hasThumbnail) return null;
|
||||||
return MatrixClientPeg.get().mxcUrlToHttp(this.thumbnailMxc);
|
return this.client.mxcUrlToHttp(this.thumbnailMxc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,7 +96,7 @@ export class Media {
|
||||||
*/
|
*/
|
||||||
public getThumbnailHttp(width: number, height: number, mode: ResizeMethod = "scale"): string | null | undefined {
|
public getThumbnailHttp(width: number, height: number, mode: ResizeMethod = "scale"): string | null | undefined {
|
||||||
if (!this.hasThumbnail) return null;
|
if (!this.hasThumbnail) return null;
|
||||||
return MatrixClientPeg.get().mxcUrlToHttp(this.thumbnailMxc, width, height, mode);
|
return this.client.mxcUrlToHttp(this.thumbnailMxc, width, height, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,7 +107,7 @@ export class Media {
|
||||||
* @returns {string} The HTTP URL which points to the thumbnail.
|
* @returns {string} The HTTP URL which points to the thumbnail.
|
||||||
*/
|
*/
|
||||||
public getThumbnailOfSourceHttp(width: number, height: number, mode: ResizeMethod = "scale"): string {
|
public getThumbnailOfSourceHttp(width: number, height: number, mode: ResizeMethod = "scale"): string {
|
||||||
return MatrixClientPeg.get().mxcUrlToHttp(this.srcMxc, width, height, mode);
|
return this.client.mxcUrlToHttp(this.srcMxc, width, height, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,17 +135,19 @@ export class Media {
|
||||||
/**
|
/**
|
||||||
* Creates a media object from event content.
|
* Creates a media object from event content.
|
||||||
* @param {IMediaEventContent} content The event content.
|
* @param {IMediaEventContent} content The event content.
|
||||||
|
* @param {MatrixClient} client? Optional client to use.
|
||||||
* @returns {Media} The media object.
|
* @returns {Media} The media object.
|
||||||
*/
|
*/
|
||||||
export function mediaFromContent(content: IMediaEventContent): Media {
|
export function mediaFromContent(content: IMediaEventContent, client?: MatrixClient): Media {
|
||||||
return new Media(prepEventContentAsMedia(content));
|
return new Media(prepEventContentAsMedia(content), client);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a media object from an MXC URI.
|
* Creates a media object from an MXC URI.
|
||||||
* @param {string} mxc The MXC URI.
|
* @param {string} mxc The MXC URI.
|
||||||
|
* @param {MatrixClient} client? Optional client to use.
|
||||||
* @returns {Media} The media object.
|
* @returns {Media} The media object.
|
||||||
*/
|
*/
|
||||||
export function mediaFromMxc(mxc: string): Media {
|
export function mediaFromMxc(mxc: string, client?: MatrixClient): Media {
|
||||||
return mediaFromContent({url: mxc});
|
return mediaFromContent({url: mxc}, client);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
"unknown error code": "neznámý kód chyby",
|
"unknown error code": "neznámý kód chyby",
|
||||||
"OK": "OK",
|
"OK": "OK",
|
||||||
"Failed to forget room %(errCode)s": "Nepodařilo se zapomenout místnost %(errCode)s",
|
"Failed to forget room %(errCode)s": "Nepodařilo se zapomenout místnost %(errCode)s",
|
||||||
"Dismiss": "Zahodit",
|
"Dismiss": "Zavřít",
|
||||||
"powered by Matrix": "používá protokol Matrix",
|
"powered by Matrix": "používá protokol Matrix",
|
||||||
"Custom Server Options": "Vlastní nastavení serveru",
|
"Custom Server Options": "Vlastní nastavení serveru",
|
||||||
"Add a widget": "Přidat widget",
|
"Add a widget": "Přidat widget",
|
||||||
|
@ -228,7 +228,7 @@
|
||||||
"Who can access this room?": "Kdo má přístup do této místnosti?",
|
"Who can access this room?": "Kdo má přístup do této místnosti?",
|
||||||
"Who can read history?": "Kdo může číst historii?",
|
"Who can read history?": "Kdo může číst historii?",
|
||||||
"You are not in this room.": "Nejste v této místnosti.",
|
"You are not in this room.": "Nejste v této místnosti.",
|
||||||
"You do not have permission to do that in this room.": "V této místnosti nemáte na toto právo.",
|
"You do not have permission to do that in this room.": "V této místnosti k tomu nemáte oprávnění.",
|
||||||
"You cannot place a call with yourself.": "Nemůžete volat sami sobě.",
|
"You cannot place a call with yourself.": "Nemůžete volat sami sobě.",
|
||||||
"You cannot place VoIP calls in this browser.": "V tomto prohlížeči nelze vytáčet VoIP hovory.",
|
"You cannot place VoIP calls in this browser.": "V tomto prohlížeči nelze vytáčet VoIP hovory.",
|
||||||
"You do not have permission to post to this room": "Nemáte oprávnění zveřejňovat příspěvky v této místnosti",
|
"You do not have permission to post to this room": "Nemáte oprávnění zveřejňovat příspěvky v této místnosti",
|
||||||
|
@ -749,7 +749,7 @@
|
||||||
"A call is currently being placed!": "Právě probíhá jiný hovor!",
|
"A call is currently being placed!": "Právě probíhá jiný hovor!",
|
||||||
"A call is already in progress!": "Jeden hovor už probíhá!",
|
"A call is already in progress!": "Jeden hovor už probíhá!",
|
||||||
"Permission Required": "Vyžaduje oprávnění",
|
"Permission Required": "Vyžaduje oprávnění",
|
||||||
"You do not have permission to start a conference call in this room": "Nemáte oprávnění v této místnosti začít konferenční hovor",
|
"You do not have permission to start a conference call in this room": "V této místnosti nemáte oprávnění zahájit konferenční hovor",
|
||||||
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s",
|
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s",
|
||||||
"Missing roomId.": "Chybějící ID místnosti.",
|
"Missing roomId.": "Chybějící ID místnosti.",
|
||||||
"Opens the Developer Tools dialog": "Otevře dialog nástrojů pro vývojáře",
|
"Opens the Developer Tools dialog": "Otevře dialog nástrojů pro vývojáře",
|
||||||
|
@ -818,7 +818,7 @@
|
||||||
"Share Room Message": "Sdílet zprávu z místnosti",
|
"Share Room Message": "Sdílet zprávu z místnosti",
|
||||||
"Link to selected message": "Odkaz na vybranou zprávu",
|
"Link to selected message": "Odkaz na vybranou zprávu",
|
||||||
"COPY": "Kopírovat",
|
"COPY": "Kopírovat",
|
||||||
"Share Message": "Sdílet",
|
"Share Message": "Sdílet zprávu",
|
||||||
"Collapse Reply Thread": "Sbalit vlákno odpovědi",
|
"Collapse Reply Thread": "Sbalit vlákno odpovědi",
|
||||||
"Unable to join community": "Není možné vstoupit do skupiny",
|
"Unable to join community": "Není možné vstoupit do skupiny",
|
||||||
"Unable to leave community": "Není možné opustit skupinu",
|
"Unable to leave community": "Není možné opustit skupinu",
|
||||||
|
@ -1941,7 +1941,7 @@
|
||||||
"Indexed rooms:": "Indexované místnosti:",
|
"Indexed rooms:": "Indexované místnosti:",
|
||||||
"Message downloading sleep time(ms)": "Čas na stažení zprávy (ms)",
|
"Message downloading sleep time(ms)": "Čas na stažení zprávy (ms)",
|
||||||
"Sign In or Create Account": "Přihlásit nebo vytvořit nový účet",
|
"Sign In or Create Account": "Přihlásit nebo vytvořit nový účet",
|
||||||
"Use your account or create a new one to continue.": "Pro pokračování se přihlaste existujícím účtem, nebo si vytvořte nový.",
|
"Use your account or create a new one to continue.": "Pro pokračování se přihlaste stávajícím účtem, nebo si vytvořte nový.",
|
||||||
"Create Account": "Vytvořit účet",
|
"Create Account": "Vytvořit účet",
|
||||||
"Order rooms by name": "Seřadit místnosti podle názvu",
|
"Order rooms by name": "Seřadit místnosti podle názvu",
|
||||||
"Show rooms with unread notifications first": "Zobrazovat místnosti s nepřečtenými oznámeními navrchu",
|
"Show rooms with unread notifications first": "Zobrazovat místnosti s nepřečtenými oznámeními navrchu",
|
||||||
|
@ -2982,7 +2982,7 @@
|
||||||
"Abort": "Přerušit",
|
"Abort": "Přerušit",
|
||||||
"Are you sure you wish to abort creation of the host? The process cannot be continued.": "Opravdu chcete přerušit vytváření hostitele? Proces nemůže být navázán.",
|
"Are you sure you wish to abort creation of the host? The process cannot be continued.": "Opravdu chcete přerušit vytváření hostitele? Proces nemůže být navázán.",
|
||||||
"Confirm abort of host creation": "Potvrďte přerušení vytváření hostitele",
|
"Confirm abort of host creation": "Potvrďte přerušení vytváření hostitele",
|
||||||
"Upgrade to %(hostSignupBrand)s": "Aktualizovat na %(hostSignupBrand)s",
|
"Upgrade to %(hostSignupBrand)s": "Povýšit na %(hostSignupBrand)s",
|
||||||
"Edit Values": "Upravit hodnoty",
|
"Edit Values": "Upravit hodnoty",
|
||||||
"Values at explicit levels in this room:": "Hodnoty na explicitních úrovních v této místnosti:",
|
"Values at explicit levels in this room:": "Hodnoty na explicitních úrovních v této místnosti:",
|
||||||
"Values at explicit levels:": "Hodnoty na explicitních úrovních:",
|
"Values at explicit levels:": "Hodnoty na explicitních úrovních:",
|
||||||
|
@ -3003,5 +3003,120 @@
|
||||||
"Setting ID": "ID nastavení",
|
"Setting ID": "ID nastavení",
|
||||||
"Failed to save settings": "Nastavení se nepodařilo uložit",
|
"Failed to save settings": "Nastavení se nepodařilo uložit",
|
||||||
"Settings Explorer": "Průzkumník nastavení",
|
"Settings Explorer": "Průzkumník nastavení",
|
||||||
"Show chat effects (animations when receiving e.g. confetti)": "Zobrazit efekty chatu (animace např. při přijetí konfet)"
|
"Show chat effects (animations when receiving e.g. confetti)": "Zobrazit efekty chatu (animace např. při přijetí konfet)",
|
||||||
|
"Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "Spaces jsou nový způsob, jak seskupovat místnosti a lidi. Chcete-li se připojit k existujícímu space, budete potřebovat pozvánku",
|
||||||
|
"We'll create rooms for each of them. You can add existing rooms after setup.": "Pro každý z nich vytvoříme místnost. Po nastavení můžete přidat stávající místnosti.",
|
||||||
|
"What projects are you working on?": "Na jakých projektech pracujete?",
|
||||||
|
"We'll create rooms for each topic.": "Pro každé téma vytvoříme místnosti.",
|
||||||
|
"What are some things you want to discuss?": "O kterých věcech chcete diskutovat?",
|
||||||
|
"Inviting...": "Pozvání...",
|
||||||
|
"Invite by username": "Pozvat podle uživatelského jména",
|
||||||
|
"Invite your teammates": "Pozvěte své spolupracovníky",
|
||||||
|
"Failed to invite the following users to your space: %(csvUsers)s": "Nepodařilo se pozvat následující uživatele do vašeho space: %(csvUsers)s",
|
||||||
|
"A private space for you and your teammates": "Soukromý space pro Vás a vaše spolupracovníky",
|
||||||
|
"Me and my teammates": "Já a moji spolupracovníci",
|
||||||
|
"A private space just for you": "Soukromý space právě pro vás",
|
||||||
|
"Just Me": "Pouze já",
|
||||||
|
"Ensure the right people have access to the space.": "Zajistěte, aby do prostoru měli přístup správní lidé.",
|
||||||
|
"Who are you working with?": "S kým pracujete?",
|
||||||
|
"At the moment only you can see it.": "V tuto chvíli to vidíte jen Vy.",
|
||||||
|
"Creating rooms...": "Vytváření místností...",
|
||||||
|
"Skip for now": "Prozatím přeskočit",
|
||||||
|
"Failed to create initial space rooms": "Vytvoření počátečních místností ve space se nezdařilo",
|
||||||
|
"Random": "Náhodný",
|
||||||
|
"Your private space <name/>": "Váš soukromý space <name/>",
|
||||||
|
"Your public space <name/>": "Váš veřejný space <name/>",
|
||||||
|
"You have been invited to <name/>": "Byli jste pozváni do <name/>",
|
||||||
|
"<inviter/> invited you to <name/>": "<inviter/> vás pozval do <name/>",
|
||||||
|
"%(count)s members|one": "%(count)s člen",
|
||||||
|
"%(count)s members|other": "%(count)s členů",
|
||||||
|
"Your server does not support showing space hierarchies.": "Váš server nepodporuje zobrazování hierarchií spaces.",
|
||||||
|
"Default Rooms": "Výchozí místnosti",
|
||||||
|
"Add existing rooms & spaces": "Přidat stávající místnosti a spaces",
|
||||||
|
"Accept Invite": "Přijmout pozvání",
|
||||||
|
"Find a room...": "Najít místnost...",
|
||||||
|
"Manage rooms": "Spravovat místnosti",
|
||||||
|
"Promoted to users": "Propagováno uživatelům",
|
||||||
|
"Save changes": "Uložit změny",
|
||||||
|
"You're in this room": "Jste v této místnosti",
|
||||||
|
"You're in this space": "Jste v tomto space",
|
||||||
|
"No permissions": "Žádná oprávnění",
|
||||||
|
"Remove from Space": "Odebrat ze space",
|
||||||
|
"Undo": "Vrátit",
|
||||||
|
"Your message wasn't sent because this homeserver has been blocked by it's administrator. Please <a>contact your service administrator</a> to continue using the service.": "Vaše zpráva nebyla odeslána, protože tento domovský server byl zablokován jeho správcem. <a>Kontaktujte svého správce služby</a>, abyste mohli službu nadále používat.",
|
||||||
|
"Are you sure you want to leave the space '%(spaceName)s'?": "Opravdu chcete opustit space '%(spaceName)s'?",
|
||||||
|
"This space is not public. You will not be able to rejoin without an invite.": "Tento space není veřejný. Bez pozvánky se nebudete moci znovu připojit.",
|
||||||
|
"Start audio stream": "Zahájit audio přenos",
|
||||||
|
"Failed to start livestream": "Nepodařilo spustit živý přenos",
|
||||||
|
"Unable to start audio streaming.": "Nelze spustit streamování zvuku.",
|
||||||
|
"View dev tools": "Zobrazit nástroje pro vývojáře",
|
||||||
|
"Leave Space": "Opustit space",
|
||||||
|
"Make this space private": "Nastavit tento space jako soukromý",
|
||||||
|
"Edit settings relating to your space.": "Upravte nastavení týkající se vašeho space.",
|
||||||
|
"Space settings": "Nastavení space",
|
||||||
|
"Failed to save space settings.": "Nastavení space se nepodařilo uložit.",
|
||||||
|
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.": "Pozvěte někoho pomocí jeho jména, uživatelského jména (například <userId/>) nebo <a>sdílejte tento space</a>.",
|
||||||
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "Pozvěte někoho pomocí jeho jména, e-mailové adresy, uživatelského jména (například <userId/>) nebo <a>sdílejte tento space</a>.",
|
||||||
|
"Unnamed Space": "Nejmenovaný space",
|
||||||
|
"Invite to %(spaceName)s": "Pozvat do %(spaceName)s",
|
||||||
|
"Failed to add rooms to space": "Nepodařilo se přidat místnosti do space",
|
||||||
|
"Applying...": "Potvrzuji...",
|
||||||
|
"Apply": "Použít",
|
||||||
|
"Create a new room": "Vytvořit novou místnost",
|
||||||
|
"Don't want to add an existing room?": "Nechcete přidat existující místnost?",
|
||||||
|
"Spaces": "Spaces",
|
||||||
|
"Filter your rooms and spaces": "Filtrujte své místnosti a spaces",
|
||||||
|
"Add existing spaces/rooms": "Přidat existující space/místnost",
|
||||||
|
"Space selection": "Výběr space",
|
||||||
|
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the space it will be impossible to regain privileges.": "Tuto změnu nebudete moci vrátit zpět, protože budete degradováni, pokud jste posledním privilegovaným uživatelem v daném space, nebude možné znovu získat oprávnění.",
|
||||||
|
"Empty room": "Prázdná místnost",
|
||||||
|
"Suggested Rooms": "Doporučené místnosti",
|
||||||
|
"Explore space rooms": "Prozkoumat místnosti space",
|
||||||
|
"You do not have permissions to add rooms to this space": "Nemáte oprávnění k přidávání místností do tohoto space",
|
||||||
|
"Add existing room": "Přidat existující místnost",
|
||||||
|
"You do not have permissions to create new rooms in this space": "Nemáte oprávnění k vytváření nových místností v tomto space",
|
||||||
|
"Send message": "Poslat zprávu",
|
||||||
|
"Invite to this space": "Pozvat do tohoto space",
|
||||||
|
"Your message was sent": "Zpráva byla odeslána",
|
||||||
|
"Encrypting your message...": "Šifrování zprávy...",
|
||||||
|
"Sending your message...": "Odesílání zprávy...",
|
||||||
|
"Spell check dictionaries": "Slovníky pro kontrolu pravopisu",
|
||||||
|
"Space options": "Nastavení space",
|
||||||
|
"Space Home": "Domov space",
|
||||||
|
"New room": "Nová místnost",
|
||||||
|
"Leave space": "Opusit space",
|
||||||
|
"Invite people": "Pozvat lidi",
|
||||||
|
"Share your public space": "Sdílejte svůj veřejný space",
|
||||||
|
"Invite members": "Pozvat členy",
|
||||||
|
"Invite by email or username": "Pozvěte e-mailem nebo uživatelským jménem",
|
||||||
|
"Share invite link": "Sdílet odkaz na pozvánku",
|
||||||
|
"Click to copy": "Kliknutím zkopírujte",
|
||||||
|
"Expand space panel": "Rozbalit space panel",
|
||||||
|
"Collapse space panel": "Sbalit space panel",
|
||||||
|
"Creating...": "Vytváření...",
|
||||||
|
"You can change these at any point.": "Můžete je kdykoli změnit.",
|
||||||
|
"Give it a photo, name and description to help you identify it.": "Přiřaďte mu obrázek, jméno a popis, abyste jej mohli lépe identifikovat.",
|
||||||
|
"Your private space": "Váš soukromý space",
|
||||||
|
"Your public space": "Váš veřejný space",
|
||||||
|
"You can change this later": "Toto můžete změnit později",
|
||||||
|
"Invite only, best for yourself or teams": "Pouze pozvat, nejlepší pro sebe nebo pro týmy",
|
||||||
|
"Private": "Soukromý",
|
||||||
|
"Open space for anyone, best for communities": "Otevřený space pro kohokoli, nejlepší pro komunity",
|
||||||
|
"Public": "Veřejný",
|
||||||
|
"Create a space": "Vytvořit space",
|
||||||
|
"Jump to the bottom of the timeline when you send a message": "Při odesílání zprávy přeskočit na konec časové osy",
|
||||||
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Spaces prototyp. Nejsou kompatibilní se skupinami, skupinami v2 a vlastními štítky. Pro některé funkce je vyžadován kompatibilní domovský server.",
|
||||||
|
"This homeserver has been blocked by its administrator.": "Tento domovský server byl zablokován jeho správcem.",
|
||||||
|
"You're already in a call with this person.": "S touto osobou již telefonujete.",
|
||||||
|
"Already in call": "Již máte hovor",
|
||||||
|
"Delete": "Smazat",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "Tento domovský server byl zablokován jeho správcem.",
|
||||||
|
"Original event source": "Původní zdroj události",
|
||||||
|
"Decrypted event source": "Dešifrovaný zdroj události",
|
||||||
|
"Saving...": "Ukládám...",
|
||||||
|
"Save Changes": "Uložit změny",
|
||||||
|
"Welcome to <name/>": "Vítejte v <name/>",
|
||||||
|
"Support": "Podpora",
|
||||||
|
"Room name": "Název místnosti",
|
||||||
|
"Finish": "Dokončit"
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -114,7 +114,7 @@
|
||||||
"New passwords must match each other.": "Οι νέοι κωδικοί πρόσβασης πρέπει να ταιριάζουν.",
|
"New passwords must match each other.": "Οι νέοι κωδικοί πρόσβασης πρέπει να ταιριάζουν.",
|
||||||
"(not supported by this browser)": "(δεν υποστηρίζεται από τον περιηγητή)",
|
"(not supported by this browser)": "(δεν υποστηρίζεται από τον περιηγητή)",
|
||||||
"<not supported>": "<δεν υποστηρίζεται>",
|
"<not supported>": "<δεν υποστηρίζεται>",
|
||||||
"No more results": "Δεν υπάρχουν αποτελέσματα",
|
"No more results": "Δεν υπάρχουν άλλα αποτελέσματα",
|
||||||
"No results": "Κανένα αποτέλεσμα",
|
"No results": "Κανένα αποτέλεσμα",
|
||||||
"OK": "Εντάξει",
|
"OK": "Εντάξει",
|
||||||
"olm version:": "Έκδοση olm:",
|
"olm version:": "Έκδοση olm:",
|
||||||
|
@ -921,5 +921,9 @@
|
||||||
"Your user agent": "Η συσκευή σας",
|
"Your user agent": "Η συσκευή σας",
|
||||||
"Confirm adding phone number": "Επιβεβαιώστε την προσθήκη του τηλεφωνικού αριθμού",
|
"Confirm adding phone number": "Επιβεβαιώστε την προσθήκη του τηλεφωνικού αριθμού",
|
||||||
"Click the button below to confirm adding this email address.": "Πιέστε το κουμπί από κάτω για να επιβεβαιώσετε την προσθήκη της διεύθυνσης ηλ. ταχυδρομείου.",
|
"Click the button below to confirm adding this email address.": "Πιέστε το κουμπί από κάτω για να επιβεβαιώσετε την προσθήκη της διεύθυνσης ηλ. ταχυδρομείου.",
|
||||||
"Confirm adding email": "Επιβεβαιώστε την προσθήκη διεύθυνσης ηλ. ταχυδρομείου"
|
"Confirm adding email": "Επιβεβαιώστε την προσθήκη διεύθυνσης ηλ. ταχυδρομείου",
|
||||||
|
"Done": "Τέλος",
|
||||||
|
"Not Trusted": "Μη Έμπιστο",
|
||||||
|
"You're already in a call with this person.": "Είστε ήδη σε κλήση με αυτόν τον χρήστη.",
|
||||||
|
"Already in call": "Ήδη σε κλήση"
|
||||||
}
|
}
|
||||||
|
|
|
@ -723,13 +723,15 @@
|
||||||
"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",
|
||||||
|
"Invite to %(spaceName)s": "Invite to %(spaceName)s",
|
||||||
|
"Share your public space": "Share your public space",
|
||||||
"Unknown App": "Unknown App",
|
"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>.",
|
||||||
"Yes": "Yes",
|
"Yes": "Yes",
|
||||||
"No": "No",
|
"No": "No",
|
||||||
"You have unverified logins": "You have unverified logins",
|
"You have unverified logins": "You have unverified logins",
|
||||||
"Verify all your sessions to ensure your account & messages are safe": "Verify all your sessions to ensure your account & messages are safe",
|
"Review to ensure your account is safe": "Review to ensure your account is safe",
|
||||||
"Review": "Review",
|
"Review": "Review",
|
||||||
"Later": "Later",
|
"Later": "Later",
|
||||||
"Don't miss a reply": "Don't miss a reply",
|
"Don't miss a reply": "Don't miss a reply",
|
||||||
|
@ -753,7 +755,7 @@
|
||||||
"Safeguard against losing access to encrypted messages & data": "Safeguard against losing access to encrypted messages & data",
|
"Safeguard against losing access to encrypted messages & data": "Safeguard against losing access to encrypted messages & data",
|
||||||
"Other users may not trust it": "Other users may not trust it",
|
"Other users may not trust it": "Other users may not trust it",
|
||||||
"New login. Was this you?": "New login. Was this you?",
|
"New login. Was this you?": "New login. Was this you?",
|
||||||
"A new login is accessing your account: %(name)s (%(deviceID)s) at %(ip)s": "A new login is accessing your account: %(name)s (%(deviceID)s) at %(ip)s",
|
"%(deviceId)s from %(ip)s": "%(deviceId)s from %(ip)s",
|
||||||
"Check your devices": "Check your devices",
|
"Check your devices": "Check your devices",
|
||||||
"What's new?": "What's new?",
|
"What's new?": "What's new?",
|
||||||
"What's New": "What's New",
|
"What's New": "What's New",
|
||||||
|
@ -783,6 +785,7 @@
|
||||||
"%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s",
|
"%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s",
|
||||||
"Change notification settings": "Change notification settings",
|
"Change notification settings": "Change notification settings",
|
||||||
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.",
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.",
|
||||||
|
"Send and receive voice messages (in development)": "Send and receive voice messages (in development)",
|
||||||
"Render LaTeX maths in messages": "Render LaTeX maths in messages",
|
"Render LaTeX maths in messages": "Render LaTeX maths in messages",
|
||||||
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.",
|
"Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.",
|
||||||
"New spinner design": "New spinner design",
|
"New spinner design": "New spinner design",
|
||||||
|
@ -796,6 +799,7 @@
|
||||||
"Show message previews for reactions in DMs": "Show message previews for reactions in DMs",
|
"Show message previews for reactions in DMs": "Show message previews for reactions in DMs",
|
||||||
"Show message previews for reactions in all rooms": "Show message previews for reactions in all rooms",
|
"Show message previews for reactions in all rooms": "Show message previews for reactions in all rooms",
|
||||||
"Offline encrypted messaging using dehydrated devices": "Offline encrypted messaging using dehydrated devices",
|
"Offline encrypted messaging using dehydrated devices": "Offline encrypted messaging using dehydrated devices",
|
||||||
|
"Share decryption keys for room history when inviting users": "Share decryption keys for room history when inviting users",
|
||||||
"Enable advanced debugging for the room list": "Enable advanced debugging for the room list",
|
"Enable advanced debugging for the room list": "Enable advanced debugging for the room list",
|
||||||
"Show info about bridges in room settings": "Show info about bridges in room settings",
|
"Show info about bridges in room settings": "Show info about bridges in room settings",
|
||||||
"Font size": "Font size",
|
"Font size": "Font size",
|
||||||
|
@ -981,7 +985,6 @@
|
||||||
"Folder": "Folder",
|
"Folder": "Folder",
|
||||||
"Pin": "Pin",
|
"Pin": "Pin",
|
||||||
"Your server isn't responding to some <a>requests</a>.": "Your server isn't responding to some <a>requests</a>.",
|
"Your server isn't responding to some <a>requests</a>.": "Your server isn't responding to some <a>requests</a>.",
|
||||||
"From %(deviceName)s (%(deviceId)s) at %(ip)s": "From %(deviceName)s (%(deviceId)s) at %(ip)s",
|
|
||||||
"Decline (%(counter)s)": "Decline (%(counter)s)",
|
"Decline (%(counter)s)": "Decline (%(counter)s)",
|
||||||
"Accept <policyLink /> to continue:": "Accept <policyLink /> to continue:",
|
"Accept <policyLink /> to continue:": "Accept <policyLink /> to continue:",
|
||||||
"Delete": "Delete",
|
"Delete": "Delete",
|
||||||
|
@ -989,7 +992,7 @@
|
||||||
"Name": "Name",
|
"Name": "Name",
|
||||||
"Description": "Description",
|
"Description": "Description",
|
||||||
"Create a space": "Create a space",
|
"Create a space": "Create a space",
|
||||||
"Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite",
|
"Spaces are new ways to group rooms and people. To join an existing space you'll need an invite.": "Spaces are new ways to group rooms and people. To join an existing space you'll need an invite.",
|
||||||
"Public": "Public",
|
"Public": "Public",
|
||||||
"Open space for anyone, best for communities": "Open space for anyone, best for communities",
|
"Open space for anyone, best for communities": "Open space for anyone, best for communities",
|
||||||
"Private": "Private",
|
"Private": "Private",
|
||||||
|
@ -998,8 +1001,8 @@
|
||||||
"Go back": "Go back",
|
"Go back": "Go back",
|
||||||
"Your public space": "Your public space",
|
"Your public space": "Your public space",
|
||||||
"Your private space": "Your private space",
|
"Your private space": "Your private space",
|
||||||
"Give it a photo, name and description to help you identify it.": "Give it a photo, name and description to help you identify it.",
|
"Add some details to help people recognise it.": "Add some details to help people recognise it.",
|
||||||
"You can change these at any point.": "You can change these at any point.",
|
"You can change these anytime.": "You can change these anytime.",
|
||||||
"Creating...": "Creating...",
|
"Creating...": "Creating...",
|
||||||
"Create": "Create",
|
"Create": "Create",
|
||||||
"Expand space panel": "Expand space panel",
|
"Expand space panel": "Expand space panel",
|
||||||
|
@ -1009,15 +1012,14 @@
|
||||||
"Copied!": "Copied!",
|
"Copied!": "Copied!",
|
||||||
"Failed to copy": "Failed to copy",
|
"Failed to copy": "Failed to copy",
|
||||||
"Share invite link": "Share invite link",
|
"Share invite link": "Share invite link",
|
||||||
"Invite by email or username": "Invite by email or username",
|
|
||||||
"Invite members": "Invite members",
|
|
||||||
"Share your public space": "Share your public space",
|
|
||||||
"Invite people": "Invite people",
|
"Invite people": "Invite people",
|
||||||
|
"Invite with email or username": "Invite with email or username",
|
||||||
"Settings": "Settings",
|
"Settings": "Settings",
|
||||||
"Leave space": "Leave space",
|
"Leave space": "Leave space",
|
||||||
"New room": "New room",
|
"Create new room": "Create new room",
|
||||||
"Space Home": "Space Home",
|
"Add existing room": "Add existing room",
|
||||||
"Members": "Members",
|
"Members": "Members",
|
||||||
|
"Manage & explore rooms": "Manage & explore rooms",
|
||||||
"Explore rooms": "Explore rooms",
|
"Explore rooms": "Explore rooms",
|
||||||
"Space options": "Space options",
|
"Space options": "Space options",
|
||||||
"Remove": "Remove",
|
"Remove": "Remove",
|
||||||
|
@ -1081,6 +1083,7 @@
|
||||||
"Securely cache encrypted messages locally for them to appear in search results.": "Securely cache encrypted messages locally for them to appear in search results.",
|
"Securely cache encrypted messages locally for them to appear in search results.": "Securely cache encrypted messages locally for them to appear in search results.",
|
||||||
"%(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 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 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 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 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 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 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 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.",
|
||||||
|
"Message search initilisation failed": "Message search initilisation failed",
|
||||||
"Connecting to integration manager...": "Connecting to integration manager...",
|
"Connecting to integration manager...": "Connecting to integration manager...",
|
||||||
"Cannot connect to integration manager": "Cannot connect to integration manager",
|
"Cannot connect to integration manager": "Cannot connect to integration manager",
|
||||||
"The integration manager is offline or it cannot reach your homeserver.": "The integration manager is offline or it cannot reach your homeserver.",
|
"The integration manager is offline or it cannot reach your homeserver.": "The integration manager is offline or it cannot reach your homeserver.",
|
||||||
|
@ -1478,6 +1481,7 @@
|
||||||
"<a>Add a topic</a> to help people know what it is about.": "<a>Add a topic</a> to help people know what it is about.",
|
"<a>Add a topic</a> to help people know what it is about.": "<a>Add a topic</a> to help people know what it is about.",
|
||||||
"You created this room.": "You created this room.",
|
"You created this room.": "You created this room.",
|
||||||
"%(displayName)s created this room.": "%(displayName)s created this room.",
|
"%(displayName)s created this room.": "%(displayName)s created this room.",
|
||||||
|
"Invite to just this room": "Invite to just this room",
|
||||||
"Add a photo, so people can easily spot your room.": "Add a photo, so people can easily spot your room.",
|
"Add a photo, so people can easily spot your room.": "Add a photo, so people can easily spot your room.",
|
||||||
"This is the start of <roomName/>.": "This is the start of <roomName/>.",
|
"This is the start of <roomName/>.": "This is the start of <roomName/>.",
|
||||||
"No pinned messages.": "No pinned messages.",
|
"No pinned messages.": "No pinned messages.",
|
||||||
|
@ -1527,11 +1531,8 @@
|
||||||
"Start chat": "Start chat",
|
"Start chat": "Start chat",
|
||||||
"Rooms": "Rooms",
|
"Rooms": "Rooms",
|
||||||
"Add room": "Add room",
|
"Add room": "Add room",
|
||||||
"Create new room": "Create new room",
|
|
||||||
"You do not have permissions to create new rooms in this space": "You do not have permissions to create new rooms in this space",
|
"You do not have permissions to create new rooms in this space": "You do not have permissions to create new rooms in this space",
|
||||||
"Add existing room": "Add existing room",
|
|
||||||
"You do not have permissions to add rooms to this space": "You do not have permissions to add rooms to this space",
|
"You do not have permissions to add rooms to this space": "You do not have permissions to add rooms to this space",
|
||||||
"Explore space rooms": "Explore space rooms",
|
|
||||||
"Explore community rooms": "Explore community rooms",
|
"Explore community rooms": "Explore community rooms",
|
||||||
"Explore public rooms": "Explore public rooms",
|
"Explore public rooms": "Explore public rooms",
|
||||||
"Low priority": "Low priority",
|
"Low priority": "Low priority",
|
||||||
|
@ -1543,6 +1544,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?",
|
||||||
"Start a new chat": "Start a new chat",
|
"Start a new chat": "Start a new chat",
|
||||||
"Explore all public rooms": "Explore all public rooms",
|
"Explore all public rooms": "Explore all public rooms",
|
||||||
|
"Quick actions": "Quick actions",
|
||||||
"Use the + to make a new room or explore existing ones below": "Use the + to make a new room or explore existing ones below",
|
"Use the + to make a new room or explore existing ones below": "Use the + to make a new room or explore existing ones below",
|
||||||
"%(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",
|
||||||
|
@ -1639,6 +1641,8 @@
|
||||||
"Invited by %(sender)s": "Invited by %(sender)s",
|
"Invited by %(sender)s": "Invited by %(sender)s",
|
||||||
"Jump to first unread message.": "Jump to first unread message.",
|
"Jump to first unread message.": "Jump to first unread message.",
|
||||||
"Mark all as read": "Mark all as read",
|
"Mark all as read": "Mark all as read",
|
||||||
|
"Record a voice message": "Record a voice message",
|
||||||
|
"Stop & send recording": "Stop & send recording",
|
||||||
"Error updating main address": "Error updating main address",
|
"Error updating main address": "Error updating main address",
|
||||||
"There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.",
|
"There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.",
|
||||||
"There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.",
|
"There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.",
|
||||||
|
@ -1677,7 +1681,7 @@
|
||||||
"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",
|
"Back": "Back",
|
||||||
"Waiting for you to accept on your other session…": "Waiting for you to accept on your other session…",
|
"Accept on your other login…": "Accept on your other login…",
|
||||||
"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…",
|
||||||
"Start Verification": "Start Verification",
|
"Start Verification": "Start Verification",
|
||||||
|
@ -1909,6 +1913,8 @@
|
||||||
"Please <newIssueLink>create a new issue</newIssueLink> on GitHub so that we can investigate this bug.": "Please <newIssueLink>create a new issue</newIssueLink> on GitHub so that we can investigate this bug.",
|
"Please <newIssueLink>create a new issue</newIssueLink> on GitHub so that we can investigate this bug.": "Please <newIssueLink>create a new issue</newIssueLink> on GitHub so that we can investigate this bug.",
|
||||||
"collapse": "collapse",
|
"collapse": "collapse",
|
||||||
"expand": "expand",
|
"expand": "expand",
|
||||||
|
"%(count)s people you know have already joined|other": "%(count)s people you know have already joined",
|
||||||
|
"%(count)s people you know have already joined|one": "%(count)s person you know has already joined",
|
||||||
"You cannot delete this image. (%(code)s)": "You cannot delete this image. (%(code)s)",
|
"You cannot delete this image. (%(code)s)": "You cannot delete this image. (%(code)s)",
|
||||||
"Uploaded on %(date)s by %(user)s": "Uploaded on %(date)s by %(user)s",
|
"Uploaded on %(date)s by %(user)s": "Uploaded on %(date)s by %(user)s",
|
||||||
"Rotate Left": "Rotate Left",
|
"Rotate Left": "Rotate Left",
|
||||||
|
@ -2004,14 +2010,13 @@
|
||||||
"%(networkName)s rooms": "%(networkName)s rooms",
|
"%(networkName)s rooms": "%(networkName)s rooms",
|
||||||
"Matrix rooms": "Matrix rooms",
|
"Matrix rooms": "Matrix rooms",
|
||||||
"Space selection": "Space selection",
|
"Space selection": "Space selection",
|
||||||
"Add existing spaces/rooms": "Add existing spaces/rooms",
|
"Add existing rooms": "Add existing rooms",
|
||||||
"Filter your rooms and spaces": "Filter your rooms and spaces",
|
"Filter your rooms and spaces": "Filter your rooms and spaces",
|
||||||
"Spaces": "Spaces",
|
"Spaces": "Spaces",
|
||||||
"Don't want to add an existing room?": "Don't want to add an existing room?",
|
"Don't want to add an existing room?": "Don't want to add an existing room?",
|
||||||
"Create a new room": "Create a new room",
|
"Create a new room": "Create a new room",
|
||||||
"Applying...": "Applying...",
|
|
||||||
"Apply": "Apply",
|
|
||||||
"Failed to add rooms to space": "Failed to add rooms to space",
|
"Failed to add rooms to space": "Failed to add rooms to space",
|
||||||
|
"Adding...": "Adding...",
|
||||||
"Matrix ID": "Matrix ID",
|
"Matrix ID": "Matrix ID",
|
||||||
"Matrix Room ID": "Matrix Room ID",
|
"Matrix Room ID": "Matrix Room ID",
|
||||||
"email address": "email address",
|
"email address": "email address",
|
||||||
|
@ -2187,7 +2192,7 @@
|
||||||
"Click the button below to confirm your identity.": "Click the button below to confirm your identity.",
|
"Click the button below to confirm your identity.": "Click the button below to confirm your identity.",
|
||||||
"Invite by email": "Invite by email",
|
"Invite by email": "Invite by email",
|
||||||
"Failed to invite the following users to chat: %(csvUsers)s": "Failed to invite the following users to chat: %(csvUsers)s",
|
"Failed to invite the following users to chat: %(csvUsers)s": "Failed to invite the following users to chat: %(csvUsers)s",
|
||||||
"We couldn't create your DM. Please check the users you want to invite and try again.": "We couldn't create your DM. Please check the users you want to invite and try again.",
|
"We couldn't create your DM.": "We couldn't create your DM.",
|
||||||
"Something went wrong trying to invite the users.": "Something went wrong trying to invite the users.",
|
"Something went wrong trying to invite the users.": "Something went wrong trying to invite the users.",
|
||||||
"We couldn't invite those users. Please check the users you want to invite and try again.": "We couldn't invite those users. Please check the users you want to invite and try again.",
|
"We couldn't invite those users. Please check the users you want to invite and try again.": "We couldn't invite those users. Please check the users you want to invite and try again.",
|
||||||
"A call can only be transferred to a single user.": "A call can only be transferred to a single user.",
|
"A call can only be transferred to a single user.": "A call can only be transferred to a single user.",
|
||||||
|
@ -2203,13 +2208,13 @@
|
||||||
"Start a conversation with someone using their name or username (like <userId/>).": "Start a conversation with someone using their name or username (like <userId/>).",
|
"Start a conversation with someone using their name or username (like <userId/>).": "Start a conversation with someone using their name or username (like <userId/>).",
|
||||||
"This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>": "This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>",
|
"This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>": "This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>",
|
||||||
"Go": "Go",
|
"Go": "Go",
|
||||||
"Invite to %(spaceName)s": "Invite to %(spaceName)s",
|
|
||||||
"Unnamed Space": "Unnamed Space",
|
"Unnamed Space": "Unnamed Space",
|
||||||
"Invite to %(roomName)s": "Invite to %(roomName)s",
|
"Invite to %(roomName)s": "Invite to %(roomName)s",
|
||||||
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.",
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.",
|
||||||
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.": "Invite someone using their name, username (like <userId/>) or <a>share this space</a>.",
|
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.": "Invite someone using their name, username (like <userId/>) or <a>share this space</a>.",
|
||||||
"Invite someone using their name, email address, username (like <userId/>) or <a>share this room</a>.": "Invite someone using their name, email address, username (like <userId/>) or <a>share this room</a>.",
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this room</a>.": "Invite someone using their name, email address, username (like <userId/>) or <a>share this room</a>.",
|
||||||
"Invite someone using their name, username (like <userId/>) or <a>share this room</a>.": "Invite someone using their name, username (like <userId/>) or <a>share this room</a>.",
|
"Invite someone using their name, username (like <userId/>) or <a>share this room</a>.": "Invite someone using their name, username (like <userId/>) or <a>share this room</a>.",
|
||||||
|
"Invited people will be able to read old messages.": "Invited people will be able to read old messages.",
|
||||||
"Transfer": "Transfer",
|
"Transfer": "Transfer",
|
||||||
"a new master key signature": "a new master key signature",
|
"a new master key signature": "a new master key signature",
|
||||||
"a new cross-signing key signature": "a new cross-signing key signature",
|
"a new cross-signing key signature": "a new cross-signing key signature",
|
||||||
|
@ -2351,7 +2356,7 @@
|
||||||
"Upload %(count)s other files|one": "Upload %(count)s other file",
|
"Upload %(count)s other files|one": "Upload %(count)s other file",
|
||||||
"Cancel All": "Cancel All",
|
"Cancel All": "Cancel All",
|
||||||
"Upload Error": "Upload Error",
|
"Upload Error": "Upload Error",
|
||||||
"Verify other session": "Verify other session",
|
"Verify other login": "Verify other login",
|
||||||
"Verification Request": "Verification Request",
|
"Verification Request": "Verification Request",
|
||||||
"Approve widget permissions": "Approve widget permissions",
|
"Approve widget permissions": "Approve widget permissions",
|
||||||
"This widget would like to:": "This widget would like to:",
|
"This widget would like to:": "This widget would like to:",
|
||||||
|
@ -2552,7 +2557,7 @@
|
||||||
"Review terms and conditions": "Review terms and conditions",
|
"Review terms and conditions": "Review terms and conditions",
|
||||||
"Old cryptography data detected": "Old cryptography data detected",
|
"Old cryptography data detected": "Old cryptography data detected",
|
||||||
"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.": "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.",
|
"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.": "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.",
|
||||||
"Self-verification request": "Self-verification request",
|
"Verification requested": "Verification requested",
|
||||||
"Logout": "Logout",
|
"Logout": "Logout",
|
||||||
"%(creator)s created this DM.": "%(creator)s created this DM.",
|
"%(creator)s created this DM.": "%(creator)s created this DM.",
|
||||||
"%(creator)s created and configured the room.": "%(creator)s created and configured the room.",
|
"%(creator)s created and configured the room.": "%(creator)s created and configured the room.",
|
||||||
|
@ -2610,25 +2615,31 @@
|
||||||
"Drop file here to upload": "Drop file here to upload",
|
"Drop file here to upload": "Drop file here to upload",
|
||||||
"You have %(count)s unread notifications in a prior version of this room.|other": "You have %(count)s unread notifications in a prior version of this room.",
|
"You have %(count)s unread notifications in a prior version of this room.|other": "You have %(count)s unread notifications in a prior version of this room.",
|
||||||
"You have %(count)s unread notifications in a prior version of this room.|one": "You have %(count)s unread notification in a prior version of this room.",
|
"You have %(count)s unread notifications in a prior version of this room.|one": "You have %(count)s unread notification in a prior version of this room.",
|
||||||
"Undo": "Undo",
|
"You don't have permission": "You don't have permission",
|
||||||
"Remove from Space": "Remove from Space",
|
|
||||||
"No permissions": "No permissions",
|
|
||||||
"You're in this space": "You're in this space",
|
|
||||||
"You're in this room": "You're in this room",
|
|
||||||
"Save changes": "Save changes",
|
|
||||||
"Promoted to users": "Promoted to users",
|
|
||||||
"Manage rooms": "Manage rooms",
|
|
||||||
"Find a room...": "Find a room...",
|
|
||||||
"<inviter/> invites you": "<inviter/> invites you",
|
|
||||||
"Public space": "Public space",
|
|
||||||
"Private space": "Private space",
|
|
||||||
"%(count)s members|other": "%(count)s members",
|
"%(count)s members|other": "%(count)s members",
|
||||||
"%(count)s members|one": "%(count)s member",
|
"%(count)s members|one": "%(count)s member",
|
||||||
"Add existing rooms & spaces": "Add existing rooms & spaces",
|
"%(count)s rooms|other": "%(count)s rooms",
|
||||||
"Default Rooms": "Default Rooms",
|
"%(count)s rooms|one": "%(count)s room",
|
||||||
|
"This room is suggested as a good one to join": "This room is suggested as a good one to join",
|
||||||
|
"Suggested": "Suggested",
|
||||||
|
"%(count)s rooms and %(numSpaces)s spaces|other": "%(count)s rooms and %(numSpaces)s spaces",
|
||||||
|
"%(count)s rooms and %(numSpaces)s spaces|one": "%(count)s room and %(numSpaces)s spaces",
|
||||||
|
"%(count)s rooms and 1 space|other": "%(count)s rooms and 1 space",
|
||||||
|
"%(count)s rooms and 1 space|one": "%(count)s room and 1 space",
|
||||||
|
"Failed to remove some rooms. Try again later": "Failed to remove some rooms. Try again later",
|
||||||
|
"Removing...": "Removing...",
|
||||||
|
"Mark as not suggested": "Mark as not suggested",
|
||||||
|
"Mark as suggested": "Mark as suggested",
|
||||||
|
"No results found": "No results found",
|
||||||
|
"You may want to try a different search or check for typos.": "You may want to try a different search or check for typos.",
|
||||||
"Your server does not support showing space hierarchies.": "Your server does not support showing space hierarchies.",
|
"Your server does not support showing space hierarchies.": "Your server does not support showing space hierarchies.",
|
||||||
"Your public space <name/>": "Your public space <name/>",
|
"Search names and description": "Search names and description",
|
||||||
"Your private space <name/>": "Your private space <name/>",
|
"If you can't find the room you're looking for, ask for an invite or <a>create a new room</a>.": "If you can't find the room you're looking for, ask for an invite or <a>create a new room</a>.",
|
||||||
|
"Create room": "Create room",
|
||||||
|
"Public space": "Public space",
|
||||||
|
"Private space": "Private space",
|
||||||
|
"<inviter/> invites you": "<inviter/> invites you",
|
||||||
|
"Add existing rooms & spaces": "Add existing rooms & spaces",
|
||||||
"Welcome to <name/>": "Welcome to <name/>",
|
"Welcome to <name/>": "Welcome to <name/>",
|
||||||
"Random": "Random",
|
"Random": "Random",
|
||||||
"Support": "Support",
|
"Support": "Support",
|
||||||
|
@ -2636,22 +2647,25 @@
|
||||||
"Failed to create initial space rooms": "Failed to create initial space rooms",
|
"Failed to create initial space rooms": "Failed to create initial space rooms",
|
||||||
"Skip for now": "Skip for now",
|
"Skip for now": "Skip for now",
|
||||||
"Creating rooms...": "Creating rooms...",
|
"Creating rooms...": "Creating rooms...",
|
||||||
"At the moment only you can see it.": "At the moment only you can see it.",
|
"Share %(name)s": "Share %(name)s",
|
||||||
"Finish": "Finish",
|
"It's just you at the moment, it will be even better with others.": "It's just you at the moment, it will be even better with others.",
|
||||||
|
"Go to my first room": "Go to my first room",
|
||||||
"Who are you working with?": "Who are you working with?",
|
"Who are you working with?": "Who are you working with?",
|
||||||
"Ensure the right people have access to the space.": "Ensure the right people have access to the space.",
|
"Make sure the right people have access to %(name)s": "Make sure the right people have access to %(name)s",
|
||||||
"Just Me": "Just Me",
|
"Just me": "Just me",
|
||||||
"A private space just for you": "A private space just for you",
|
"A private space to organise your rooms": "A private space to organise your rooms",
|
||||||
"Me and my teammates": "Me and my teammates",
|
"Me and my teammates": "Me and my teammates",
|
||||||
"A private space for you and your teammates": "A private space for you and your teammates",
|
"A private space for you and your teammates": "A private space for you and your teammates",
|
||||||
"Failed to invite the following users to your space: %(csvUsers)s": "Failed to invite the following users to your space: %(csvUsers)s",
|
"Failed to invite the following users to your space: %(csvUsers)s": "Failed to invite the following users to your space: %(csvUsers)s",
|
||||||
"Invite your teammates": "Invite your teammates",
|
|
||||||
"Invite by username": "Invite by username",
|
|
||||||
"Inviting...": "Inviting...",
|
"Inviting...": "Inviting...",
|
||||||
"What are some things you want to discuss?": "What are some things you want to discuss?",
|
"Invite your teammates": "Invite your teammates",
|
||||||
"We'll create rooms for each topic.": "We'll create rooms for each topic.",
|
"Make sure the right people have access. You can invite more later.": "Make sure the right people have access. You can invite more later.",
|
||||||
|
"Invite by username": "Invite by username",
|
||||||
|
"What are some things you want to discuss in %(spaceName)s?": "What are some things you want to discuss in %(spaceName)s?",
|
||||||
|
"Let's create a room for each of them.": "Let's create a room for each of them.",
|
||||||
|
"You can add more later too, including already existing ones.": "You can add more later too, including already existing ones.",
|
||||||
"What projects are you working on?": "What projects are you working on?",
|
"What projects are you working on?": "What projects are you working on?",
|
||||||
"We'll create rooms for each of them. You can add existing rooms after setup.": "We'll create rooms for each of them. You can add existing rooms after setup.",
|
"We'll create rooms for each of them. You can add more later too, including already existing ones.": "We'll create rooms for each of them. You can add more later too, including already existing ones.",
|
||||||
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.",
|
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.",
|
||||||
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.",
|
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.",
|
||||||
"Failed to load timeline position": "Failed to load timeline position",
|
"Failed to load timeline position": "Failed to load timeline position",
|
||||||
|
@ -2730,11 +2744,11 @@
|
||||||
"Decide where your account is hosted": "Decide where your account is hosted",
|
"Decide where your account is hosted": "Decide where your account is hosted",
|
||||||
"Use Security Key or Phrase": "Use Security Key or Phrase",
|
"Use Security Key or Phrase": "Use Security Key or Phrase",
|
||||||
"Use Security Key": "Use Security Key",
|
"Use Security Key": "Use Security Key",
|
||||||
"Verify with another session": "Verify with another session",
|
"Use another login": "Use another login",
|
||||||
"Verify this login to access your encrypted messages and prove to others that this login is really you.": "Verify this login to access your encrypted messages and prove to others that this login is really you.",
|
"Verify your identity to access encrypted messages and prove your identity to others.": "Verify your identity to access encrypted messages and prove your identity to others.",
|
||||||
"Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.",
|
"Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.",
|
||||||
"Your new session is now verified. Other users will see it as trusted.": "Your new session is now verified. Other users will see it as trusted.",
|
"Your new session is now verified. Other users will see it as trusted.": "Your new session is now verified. Other users will see it as trusted.",
|
||||||
"Without completing security on this session, it won’t have access to encrypted messages.": "Without completing security on this session, it won’t have access to encrypted messages.",
|
"Without verifying, you won’t have access to all your messages and may appear as untrusted to others.": "Without verifying, you won’t have access to all your messages and may appear as untrusted to others.",
|
||||||
"Failed to re-authenticate due to a homeserver problem": "Failed to re-authenticate due to a homeserver problem",
|
"Failed to re-authenticate due to a homeserver problem": "Failed to re-authenticate due to a homeserver problem",
|
||||||
"Incorrect password": "Incorrect password",
|
"Incorrect password": "Incorrect password",
|
||||||
"Failed to re-authenticate": "Failed to re-authenticate",
|
"Failed to re-authenticate": "Failed to re-authenticate",
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
"Always show message timestamps": "Siempre mostrar las marcas temporales de mensajes",
|
"Always show message timestamps": "Siempre mostrar las marcas temporales de mensajes",
|
||||||
"Authentication": "Autenticación",
|
"Authentication": "Autenticación",
|
||||||
"%(items)s and %(lastItem)s": "%(items)s y %(lastItem)s",
|
"%(items)s and %(lastItem)s": "%(items)s y %(lastItem)s",
|
||||||
"and %(count)s others...|other": "y otros %(count)s...",
|
"and %(count)s others...|other": "y otros %(count)s…",
|
||||||
"and %(count)s others...|one": "y otro más...",
|
"and %(count)s others...|one": "y otro más…",
|
||||||
"A new password must be entered.": "Debes ingresar una contraseña nueva.",
|
"A new password must be entered.": "Debes ingresar una contraseña nueva.",
|
||||||
"%(senderName)s answered the call.": "%(senderName)s contestó la llamada.",
|
"%(senderName)s answered the call.": "%(senderName)s contestó la llamada.",
|
||||||
"An error has occurred.": "Un error ha ocurrido.",
|
"An error has occurred.": "Un error ha ocurrido.",
|
||||||
|
@ -59,12 +59,12 @@
|
||||||
"Error": "Error",
|
"Error": "Error",
|
||||||
"Error decrypting attachment": "Error al descifrar adjunto",
|
"Error decrypting attachment": "Error al descifrar adjunto",
|
||||||
"Existing Call": "Llamada Existente",
|
"Existing Call": "Llamada Existente",
|
||||||
"Export E2E room keys": "Exportar claves de salas con Cifrado de Extremo a Extremo",
|
"Export E2E room keys": "Exportar claves de salas con cifrado de extremo a extremo",
|
||||||
"Failed to ban user": "Bloqueo del usuario falló",
|
"Failed to ban user": "Bloqueo del usuario falló",
|
||||||
"Failed to change password. Is your password correct?": "No se ha podido cambiar la contraseña. ¿Has escrito tu contraseña actual correctamente?",
|
"Failed to change password. Is your password correct?": "No se ha podido cambiar la contraseña. ¿Has escrito tu contraseña actual correctamente?",
|
||||||
"Failed to change power level": "Falló al cambiar de nivel de acceso",
|
"Failed to change power level": "Falló al cambiar de nivel de acceso",
|
||||||
"Failed to forget room %(errCode)s": "No se pudo olvidar la sala %(errCode)s",
|
"Failed to forget room %(errCode)s": "No se pudo olvidar la sala %(errCode)s",
|
||||||
"Failed to join room": "No se pudo unir a la sala",
|
"Failed to join room": "No se ha podido entrar a la sala",
|
||||||
"Failed to kick": "No se ha podido echar",
|
"Failed to kick": "No se ha podido echar",
|
||||||
"Failed to leave room": "No se pudo salir de la sala",
|
"Failed to leave room": "No se pudo salir de la sala",
|
||||||
"Failed to load timeline position": "Fallo al cargar el historial",
|
"Failed to load timeline position": "Fallo al cargar el historial",
|
||||||
|
@ -84,21 +84,21 @@
|
||||||
"Forget room": "Olvidar sala",
|
"Forget room": "Olvidar sala",
|
||||||
"For security, this session has been signed out. Please sign in again.": "Por seguridad, esta sesión ha sido cerrada. Por favor inicia sesión nuevamente.",
|
"For security, this session has been signed out. Please sign in again.": "Por seguridad, esta sesión ha sido cerrada. Por favor inicia sesión nuevamente.",
|
||||||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s a %(toPowerLevel)s",
|
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s a %(toPowerLevel)s",
|
||||||
"Guests cannot join this room even if explicitly invited.": "Invitados no pueden unirse a esta sala aun cuando han sido invitados explícitamente.",
|
"Guests cannot join this room even if explicitly invited.": "Los invitados no pueden unirse a esta sala incluso si se les invita explícitamente.",
|
||||||
"Hangup": "Colgar",
|
"Hangup": "Colgar",
|
||||||
"Historical": "Historial",
|
"Historical": "Historial",
|
||||||
"Homeserver is": "El servidor base es",
|
"Homeserver is": "El servidor base es",
|
||||||
"Identity Server is": "El Servidor de Identidad es",
|
"Identity Server is": "El Servidor de Identidad es",
|
||||||
"I have verified my email address": "He verificado mi dirección de correo electrónico",
|
"I have verified my email address": "He verificado mi dirección de correo electrónico",
|
||||||
"Import E2E room keys": "Importar claves de salas con Cifrado de Extremo a Extremo",
|
"Import E2E room keys": "Importar claves de salas con cifrado de extremo a extremo",
|
||||||
"Incorrect verification code": "Verificación de código incorrecta",
|
"Incorrect verification code": "Verificación de código incorrecta",
|
||||||
"Invalid Email Address": "Dirección de Correo Electrónico Inválida",
|
"Invalid Email Address": "Dirección de Correo Electrónico Inválida",
|
||||||
"Invalid file%(extra)s": "Archivo inválido %(extra)s",
|
"Invalid file%(extra)s": "Archivo inválido %(extra)s",
|
||||||
"%(senderName)s invited %(targetName)s.": "%(senderName)s invitó a %(targetName)s.",
|
"%(senderName)s invited %(targetName)s.": "%(senderName)s invitó a %(targetName)s.",
|
||||||
"Invites": "Invitaciones",
|
"Invites": "Invitaciones",
|
||||||
"Invites user with given id to current room": "Invita al usuario con la ID dada a la sala actual",
|
"Invites user with given id to current room": "Invita al usuario con la ID dada a la sala actual",
|
||||||
"Sign in with": "Quiero iniciar sesión con",
|
"Sign in with": "Iniciar sesión con",
|
||||||
"Join Room": "Unirse a la Sala",
|
"Join Room": "Unirme a la Sala",
|
||||||
"%(targetName)s joined the room.": "%(targetName)s se unió a la sala.",
|
"%(targetName)s joined the room.": "%(targetName)s se unió a la sala.",
|
||||||
"%(senderName)s kicked %(targetName)s.": "%(senderName)s echó a %(targetName)s.",
|
"%(senderName)s kicked %(targetName)s.": "%(senderName)s echó a %(targetName)s.",
|
||||||
"Kick": "Echar",
|
"Kick": "Echar",
|
||||||
|
@ -141,7 +141,7 @@
|
||||||
"%(senderName)s made future room history visible to anyone.": "%(senderName)s hizo visible el historial futuro de la sala para cualquier persona.",
|
"%(senderName)s made future room history visible to anyone.": "%(senderName)s hizo visible el historial futuro de la sala para cualquier persona.",
|
||||||
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s hizo visible el historial futuro de la sala para desconocido (%(visibility)s).",
|
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s hizo visible el historial futuro de la sala para desconocido (%(visibility)s).",
|
||||||
"Something went wrong!": "¡Algo ha fallado!",
|
"Something went wrong!": "¡Algo ha fallado!",
|
||||||
"Please select the destination room for this message": "Por favor, seleccione la sala destino para este mensaje",
|
"Please select the destination room for this message": "Por favor, selecciona la sala de destino para este mensaje",
|
||||||
"Create new room": "Crear nueva sala",
|
"Create new room": "Crear nueva sala",
|
||||||
"Start chat": "Iniciar conversación",
|
"Start chat": "Iniciar conversación",
|
||||||
"New Password": "Contraseña nueva",
|
"New Password": "Contraseña nueva",
|
||||||
|
@ -168,7 +168,7 @@
|
||||||
"Search": "Buscar",
|
"Search": "Buscar",
|
||||||
"Search failed": "Falló la búsqueda",
|
"Search failed": "Falló la búsqueda",
|
||||||
"Seen by %(userName)s at %(dateTime)s": "Visto por %(userName)s el %(dateTime)s",
|
"Seen by %(userName)s at %(dateTime)s": "Visto por %(userName)s el %(dateTime)s",
|
||||||
"Send Reset Email": "Enviar Correo Electrónico de Restauración",
|
"Send Reset Email": "Enviar correo electrónico de restauración",
|
||||||
"%(senderDisplayName)s sent an image.": "%(senderDisplayName)s envió una imagen.",
|
"%(senderDisplayName)s sent an image.": "%(senderDisplayName)s envió una imagen.",
|
||||||
"%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s invitó a %(targetDisplayName)s a unirse a la sala.",
|
"%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s invitó a %(targetDisplayName)s a unirse a la sala.",
|
||||||
"Server error": "Error del servidor",
|
"Server error": "Error del servidor",
|
||||||
|
@ -180,7 +180,7 @@
|
||||||
"%(senderName)s set their display name to %(displayName)s.": "%(senderName)s estableció %(displayName)s como su nombre público.",
|
"%(senderName)s set their display name to %(displayName)s.": "%(senderName)s estableció %(displayName)s como su nombre público.",
|
||||||
"Settings": "Ajustes",
|
"Settings": "Ajustes",
|
||||||
"Signed Out": "Desconectado",
|
"Signed Out": "Desconectado",
|
||||||
"Sign in": "Conectar",
|
"Sign in": "Iniciar sesión",
|
||||||
"Sign out": "Cerrar sesión",
|
"Sign out": "Cerrar sesión",
|
||||||
"%(count)s of your messages have not been sent.|other": "Algunos de tus mensajes no han sido enviados.",
|
"%(count)s of your messages have not been sent.|other": "Algunos de tus mensajes no han sido enviados.",
|
||||||
"Someone": "Alguien",
|
"Someone": "Alguien",
|
||||||
|
@ -228,7 +228,7 @@
|
||||||
"Profile": "Perfil",
|
"Profile": "Perfil",
|
||||||
"Public Chat": "Sala pública",
|
"Public Chat": "Sala pública",
|
||||||
"Reason": "Motivo",
|
"Reason": "Motivo",
|
||||||
"Register": "Registrar",
|
"Register": "Crear cuenta",
|
||||||
"%(targetName)s rejected the invitation.": "%(targetName)s rechazó la invitación.",
|
"%(targetName)s rejected the invitation.": "%(targetName)s rechazó la invitación.",
|
||||||
"Reject invitation": "Rechazar invitación",
|
"Reject invitation": "Rechazar invitación",
|
||||||
"%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s eliminó su nombre público (%(oldDisplayName)s).",
|
"%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s eliminó su nombre público (%(oldDisplayName)s).",
|
||||||
|
@ -240,7 +240,7 @@
|
||||||
"%(brand)s does not have permission to send you notifications - please check your browser settings": "%(brand)s no tiene permiso para enviarte notificaciones - por favor, comprueba los ajustes de tu navegador",
|
"%(brand)s does not have permission to send you notifications - please check your browser settings": "%(brand)s no tiene permiso para enviarte notificaciones - por favor, comprueba los ajustes de tu navegador",
|
||||||
"%(brand)s was not given permission to send notifications - please try again": "No le has dado permiso a %(brand)s para enviar notificaciones. Por favor, inténtalo de nuevo",
|
"%(brand)s was not given permission to send notifications - please try again": "No le has dado permiso a %(brand)s para enviar notificaciones. Por favor, inténtalo de nuevo",
|
||||||
"%(brand)s version:": "Versión de %(brand)s:",
|
"%(brand)s version:": "Versión de %(brand)s:",
|
||||||
"Room %(roomId)s not visible": "La sala %(roomId)s no está visible",
|
"Room %(roomId)s not visible": "La sala %(roomId)s no es visible",
|
||||||
"Searches DuckDuckGo for results": "Busca resultados en DuckDuckGo",
|
"Searches DuckDuckGo for results": "Busca resultados en DuckDuckGo",
|
||||||
"Show timestamps in 12 hour format (e.g. 2:30pm)": "Mostrar marcas temporales en formato de 12 horas (ej. 2:30pm)",
|
"Show timestamps in 12 hour format (e.g. 2:30pm)": "Mostrar marcas temporales en formato de 12 horas (ej. 2:30pm)",
|
||||||
"This email address is already in use": "Esta dirección de correo electrónico ya está en uso",
|
"This email address is already in use": "Esta dirección de correo electrónico ya está en uso",
|
||||||
|
@ -345,7 +345,7 @@
|
||||||
"Jun": "Jun",
|
"Jun": "Jun",
|
||||||
"Jul": "Jul",
|
"Jul": "Jul",
|
||||||
"Aug": "Ago",
|
"Aug": "Ago",
|
||||||
"Add rooms to this community": "Agregar salas a esta comunidad",
|
"Add rooms to this community": "Añadir salas a esta comunidad",
|
||||||
"Call Failed": "Llamada fallida",
|
"Call Failed": "Llamada fallida",
|
||||||
"Sep": "Sep",
|
"Sep": "Sep",
|
||||||
"Oct": "Oct",
|
"Oct": "Oct",
|
||||||
|
@ -360,7 +360,7 @@
|
||||||
"Your language of choice": "Idioma elegido",
|
"Your language of choice": "Idioma elegido",
|
||||||
"Your homeserver's URL": "La URL de tu servidor base",
|
"Your homeserver's URL": "La URL de tu servidor base",
|
||||||
"The information being sent to us to help make %(brand)s better includes:": "La información que se nos envía para ayudarnos a mejorar %(brand)s incluye:",
|
"The information being sent to us to help make %(brand)s better includes:": "La información que se nos envía para ayudarnos a mejorar %(brand)s incluye:",
|
||||||
"Whether or not you're using the Richtext mode of the Rich Text Editor": "Estés utilizando o no el modo de Texto Enriquecido del Editor de Texto Enriquecido",
|
"Whether or not you're using the Richtext mode of the Rich Text Editor": "Estés utilizando o no el modo de texto enriquecido del editor de texto enriquecido",
|
||||||
"Who would you like to add to this community?": "¿A quién te gustaría añadir a esta comunidad?",
|
"Who would you like to add to this community?": "¿A quién te gustaría añadir a esta comunidad?",
|
||||||
"Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Advertencia: cualquier persona que añadas a una comunidad será públicamente visible a cualquiera que conozca la ID de la comunidad",
|
"Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Advertencia: cualquier persona que añadas a una comunidad será públicamente visible a cualquiera que conozca la ID de la comunidad",
|
||||||
"Invite new community members": "Invita nuevos miembros a la comunidad",
|
"Invite new community members": "Invita nuevos miembros a la comunidad",
|
||||||
|
@ -417,7 +417,7 @@
|
||||||
"Collecting app version information": "Recolectando información de la versión de la aplicación",
|
"Collecting app version information": "Recolectando información de la versión de la aplicación",
|
||||||
"Keywords": "Palabras clave",
|
"Keywords": "Palabras clave",
|
||||||
"Enable notifications for this account": "Activar notificaciones para esta cuenta",
|
"Enable notifications for this account": "Activar notificaciones para esta cuenta",
|
||||||
"Invite to this community": "Invitar a esta comunidad",
|
"Invite to this community": "Invitar a la comunidad",
|
||||||
"Messages containing <span>keywords</span>": "Mensajes que contienen <span>palabras clave</span>",
|
"Messages containing <span>keywords</span>": "Mensajes que contienen <span>palabras clave</span>",
|
||||||
"Error saving email notification preferences": "Error al guardar las preferencias de notificación por email",
|
"Error saving email notification preferences": "Error al guardar las preferencias de notificación por email",
|
||||||
"Tuesday": "Martes",
|
"Tuesday": "Martes",
|
||||||
|
@ -444,16 +444,16 @@
|
||||||
"Collecting logs": "Recolectando registros",
|
"Collecting logs": "Recolectando registros",
|
||||||
"You must specify an event type!": "Debes especificar un tipo de evento!",
|
"You must specify an event type!": "Debes especificar un tipo de evento!",
|
||||||
"(HTTP status %(httpStatus)s)": "(estado HTTP %(httpStatus)s)",
|
"(HTTP status %(httpStatus)s)": "(estado HTTP %(httpStatus)s)",
|
||||||
"Invite to this room": "Invitar a esta sala",
|
"Invite to this room": "Invitar a la sala",
|
||||||
"Send": "Enviar",
|
"Send": "Enviar",
|
||||||
"Send logs": "Enviar registros",
|
"Send logs": "Enviar registros",
|
||||||
"All messages": "Todos los mensajes",
|
"All messages": "Todos los mensajes",
|
||||||
"Call invitation": "Cuando me inviten a una llamada",
|
"Call invitation": "Cuando me inviten a una llamada",
|
||||||
"Thank you!": "¡Gracias!",
|
"Thank you!": "¡Gracias!",
|
||||||
"Downloading update...": "Descargando actualizaciones...",
|
"Downloading update...": "Descargando actualización…",
|
||||||
"State Key": "Clave de estado",
|
"State Key": "Clave de estado",
|
||||||
"Failed to send custom event.": "Ha fallado el envio del evento personalizado.",
|
"Failed to send custom event.": "Ha fallado el envio del evento personalizado.",
|
||||||
"What's new?": "¿Qué hay de nuevo?",
|
"What's new?": "Novedades",
|
||||||
"Notify me for anything else": "Notificarme para cualquier otra cosa",
|
"Notify me for anything else": "Notificarme para cualquier otra cosa",
|
||||||
"When I'm invited to a room": "Cuando me inviten a una sala",
|
"When I'm invited to a room": "Cuando me inviten a una sala",
|
||||||
"Can't update user notification settings": "No se puede actualizar los ajustes de notificaciones del usuario",
|
"Can't update user notification settings": "No se puede actualizar los ajustes de notificaciones del usuario",
|
||||||
|
@ -467,7 +467,7 @@
|
||||||
"Logs sent": "Registros enviados",
|
"Logs sent": "Registros enviados",
|
||||||
"Back": "Atrás",
|
"Back": "Atrás",
|
||||||
"Reply": "Responder",
|
"Reply": "Responder",
|
||||||
"Show message in desktop notification": "Mostrar mensaje en la notificación del escritorio",
|
"Show message in desktop notification": "Mostrar mensaje en las notificaciones de escritorio",
|
||||||
"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.": "Los registros de depuración contienen datos de uso de la aplicación como nombre de usuario, ID o alias de las salas o grupos que hayas visitado (y nombres de usuario de otros usuarios). No contienen mensajes.",
|
"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.": "Los registros de depuración contienen datos de uso de la aplicación como nombre de usuario, ID o alias de las salas o grupos que hayas visitado (y nombres de usuario de otros usuarios). No contienen mensajes.",
|
||||||
"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",
|
||||||
|
@ -496,7 +496,7 @@
|
||||||
"Unable to fetch notification target list": "No se puede obtener la lista de destinos de notificación",
|
"Unable to fetch notification target list": "No se puede obtener la lista de destinos de notificación",
|
||||||
"Quote": "Citar",
|
"Quote": "Citar",
|
||||||
"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!": "En su navegador actual, la apariencia y comportamiento de la aplicación puede ser completamente incorrecta, y algunas de las características podrían no funcionar. Si aún desea probarlo puede continuar, pero ¡no podremos ofrecer soporte por cualquier problema que pudiese tener!",
|
"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!": "En su navegador actual, la apariencia y comportamiento de la aplicación puede ser completamente incorrecta, y algunas de las características podrían no funcionar. Si aún desea probarlo puede continuar, pero ¡no podremos ofrecer soporte por cualquier problema que pudiese tener!",
|
||||||
"Checking for an update...": "Comprobando actualizaciones...",
|
"Checking for an update...": "Comprobando actualizaciones…",
|
||||||
"Every page you use in the app": "Cada página que utilizas en la aplicación",
|
"Every page you use in the app": "Cada página que utilizas en la aplicación",
|
||||||
"Your device resolution": "La resolución de tu dispositivo",
|
"Your device resolution": "La resolución de tu dispositivo",
|
||||||
"Which officially provided instance you are using, if any": "Qué instancia proporcionada oficialmente estás utilizando, si estás utilizando alguna",
|
"Which officially provided instance you are using, if any": "Qué instancia proporcionada oficialmente estás utilizando, si estás utilizando alguna",
|
||||||
|
@ -520,7 +520,7 @@
|
||||||
"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 pudieron añadir 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",
|
||||||
"Ignored user": "Usuario ignorado",
|
"Ignored user": "Usuario ignorado",
|
||||||
"You are now ignoring %(userId)s": "Ahora ignoras a %(userId)s",
|
"You are now ignoring %(userId)s": "Ahora ignoras a %(userId)s",
|
||||||
|
@ -538,11 +538,11 @@
|
||||||
"Message Pinning": "Mensajes anclados",
|
"Message Pinning": "Mensajes anclados",
|
||||||
"Always show encryption icons": "Mostrar siempre iconos de cifrado",
|
"Always show encryption icons": "Mostrar siempre iconos de cifrado",
|
||||||
"Automatically replace plain text Emoji": "Reemplazar automáticamente texto por Emojis",
|
"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": "Invertir horizontalmente el vídeo local (espejo)",
|
||||||
"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": "Activar vistas previas de URLs en línea por defecto",
|
"Enable inline URL previews by default": "Activar vistas previas de URLs en línea por defecto",
|
||||||
"Enable URL previews for this room (only affects you)": "Activar vista previa de URL en esta sala (te afecta a ti)",
|
"Enable URL previews for this room (only affects you)": "Activar vista previa de URLs en esta sala (solo para ti)",
|
||||||
"Enable URL previews by default for participants in this room": "Activar vista previa de URL por defecto para los participantes en esta sala",
|
"Enable URL previews by default for participants in this room": "Activar vista previa de URLs por defecto para los participantes en esta sala",
|
||||||
"Enable widget screenshots on supported widgets": "Activar capturas de pantalla de widget en los widgets soportados",
|
"Enable widget screenshots on supported widgets": "Activar capturas de pantalla de widget en los widgets soportados",
|
||||||
"Drop file here to upload": "Soltar aquí el fichero a subir",
|
"Drop file here to upload": "Soltar aquí el fichero a subir",
|
||||||
" (unsupported)": " (no soportado)",
|
" (unsupported)": " (no soportado)",
|
||||||
|
@ -569,7 +569,7 @@
|
||||||
"Send an encrypted message…": "Enviar un mensaje cifrado…",
|
"Send an encrypted message…": "Enviar un mensaje cifrado…",
|
||||||
"Jump to message": "Ir al mensaje",
|
"Jump to message": "Ir al mensaje",
|
||||||
"No pinned messages.": "No hay mensajes anclados.",
|
"No pinned messages.": "No hay mensajes anclados.",
|
||||||
"Loading...": "Cargando...",
|
"Loading...": "Cargando…",
|
||||||
"Pinned Messages": "Mensajes anclados",
|
"Pinned Messages": "Mensajes anclados",
|
||||||
"%(duration)ss": "%(duration)ss",
|
"%(duration)ss": "%(duration)ss",
|
||||||
"%(duration)sm": "%(duration)sm",
|
"%(duration)sm": "%(duration)sm",
|
||||||
|
@ -598,15 +598,15 @@
|
||||||
"Hide Stickers": "Ocultar Pegatinas",
|
"Hide Stickers": "Ocultar Pegatinas",
|
||||||
"Show Stickers": "Pegatinas",
|
"Show Stickers": "Pegatinas",
|
||||||
"Invalid community ID": "ID de comunidad inválida",
|
"Invalid community ID": "ID de comunidad inválida",
|
||||||
"'%(groupId)s' is not a valid community ID": "'%(groupId)s' no es una ID de comunidad válida",
|
"'%(groupId)s' is not a valid community ID": "«%(groupId)s no es una ID de comunidad válida",
|
||||||
"Flair": "Insignia",
|
"Flair": "Insignia",
|
||||||
"Showing flair for these communities:": "Mostrar insignias de las siguientes comunidades:",
|
"Showing flair for these communities:": "Mostrar insignias de las siguientes comunidades:",
|
||||||
"This room is not showing flair for any communities": "Esta sala no está mostrando insignias de ninguna comunidad",
|
"This room is not showing flair for any communities": "Esta sala no está mostrando insignias de ninguna comunidad",
|
||||||
"New community ID (e.g. +foo:%(localDomain)s)": "Nueva ID de comunidad (ej. +foo:%(localDomain)s)",
|
"New community ID (e.g. +foo:%(localDomain)s)": "Nueva ID de comunidad (ej. +foo:%(localDomain)s)",
|
||||||
"URL previews are enabled by default for participants in this room.": "La vista previa de URL se activa por defecto en los participantes de esta sala.",
|
"URL previews are enabled by default for participants in this room.": "La vista previa de URLs se activa por defecto en los participantes de esta sala.",
|
||||||
"URL previews are disabled by default for participants in this room.": "La vista previa se desactiva por defecto para los participantes de esta sala.",
|
"URL previews are disabled by default for participants in this room.": "La vista previa de URLs se desactiva por defecto para los participantes de esta sala.",
|
||||||
"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.": "En salas cifradas como ésta, la vista previa de las URL se desactiva por defecto para asegurar que el servidor base (donde se generan) no puede recopilar información de los enlaces que veas en esta sala.",
|
"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.": "En salas cifradas como ésta, la vista previa de las URLs se desactiva por defecto para asegurar que el servidor base (donde se generan) no pueda recopilar información de los enlaces que veas en esta sala.",
|
||||||
"URL Previews": "Vista previa de URL",
|
"URL Previews": "Vista previa de URLs",
|
||||||
"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.": "Cuando alguien incluye una URL en su mensaje, se mostrará una vista previa para ofrecer información sobre el enlace, que incluirá el título, descripción, y una imagen del sitio web.",
|
"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.": "Cuando alguien incluye una URL en su mensaje, se mostrará una vista previa para ofrecer información sobre el enlace, que incluirá el título, descripción, y una imagen del sitio web.",
|
||||||
"Error decrypting audio": "Error al descifrar el sonido",
|
"Error decrypting audio": "Error al descifrar el sonido",
|
||||||
"Error decrypting image": "Error al descifrar imagen",
|
"Error decrypting image": "Error al descifrar imagen",
|
||||||
|
@ -617,12 +617,12 @@
|
||||||
"Copied!": "¡Copiado!",
|
"Copied!": "¡Copiado!",
|
||||||
"Failed to copy": "Falló la copia",
|
"Failed to copy": "Falló la copia",
|
||||||
"Add an Integration": "Añadir una Integración",
|
"Add an Integration": "Añadir una Integración",
|
||||||
"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?": "Estás a punto de ir a un sitio de terceros de modo que pueda autenticar su cuenta para usarla con %(integrationsUrl)s. ¿Quieres continuar?",
|
"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?": "Estás a punto de ir a un sitio externo para que puedas iniciar sesión con tu cuenta y usarla en %(integrationsUrl)s. ¿Quieres seguir?",
|
||||||
"An email has been sent to %(emailAddress)s": "Se envió un correo electrónico a %(emailAddress)s",
|
"An email has been sent to %(emailAddress)s": "Se envió un correo electrónico a %(emailAddress)s",
|
||||||
"Please check your email to continue registration.": "Por favor consulta tu correo electrónico para continuar con el registro.",
|
"Please check your email to continue registration.": "Por favor consulta tu correo electrónico para continuar con el registro.",
|
||||||
"Token incorrect": "Token incorrecto",
|
"Token incorrect": "Token incorrecto",
|
||||||
"A text message has been sent to %(msisdn)s": "Se envió un mensaje de texto a %(msisdn)s",
|
"A text message has been sent to %(msisdn)s": "Se envió un mensaje de texto a %(msisdn)s",
|
||||||
"Please enter the code it contains:": "Por favor introduzca el código que contiene:",
|
"Please enter the code it contains:": "Por favor, escribe el código que contiene:",
|
||||||
"Code": "Código",
|
"Code": "Código",
|
||||||
"The email field must not be blank.": "El campo de correo electrónico no debe estar en blanco.",
|
"The email field must not be blank.": "El campo de correo electrónico no debe estar en blanco.",
|
||||||
"The phone number field must not be blank.": "El campo de número telefónico no debe estar en blanco.",
|
"The phone number field must not be blank.": "El campo de número telefónico no debe estar en blanco.",
|
||||||
|
@ -634,12 +634,12 @@
|
||||||
"Failed to withdraw invitation": "Falló la retirada de la invitación",
|
"Failed to withdraw invitation": "Falló la retirada de la invitación",
|
||||||
"Failed to remove user from community": "Falló la eliminación de este usuario de la comunidad",
|
"Failed to remove user from community": "Falló la eliminación de este usuario de la comunidad",
|
||||||
"Filter community members": "Filtrar miembros de la comunidad",
|
"Filter community members": "Filtrar miembros de la comunidad",
|
||||||
"Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "¿Seguro que quieres eliminar a '%(roomName)s' de %(groupId)s?",
|
"Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "¿Seguro que quieres eliminar a «%(roomName)s de %(groupId)s?",
|
||||||
"Removing a room from the community will also remove it from the community page.": "Al eliminar una sala de la comunidad también se eliminará de su página.",
|
"Removing a room from the community will also remove it from the community page.": "Al eliminar una sala de la comunidad también se eliminará de su página.",
|
||||||
"Failed to remove room from community": "Falló la eliminación de la sala de la comunidad",
|
"Failed to remove room from community": "Falló la eliminación de la sala de la comunidad",
|
||||||
"Failed to remove '%(roomName)s' from %(groupId)s": "Falló la eliminación de '%(roomName)s' de %(groupId)s",
|
"Failed to remove '%(roomName)s' from %(groupId)s": "Ha fallado la eliminación de «%(roomName)s» de %(groupId)s",
|
||||||
"The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "La visibilidad de '%(roomName)s' en %(groupId)s no se pudo actualizar.",
|
"The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "La visibilidad de «%(roomName)s» en %(groupId)s no se ha podido actualizar.",
|
||||||
"Visibility in Room List": "Visibilidad en la Lista de Salas",
|
"Visibility in Room List": "Visibilidad en la lista de salas",
|
||||||
"Visible to everyone": "Visible a todo el mundo",
|
"Visible to everyone": "Visible a todo el mundo",
|
||||||
"Only visible to community members": "Sólo visible a los miembros de la comunidad",
|
"Only visible to community members": "Sólo visible a los miembros de la comunidad",
|
||||||
"Filter community rooms": "Filtrar salas de la comunidad",
|
"Filter community rooms": "Filtrar salas de la comunidad",
|
||||||
|
@ -665,8 +665,8 @@
|
||||||
"%(oneUser)sleft %(count)s times|one": "%(oneUser)s salió",
|
"%(oneUser)sleft %(count)s times|one": "%(oneUser)s salió",
|
||||||
"%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s se unieron y fueron %(count)s veces",
|
"%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s se unieron y fueron %(count)s veces",
|
||||||
"%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s se unieron y fueron",
|
"%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s se unieron y fueron",
|
||||||
"%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s se unió y fue %(count)s veces",
|
"%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s se unió y se fue %(count)s veces",
|
||||||
"%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s se unió y fue",
|
"%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s se unió y se fue",
|
||||||
"%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s se fueron y volvieron a unirse %(count)s veces",
|
"%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)s se fueron y volvieron a unirse %(count)s veces",
|
||||||
"%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s se fueron y volvieron a unirse",
|
"%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s se fueron y volvieron a unirse",
|
||||||
"%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s se fue y volvió a unirse %(count)s veces",
|
"%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s se fue y volvió a unirse %(count)s veces",
|
||||||
|
@ -709,18 +709,18 @@
|
||||||
"expand": "expandir",
|
"expand": "expandir",
|
||||||
"Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "No se pudo cargar el evento al que se respondió, bien porque no existe o no tiene permiso para verlo.",
|
"Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "No se pudo cargar el evento al que se respondió, bien porque no existe o no tiene permiso para verlo.",
|
||||||
"<a>In reply to</a> <pill>": "<a>En respuesta a </a> <pill>",
|
"<a>In reply to</a> <pill>": "<a>En respuesta a </a> <pill>",
|
||||||
"And %(count)s more...|other": "Y %(count)s más...",
|
"And %(count)s more...|other": "Y %(count)s más…",
|
||||||
"ex. @bob:example.com": "ej. @bob:ejemplo.com",
|
"ex. @bob:example.com": "ej. @bob:ejemplo.com",
|
||||||
"Add User": "Agregar Usuario",
|
"Add User": "Agregar Usuario",
|
||||||
"Matrix ID": "ID de Matrix",
|
"Matrix ID": "ID de Matrix",
|
||||||
"Matrix Room ID": "ID de Sala de Matrix",
|
"Matrix Room ID": "ID de sala de Matrix",
|
||||||
"email address": "dirección de correo electrónico",
|
"email address": "dirección de correo electrónico",
|
||||||
"You have entered an invalid address.": "No ha introducido una dirección correcta.",
|
"You have entered an invalid address.": "No ha introducido una dirección correcta.",
|
||||||
"Try using one of the following valid address types: %(validTypesList)s.": "Intente usar uno de los tipos de direcciones válidos: %(validTypesList)s.",
|
"Try using one of the following valid address types: %(validTypesList)s.": "Intente usar uno de los tipos de direcciones válidos: %(validTypesList)s.",
|
||||||
"Confirm Removal": "Confirmar eliminación",
|
"Confirm Removal": "Confirmar eliminación",
|
||||||
"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.": "¿Seguro que quieres eliminar este evento? Ten en cuenta que, si borras un cambio de nombre o tema de sala, podrías deshacer el cambio.",
|
"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.": "¿Seguro que quieres eliminar este evento? Ten en cuenta que, si borras un cambio de nombre o tema de sala, podrías deshacer el cambio.",
|
||||||
"Community IDs cannot be empty.": "Las IDs de comunidad no pueden estar vacías.",
|
"Community IDs cannot be empty.": "Las IDs de comunidad no pueden estar vacías.",
|
||||||
"Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Las IDs de comunidad sólo pueden contener caracteres a-z, 0-9, ó '=_-./'",
|
"Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Las IDs de comunidad solo pueden contener caracteres de la «a» a la «z» excluyendo la «ñ», dígitos o «=_-./»",
|
||||||
"Something went wrong whilst creating your community": "Algo fue mal mientras se creaba la comunidad",
|
"Something went wrong whilst creating your community": "Algo fue mal mientras se creaba la comunidad",
|
||||||
"Create Community": "Crear Comunidad",
|
"Create Community": "Crear Comunidad",
|
||||||
"Community Name": "Nombre de Comunidad",
|
"Community Name": "Nombre de Comunidad",
|
||||||
|
@ -756,22 +756,22 @@
|
||||||
"Collapse Reply Thread": "Colapsar Hilo de Respuestas",
|
"Collapse Reply Thread": "Colapsar Hilo de Respuestas",
|
||||||
"There are no visible files in this room": "No hay archivos visibles en esta sala",
|
"There are no visible files in this room": "No hay archivos visibles en esta sala",
|
||||||
"<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": "HTML para la página de tu comunidad. Usa la descripción larga para su presentación, o distribuir enlaces de interés. Puedes incluso usar etiquetas 'img'\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": "HTML para la página de tu comunidad. Usa la descripción larga para su presentación, o distribuir enlaces de interés. Puedes incluso usar etiquetas 'img'\n",
|
||||||
"Add rooms to the community summary": "Agregar salas al resumen de la comunidad",
|
"Add rooms to the community summary": "Añadir salas al resumen de la comunidad",
|
||||||
"Which rooms would you like to add to this summary?": "¿Cuáles salas desea agregar a este resumen?",
|
"Which rooms would you like to add to this summary?": "¿Cuáles salas quieres añadir a este resumen?",
|
||||||
"Add to summary": "Agregar a resumen",
|
"Add to summary": "Añadir al resumen",
|
||||||
"Failed to add the following rooms to the summary of %(groupId)s:": "Falló la agregación de las salas siguientes al resumen de %(groupId)s:",
|
"Failed to add the following rooms to the summary of %(groupId)s:": "Falló la agregación de las salas siguientes al resumen de %(groupId)s:",
|
||||||
"Add a Room": "Agregar una Sala",
|
"Add a Room": "Añadir una sala",
|
||||||
"Failed to remove the room from the summary of %(groupId)s": "Falló la eliminación de la sala del resumen de %(groupId)s",
|
"Failed to remove the room from the summary of %(groupId)s": "Falló la eliminación de la sala del resumen de %(groupId)s",
|
||||||
"The room '%(roomName)s' could not be removed from the summary.": "La sala '%(roomName)s' no se pudo eliminar del resumen.",
|
"The room '%(roomName)s' could not be removed from the summary.": "La sala «%(roomName)s no se pudo eliminar del resumen.",
|
||||||
"Add users to the community summary": "Agregar usuario al resumen de la comunidad",
|
"Add users to the community summary": "Añadir usuario al resumen de la comunidad",
|
||||||
"Who would you like to add to this summary?": "¿A quién le gustaría agregar a este resumen?",
|
"Who would you like to add to this summary?": "¿A quién te gustaría añadir a este resumen?",
|
||||||
"Failed to add the following users to the summary of %(groupId)s:": "Falló la adición de los usuarios siguientes al resumen de %(groupId)s:",
|
"Failed to add the following users to the summary of %(groupId)s:": "Falló la adición de los usuarios siguientes al resumen de %(groupId)s:",
|
||||||
"Add a User": "Agregar un usuario",
|
"Add a User": "Añadir un usuario",
|
||||||
"Failed to remove a user from the summary of %(groupId)s": "Falló la eliminación de un usuario del resumen de %(groupId)s",
|
"Failed to remove a user from the summary of %(groupId)s": "Falló la eliminación de un usuario del resumen de %(groupId)s",
|
||||||
"The user '%(displayName)s' could not be removed from the summary.": "No se pudo eliminar al usuario '%(displayName)s' del resumen.",
|
"The user '%(displayName)s' could not be removed from the summary.": "No se ha podido eliminar al usuario «%(displayName)s» del resumen.",
|
||||||
"Failed to upload image": "No se pudo cargar la imagen",
|
"Failed to upload image": "No se pudo cargar la imagen",
|
||||||
"Failed to update community": "Falló la actualización de la comunidad",
|
"Failed to update community": "Falló la actualización de la comunidad",
|
||||||
"Unable to accept invite": "No se pudo aceptar la invitación",
|
"Unable to accept invite": "No se ha podido aceptar la invitación",
|
||||||
"Unable to join community": "No se pudo unir a comunidad",
|
"Unable to join community": "No se pudo unir a comunidad",
|
||||||
"Leave Community": "Salir de la Comunidad",
|
"Leave Community": "Salir de la Comunidad",
|
||||||
"Leave %(groupName)s?": "¿Salir de %(groupName)s?",
|
"Leave %(groupName)s?": "¿Salir de %(groupName)s?",
|
||||||
|
@ -810,7 +810,7 @@
|
||||||
"You can't send any messages until you review and agree to <consentLink>our terms and conditions</consentLink>.": "No puedes enviar ningún mensaje hasta que revises y estés de acuerdo con <consentLink>nuestros términos y condiciones</consentLink>.",
|
"You can't send any messages until you review and agree to <consentLink>our terms and conditions</consentLink>.": "No puedes enviar ningún mensaje hasta que revises y estés de acuerdo con <consentLink>nuestros términos y condiciones</consentLink>.",
|
||||||
"%(count)s of your messages have not been sent.|one": "No se ha enviado tu mensaje.",
|
"%(count)s of your messages have not been sent.|one": "No se ha enviado tu mensaje.",
|
||||||
"%(count)s <resendText>Resend all</resendText> or <cancelText>cancel all</cancelText> now. You can also select individual messages to resend or cancel.|other": "<resendText>Reenviar todo</resendText> o <cancelText>cancelar todo</cancelText> ahora. También puedes seleccionar mensajes individuales para reenviar o cancelar.",
|
"%(count)s <resendText>Resend all</resendText> or <cancelText>cancel all</cancelText> now. You can also select individual messages to resend or cancel.|other": "<resendText>Reenviar todo</resendText> o <cancelText>cancelar todo</cancelText> ahora. También puedes seleccionar mensajes individuales para reenviar o cancelar.",
|
||||||
"%(count)s <resendText>Resend all</resendText> or <cancelText>cancel all</cancelText> now. You can also select individual messages to resend or cancel.|one": "<resendText>Reenviar mensaje</resendText> o <cancelText>cancelar mensaje</cancelText> ahora.",
|
"%(count)s <resendText>Resend all</resendText> or <cancelText>cancel all</cancelText> now. You can also select individual messages to resend or cancel.|one": "<resendText>Reenviar mensaje</resendText> o <cancelText>cancelar el envío</cancelText> ahora.",
|
||||||
"Connectivity to the server has been lost.": "Se ha perdido la conexión con el servidor.",
|
"Connectivity to the server has been lost.": "Se ha perdido la conexión con el servidor.",
|
||||||
"Sent messages will be stored until your connection has returned.": "Los mensajes enviados se almacenarán hasta que vuelva la conexión.",
|
"Sent messages will be stored until your connection has returned.": "Los mensajes enviados se almacenarán hasta que vuelva la conexión.",
|
||||||
"Active call": "Llamada activa",
|
"Active call": "Llamada activa",
|
||||||
|
@ -861,7 +861,7 @@
|
||||||
"The room upgrade could not be completed": "La actualización de la sala no pudo ser completada",
|
"The room upgrade could not be completed": "La actualización de la sala no pudo ser completada",
|
||||||
"Upgrade this room to version %(version)s": "Actualiza esta sala a la versión %(version)s",
|
"Upgrade this room to version %(version)s": "Actualiza esta sala a la versión %(version)s",
|
||||||
"Legal": "Legal",
|
"Legal": "Legal",
|
||||||
"Unable to connect to Homeserver. Retrying...": "No ha sido posible conectarse al servidor base. Volviendo a intentar...",
|
"Unable to connect to Homeserver. Retrying...": "No ha sido posible conectarse al servidor base. Volviéndolo a intentar…",
|
||||||
"%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s estableció la dirección principal para esta sala como %(address)s.",
|
"%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s estableció la dirección principal para esta sala como %(address)s.",
|
||||||
"%(senderName)s removed the main address for this room.": "%(senderName)s eliminó la dirección principal para esta sala.",
|
"%(senderName)s removed the main address for this room.": "%(senderName)s eliminó la dirección principal para esta sala.",
|
||||||
"%(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 ahora utiliza de 3 a 5 veces menos memoria, porque solo carga información sobre otros usuarios cuando es necesario. Por favor, ¡aguarda mientras volvemos a sincronizar con el servidor!",
|
"%(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 ahora utiliza de 3 a 5 veces menos memoria, porque solo carga información sobre otros usuarios cuando es necesario. Por favor, ¡aguarda mientras volvemos a sincronizar con el servidor!",
|
||||||
|
@ -879,7 +879,7 @@
|
||||||
"Phone numbers": "Números de teléfono",
|
"Phone numbers": "Números de teléfono",
|
||||||
"Email addresses": "Correos electrónicos",
|
"Email addresses": "Correos electrónicos",
|
||||||
"Language and region": "Idioma y región",
|
"Language and region": "Idioma y región",
|
||||||
"The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "El fichero %(fileName)s supera el tamaño límite del servidor para subidas",
|
"The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "El archivo «%(fileName)s» supera el tamaño límite del servidor para subidas",
|
||||||
"Unable to load! Check your network connectivity and try again.": "No se ha podido cargar. Comprueba tu conexión de red e inténtalo de nuevo.",
|
"Unable to load! Check your network connectivity and try again.": "No se ha podido cargar. Comprueba tu conexión de red e inténtalo de nuevo.",
|
||||||
"Failed to invite users to the room:": "Fallo al invitar usuarios a la sala:",
|
"Failed to invite users to the room:": "Fallo al invitar usuarios a la sala:",
|
||||||
"Upgrades a room to a new version": "Actualiza una sala a una nueva versión",
|
"Upgrades a room to a new version": "Actualiza una sala a una nueva versión",
|
||||||
|
@ -907,9 +907,9 @@
|
||||||
"Capitalization doesn't help very much": "Las mayúsculas no ayudan mucho",
|
"Capitalization doesn't help very much": "Las mayúsculas no ayudan mucho",
|
||||||
"All-uppercase is almost as easy to guess as all-lowercase": "Todo en mayúsculas es tan inseguro como todo en minúsculas",
|
"All-uppercase is almost as easy to guess as all-lowercase": "Todo en mayúsculas es tan inseguro como todo en minúsculas",
|
||||||
"Reversed words aren't much harder to guess": "Las palabras al revés no son muy dificiles de adivinar",
|
"Reversed words aren't much harder to guess": "Las palabras al revés no son muy dificiles de adivinar",
|
||||||
"Predictable substitutions like '@' instead of 'a' don't help very much": "Sustituciones predecibles como ''@' en vez de 'a' no ayudan mucho",
|
"Predictable substitutions like '@' instead of 'a' don't help very much": "Sustituciones predecibles como «@ en vez de 'a' no ayudan mucho",
|
||||||
"Add another word or two. Uncommon words are better.": "Añade una o dos palabras más. Palabras raras mejor.",
|
"Add another word or two. Uncommon words are better.": "Añade una o dos palabras más. Palabras raras mejor.",
|
||||||
"Repeats like \"aaa\" are easy to guess": "Repetición como 'aaa' son muy fáciles de adivinar",
|
"Repeats like \"aaa\" are easy to guess": "Los caracteres repetidos como «aaa» son muy fáciles de adivinar",
|
||||||
"Repeats like \"abcabcabc\" are only slightly harder to guess than \"abc\"": "Repeticiones como \"abcabcabc\" son solo ligeramente más difíciles de adivinar que \"abc\"",
|
"Repeats like \"abcabcabc\" are only slightly harder to guess than \"abc\"": "Repeticiones como \"abcabcabc\" son solo ligeramente más difíciles de adivinar que \"abc\"",
|
||||||
"Sequences like abc or 6543 are easy to guess": "Secuencias como abc or 6543 son faciles de adivinar",
|
"Sequences like abc or 6543 are easy to guess": "Secuencias como abc or 6543 son faciles de adivinar",
|
||||||
"Recent years are easy to guess": "Años recientes son fáciles de adivinar",
|
"Recent years are easy to guess": "Años recientes son fáciles de adivinar",
|
||||||
|
@ -923,7 +923,7 @@
|
||||||
"Common names and surnames are easy to guess": "Nombres y apellidos comunes son fáciles de adivinar",
|
"Common names and surnames are easy to guess": "Nombres y apellidos comunes son fáciles de adivinar",
|
||||||
"Straight rows of keys are easy to guess": "Palabras formadas por secuencias de teclas alineadas son fáciles de adivinar",
|
"Straight rows of keys are easy to guess": "Palabras formadas por secuencias de teclas alineadas son fáciles de adivinar",
|
||||||
"Short keyboard patterns are easy to guess": "Patrones de tecleo cortos son fáciles de adivinar",
|
"Short keyboard patterns are easy to guess": "Patrones de tecleo cortos son fáciles de adivinar",
|
||||||
"There was an error joining the room": "Hubo un error al unirse a la sala",
|
"There was an error joining the room": "Ha ocurrido un error al unirse a la sala",
|
||||||
"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",
|
||||||
|
@ -936,7 +936,7 @@
|
||||||
"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": "Activar emojis grandes en el chat",
|
"Enable big emoji in chat": "Activar 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 conexiones «peer-to-peer 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álidas",
|
"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",
|
||||||
|
@ -979,7 +979,7 @@
|
||||||
"Pizza": "Pizza",
|
"Pizza": "Pizza",
|
||||||
"Cake": "Tarta",
|
"Cake": "Tarta",
|
||||||
"Heart": "Corazón",
|
"Heart": "Corazón",
|
||||||
"Smiley": "Sonriente",
|
"Smiley": "Emoticono",
|
||||||
"Robot": "Robot",
|
"Robot": "Robot",
|
||||||
"Hat": "Sombrero",
|
"Hat": "Sombrero",
|
||||||
"Glasses": "Gafas",
|
"Glasses": "Gafas",
|
||||||
|
@ -1021,7 +1021,7 @@
|
||||||
"Unable to load key backup status": "No se pudo cargar el estado de la copia de la clave",
|
"Unable to load key backup status": "No se pudo cargar el estado de la copia de la clave",
|
||||||
"Restore from Backup": "Restaurar desde copia",
|
"Restore from Backup": "Restaurar desde copia",
|
||||||
"Back up your keys before signing out to avoid losing them.": "Haz copia de tus claves antes de salir para evitar perderlas.",
|
"Back up your keys before signing out to avoid losing them.": "Haz copia de tus claves antes de salir para evitar perderlas.",
|
||||||
"Backing up %(sessionsRemaining)s keys...": "Haciendo copia de %(sessionsRemaining)s claves...",
|
"Backing up %(sessionsRemaining)s keys...": "Haciendo copia de %(sessionsRemaining)s claves…",
|
||||||
"All keys backed up": "Se han copiado todas las claves",
|
"All keys backed up": "Se han copiado todas las claves",
|
||||||
"Backup version: ": "Versión de la copia: ",
|
"Backup version: ": "Versión de la copia: ",
|
||||||
"Algorithm: ": "Algoritmo: ",
|
"Algorithm: ": "Algoritmo: ",
|
||||||
|
@ -1032,11 +1032,11 @@
|
||||||
"Phone Number": "Número de teléfono",
|
"Phone Number": "Número de teléfono",
|
||||||
"Profile picture": "Foto de perfil",
|
"Profile picture": "Foto de perfil",
|
||||||
"Display Name": "Nombre a mostrar",
|
"Display Name": "Nombre a mostrar",
|
||||||
"Internal room ID:": "ID de Sala Interna:",
|
"Internal room ID:": "ID de sala Interna:",
|
||||||
"Open Devtools": "Abrir devtools",
|
"Open Devtools": "Abrir devtools",
|
||||||
"General": "General",
|
"General": "General",
|
||||||
"Room Addresses": "Direcciones de sala",
|
"Room Addresses": "Direcciones de sala",
|
||||||
"Set a new account password...": "Elegir una nueva contraseña para la cuenta...",
|
"Set a new account password...": "Cambiar la contraseña de tu cuenta…",
|
||||||
"Account management": "Gestión de la cuenta",
|
"Account management": "Gestión de la cuenta",
|
||||||
"Deactivating your account is a permanent action - be careful!": "Desactivar tu cuenta es permanente. ¡Cuidado!",
|
"Deactivating your account is a permanent action - be careful!": "Desactivar tu cuenta es permanente. ¡Cuidado!",
|
||||||
"Credits": "Créditos",
|
"Credits": "Créditos",
|
||||||
|
@ -1083,7 +1083,7 @@
|
||||||
"Incompatible Database": "Base de datos incompatible",
|
"Incompatible Database": "Base de datos incompatible",
|
||||||
"Continue With Encryption Disabled": "Seguir con cifrado desactivado",
|
"Continue With Encryption Disabled": "Seguir con cifrado desactivado",
|
||||||
"Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Verifica a este usuario para marcarlo como de confianza. Confiar en usuarios aporta tranquilidad en los mensajes cifrados de extremo a extremo.",
|
"Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Verifica a este usuario para marcarlo como de confianza. Confiar en usuarios aporta tranquilidad en los mensajes cifrados de extremo a extremo.",
|
||||||
"Waiting for partner to confirm...": "Esperando que confirme el compañero...",
|
"Waiting for partner to confirm...": "Esperando que confirme la otra parte…",
|
||||||
"Incoming Verification Request": "Petición de verificación entrante",
|
"Incoming Verification Request": "Petición de verificación entrante",
|
||||||
"%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s cambió la regla para unirse a %(rule)s",
|
"%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s cambió la regla para unirse a %(rule)s",
|
||||||
"%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s cambió el acceso para invitados a %(rule)s",
|
"%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s cambió el acceso para invitados a %(rule)s",
|
||||||
|
@ -1095,7 +1095,7 @@
|
||||||
"Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Uses o no las «migas de pan» (iconos sobre la lista de salas)",
|
"Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Uses o no las «migas de pan» (iconos sobre la lista de salas)",
|
||||||
"Replying With Files": "Respondiendo con archivos",
|
"Replying With Files": "Respondiendo con archivos",
|
||||||
"At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "En este momento no es posible responder con un archivo. ¿Te gustaría subir el archivo sin responder?",
|
"At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "En este momento no es posible responder con un archivo. ¿Te gustaría subir el archivo sin responder?",
|
||||||
"The file '%(fileName)s' failed to upload.": "La subida del archivo '%(fileName)s' ha fallado.",
|
"The file '%(fileName)s' failed to upload.": "La subida del archivo «%(fileName)s ha fallado.",
|
||||||
"The server does not support the room version specified.": "El servidor no soporta la versión de sala especificada.",
|
"The server does not support the room version specified.": "El servidor no soporta la versión de sala especificada.",
|
||||||
"Name or Matrix ID": "Nombre o ID de Matrix",
|
"Name or Matrix ID": "Nombre o ID de Matrix",
|
||||||
"Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Añade ¯\\_(ツ)_/¯ al principio de un mensaje de texto plano",
|
"Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Añade ¯\\_(ツ)_/¯ al principio de un mensaje de texto plano",
|
||||||
|
@ -1151,11 +1151,11 @@
|
||||||
"Add Phone Number": "Añadir número de teléfono",
|
"Add Phone Number": "Añadir número de teléfono",
|
||||||
"Identity server has no terms of service": "El servidor de identidad no tiene términos de servicio",
|
"Identity server has no terms of service": "El servidor de identidad no tiene términos de servicio",
|
||||||
"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.": "Esta acción necesita acceder al servidor de identidad por defecto <server /> para validar un correo o un teléfono, pero el servidor no tiene términos de servicio.",
|
"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.": "Esta acción necesita acceder al servidor de identidad por defecto <server /> para validar un correo o un teléfono, pero el servidor no tiene términos de servicio.",
|
||||||
"Only continue if you trust the owner of the server.": "Continúe solamente si confía en el propietario del servidor.",
|
"Only continue if you trust the owner of the server.": "Continúa solamente si confías en el propietario del servidor.",
|
||||||
"Trust": "Confianza",
|
"Trust": "Confiar",
|
||||||
"Custom (%(level)s)": "Personalizado (%(level)s)",
|
"Custom (%(level)s)": "Personalizado (%(level)s)",
|
||||||
"Error upgrading room": "Fallo al mejorar la sala",
|
"Error upgrading room": "Fallo al mejorar la sala",
|
||||||
"Double check that your server supports the room version chosen and try again.": "Asegúrese de que su servidor soporta la versión de sala elegida y pruebe otra vez.",
|
"Double check that your server supports the room version chosen and try again.": "Asegúrate de que tu servidor es compatible con la versión de sala elegida y prueba de nuevo.",
|
||||||
"%(senderName)s placed a voice call.": "%(senderName)s hizo una llamada de voz.",
|
"%(senderName)s placed a voice call.": "%(senderName)s hizo una llamada de voz.",
|
||||||
"%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s hizo una llamada de voz. (no soportada por este navegador)",
|
"%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s hizo una llamada de voz. (no soportada por este navegador)",
|
||||||
"%(senderName)s placed a video call.": "%(senderName)s hizo una llamada de vídeo.",
|
"%(senderName)s placed a video call.": "%(senderName)s hizo una llamada de vídeo.",
|
||||||
|
@ -1168,10 +1168,10 @@
|
||||||
"My Ban List": "Mi lista de baneos",
|
"My Ban List": "Mi lista de baneos",
|
||||||
"This is your list of users/servers you have blocked - don't leave the room!": "Esta es la lista de usuarios y/o servidores que has bloqueado. ¡No te salgas de la sala!",
|
"This is your list of users/servers you have blocked - don't leave the room!": "Esta es la lista de usuarios y/o servidores que has bloqueado. ¡No te salgas de la sala!",
|
||||||
"Decline (%(counter)s)": "Declinar (%(counter)s)",
|
"Decline (%(counter)s)": "Declinar (%(counter)s)",
|
||||||
"Accept <policyLink /> to continue:": "Aceptar <policyLink /> para continuar:",
|
"Accept <policyLink /> to continue:": "<policyLink />, acepta para continuar:",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"Public Name": "Nombre público",
|
"Public Name": "Nombre público",
|
||||||
"Connecting to integration manager...": "Conectando al gestor de integraciones...",
|
"Connecting to integration manager...": "Conectando al gestor de integraciones…",
|
||||||
"Cannot connect to integration manager": "No se puede conectar al gestor de integraciones",
|
"Cannot connect to integration manager": "No se puede conectar al gestor de integraciones",
|
||||||
"The integration manager is offline or it cannot reach your homeserver.": "El gestor de integraciones está desconectado o no puede conectar con su servidor.",
|
"The integration manager is offline or it cannot reach your homeserver.": "El gestor de integraciones está desconectado o no puede conectar con su servidor.",
|
||||||
"%(count)s unread messages including mentions.|other": "%(count)s mensajes sin leer incluyendo menciones.",
|
"%(count)s unread messages including mentions.|other": "%(count)s mensajes sin leer incluyendo menciones.",
|
||||||
|
@ -1184,7 +1184,7 @@
|
||||||
"You have %(count)s unread notifications in a prior version of this room.|other": "Tiene %(count)s notificaciones sin leer en una versión anterior de esta sala.",
|
"You have %(count)s unread notifications in a prior version of this room.|other": "Tiene %(count)s notificaciones sin leer en una versión anterior de esta sala.",
|
||||||
"You have %(count)s unread notifications in a prior version of this room.|one": "Tiene %(count)s notificaciones sin leer en una versión anterior de esta sala.",
|
"You have %(count)s unread notifications in a prior version of this room.|one": "Tiene %(count)s notificaciones sin leer en una versión anterior de esta sala.",
|
||||||
"Setting up keys": "Configurando claves",
|
"Setting up keys": "Configurando claves",
|
||||||
"Verify this session": "Verificar esta sesión",
|
"Verify this session": "Verifica esta sesión",
|
||||||
"Encryption upgrade available": "Mejora de cifrado disponible",
|
"Encryption upgrade available": "Mejora de cifrado disponible",
|
||||||
"Set up encryption": "Configurar la encriptación",
|
"Set up encryption": "Configurar la encriptación",
|
||||||
"Verifies a user, session, and pubkey tuple": "Verifica a un usuario, sesión y tupla de clave pública",
|
"Verifies a user, session, and pubkey tuple": "Verifica a un usuario, sesión y tupla de clave pública",
|
||||||
|
@ -1246,9 +1246,9 @@
|
||||||
"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 la nueva, dándole acceso a mensajes cifrados:",
|
"Use this session to verify your new one, granting it access to encrypted messages:": "Usa esta sesión para verificar la nueva, dándole acceso a los mensajes cifrados:",
|
||||||
"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 he sido 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.",
|
||||||
"Report bugs & give feedback": "Reportar errores y compartir mi opinión",
|
"Report bugs & give feedback": "Reportar errores y compartir mi opinión",
|
||||||
"Please fill why you're reporting.": "Por favor, explica por qué estás reportando.",
|
"Please fill why you're reporting.": "Por favor, explica por qué estás reportando.",
|
||||||
|
@ -1274,7 +1274,7 @@
|
||||||
"Be found by phone or email": "Ser encontrado por teléfono o email",
|
"Be found by phone or email": "Ser encontrado por teléfono o email",
|
||||||
"Use bots, bridges, widgets and sticker packs": "Usar robots, puentes, widgets, o packs de pegatinas",
|
"Use bots, bridges, widgets and sticker packs": "Usar robots, puentes, widgets, o packs de pegatinas",
|
||||||
"Terms of Service": "Términos de servicio",
|
"Terms of Service": "Términos de servicio",
|
||||||
"To continue you need to accept the terms of this service.": "Para continuar necesitas aceptar estos términos de servicio.",
|
"To continue you need to accept the terms of this service.": "Para continuar, necesitas aceptar estos términos de servicio.",
|
||||||
"Service": "Servicio",
|
"Service": "Servicio",
|
||||||
"Summary": "Resumen",
|
"Summary": "Resumen",
|
||||||
"Document": "Documento",
|
"Document": "Documento",
|
||||||
|
@ -1293,7 +1293,7 @@
|
||||||
"Remember my selection for this widget": "Recordar mi selección para este widget",
|
"Remember my selection for this widget": "Recordar mi selección para este widget",
|
||||||
"Deny": "Rechazar",
|
"Deny": "Rechazar",
|
||||||
"Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Tu contraseña ha sido cambiada satisfactoriamente. No recibirás notificaciones push en otras sesiones hasta que te conectes de nuevo a ellas",
|
"Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Tu contraseña ha sido cambiada satisfactoriamente. No recibirás notificaciones push en otras sesiones hasta que te conectes de nuevo a ellas",
|
||||||
"Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Aceptar los Términos de Servicio del servidor de identidad %(serverName)s para poder ser descubierto por dirección de email o número de teléfono.",
|
"Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Acepta los términos de servicio del servidor de identidad %(serverName)s para poder ser encontrado por dirección de correo electrónico o número de teléfono.",
|
||||||
"Discovery": "Descubrimiento",
|
"Discovery": "Descubrimiento",
|
||||||
"Deactivate account": "Desactivar cuenta",
|
"Deactivate account": "Desactivar cuenta",
|
||||||
"Clear cache and reload": "Limpiar caché y recargar",
|
"Clear cache and reload": "Limpiar caché y recargar",
|
||||||
|
@ -1314,7 +1314,7 @@
|
||||||
"⚠ These settings are meant for advanced users.": "⚠ Estas opciones son indicadas para usuarios avanzados.",
|
"⚠ These settings are meant for advanced users.": "⚠ Estas opciones son indicadas para usuarios avanzados.",
|
||||||
"Personal ban list": "Lista de bloqueo personal",
|
"Personal ban list": "Lista de bloqueo personal",
|
||||||
"Server or user ID to ignore": "Servidor o ID de usuario a ignorar",
|
"Server or user ID to ignore": "Servidor o ID de usuario a ignorar",
|
||||||
"eg: @bot:* or example.org": "p. ej.: @bot:* o ejemplo.org",
|
"eg: @bot:* or example.org": "ej.: @bot:* o ejemplo.org",
|
||||||
"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.",
|
||||||
|
@ -1350,12 +1350,12 @@
|
||||||
"Never send encrypted messages to unverified sessions in this room from this session": "No enviar nunca mensajes cifrados a sesiones sin verificar en esta sala desde esta sesión",
|
"Never send encrypted messages to unverified sessions in this room from this session": "No enviar nunca mensajes cifrados a sesiones sin verificar en esta sala desde esta sesión",
|
||||||
"Enable message search in encrypted rooms": "Activar la búsqueda de mensajes en salas cifradas",
|
"Enable message search in encrypted rooms": "Activar la búsqueda de mensajes en salas cifradas",
|
||||||
"How fast should messages be downloaded.": "Con qué rapidez deben ser descargados los mensajes.",
|
"How fast should messages be downloaded.": "Con qué rapidez deben ser descargados los mensajes.",
|
||||||
"Verify this session by completing one of the following:": "Verifica esta sesión completando uno de los siguientes:",
|
"Verify this session by completing one of the following:": "Verifica esta sesión de una de las siguientes formas:",
|
||||||
"Scan this unique code": "Escanea este código único",
|
"Scan this unique code": "Escanea este código único",
|
||||||
"or": "o",
|
"or": "o",
|
||||||
"Compare unique emoji": "Comparar emoji único",
|
"Compare unique emoji": "Comparar iconos",
|
||||||
"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 iconos si no tienes cámara en ninguno de los dispositivos",
|
||||||
"Start": "Inicio",
|
"Start": "Empezar",
|
||||||
"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",
|
||||||
|
@ -1472,9 +1472,9 @@
|
||||||
"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 tu servidor base no lo ofrezca (tu 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 tu servidor base no lo ofrezca (tu 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": "Verificar 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 iconos de abajo se muestran en el mismo orden en ambas sesiones:",
|
||||||
"Verify this session by confirming the following number appears on its screen.": "Verifica 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.": "Verifica 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 la otra sesión lo verifique también %(deviceName)s (%(deviceId)s)…",
|
||||||
"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",
|
||||||
|
@ -1515,12 +1515,12 @@
|
||||||
"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.": "Esta sesión no <b> ha creado una copia de seguridad de tus llaves</b>, pero tienes una copia de seguridad existente de la que puedes restaurar y añadir para proceder.",
|
"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.": "Esta sesión no <b> ha creado una copia de seguridad de tus llaves</b>, pero tienes una copia de seguridad existente de la que puedes restaurar y añadir para proceder.",
|
||||||
"Connect this session to key backup before signing out to avoid losing any keys that may only be on this session.": "Conecte esta sesión a la copia de seguridad de las claves antes de firmar y así evitar perder las claves que sólo existen en esta sesión.",
|
"Connect this session to key backup before signing out to avoid losing any keys that may only be on this session.": "Conecte esta sesión a la copia de seguridad de las claves antes de firmar y así evitar perder las claves que sólo existen en esta sesión.",
|
||||||
"Connect this session to Key Backup": "Conecte esta sesión a la copia de respaldo de tu clave",
|
"Connect this session to Key Backup": "Conecte esta sesión a la copia de respaldo de tu clave",
|
||||||
"Backup has a <validity>valid</validity> signature from this user": "La copia de seguridad tiene una firma de <validity>valido</validity> de este usuario",
|
"Backup has a <validity>valid</validity> signature from this user": "La copia de seguridad tiene una firma <validity>válida</validity> de este usuario",
|
||||||
"Backup has a <validity>invalid</validity> signature from this user": "La copia de seguridad tiene una firma de <validity>no_valida</validity> de este usuario",
|
"Backup has a <validity>invalid</validity> signature from this user": "La copia de seguridad tiene una firma <validity>inválida</validity> de este usuario",
|
||||||
"Backup has a signature from <verify>unknown</verify> user with ID %(deviceId)s": "La copia de seguridad tiene una firma de <verify>desconocido</verify> del usuario con ID %(deviceId)s",
|
"Backup has a signature from <verify>unknown</verify> user with ID %(deviceId)s": "La copia de seguridad tiene una firma <verify>desconocida</verify> del usuario con ID %(deviceId)s",
|
||||||
"Backup has a signature from <verify>unknown</verify> session with ID %(deviceId)s": "La copia de seguridad tiene una firma de <verify>desconocido</verify> de la sesión con ID %(deviceId)s",
|
"Backup has a signature from <verify>unknown</verify> session with ID %(deviceId)s": "La copia de seguridad tiene una firma de <verify>desconocido</verify> de la sesión con ID %(deviceId)s",
|
||||||
"Backup has a <validity>valid</validity> signature from this session": "La copia de seguridad tiene una firma <validity>válida</validity> de esta sesión",
|
"Backup has a <validity>valid</validity> signature from this session": "La copia de seguridad tiene una firma <validity>válida</validity> de esta sesión",
|
||||||
"Backup has an <validity>invalid</validity> signature from this session": "La copia de seguridad tiene una firma <validity>no_válida</validity> de esta sesión",
|
"Backup has an <validity>invalid</validity> signature from this session": "La copia de seguridad tiene una firma <validity>inválida</validity> de esta sesión",
|
||||||
"Backup has a <validity>valid</validity> signature from <verify>verified</verify> session <device></device>": "La copia de seguridad tiene una firma <validity>válida</validity> de <verify>verificada</verify> sesión <device></device>",
|
"Backup has a <validity>valid</validity> signature from <verify>verified</verify> session <device></device>": "La copia de seguridad tiene una firma <validity>válida</validity> de <verify>verificada</verify> sesión <device></device>",
|
||||||
"Backup has a <validity>valid</validity> signature from <verify>unverified</verify> session <device></device>": "La copia de seguridad tiene una firma de <validity>válida</validity> de sesión <verify>no verificada</verify> <device></device>",
|
"Backup has a <validity>valid</validity> signature from <verify>unverified</verify> session <device></device>": "La copia de seguridad tiene una firma de <validity>válida</validity> de sesión <verify>no verificada</verify> <device></device>",
|
||||||
"Backup has an <validity>invalid</validity> signature from <verify>verified</verify> session <device></device>": "La copia de seguridad tiene una firma de <validity>no válida</validity> de sesión <verify>verificada</verify> <device></device>",
|
"Backup has an <validity>invalid</validity> signature from <verify>verified</verify> session <device></device>": "La copia de seguridad tiene una firma de <validity>no válida</validity> de sesión <verify>verificada</verify> <device></device>",
|
||||||
|
@ -1574,7 +1574,7 @@
|
||||||
"This room isn’t bridging messages to any platforms. <a>Learn more.</a>": "Esta sala no está haciendo puente con ninguna plataforma. <a>Aprende más</a>",
|
"This room isn’t bridging messages to any platforms. <a>Learn more.</a>": "Esta sala no está haciendo puente con ninguna plataforma. <a>Aprende más</a>",
|
||||||
"Bridges": "Puentes",
|
"Bridges": "Puentes",
|
||||||
"Uploaded sound": "Sonido subido",
|
"Uploaded sound": "Sonido subido",
|
||||||
"Reset": "Resetear",
|
"Reset": "Restablecer",
|
||||||
"Unable to revoke sharing for email address": "No se logró revocar el compartir para la dirección de correo electrónico",
|
"Unable to revoke sharing for email address": "No se logró revocar el compartir para la dirección de correo electrónico",
|
||||||
"Unable to share email address": "No se logró compartir la dirección de correo electrónico",
|
"Unable to share email address": "No se logró compartir la dirección de correo electrónico",
|
||||||
"Click the link in the email you received to verify and then click continue again.": "Haz clic en el enlace del correo electrónico para verificar, y luego nuevamente haz clic en continuar.",
|
"Click the link in the email you received to verify and then click continue again.": "Haz clic en el enlace del correo electrónico para verificar, y luego nuevamente haz clic en continuar.",
|
||||||
|
@ -1585,7 +1585,7 @@
|
||||||
"Please enter verification code sent via text.": "Por favor, introduce el código de verificación enviado por SMS.",
|
"Please enter verification code sent via text.": "Por favor, introduce el código de verificación enviado por SMS.",
|
||||||
"Discovery options will appear once you have added a phone number above.": "Las opciones de descubrimiento aparecerán una vez que haya añadido un número de teléfono arriba.",
|
"Discovery options will appear once you have added a phone number above.": "Las opciones de descubrimiento aparecerán una vez que haya añadido un número de teléfono arriba.",
|
||||||
"Remove %(phone)s?": "¿Eliminar %(phone)s?",
|
"Remove %(phone)s?": "¿Eliminar %(phone)s?",
|
||||||
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "Se ha enviado un mensaje de texto a +%(msisdn)s. Por favor, introduzca el código de verificación que contiene.",
|
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "Se ha enviado un mensaje de texto a +%(msisdn)s. Por favor, escribe el código de verificación que contiene.",
|
||||||
"This user has not verified all of their sessions.": "Este usuario no ha verificado todas sus sesiones.",
|
"This user has not verified all of their sessions.": "Este usuario no ha verificado todas sus sesiones.",
|
||||||
"You have not verified this user.": "No has verificado a este usuario.",
|
"You have not verified this user.": "No has verificado a este usuario.",
|
||||||
"You have verified this user. This user has verified all of their sessions.": "Usted ha verificado este usuario. Este usuario ha verificado todas sus sesiones.",
|
"You have verified this user. This user has verified all of their sessions.": "Usted ha verificado este usuario. Este usuario ha verificado todas sus sesiones.",
|
||||||
|
@ -1609,9 +1609,9 @@
|
||||||
"e.g. my-room": "p.ej. mi-sala",
|
"e.g. my-room": "p.ej. mi-sala",
|
||||||
"Some characters not allowed": "Algunos caracteres no están permitidos",
|
"Some characters not allowed": "Algunos caracteres no están permitidos",
|
||||||
"Sign in with single sign-on": "Ingresar con un Registro Único",
|
"Sign in with single sign-on": "Ingresar con un Registro Único",
|
||||||
"Enter a server name": "Introduzca un nombre de servidor",
|
"Enter a server name": "Introduce un nombre de servidor",
|
||||||
"Looks good": "Se ve bien",
|
"Looks good": "Se ve bien",
|
||||||
"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 se ha podido 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ás seguro de querer eliminar <b>%(serverName)s</b>?",
|
"Are you sure you want to remove <b>%(serverName)s</b>": "¿Estás seguro de querer eliminar <b>%(serverName)s</b>?",
|
||||||
|
@ -1620,15 +1620,15 @@
|
||||||
"Add a new server": "Añadir un nuevo servidor",
|
"Add a new server": "Añadir un nuevo servidor",
|
||||||
"Enter the name of a new server you want to explore.": "Introduce el nombre de un nuevo servidor que quieras explorar.",
|
"Enter the name of a new server you want to explore.": "Introduce el nombre de un nuevo servidor que quieras explorar.",
|
||||||
"Server name": "Nombre del servidor",
|
"Server name": "Nombre del servidor",
|
||||||
"Add a new server...": "Añade un nuevo servidor ...",
|
"Add a new server...": "Añadir otro servidor…",
|
||||||
"%(networkName)s rooms": "%(networkName)s sala",
|
"%(networkName)s rooms": "%(networkName)s sala",
|
||||||
"Matrix rooms": "Salas de Matrix",
|
"Matrix rooms": "Salas de Matrix",
|
||||||
"Use an identity server to invite by email. <default>Use the default (%(defaultIdentityServerName)s)</default> or manage in <settings>Settings</settings>.": "Usar un servidor de identidad para invitar vía correo electrónico. <default>. Usar (%(defaultIdentityServerName)s)</default>o seleccione en <settings>Ajustes</settings>.",
|
"Use an identity server to invite by email. <default>Use the default (%(defaultIdentityServerName)s)</default> or manage in <settings>Settings</settings>.": "Usar un servidor de identidad para invitar vía correo electrónico. <default>. Usar (%(defaultIdentityServerName)s)</default>o seleccione en <settings>Ajustes</settings>.",
|
||||||
"Use an identity server to invite by email. Manage in <settings>Settings</settings>.": "Utilice un servidor de identidad para invitar por correo electrónico. Gestionar en <settings>Ajustes</settings>.",
|
"Use an identity server to invite by email. Manage in <settings>Settings</settings>.": "Utilice un servidor de identidad para invitar por correo electrónico. Gestionar en <settings>Ajustes</settings>.",
|
||||||
"Close dialog": "Cerrar diálogo",
|
"Close dialog": "Cerrar diálogo",
|
||||||
"Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "Por favor, díganos qué salió mal o, mejor aún, cree un reporte de GitHub que describa el problema.",
|
"Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "Por favor, cuéntanos qué ha ido mal o, mejor aún, cree una incidencia en GitHub que describa el problema.",
|
||||||
"Reminder: Your browser is unsupported, so your experience may be unpredictable.": "Recordatorio: Su navegador no es compatible, por lo que su experiencia puede ser impredecible.",
|
"Reminder: Your browser is unsupported, so your experience may be unpredictable.": "Recordatorio: Su navegador no es compatible, por lo que su experiencia puede ser impredecible.",
|
||||||
"GitHub issue": "reporte GitHub",
|
"GitHub issue": "Incidencia de GitHub",
|
||||||
"Notes": "Notas",
|
"Notes": "Notas",
|
||||||
"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.": "Si hay algún contexto adicional que ayude a analizar el tema, como por ejemplo lo que estaba haciendo en ese momento, nombre (ID) de sala, nombre (ID)de usuario, etc., por favor incluya esas cosas aquí.",
|
"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.": "Si hay algún contexto adicional que ayude a analizar el tema, como por ejemplo lo que estaba haciendo en ese momento, nombre (ID) de sala, nombre (ID)de usuario, etc., por favor incluya esas cosas aquí.",
|
||||||
"Removing…": "Quitando…",
|
"Removing…": "Quitando…",
|
||||||
|
@ -1638,14 +1638,14 @@
|
||||||
"Clear all data in this session?": "¿Borrar todos los datos en esta sesión?",
|
"Clear all data in this session?": "¿Borrar todos los datos en esta sesión?",
|
||||||
"Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "La eliminación de todos los datos de esta sesión es definitiva. Los mensajes cifrados se perderán, a menos que se haya hecho una copia de seguridad de sus claves.",
|
"Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "La eliminación de todos los datos de esta sesión es definitiva. Los mensajes cifrados se perderán, a menos que se haya hecho una copia de seguridad de sus claves.",
|
||||||
"Clear all data": "Borrar todos los datos",
|
"Clear all data": "Borrar todos los datos",
|
||||||
"Please enter a name for the room": "Por favor, introduzca un nombre para la sala",
|
"Please enter a name for the room": "Elige un nombre para la sala",
|
||||||
"This room is private, and can only be joined by invitation.": "Esta sala es privada, y sólo se puede acceder a ella por invitación.",
|
"This room is private, and can only be joined by invitation.": "Esta sala es privada, y sólo se puede acceder a ella por invitación.",
|
||||||
"Enable end-to-end encryption": "Activar el cifrado de extremo a extremo",
|
"Enable end-to-end encryption": "Activar el cifrado de extremo a extremo",
|
||||||
"You can’t disable this later. Bridges & most bots won’t work yet.": "No puedes desactivar esto después. Los puentes y la mayoría de los bots no funcionarán todavía.",
|
"You can’t disable this later. Bridges & most bots won’t work yet.": "No puedes desactivar esto después. Los puentes y la mayoría de los bots no funcionarán todavía.",
|
||||||
"Create a public room": "Crear una sala pública",
|
"Create a public room": "Crear una sala pública",
|
||||||
"Create a private room": "Crear una sala privada",
|
"Create a private room": "Crear una sala privada",
|
||||||
"Topic (optional)": "Tema (opcional)",
|
"Topic (optional)": "Tema (opcional)",
|
||||||
"Make this room public": "Haz la sala pública",
|
"Make this room public": "Hacer la sala pública",
|
||||||
"Hide advanced": "Ocultar ajustes avanzados",
|
"Hide advanced": "Ocultar ajustes avanzados",
|
||||||
"Show advanced": "Mostrar ajustes avanzados",
|
"Show advanced": "Mostrar ajustes avanzados",
|
||||||
"Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "Evitar que usuarios de otros servidores Matrix se unan a esta sala (¡Este ajuste no puede ser cambiada más tarde!)",
|
"Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "Evitar que usuarios de otros servidores Matrix se unan a esta sala (¡Este ajuste no puede ser cambiada más tarde!)",
|
||||||
|
@ -1692,7 +1692,7 @@
|
||||||
"You can only join it with a working invite.": "Sólo puedes unirte con una invitación que funciona.",
|
"You can only join it with a working invite.": "Sólo puedes unirte con una invitación que funciona.",
|
||||||
"Try to join anyway": "Intentar unirse de todas formas",
|
"Try to join anyway": "Intentar unirse de todas formas",
|
||||||
"You can still join it because this is a public room.": "Todavía puedes unirte, ya que es una sala pública.",
|
"You can still join it because this is a public room.": "Todavía puedes unirte, ya que es una sala pública.",
|
||||||
"Join the discussion": "Unirse a la sala",
|
"Join the discussion": "Unirme a la Sala",
|
||||||
"Do you want to chat with %(user)s?": "¿Quieres chatear con %(user)s?",
|
"Do you want to chat with %(user)s?": "¿Quieres chatear con %(user)s?",
|
||||||
"Do you want to join %(roomName)s?": "¿Quieres unirte a %(roomName)s?",
|
"Do you want to join %(roomName)s?": "¿Quieres unirte a %(roomName)s?",
|
||||||
"<userName/> invited you": "<userName/> te ha invitado",
|
"<userName/> invited you": "<userName/> te ha invitado",
|
||||||
|
@ -1746,8 +1746,8 @@
|
||||||
"This room is running room version <roomVersion />, which this homeserver has marked as <i>unstable</i>.": "Esta sala está ejecutando la versión de sala <roomVersion />, la cual ha sido marcado por este servidor base como <i>inestable</i>.",
|
"This room is running room version <roomVersion />, which this homeserver has marked as <i>unstable</i>.": "Esta sala está ejecutando la versión de sala <roomVersion />, la cual ha sido marcado por este servidor base como <i>inestable</i>.",
|
||||||
"Unknown Command": "Comando desconocido",
|
"Unknown Command": "Comando desconocido",
|
||||||
"Unrecognised command: %(commandText)s": "Comando no reconocido: %(commandText)s",
|
"Unrecognised command: %(commandText)s": "Comando no reconocido: %(commandText)s",
|
||||||
"You can use <code>/help</code> to list available commands. Did you mean to send this as a message?": "Puedes usar <code>/ayuda</code> para listar los comandos disponibles. ¿Querías enviarlo como un mensaje?",
|
"You can use <code>/help</code> to list available commands. Did you mean to send this as a message?": "Puedes usar <code>/help</code> para ver los comandos disponibles. ¿Querías enviarlo como mensaje?",
|
||||||
"Hint: Begin your message with <code>//</code> to start it with a slash.": "Sugerencia: Comienza tu mensaje con <code>//</code> para que inicie con una barra inclinada.",
|
"Hint: Begin your message with <code>//</code> to start it with a slash.": "Sugerencia: empieza tu mensaje con <code>//</code> para que inicie con una barra inclinada.",
|
||||||
"Send as message": "Enviar como mensaje",
|
"Send as message": "Enviar como mensaje",
|
||||||
"Failed to connect to integration manager": "Error al conectarse con el administrador de integración",
|
"Failed to connect to integration manager": "Error al conectarse con el administrador de integración",
|
||||||
"Failed to revoke invite": "Error al revocar la invitación",
|
"Failed to revoke invite": "Error al revocar la invitación",
|
||||||
|
@ -1760,7 +1760,7 @@
|
||||||
"There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "Hubo un error al actualizar la dirección alternativa de la sala. Posiblemente el servidor no lo permita o se produjo un error temporal.",
|
"There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "Hubo un error al actualizar la dirección alternativa de la sala. Posiblemente el servidor no lo permita o se produjo un error temporal.",
|
||||||
"Local address": "Dirección local",
|
"Local address": "Dirección local",
|
||||||
"Published Addresses": "Direcciones publicadas",
|
"Published Addresses": "Direcciones publicadas",
|
||||||
"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.": "Las direcciones publicadas pueden ser usadas por cualquier usuario en cualquier servidor para unirse a tu salas. Para publicar una dirección, primero hay que establecerla como dirección local.",
|
"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.": "Las direcciones publicadas pueden ser usadas por cualquier usuario en cualquier servidor para unirse. Para publicar una dirección, primero hay que añadirla como dirección local.",
|
||||||
"Other published addresses:": "Otras direcciones publicadas:",
|
"Other published addresses:": "Otras direcciones publicadas:",
|
||||||
"No other published addresses yet, add one below": "Todavía no hay direcciones publicadas, puedes añadir una más abajo",
|
"No other published addresses yet, add one below": "Todavía no hay direcciones publicadas, puedes añadir una más abajo",
|
||||||
"New published address (e.g. #alias:server)": "Nueva dirección publicada (p.ej.. #alias:server)",
|
"New published address (e.g. #alias:server)": "Nueva dirección publicada (p.ej.. #alias:server)",
|
||||||
|
@ -1806,7 +1806,7 @@
|
||||||
"Almost there! Is %(displayName)s showing the same shield?": "¡Ya casi está! ¿Está %(displayName)s mostrando el mismo escudo?",
|
"Almost there! Is %(displayName)s showing the same shield?": "¡Ya casi está! ¿Está %(displayName)s mostrando el mismo escudo?",
|
||||||
"Verify all users in a room to ensure it's secure.": "Verifica a todos los usuarios de una sala para asegurar que es segura.",
|
"Verify all users in a room to ensure it's secure.": "Verifica a todos los usuarios de una sala para asegurar que es segura.",
|
||||||
"In encrypted rooms, verify all users to ensure it’s secure.": "En las salas cifrar, verificar a todos los usuarios para asegurarse de son seguras.",
|
"In encrypted rooms, verify all users to ensure it’s secure.": "En las salas cifrar, verificar a todos los usuarios para asegurarse de son seguras.",
|
||||||
"You've successfully verified %(deviceName)s (%(deviceId)s)!": "¡Has verificado con éxito los %(deviceName)s (%(deviceId)s)!",
|
"You've successfully verified %(deviceName)s (%(deviceId)s)!": "Has verificado con éxito %(deviceName)s (%(deviceId)s)",
|
||||||
"You've successfully verified %(displayName)s!": "¡Has verificado con éxito a %(displayName)s!",
|
"You've successfully verified %(displayName)s!": "¡Has verificado con éxito a %(displayName)s!",
|
||||||
"Verified": "Verificado",
|
"Verified": "Verificado",
|
||||||
"Got it": "Aceptar",
|
"Got it": "Aceptar",
|
||||||
|
@ -1825,7 +1825,7 @@
|
||||||
"React": "Reaccionar",
|
"React": "Reaccionar",
|
||||||
"Message Actions": "Acciones de mensaje",
|
"Message Actions": "Acciones de mensaje",
|
||||||
"Show image": "Mostrar imagen",
|
"Show image": "Mostrar imagen",
|
||||||
"You have ignored this user, so their message is hidden. <a>Show anyways.</a>": "Ha ignorado a este usuario, así que su mensaje se ha ocultado. <a>Mostrar de todos modos.</a>",
|
"You have ignored this user, so their message is hidden. <a>Show anyways.</a>": "Ha ignorado a esta cuenta, así que su mensaje está oculto. <a>Ver de todos modos.</a>",
|
||||||
"You verified %(name)s": "Has verificado a %(name)s",
|
"You verified %(name)s": "Has verificado a %(name)s",
|
||||||
"You cancelled verifying %(name)s": "Has cancelado la verificación de %(name)s",
|
"You cancelled verifying %(name)s": "Has cancelado la verificación de %(name)s",
|
||||||
"%(name)s cancelled verifying": "%(name)s canceló la verificación",
|
"%(name)s cancelled verifying": "%(name)s canceló la verificación",
|
||||||
|
@ -1847,7 +1847,7 @@
|
||||||
"Message deleted by %(name)s": "Mensaje eliminado por %(name)s",
|
"Message deleted by %(name)s": "Mensaje eliminado por %(name)s",
|
||||||
"Edited at %(date)s. Click to view edits.": "Editado el día %(date)s. Haz clic para ver las ediciones.",
|
"Edited at %(date)s. Click to view edits.": "Editado el día %(date)s. Haz clic para ver las ediciones.",
|
||||||
"edited": "editado",
|
"edited": "editado",
|
||||||
"Can't load this message": "No puedo cargar este mensaje",
|
"Can't load this message": "No se ha podido cargar este mensaje",
|
||||||
"Submit logs": "Enviar registros",
|
"Submit logs": "Enviar registros",
|
||||||
"Frequently Used": "Frecuente",
|
"Frequently Used": "Frecuente",
|
||||||
"Smileys & People": "Caritas y personas",
|
"Smileys & People": "Caritas y personas",
|
||||||
|
@ -1866,7 +1866,7 @@
|
||||||
"Your user ID": "Tu ID de usuario",
|
"Your user ID": "Tu ID de usuario",
|
||||||
"Your theme": "Su tema",
|
"Your theme": "Su tema",
|
||||||
"%(brand)s URL": "URL de %(brand)s",
|
"%(brand)s URL": "URL de %(brand)s",
|
||||||
"Room ID": "Identidad (ID) de la sala",
|
"Room ID": "ID de la sala",
|
||||||
"Widget ID": "ID del widget",
|
"Widget ID": "ID del widget",
|
||||||
"Using this widget may share data <helpIcon /> with %(widgetDomain)s & your Integration Manager.": "Usar este widget puede resultar en que se compartan datos <helpIcon /> con %(widgetDomain)s y su administrador de integración.",
|
"Using this widget may share data <helpIcon /> with %(widgetDomain)s & your Integration Manager.": "Usar este widget puede resultar en que se compartan datos <helpIcon /> con %(widgetDomain)s y su administrador de integración.",
|
||||||
"Using this widget may share data <helpIcon /> with %(widgetDomain)s.": "Usar este widget puede resultar en que se compartan datos <helpIcon /> con %(widgetDomain)s.",
|
"Using this widget may share data <helpIcon /> with %(widgetDomain)s.": "Usar este widget puede resultar en que se compartan datos <helpIcon /> con %(widgetDomain)s.",
|
||||||
|
@ -1881,7 +1881,7 @@
|
||||||
"Cancelled signature upload": "Subida de firma cancelada",
|
"Cancelled signature upload": "Subida de firma cancelada",
|
||||||
"Unable to upload": "No se puede subir",
|
"Unable to upload": "No se puede subir",
|
||||||
"Signature upload success": "Subida de firma exitosa",
|
"Signature upload success": "Subida de firma exitosa",
|
||||||
"Signature upload failed": "Subida de firma falló",
|
"Signature upload failed": "Subida de firma ha fallado",
|
||||||
"Confirm by comparing the following with the User Settings in your other session:": "Confirme comparando lo siguiente con los ajustes de usuario de su otra sesión:",
|
"Confirm by comparing the following with the User Settings in your other session:": "Confirme comparando lo siguiente con los ajustes de usuario de su otra sesión:",
|
||||||
"Confirm this user's session by comparing the following with their User Settings:": "Confirma la sesión de este usuario comparando lo siguiente con su configuración:",
|
"Confirm this user's session by comparing the following with their User Settings:": "Confirma la sesión de este usuario comparando lo siguiente con su configuración:",
|
||||||
"If they don't match, the security of your communication may be compromised.": "Si no coinciden, la seguridad de su comunicación puede estar comprometida.",
|
"If they don't match, the security of your communication may be compromised.": "Si no coinciden, la seguridad de su comunicación puede estar comprometida.",
|
||||||
|
@ -1892,7 +1892,7 @@
|
||||||
"The internet connection either session is using": "La conexión a Internet usado por cualquiera de las dos sesiones",
|
"The internet connection either session is using": "La conexión a Internet usado por cualquiera de las dos sesiones",
|
||||||
"We recommend you change your password and recovery key in Settings immediately": "Le recomendamos que cambie inmediatamente su contraseña y su clave de recuperación en Configuración",
|
"We recommend you change your password and recovery key in Settings immediately": "Le recomendamos que cambie inmediatamente su contraseña y su clave de recuperación en Configuración",
|
||||||
"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.": "Para ayudar a evitar la duplicación de entradas, por favor <existingIssuesLink> ver primero los entradas existentes</existingIssuesLink> (y añadir un +1) o, <newIssueLink> si no lo encuentra, crear una nueva entrada </newIssueLink>.",
|
"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.": "Para ayudar a evitar la duplicación de entradas, por favor <existingIssuesLink> ver primero los entradas existentes</existingIssuesLink> (y añadir un +1) o, <newIssueLink> si no lo encuentra, crear una nueva entrada </newIssueLink>.",
|
||||||
"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.": "Reportar este mensaje enviará su único 'event ID' al administrador de tu servidor base. Si los mensajes en esta sala están cifrados, el administrador de tu servidor no podrá leer el texto del mensaje ni ver ningún archivo o imagen.",
|
"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.": "Reportar este mensaje enviará su único «event ID al administrador de tu servidor base. Si los mensajes en esta sala están cifrados, el administrador de tu servidor no podrá leer el texto del mensaje ni ver ningún archivo o imagen.",
|
||||||
"Command Help": "Ayuda del comando",
|
"Command Help": "Ayuda del comando",
|
||||||
"Integration Manager": "Administrador de integración",
|
"Integration Manager": "Administrador de integración",
|
||||||
"Verify other session": "Verificar otra sesión",
|
"Verify other session": "Verificar otra sesión",
|
||||||
|
@ -1904,7 +1904,7 @@
|
||||||
"This looks like a valid recovery key!": "¡Esto tiene pinta de una llave de recuperación válida!",
|
"This looks like a valid recovery key!": "¡Esto tiene pinta de una llave de recuperación válida!",
|
||||||
"Not a valid recovery key": "Clave de recuperación no válida",
|
"Not a valid recovery key": "Clave de recuperación no válida",
|
||||||
"Restoring keys from backup": "Restaurando las claves desde copia de seguridad",
|
"Restoring keys from backup": "Restaurando las claves desde copia de seguridad",
|
||||||
"Fetching keys from server...": "Obteniendo las claves desde el servidor...",
|
"Fetching keys from server...": "Obteniendo las claves desde el servido…",
|
||||||
"%(completed)s of %(total)s keys restored": "%(completed)s de %(total)s llaves restauradas",
|
"%(completed)s of %(total)s keys restored": "%(completed)s de %(total)s llaves restauradas",
|
||||||
"Unable to load backup status": "No se puede cargar el estado de la copia de seguridad",
|
"Unable to load backup status": "No se puede cargar el estado de la copia de seguridad",
|
||||||
"Recovery key mismatch": "No coincide la clave de recuperación",
|
"Recovery key mismatch": "No coincide la clave de recuperación",
|
||||||
|
@ -1931,7 +1931,7 @@
|
||||||
"Clear status": "Borrar estado",
|
"Clear status": "Borrar estado",
|
||||||
"Update status": "Actualizar estado",
|
"Update status": "Actualizar estado",
|
||||||
"Set status": "Cambiar estado",
|
"Set status": "Cambiar estado",
|
||||||
"Set a new status...": "Elegir un estado nuevo...",
|
"Set a new status...": "Elegir un nuevo estado…",
|
||||||
"Hide": "Ocultar",
|
"Hide": "Ocultar",
|
||||||
"Help": "Ayuda",
|
"Help": "Ayuda",
|
||||||
"Reload": "Recargar",
|
"Reload": "Recargar",
|
||||||
|
@ -1954,12 +1954,12 @@
|
||||||
"Not sure of your password? <a>Set a new one</a>": "¿No estás seguro de tu contraseña? <a>Escoge una nueva</a>",
|
"Not sure of your password? <a>Set a new one</a>": "¿No estás seguro de tu contraseña? <a>Escoge una nueva</a>",
|
||||||
"No identity server is configured so you cannot add an email address in order to reset your password in the future.": "No se ha configurado ningún servidor de identidad, por lo que no se puede añadir una dirección de correo electrónico para restablecer la contraseña en el futuro.",
|
"No identity server is configured so you cannot add an email address in order to reset your password in the future.": "No se ha configurado ningún servidor de identidad, por lo que no se puede añadir una dirección de correo electrónico para restablecer la contraseña en el futuro.",
|
||||||
"Use an email address to recover your account": "Utilice una dirección de correo electrónico para recuperar su cuenta",
|
"Use an email address to recover your account": "Utilice una dirección de correo electrónico para recuperar su cuenta",
|
||||||
"Enter email address (required on this homeserver)": "Introduzca una dirección de correo electrónico (requerida en este servidor)",
|
"Enter email address (required on this homeserver)": "Introduce una dirección de correo electrónico (obligatorio en este servidor)",
|
||||||
"Doesn't look like a valid email address": "No parece una dirección de correo electrónico válida",
|
"Doesn't look like a valid email address": "No parece una dirección de correo electrónico válida",
|
||||||
"Enter password": "Introduzca su contraseña",
|
"Enter password": "Escribe tu contraseña",
|
||||||
"Password is allowed, but unsafe": "Contraseña permitida, pero no es segura",
|
"Password is allowed, but unsafe": "Contraseña permitida, pero no es segura",
|
||||||
"Nice, strong password!": "¡Fantástico, una contraseña fuerte!",
|
"Nice, strong password!": "¡Fantástico, una contraseña fuerte!",
|
||||||
"Keep going...": "Continúa...",
|
"Keep going...": "Continuar…",
|
||||||
"Passwords don't match": "Las contraseñas no coinciden",
|
"Passwords don't match": "Las contraseñas no coinciden",
|
||||||
"Other users can invite you to rooms using your contact details": "Otros usuarios pueden invitarte las salas utilizando tus datos de contacto",
|
"Other users can invite you to rooms using your contact details": "Otros usuarios pueden invitarte las salas utilizando tus datos de contacto",
|
||||||
"Enter phone number (required on this homeserver)": "Introduce un número de teléfono (es obligatorio en este servidor base)",
|
"Enter phone number (required on this homeserver)": "Introduce un número de teléfono (es obligatorio en este servidor base)",
|
||||||
|
@ -1986,15 +1986,15 @@
|
||||||
"Sign in to your Matrix account on <underlinedServerName />": "Inicie sesión en su cuenta de Matrix en <underlinedServerName />",
|
"Sign in to your Matrix account on <underlinedServerName />": "Inicie sesión en su cuenta de Matrix en <underlinedServerName />",
|
||||||
"Sign in with SSO": "Ingrese con SSO",
|
"Sign in with SSO": "Ingrese con SSO",
|
||||||
"Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, or <safariLink>Safari</safariLink> for the best experience.": "Por favor, instale <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, o <safariLink>Safari</safariLink> para la mejor experiencia.",
|
"Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, or <safariLink>Safari</safariLink> for the best experience.": "Por favor, instale <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, o <safariLink>Safari</safariLink> para la mejor experiencia.",
|
||||||
"Couldn't load page": "No pude cargar la página",
|
"Couldn't load page": "No se ha podido cargar la página",
|
||||||
"You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Eres un administrador de esta comunidad. No podrás volver a unirte sin una invitación de otro administrador.",
|
"You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Eres un administrador de esta comunidad. No podrás volver a unirte sin una invitación de otro administrador.",
|
||||||
"Want more than a community? <a>Get your own server</a>": "¿Quieres más que una comunidad? <a>Obtenga su propio servidor</a>",
|
"Want more than a community? <a>Get your own server</a>": "¿Quieres más que una comunidad? <a>Obtenga su propio servidor</a>",
|
||||||
"This homeserver does not support communities": "Este servidor base no permite las comunidades",
|
"This homeserver does not support communities": "Este servidor base no permite las comunidades",
|
||||||
"Welcome to %(appName)s": "Te damos la bienvenida a %(appName)s",
|
"Welcome to %(appName)s": "Te damos la bienvenida a %(appName)s",
|
||||||
"Liberate your communication": "Libera tu comunicación",
|
"Liberate your communication": "Libera tu comunicación",
|
||||||
"Send a Direct Message": "Envía un mensaje directo",
|
"Send a Direct Message": "Envía un mensaje directo",
|
||||||
"Explore Public Rooms": "Explorar salas públicas",
|
"Explore Public Rooms": "Explora las salas públicas",
|
||||||
"Create a Group Chat": "Crear un chat grupal",
|
"Create a Group Chat": "Crea un chat grupal",
|
||||||
"Explore": "Explorar",
|
"Explore": "Explorar",
|
||||||
"Filter": "Filtrar",
|
"Filter": "Filtrar",
|
||||||
"Filter rooms…": "Filtrar salas…",
|
"Filter rooms…": "Filtrar salas…",
|
||||||
|
@ -2020,7 +2020,7 @@
|
||||||
"Your Matrix account on %(serverName)s": "Su cuenta de Matrix en %(serverName)s",
|
"Your Matrix account on %(serverName)s": "Su cuenta de Matrix en %(serverName)s",
|
||||||
"Your Matrix account on <underlinedServerName />": "Su cuenta de Matrix en <underlinedServerName />",
|
"Your Matrix account on <underlinedServerName />": "Su cuenta de Matrix en <underlinedServerName />",
|
||||||
"No identity server is configured: add one in server settings to reset your password.": "No hay ningún servidor de identidad configurado: añada uno en la configuración del servidor para poder restablecer su contraseña.",
|
"No identity server is configured: add one in server settings to reset your password.": "No hay ningún servidor de identidad configurado: añada uno en la configuración del servidor para poder restablecer su contraseña.",
|
||||||
"Sign in instead": "Regístrese",
|
"Sign in instead": "Iniciar sesión",
|
||||||
"A verification email will be sent to your inbox to confirm setting your new password.": "Se enviará un correo electrónico de verificación a su bandeja de entrada para confirmar la configuración de su nueva contraseña.",
|
"A verification email will be sent to your inbox to confirm setting your new password.": "Se enviará un correo electrónico de verificación a su bandeja de entrada para confirmar la configuración de su nueva contraseña.",
|
||||||
"Your password has been reset.": "Su contraseña ha sido restablecida.",
|
"Your password has been reset.": "Su contraseña ha sido restablecida.",
|
||||||
"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.": "Ha cerrado todas las sesiones y ya no recibirá más notificaciones push. Para volver a activar las notificaciones, inicie sesión de nuevo en cada dispositivo.",
|
"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.": "Ha cerrado todas las sesiones y ya no recibirá más notificaciones push. Para volver a activar las notificaciones, inicie sesión de nuevo en cada dispositivo.",
|
||||||
|
@ -2038,7 +2038,7 @@
|
||||||
"Room name or address": "Nombre o dirección de la sala",
|
"Room name or address": "Nombre o dirección de la sala",
|
||||||
"Address (optional)": "Dirección (opcional)",
|
"Address (optional)": "Dirección (opcional)",
|
||||||
"Help us improve %(brand)s": "Ayúdanos a mejorar %(brand)s",
|
"Help us improve %(brand)s": "Ayúdanos a mejorar %(brand)s",
|
||||||
"Send <UsageDataLink>anonymous usage data</UsageDataLink> which helps us improve %(brand)s. This will use a <PolicyLink>cookie</PolicyLink>.": "Enviar <UsageDataLink>información anónima de uso</UsageDataLink> nos ayudaría bastante a mejorar %(brand)s. Esto cuenta como utilizar <PolicyLink>una cookie</PolicyLink>.",
|
"Send <UsageDataLink>anonymous usage data</UsageDataLink> which helps us improve %(brand)s. This will use a <PolicyLink>cookie</PolicyLink>.": "Enviar <UsageDataLink>información anónima de uso</UsageDataLink> nos ayuda a mejorar %(brand)s. Esto usará <PolicyLink>una cookie</PolicyLink>.",
|
||||||
"I want to help": "Quiero ayudar",
|
"I want to help": "Quiero ayudar",
|
||||||
"Ok": "Ok",
|
"Ok": "Ok",
|
||||||
"Set password": "Establecer contraseña",
|
"Set password": "Establecer contraseña",
|
||||||
|
@ -2102,7 +2102,7 @@
|
||||||
"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.",
|
"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 del texto",
|
"Font size": "Tamaño del texto",
|
||||||
"Use custom size": "Usar un tamaño personalizado",
|
"Use custom size": "Usar un tamaño personalizado",
|
||||||
"Use a more compact ‘Modern’ layout": "Usar un diseño más 'moderno' y compacto",
|
"Use a more compact ‘Modern’ layout": "Usar un diseño más «moderno y compacto",
|
||||||
"Use a system font": "Usar una fuente del sistema",
|
"Use a system font": "Usar una fuente del sistema",
|
||||||
"System font name": "Nombre de la fuente",
|
"System font name": "Nombre de la fuente",
|
||||||
"Enable experimental, compact IRC style layout": "Activar el diseño experimental de IRC compacto",
|
"Enable experimental, compact IRC style layout": "Activar el diseño experimental de IRC compacto",
|
||||||
|
@ -2115,7 +2115,7 @@
|
||||||
"Your server isn't responding to some <a>requests</a>.": "Tú servidor no esta respondiendo a ciertas <a>solicitudes</a>.",
|
"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í.",
|
"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.",
|
"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>",
|
"New version available. <a>Update now.</a>": "Nueva versión disponible. <a>Actualizar ahora.</a>",
|
||||||
"Hey you. You're the best!": "Oye, tú. ¡Eres genial!",
|
"Hey you. You're the best!": "Oye, tú. ¡Eres genial!",
|
||||||
"Size must be a number": "El tamaño debe ser un dígito",
|
"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",
|
"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",
|
||||||
|
@ -2123,7 +2123,7 @@
|
||||||
"Message layout": "Diseño del mensaje",
|
"Message layout": "Diseño del mensaje",
|
||||||
"Compact": "Compacto",
|
"Compact": "Compacto",
|
||||||
"Modern": "Moderno",
|
"Modern": "Moderno",
|
||||||
"Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Introduce el nombre de la fuente instalada en tu sistema y %(brand)s intentará utilizarla.",
|
"Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Escribe el nombre de la fuente instalada en tu sistema y %(brand)s intentará usarla.",
|
||||||
"Customise your appearance": "Personaliza la apariencia",
|
"Customise your appearance": "Personaliza la apariencia",
|
||||||
"Appearance Settings only affect this %(brand)s session.": "Cambiar las opciones de apariencia solo afecta a esta sesión de %(brand)s.",
|
"Appearance Settings only affect this %(brand)s session.": "Cambiar las opciones de apariencia solo afecta a esta sesión de %(brand)s.",
|
||||||
"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.",
|
"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.",
|
||||||
|
@ -2150,7 +2150,7 @@
|
||||||
"Cross-signing is ready for use.": "La firma cruzada está lista para su uso.",
|
"Cross-signing is ready for use.": "La firma cruzada está lista para su uso.",
|
||||||
"Cross-signing is not set up.": "La firma cruzada no está configurada.",
|
"Cross-signing is not set up.": "La firma cruzada no está configurada.",
|
||||||
"Master private key:": "Clave privada maestra:",
|
"Master private key:": "Clave privada maestra:",
|
||||||
"%(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 no puede almacenar en caché de forma segura mensajes cifrados localmente mientras se ejecuta en un navegador web. Utilizar <desktopLink> %(brand)s Escritorio</desktopLink> para que los mensajes cifrados aparezcan en los resultados de búsqueda.",
|
"%(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 no puede almacenar en caché de forma segura mensajes cifrados localmente mientras se ejecuta en un navegador web. Usa <desktopLink> %(brand)s Escritorio</desktopLink> para que los mensajes cifrados aparezcan en los resultados de búsqueda.",
|
||||||
"Backup version:": "Versión de respaldo:",
|
"Backup version:": "Versión de respaldo:",
|
||||||
"Algorithm:": "Algoritmo:",
|
"Algorithm:": "Algoritmo:",
|
||||||
"Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Recovery Key.": "Haga una copia de seguridad de sus claves de cifrado con los datos de su cuenta en caso de que pierda el acceso a sus sesiones. Sus claves estarán protegidas con una clave de recuperación única.",
|
"Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Recovery Key.": "Haga una copia de seguridad de sus claves de cifrado con los datos de su cuenta en caso de que pierda el acceso a sus sesiones. Sus claves estarán protegidas con una clave de recuperación única.",
|
||||||
|
@ -2214,7 +2214,7 @@
|
||||||
"This address is already in use": "Esta dirección ya está en uso",
|
"This address is already in use": "Esta dirección ya está en uso",
|
||||||
"Preparing to download logs": "Preparándose para descargar registros",
|
"Preparing to download logs": "Preparándose para descargar registros",
|
||||||
"Download logs": "Descargar registros",
|
"Download logs": "Descargar registros",
|
||||||
"Add another email": "Agregar otro correo electrónico",
|
"Add another email": "Añadir otro correo electrónico",
|
||||||
"People you know on %(brand)s": "Gente que conoces %(brand)s",
|
"People you know on %(brand)s": "Gente que conoces %(brand)s",
|
||||||
"Show": "Mostrar",
|
"Show": "Mostrar",
|
||||||
"Send %(count)s invites|other": "Enviar %(count)s invitaciones",
|
"Send %(count)s invites|other": "Enviar %(count)s invitaciones",
|
||||||
|
@ -2226,10 +2226,10 @@
|
||||||
"You can change this later if needed.": "Puede cambiar esto más tarde si es necesario.",
|
"You can change this later if needed.": "Puede cambiar esto más tarde si es necesario.",
|
||||||
"What's the name of your community or team?": "¿Cuál es el nombre de tu comunidad o equipo?",
|
"What's the name of your community or team?": "¿Cuál es el nombre de tu comunidad o equipo?",
|
||||||
"Enter name": "Introduce un nombre",
|
"Enter name": "Introduce un nombre",
|
||||||
"Add image (optional)": "Agregar imagen (opcional)",
|
"Add image (optional)": "Añadir imagen (opcional)",
|
||||||
"An image will help people identify your community.": "Una imagen ayudará a las personas a identificar su comunidad.",
|
"An image will help people identify your community.": "Una imagen ayudará a las personas a identificar su comunidad.",
|
||||||
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Las salas privadas se pueden encontrar y unirse solo con invitación. Cualquier persona puede encontrar y unirse a las salas públicas.",
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Las salas privadas solo se pueden encontrar y unirse con invitación. Cualquier persona puede encontrar y unirse a las salas públicas.",
|
||||||
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Las salas privadas se pueden encontrar y unirse solo con invitación. Cualquier persona de esta comunidad puede encontrar salas públicas y unirse a ellas.",
|
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Las salas privadas solo se pueden encontrar y unirse con invitación. Cualquier persona de esta comunidad puede encontrar salas públicas y unirse a ellas.",
|
||||||
"You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Puedes activar esto si la sala solo se usará para colaborar con equipos internos en tu servidor base. No se puede cambiar después.",
|
"You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "Puedes activar esto si la sala solo se usará para colaborar con equipos internos en tu servidor base. No se puede cambiar después.",
|
||||||
"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.": "Puedes desactivar esto si la sala se utilizará para colaborar con equipos externos que tengan su propio servidor base. Esto no se puede cambiar después.",
|
"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.": "Puedes desactivar esto si la sala se utilizará para colaborar con equipos externos que tengan su propio servidor base. Esto no se puede cambiar después.",
|
||||||
"Create a room in %(communityName)s": "Crea una sala en %(communityName)s",
|
"Create a room in %(communityName)s": "Crea una sala en %(communityName)s",
|
||||||
|
@ -2243,7 +2243,7 @@
|
||||||
"May include members not in %(communityName)s": "Puede incluir miembros que no están en %(communityName)s",
|
"May include members not in %(communityName)s": "Puede incluir miembros que no 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>.": "Inicie una conversación con alguien usando su nombre, nombre de usuario (como<userId/>) o dirección de correo electrónico. Esto no los invitará a %(communityName)s Para invitar a alguien a %(communityName)s, haga clic <a>aquí</a>.",
|
"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>.": "Inicie una conversación con alguien usando su nombre, nombre de usuario (como<userId/>) o dirección de correo electrónico. Esto no los invitará a %(communityName)s Para invitar a alguien a %(communityName)s, haga clic <a>aquí</a>.",
|
||||||
"You're all caught up.": "Estás al día.",
|
"You're all caught up.": "Estás al día.",
|
||||||
"Server isn't responding": "El servidor no responde",
|
"Server isn't responding": "El servidor no está respondiendo",
|
||||||
"Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Su servidor no responde a algunas de sus solicitudes. A continuación se presentan algunas de las razones más probables.",
|
"Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Su servidor no responde a algunas de sus solicitudes. A continuación se presentan algunas de las razones más probables.",
|
||||||
"The server (%(serverName)s) took too long to respond.": "El servidor (%(serverName)s) tardó demasiado en responder.",
|
"The server (%(serverName)s) took too long to respond.": "El servidor (%(serverName)s) tardó demasiado en responder.",
|
||||||
"Your firewall or anti-virus is blocking the request.": "Tu firewall o antivirus está bloqueando la solicitud.",
|
"Your firewall or anti-virus is blocking the request.": "Tu firewall o antivirus está bloqueando la solicitud.",
|
||||||
|
@ -2283,15 +2283,15 @@
|
||||||
"Feedback": "Realimentación",
|
"Feedback": "Realimentación",
|
||||||
"Community settings": "Configuración de la comunidad",
|
"Community settings": "Configuración de la comunidad",
|
||||||
"User settings": "Ajustes de usuario",
|
"User settings": "Ajustes de usuario",
|
||||||
"Switch to light mode": "Cambiar al modo claro",
|
"Switch to light mode": "Cambiar al tema claro",
|
||||||
"Switch to dark mode": "Cambiar al tema oscuro",
|
"Switch to dark mode": "Cambiar al tema oscuro",
|
||||||
"Switch theme": "Cambiar tema",
|
"Switch theme": "Cambiar tema",
|
||||||
"User menu": "Menú del Usuario",
|
"User menu": "Menú del Usuario",
|
||||||
"Community and user menu": "Menú de comunidad y usuario",
|
"Community and user menu": "Menú de comunidad y usuario",
|
||||||
"Failed to perform homeserver discovery": "No se ha podido realizar el descubrimiento del servidor base",
|
"Failed to perform homeserver discovery": "No se ha podido realizar el descubrimiento del servidor base",
|
||||||
"Syncing...": "Sincronizando ...",
|
"Syncing...": "Sincronizando…",
|
||||||
"Signing In...": "Iniciando sesión...",
|
"Signing In...": "Iniciando sesión…",
|
||||||
"If you've joined lots of rooms, this might take a while": "Si se ha unido a muchas salas, esto puede llevar un tiempo",
|
"If you've joined lots of rooms, this might take a while": "Si te has unido a muchas salas, esto puede llevar un tiempo",
|
||||||
"Create account": "Crear una cuenta",
|
"Create account": "Crear una cuenta",
|
||||||
"Unable to query for supported registration methods.": "No se pueden consultar los métodos de registro admitidos.",
|
"Unable to query for supported registration methods.": "No se pueden consultar los métodos de registro admitidos.",
|
||||||
"Registration has been disabled on this homeserver.": "Se han desactivado los registros en este servidor base.",
|
"Registration has been disabled on this homeserver.": "Se han desactivado los registros en este servidor base.",
|
||||||
|
@ -2345,7 +2345,7 @@
|
||||||
"Great! This recovery passphrase looks strong enough.": "¡Excelente! Esta frase de contraseña de recuperación parece lo suficientemente sólida.",
|
"Great! This recovery passphrase looks strong enough.": "¡Excelente! Esta frase de contraseña de recuperación parece lo suficientemente sólida.",
|
||||||
"That matches!": "¡Eso combina!",
|
"That matches!": "¡Eso combina!",
|
||||||
"Use a different passphrase?": "¿Utiliza una frase de contraseña diferente?",
|
"Use a different passphrase?": "¿Utiliza una frase de contraseña diferente?",
|
||||||
"That doesn't match.": "Eso no coincide.",
|
"That doesn't match.": "No coincide.",
|
||||||
"Go back to set it again.": "Regrese para configurarlo nuevamente.",
|
"Go back to set it again.": "Regrese para configurarlo nuevamente.",
|
||||||
"Enter your recovery passphrase a second time to confirm it.": "Ingrese su contraseña de recuperación por segunda vez para confirmarla.",
|
"Enter your recovery passphrase a second time to confirm it.": "Ingrese su contraseña de recuperación por segunda vez para confirmarla.",
|
||||||
"Confirm your recovery passphrase": "Confirma tu contraseña de recuperación",
|
"Confirm your recovery passphrase": "Confirma tu contraseña de recuperación",
|
||||||
|
@ -2379,7 +2379,7 @@
|
||||||
"Set up Secure Message Recovery": "Configurar la recuperación segura de mensajes",
|
"Set up Secure Message Recovery": "Configurar la recuperación segura de mensajes",
|
||||||
"Secure your backup with a recovery passphrase": "Asegure su copia de seguridad con una frase de contraseña de recuperación",
|
"Secure your backup with a recovery passphrase": "Asegure su copia de seguridad con una frase de contraseña de recuperación",
|
||||||
"Make a copy of your recovery key": "Haz una copia de tu clave de recuperación",
|
"Make a copy of your recovery key": "Haz una copia de tu clave de recuperación",
|
||||||
"Starting backup...": "Iniciando copia de seguridad ...",
|
"Starting backup...": "Empezando copia de seguridad…",
|
||||||
"Success!": "¡Éxito!",
|
"Success!": "¡Éxito!",
|
||||||
"Create key backup": "Crear copia de seguridad de claves",
|
"Create key backup": "Crear copia de seguridad de claves",
|
||||||
"Unable to create key backup": "No se puede crear una copia de seguridad de la clave",
|
"Unable to create key backup": "No se puede crear una copia de seguridad de la clave",
|
||||||
|
@ -2416,9 +2416,9 @@
|
||||||
"Ctrl": "Ctrl",
|
"Ctrl": "Ctrl",
|
||||||
"Toggle Bold": "Alternar negrita",
|
"Toggle Bold": "Alternar negrita",
|
||||||
"Toggle Italics": "Alternar cursiva",
|
"Toggle Italics": "Alternar cursiva",
|
||||||
"Toggle Quote": "Alternar Entrecomillar",
|
"Toggle Quote": "Alternar cita",
|
||||||
"New line": "Nueva línea",
|
"New line": "Nueva línea",
|
||||||
"Navigate recent messages to edit": "Navegar por mensajes recientes para editar",
|
"Navigate recent messages to edit": "Navegar entre mensajes recientes para editar",
|
||||||
"Jump to start/end of the composer": "Saltar al inicio o final del editor",
|
"Jump to start/end of the composer": "Saltar al inicio o final del editor",
|
||||||
"Navigate composer history": "Navegar por el historial del editor",
|
"Navigate composer history": "Navegar por el historial del editor",
|
||||||
"Cancel replying to a message": "Cancelar la respuesta a un mensaje",
|
"Cancel replying to a message": "Cancelar la respuesta a un mensaje",
|
||||||
|
@ -2428,14 +2428,14 @@
|
||||||
"Dismiss read marker and jump to bottom": "Descartar el marcador de lectura y saltar al final",
|
"Dismiss read marker and jump to bottom": "Descartar el marcador de lectura y saltar al final",
|
||||||
"Jump to oldest unread message": "Ir al mensaje no leído más antiguo",
|
"Jump to oldest unread message": "Ir al mensaje no leído más antiguo",
|
||||||
"Upload a file": "Cargar un archivo",
|
"Upload a file": "Cargar un archivo",
|
||||||
"Jump to room search": "Ir a la búsqueda de Salas",
|
"Jump to room search": "Ir a la búsqueda de salas",
|
||||||
"Navigate up/down in the room list": "Navegar hacia arriba/abajo en la lista de salas",
|
"Navigate up/down in the room list": "Navegar hacia arriba/abajo en la lista de salas",
|
||||||
"Select room from the room list": "Seleccionar sala de la lista de salas",
|
"Select room from the room list": "Seleccionar sala de la lista de salas",
|
||||||
"Collapse room list section": "Contraer la sección de lista de salas",
|
"Collapse room list section": "Contraer la sección de lista de salas",
|
||||||
"Expand room list section": "Expandir la sección de la lista de salas",
|
"Expand room list section": "Expandir la sección de la lista de salas",
|
||||||
"Clear room list filter field": "Borrar campo de filtro de lista de salas",
|
"Clear room list filter field": "Borrar campo de filtro de lista de salas",
|
||||||
"Previous/next unread room or DM": "Sala o DM anterior/siguiente sin leer",
|
"Previous/next unread room or DM": "Sala o mensaje directo anterior/siguiente sin leer",
|
||||||
"Previous/next room or DM": "Sala anterior/siguiente o DM",
|
"Previous/next room or DM": "Sala anterior/siguiente o mensaje directo",
|
||||||
"Toggle the top left menu": "Alternar el menú superior izquierdo",
|
"Toggle the top left menu": "Alternar el menú superior izquierdo",
|
||||||
"Close dialog or context menu": "Cerrar cuadro de diálogo o menú contextual",
|
"Close dialog or context menu": "Cerrar cuadro de diálogo o menú contextual",
|
||||||
"Activate selected button": "Activar botón seleccionado",
|
"Activate selected button": "Activar botón seleccionado",
|
||||||
|
@ -2499,7 +2499,7 @@
|
||||||
"Great, that'll help people know it's you": "Genial, ayudará a que la gente sepa que eres tú",
|
"Great, that'll help people know it's you": "Genial, ayudará a que la gente sepa que eres tú",
|
||||||
"%(ssoButtons)s Or %(usernamePassword)s": "%(ssoButtons)s o %(usernamePassword)s",
|
"%(ssoButtons)s Or %(usernamePassword)s": "%(ssoButtons)s o %(usernamePassword)s",
|
||||||
"Please enter your Security Phrase a second time to confirm.": "Por favor, escribe tu frase de seguridad una segunda vez para confirmarla.",
|
"Please enter your Security Phrase a second time to confirm.": "Por favor, escribe tu frase de seguridad una segunda vez para confirmarla.",
|
||||||
"Repeat your Security Phrase...": "Repite tu frase de seguridad...",
|
"Repeat your Security Phrase...": "Repite tu frase de seguridad…",
|
||||||
"Your Security Key": "Tu clave de seguridad",
|
"Your Security Key": "Tu clave de seguridad",
|
||||||
"Your Security Key has been <b>copied to your clipboard</b>, paste it to:": "Tu clave de seguridad ha sido <b>copiada a tu portapapeles</b>, pégala en:",
|
"Your Security Key has been <b>copied to your clipboard</b>, paste it to:": "Tu clave de seguridad ha sido <b>copiada a tu portapapeles</b>, pégala en:",
|
||||||
"Your Security Key is in your <b>Downloads</b> folder.": "Tu clave de seguridad está en tu carpeta de <b>Descargas</b>.",
|
"Your Security Key is in your <b>Downloads</b> folder.": "Tu clave de seguridad está en tu carpeta de <b>Descargas</b>.",
|
||||||
|
@ -2508,7 +2508,7 @@
|
||||||
"Make a copy of your Security Key": "Haz una copia de tu clave de seguridad",
|
"Make a copy of your Security Key": "Haz una copia de tu clave de seguridad",
|
||||||
"A new Security Phrase and key for Secure Messages have been detected.": "Se ha detectado una nueva frase de seguridad y clave para mensajes seguros.",
|
"A new Security Phrase and key for Secure Messages have been detected.": "Se ha detectado una nueva frase de seguridad y clave para mensajes seguros.",
|
||||||
"This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Esta sesión ha detectado que tu frase de seguridad y clave para mensajes seguros ha sido eliminada.",
|
"This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Esta sesión ha detectado que tu frase de seguridad y clave para mensajes seguros ha sido eliminada.",
|
||||||
"Search (must be enabled)": "Buscar (debe estar activado)",
|
"Search (must be enabled)": "Buscar (si está activado)",
|
||||||
"Zimbabwe": "Zimbabue",
|
"Zimbabwe": "Zimbabue",
|
||||||
"Yemen": "Yemen",
|
"Yemen": "Yemen",
|
||||||
"Wallis & Futuna": "Wallis y Futuna",
|
"Wallis & Futuna": "Wallis y Futuna",
|
||||||
|
@ -2573,7 +2573,7 @@
|
||||||
"Slovenia": "Eslovenia",
|
"Slovenia": "Eslovenia",
|
||||||
"Slovakia": "Eslovaquia",
|
"Slovakia": "Eslovaquia",
|
||||||
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.": "Puedes usar la opción de editar el servidor para iniciar sesión en otros servidores de Matrix indicando una URL de servidor base diferente. Esto te permitirá usar Element con una cuenta de Matrix que ye exista en un servidor base diferente.",
|
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.": "Puedes usar la opción de editar el servidor para iniciar sesión en otros servidores de Matrix indicando una URL de servidor base diferente. Esto te permitirá usar Element con una cuenta de Matrix que ye exista en un servidor base diferente.",
|
||||||
"We call the places where you can host your account ‘homeservers’.": "Llamamos a los sitios donde puedes alojar tu cuenta «servidores base».",
|
"We call the places where you can host your account ‘homeservers’.": "Llamamos «servidores base» a los sitios donde puedes alojar tu cuenta.",
|
||||||
"Use email to optionally be discoverable by existing contacts.": "También puedes usarlo para que tus contactos te encuentren fácilmente.",
|
"Use email to optionally be discoverable by existing contacts.": "También puedes usarlo para que tus contactos te encuentren fácilmente.",
|
||||||
"Add an email to be able to reset your password.": "Añade un correo para poder restablecer tu contraseña si te olvidas.",
|
"Add an email to be able to reset your password.": "Añade un correo para poder restablecer tu contraseña si te olvidas.",
|
||||||
"Continue with %(ssoButtons)s": "Continuar con %(ssoButtons)s",
|
"Continue with %(ssoButtons)s": "Continuar con %(ssoButtons)s",
|
||||||
|
@ -2693,7 +2693,7 @@
|
||||||
"New here? <a>Create an account</a>": "¿Primera vez? <a>Crea una cuenta</a>",
|
"New here? <a>Create an account</a>": "¿Primera vez? <a>Crea una cuenta</a>",
|
||||||
"Got an account? <a>Sign in</a>": "¿Ya tienes una cuenta? <a>Iniciar sesión</a>",
|
"Got an account? <a>Sign in</a>": "¿Ya tienes una cuenta? <a>Iniciar sesión</a>",
|
||||||
"Filter rooms and people": "Filtrar salas y personas",
|
"Filter rooms and people": "Filtrar salas y personas",
|
||||||
"You have no visible notifications.": "No tienes notificaciones visibles.",
|
"You have no visible notifications.": "No tienes notificaciones pendientes.",
|
||||||
"%(creator)s created this DM.": "%(creator)s creó este mensaje directo.",
|
"%(creator)s created this DM.": "%(creator)s creó este mensaje directo.",
|
||||||
"You do not have permission to create rooms in this community.": "No tienes permisos para crear salas en esta comunidad.",
|
"You do not have permission to create rooms in this community.": "No tienes permisos para crear salas en esta comunidad.",
|
||||||
"Cannot create rooms in this community": "No puedes crear salas en esta comunidad",
|
"Cannot create rooms in this community": "No puedes crear salas en esta comunidad",
|
||||||
|
@ -2727,8 +2727,8 @@
|
||||||
"Learn more": "Más información",
|
"Learn more": "Más información",
|
||||||
"Use your preferred Matrix homeserver if you have one, or host your own.": "Usa tu servidor base de Matrix de confianza o aloja el tuyo propio.",
|
"Use your preferred Matrix homeserver if you have one, or host your own.": "Usa tu servidor base de Matrix de confianza o aloja el tuyo propio.",
|
||||||
"Other homeserver": "Otro servidor base",
|
"Other homeserver": "Otro servidor base",
|
||||||
"Sign into your homeserver": "Iniciar sesión en tu servidor base",
|
"Sign into your homeserver": "Inicia sesión en tu servidor base",
|
||||||
"Matrix.org is the biggest public homeserver in the world, so it’s a good place for many.": "Matrix.org es el mayor servidor base del mundo, por lo que es un buen sitio para muchos.",
|
"Matrix.org is the biggest public homeserver in the world, so it’s a good place for many.": "Matrix.org es el mayor servidor base del mundo, por lo que es un buen sitio para empezar.",
|
||||||
"Specify a homeserver": "Especificar un servidor base",
|
"Specify a homeserver": "Especificar un servidor base",
|
||||||
"Invalid URL": "URL inválida",
|
"Invalid URL": "URL inválida",
|
||||||
"Unable to validate homeserver": "No se ha podido validar el servidor base",
|
"Unable to validate homeserver": "No se ha podido validar el servidor base",
|
||||||
|
@ -2963,7 +2963,7 @@
|
||||||
"Unable to access secret storage. Please verify that you entered the correct Security Phrase.": "No se ha podido acceder al almacenamiento seguro. Por favor, comprueba que la frase de seguridad es correcta.",
|
"Unable to access secret storage. Please verify that you entered the correct Security Phrase.": "No se ha podido acceder al almacenamiento seguro. Por favor, comprueba que la frase de seguridad es correcta.",
|
||||||
"Just a heads up, if you don't add an email and forget your password, you could <b>permanently lose access to your account</b>.": "Ten en cuenta que, si no añades un correo electrónico y olvidas tu contraseña, podrías <b>perder accceso para siempre a tu cuenta</b>.",
|
"Just a heads up, if you don't add an email and forget your password, you could <b>permanently lose access to your account</b>.": "Ten en cuenta que, si no añades un correo electrónico y olvidas tu contraseña, podrías <b>perder accceso para siempre a tu cuenta</b>.",
|
||||||
"We recommend you change your password and Security Key in Settings immediately": "Te recomendamos que cambies tu contraseña y clave de seguridad en ajustes inmediatamente",
|
"We recommend you change your password and Security Key in Settings immediately": "Te recomendamos que cambies tu contraseña y clave de seguridad en ajustes inmediatamente",
|
||||||
"Invite someone using their name, email address, username (like <userId/>) or <a>share this room</a>.": "Invitar a alguien usando su nombre, dirección de correo, nombre de usuario (ej.: <userId/>) o <a>compartiendo esta sala</a>.",
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this room</a>.": "Invitar a alguien usando su nombre, dirección de correo, nombre de usuario (ej.: <userId/>) o <a>compartiendo la sala</a>.",
|
||||||
"This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>": "Esto no les invitará a %(communityName)s. Para invitar a alguien a %(communityName)s, haz clic <a>aquí</a>",
|
"This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click <a>here</a>": "Esto no les invitará a %(communityName)s. Para invitar a alguien a %(communityName)s, haz clic <a>aquí</a>",
|
||||||
"Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Al continuar con el proceso de configuración, %(hostSignupBrand)s podrá acceder a tu cuenta para comprobar las direcciones de correo verificadas. Los datos no se almacenan.",
|
"Continuing temporarily allows the %(hostSignupBrand)s setup process to access your account to fetch verified email addresses. This data is not stored.": "Al continuar con el proceso de configuración, %(hostSignupBrand)s podrá acceder a tu cuenta para comprobar las direcciones de correo verificadas. Los datos no se almacenan.",
|
||||||
"Failed to connect to your homeserver. Please close this dialog and try again.": "No se ha podido conectar con tu servidor base. Por favor, cierra este mensaje e inténtalo de nuevo.",
|
"Failed to connect to your homeserver. Please close this dialog and try again.": "No se ha podido conectar con tu servidor base. Por favor, cierra este mensaje e inténtalo de nuevo.",
|
||||||
|
@ -3026,5 +3026,120 @@
|
||||||
"Settings Explorer": "Explorador de ajustes",
|
"Settings Explorer": "Explorador de ajustes",
|
||||||
"Windows": "Ventanas",
|
"Windows": "Ventanas",
|
||||||
"Share your screen": "Compartir pantalla",
|
"Share your screen": "Compartir pantalla",
|
||||||
"Screens": "Pantallas"
|
"Screens": "Pantallas",
|
||||||
|
"Inviting...": "Invitando…",
|
||||||
|
"Creating rooms...": "Creando salas…",
|
||||||
|
"Find a room...": "Encontrar una sala…",
|
||||||
|
"Saving...": "Guardando…",
|
||||||
|
"Applying...": "Aplicando…",
|
||||||
|
"Encrypting your message...": "Cifrando tu mensaje…",
|
||||||
|
"Sending your message...": "Enviando tu mensaje…",
|
||||||
|
"Creating...": "Creando…",
|
||||||
|
"Promoted to users": "Ascendidos a usuarios",
|
||||||
|
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the space it will be impossible to regain privileges.": "No podrás deshacer esto, ya que te estás quitando tus permisos. Si eres la última persona con permisos en este usuario, no será posible recuperarlos.",
|
||||||
|
"Jump to the bottom of the timeline when you send a message": "Saltar abajo del todo cuando envíes un mensaje",
|
||||||
|
"Your private space <name/>": "Tu espacio privado <name/>",
|
||||||
|
"Welcome to <name/>": "Te damos la bienvenida a <name/>",
|
||||||
|
"Already in call": "Ya en una llamada",
|
||||||
|
"Original event source": "Fuente original del evento",
|
||||||
|
"Decrypted event source": "Descifrar fuente del evento",
|
||||||
|
"We'll create rooms for each of them. You can add existing rooms after setup.": "Crearemos salas para cada uno de ellos. Puedes añadir salas ya existentes después de la configuración.",
|
||||||
|
"What projects are you working on?": "¿En qué proyectos estáis trabajando?",
|
||||||
|
"We'll create rooms for each topic.": "Crearemos una sala para cada tema.",
|
||||||
|
"What are some things you want to discuss?": "¿De qué cosas quieres hablar?",
|
||||||
|
"Invite by username": "Invitar por nombre de usuario",
|
||||||
|
"Invite your teammates": "Invita a tu equipo",
|
||||||
|
"Failed to invite the following users to your space: %(csvUsers)s": "La invitación a este espacio de los siguientes usuarios ha fallado: %(csvUsers)s",
|
||||||
|
"A private space for you and your teammates": "Un espacio privado para ti y tu equipo",
|
||||||
|
"Me and my teammates": "Yo y mi equipo",
|
||||||
|
"A private space just for you": "Un espacio privado solo para ti",
|
||||||
|
"Just Me": "Solo yo",
|
||||||
|
"Ensure the right people have access to the space.": "Asegúrate de que las personas adecuadas tienen acceso a este espacio.",
|
||||||
|
"Who are you working with?": "¿Con quién estás trabajando?",
|
||||||
|
"Finish": "Terminar",
|
||||||
|
"At the moment only you can see it.": "En este momento solo tú lo puedes ver.",
|
||||||
|
"Skip for now": "Omitir por ahora",
|
||||||
|
"Failed to create initial space rooms": "No se han podido crear las salas iniciales del espacio",
|
||||||
|
"Room name": "Nombre de la sala",
|
||||||
|
"Support": "Ayuda",
|
||||||
|
"Random": "Al azar",
|
||||||
|
"Your public space <name/>": "Tu espacio público <name/>",
|
||||||
|
"You have been invited to <name/>": "Te han invitado a <name/>",
|
||||||
|
"<inviter/> invited you to <name/>": "<inviter/> te ha invitado a <name/>",
|
||||||
|
"%(count)s members|one": "%(count)s miembro",
|
||||||
|
"%(count)s members|other": "%(count)s miembros",
|
||||||
|
"Your server does not support showing space hierarchies.": "Este servidor no soporta mostrar jerarquías de espacios.",
|
||||||
|
"Default Rooms": "Salas por defecto",
|
||||||
|
"Add existing rooms & spaces": "Añadir salas y espacios ya existentes",
|
||||||
|
"Accept Invite": "Aceptar invitación",
|
||||||
|
"Manage rooms": "Gestionar salas",
|
||||||
|
"Save changes": "Guardar cambios",
|
||||||
|
"You're in this room": "Estás en esta sala",
|
||||||
|
"You're in this space": "Eres parte de este espacio",
|
||||||
|
"No permissions": "Sin permisos",
|
||||||
|
"Remove from Space": "Quitar del espacio",
|
||||||
|
"Undo": "Deshacer",
|
||||||
|
"Your message wasn't sent because this homeserver has been blocked by it's administrator. Please <a>contact your service administrator</a> to continue using the service.": "Tu mensaje no ha sido enviado porque este servidor base ha sido bloqueado por su administración. Por favor, <a>ponte en contacto con ellos</a> para continuar usando el servicio.",
|
||||||
|
"Are you sure you want to leave the space '%(spaceName)s'?": "¿Salir del espacio «%(spaceName)s»?",
|
||||||
|
"This space is not public. You will not be able to rejoin without an invite.": "Este espacio es privado. No podrás volverte a unir sin una invitación.",
|
||||||
|
"Start audio stream": "Empezar retransmisión de audio",
|
||||||
|
"Failed to start livestream": "No se ha podido empezar la retransmisión",
|
||||||
|
"Unable to start audio streaming.": "No se ha podido empezar la retransmisión del audio.",
|
||||||
|
"Save Changes": "Guardar cambios",
|
||||||
|
"View dev tools": "Ver herramientas de desarrollador",
|
||||||
|
"Leave Space": "Salir del espacio",
|
||||||
|
"Make this space private": "Hacer este espacio privado",
|
||||||
|
"Edit settings relating to your space.": "Editar ajustes relacionados con tu espacio.",
|
||||||
|
"Space settings": "Ajustes del espacio",
|
||||||
|
"Failed to save space settings.": "No se han podido guardar los ajustes del espacio.",
|
||||||
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "Invita a más gente usando su nombre, correo electrónico, nombre de usuario (ej.: <userId/>) o <a>compartiendo este espacio</a>.",
|
||||||
|
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.": "Invita a más gente usando su nombre, nombre de usuario (ej.: <userId/>) o <a>compartiendo este espacio</a>.",
|
||||||
|
"Unnamed Space": "Espacio sin nombre",
|
||||||
|
"Invite to %(spaceName)s": "Invitar a %(spaceName)s",
|
||||||
|
"Failed to add rooms to space": "No se han podido añadir las salas al espacio",
|
||||||
|
"Apply": "Aplicar",
|
||||||
|
"Create a new room": "Crea una nueva",
|
||||||
|
"Don't want to add an existing room?": "¿No quieres añadir una sala que ya exista?",
|
||||||
|
"Spaces": "Espacios",
|
||||||
|
"Filter your rooms and spaces": "Filtra tus salas y espacios",
|
||||||
|
"Add existing spaces/rooms": "Añadir espacios o salas ya existentes",
|
||||||
|
"Space selection": "Selección de espacio",
|
||||||
|
"Empty room": "Sala vacía",
|
||||||
|
"Suggested Rooms": "Salas sugeridas",
|
||||||
|
"Explore space rooms": "Explorar las salas del espacio",
|
||||||
|
"You do not have permissions to add rooms to this space": "No tienes permisos para añadir salas a este espacio",
|
||||||
|
"Add existing room": "Añadir sala ya existente",
|
||||||
|
"You do not have permissions to create new rooms in this space": "No tienes permisos para crear nuevas salas en este espacio",
|
||||||
|
"Send message": "Enviar mensaje",
|
||||||
|
"Invite to this space": "Invitar a este espacio",
|
||||||
|
"Your message was sent": "Mensaje enviado",
|
||||||
|
"Spell check dictionaries": "Diccionarios de comprobación de ortografía",
|
||||||
|
"Space options": "Opciones del espacio",
|
||||||
|
"Space Home": "Inicio del espacio",
|
||||||
|
"New room": "Nueva sala",
|
||||||
|
"Leave space": "Salir del espacio",
|
||||||
|
"Invite people": "Invitar a gente",
|
||||||
|
"Share your public space": "Comparte tu espacio público",
|
||||||
|
"Invite members": "Invitar a gente",
|
||||||
|
"Invite by email or username": "Invitar usando correo electrónico o nombre de usuario",
|
||||||
|
"Share invite link": "Compartir enlace de invitación",
|
||||||
|
"Click to copy": "Haz clic para copiar",
|
||||||
|
"Collapse space panel": "Colapsar panel del espacio",
|
||||||
|
"Expand space panel": "Expandir panel del espacio",
|
||||||
|
"You can change these at any point.": "Puedes cambiar todo esto cuando quieras.",
|
||||||
|
"Give it a photo, name and description to help you identify it.": "Añádele una foto, nombre o descripción que te ayude a identificarlo.",
|
||||||
|
"Your private space": "Tu espacio privado",
|
||||||
|
"Your public space": "Tu espacio público",
|
||||||
|
"You can change this later": "Puedes cambiar esto más adelante",
|
||||||
|
"Invite only, best for yourself or teams": "Solo con invitación, mejor para ti o para equipos",
|
||||||
|
"Private": "Privado",
|
||||||
|
"Open space for anyone, best for communities": "Espacio abierto para todo el mundo, la mejor opción para comunidades",
|
||||||
|
"Public": "Público",
|
||||||
|
"Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "Los espacios son la manera de agrupar salas y gente. Para unirte a un espacio ya existente, necesitarás que te inviten",
|
||||||
|
"Create a space": "Crear un espacio",
|
||||||
|
"Delete": "Borrar",
|
||||||
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Prototipo de espacios. No compatible con comunidades, comunidades v2 o etiquetas personalizadas. Necesita un servidor base compatible para algunas funcionalidades.",
|
||||||
|
"This homeserver has been blocked by its administrator.": "Este servidor base ha sido bloqueado por su administración.",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "Este servidor base ha sido bloqueado por su administración.",
|
||||||
|
"You're already in a call with this person.": "Ya estás en una llamada con esta persona."
|
||||||
}
|
}
|
||||||
|
|
|
@ -1132,7 +1132,7 @@
|
||||||
"Bridges": "Sõnumisillad",
|
"Bridges": "Sõnumisillad",
|
||||||
"Room Addresses": "Jututubade aadressid",
|
"Room Addresses": "Jututubade aadressid",
|
||||||
"Browse": "Sirvi",
|
"Browse": "Sirvi",
|
||||||
"Change room avatar": "Muuda jututoa profiilipilti ehk avatari",
|
"Change room avatar": "Muuda jututoa tunnuspilti ehk avatari",
|
||||||
"Change main address for the room": "Muuda jututoa põhiaadressi",
|
"Change main address for the room": "Muuda jututoa põhiaadressi",
|
||||||
"Change history visibility": "Muuda vestlusajaloo nähtavust",
|
"Change history visibility": "Muuda vestlusajaloo nähtavust",
|
||||||
"Change permissions": "Muuda õigusi",
|
"Change permissions": "Muuda õigusi",
|
||||||
|
@ -3088,5 +3088,9 @@
|
||||||
"Setting ID": "Seadistuse tunnus",
|
"Setting ID": "Seadistuse tunnus",
|
||||||
"Failed to save settings": "Seadistuste salvestamine ei õnnestunud",
|
"Failed to save settings": "Seadistuste salvestamine ei õnnestunud",
|
||||||
"Settings Explorer": "Seadistuste haldur",
|
"Settings Explorer": "Seadistuste haldur",
|
||||||
"Show chat effects (animations when receiving e.g. confetti)": "Näita vestluses edevat graafikat (näiteks kui keegi on saatnud serpentiine)"
|
"Show chat effects (animations when receiving e.g. confetti)": "Näita vestluses edevat graafikat (näiteks kui keegi on saatnud serpentiine)",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "Ligipääs sellele koduserverile on sinu serveri haldaja poolt blokeeritud.",
|
||||||
|
"This homeserver has been blocked by its administrator.": "Ligipääs sellele koduserverile on sinu serveri haldaja poolt blokeeritud.",
|
||||||
|
"You're already in a call with this person.": "Sinul juba kõne käsil selle osapoolega.",
|
||||||
|
"Already in call": "Kõne on juba pooleli"
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
"%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s a changé le rang de %(powerLevelDiffText)s.",
|
"%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s a changé le rang de %(powerLevelDiffText)s.",
|
||||||
"%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s a changé le nom du salon en %(roomName)s.",
|
"%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s a changé le nom du salon en %(roomName)s.",
|
||||||
"%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s a changé le sujet du salon en « %(topic)s ».",
|
"%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s a changé le sujet du salon en « %(topic)s ».",
|
||||||
"Changes your display nickname": "Change votre nom d’affichage",
|
"Changes your display nickname": "Modifie votre nom d’affichage",
|
||||||
"Click here to fix": "Cliquer ici pour réparer",
|
"Click here to fix": "Cliquer ici pour réparer",
|
||||||
"Click to mute audio": "Cliquer pour couper le son",
|
"Click to mute audio": "Cliquer pour couper le son",
|
||||||
"Click to mute video": "Cliquer ici pour couper la vidéo",
|
"Click to mute video": "Cliquer ici pour couper la vidéo",
|
||||||
|
@ -636,7 +636,7 @@
|
||||||
"This room is not public. You will not be able to rejoin without an invite.": "Ce salon n’est pas public. Vous ne pourrez pas y revenir sans invitation.",
|
"This room is not public. You will not be able to rejoin without an invite.": "Ce salon n’est pas public. Vous ne pourrez pas y revenir sans invitation.",
|
||||||
"Community IDs cannot be empty.": "Les identifiants de communauté ne peuvent pas être vides.",
|
"Community IDs cannot be empty.": "Les identifiants de communauté ne peuvent pas être vides.",
|
||||||
"<a>In reply to</a> <pill>": "<a>En réponse à</a> <pill>",
|
"<a>In reply to</a> <pill>": "<a>En réponse à</a> <pill>",
|
||||||
"%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s a changé son nom d’affichage en %(displayName)s.",
|
"%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s a modifié son nom d’affichage en %(displayName)s.",
|
||||||
"Failed to set direct chat tag": "Échec de l’ajout de l’étiquette discussion directe",
|
"Failed to set direct chat tag": "Échec de l’ajout de l’étiquette discussion directe",
|
||||||
"Failed to remove tag %(tagName)s from room": "Échec de la suppression de l’étiquette %(tagName)s du salon",
|
"Failed to remove tag %(tagName)s from room": "Échec de la suppression de l’étiquette %(tagName)s du salon",
|
||||||
"Failed to add tag %(tagName)s to room": "Échec de l’ajout de l’étiquette %(tagName)s au salon",
|
"Failed to add tag %(tagName)s to room": "Échec de l’ajout de l’étiquette %(tagName)s au salon",
|
||||||
|
@ -714,7 +714,7 @@
|
||||||
"%(brand)s uses many advanced browser features, some of which are not available or experimental in your current browser.": "%(brand)s utilise de nombreuses fonctionnalités avancées du navigateur, certaines ne sont pas disponibles ou expérimentales dans votre navigateur actuel.",
|
"%(brand)s uses many advanced browser features, some of which are not available or experimental in your current browser.": "%(brand)s utilise de nombreuses fonctionnalités avancées du navigateur, certaines ne sont pas disponibles ou expérimentales dans votre navigateur actuel.",
|
||||||
"Developer Tools": "Outils de développement",
|
"Developer Tools": "Outils de développement",
|
||||||
"Remember, you can always set an email address in user settings if you change your mind.": "Souvenez-vous que vous pourrez toujours définir une adresse e-mail dans les paramètres de l'utilisateur si vous changez d’avis.",
|
"Remember, you can always set an email address in user settings if you change your mind.": "Souvenez-vous que vous pourrez toujours définir une adresse e-mail dans les paramètres de l'utilisateur si vous changez d’avis.",
|
||||||
"Explore Account Data": "Explorer les données du compte",
|
"Explore Account Data": "Parcourir les données du compte",
|
||||||
"Remove from Directory": "Supprimer du répertoire",
|
"Remove from Directory": "Supprimer du répertoire",
|
||||||
"Saturday": "Samedi",
|
"Saturday": "Samedi",
|
||||||
"I understand the risks and wish to continue": "Je comprends les risques et souhaite continuer",
|
"I understand the risks and wish to continue": "Je comprends les risques et souhaite continuer",
|
||||||
|
@ -1012,7 +1012,7 @@
|
||||||
"Developer options": "Options de développeur",
|
"Developer options": "Options de développeur",
|
||||||
"General": "Général",
|
"General": "Général",
|
||||||
"Room Addresses": "Adresses du salon",
|
"Room Addresses": "Adresses du salon",
|
||||||
"Set a new account password...": "Définir un nouveau mot de passe du compte…",
|
"Set a new account password...": "Définir un nouveau mot de passe pour ce compte…",
|
||||||
"Email addresses": "Adresses e-mail",
|
"Email addresses": "Adresses e-mail",
|
||||||
"Phone numbers": "Numéros de téléphone",
|
"Phone numbers": "Numéros de téléphone",
|
||||||
"Language and region": "Langue et région",
|
"Language and region": "Langue et région",
|
||||||
|
@ -1189,7 +1189,7 @@
|
||||||
"Allow Peer-to-Peer for 1:1 calls": "Autoriser les connexions pair-à-pair pour les appels individuels",
|
"Allow Peer-to-Peer for 1:1 calls": "Autoriser les connexions pair-à-pair pour les appels individuels",
|
||||||
"Credits": "Crédits",
|
"Credits": "Crédits",
|
||||||
"If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.": "Si vous avez rencontré des problèmes ou si vous souhaitez partager votre avis, dites-le nous sur GitHub.",
|
"If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.": "Si vous avez rencontré des problèmes ou si vous souhaitez partager votre avis, dites-le nous sur GitHub.",
|
||||||
"Changes your display nickname in the current room only": "Change votre nom d’affichage seulement dans le salon actuel",
|
"Changes your display nickname in the current room only": "Modifie votre nom d’affichage seulement dans le salon actuel",
|
||||||
"%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s a activé le badge pour %(groups)s dans ce salon.",
|
"%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s a activé le badge pour %(groups)s dans ce salon.",
|
||||||
"%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s a désactivé le badge pour %(groups)s dans ce salon.",
|
"%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s a désactivé le badge pour %(groups)s dans ce salon.",
|
||||||
"%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s a activé le badge pour %(newGroups)s et désactivé le badge pour %(oldGroups)s dans ce salon.",
|
"%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s a activé le badge pour %(newGroups)s et désactivé le badge pour %(oldGroups)s dans ce salon.",
|
||||||
|
@ -1281,7 +1281,7 @@
|
||||||
"Upload Error": "Erreur d’envoi",
|
"Upload Error": "Erreur d’envoi",
|
||||||
"The server does not support the room version specified.": "Le serveur ne prend pas en charge la version de salon spécifiée.",
|
"The server does not support the room version specified.": "Le serveur ne prend pas en charge la version de salon spécifiée.",
|
||||||
"Name or Matrix ID": "Nom ou identifiant Matrix",
|
"Name or Matrix ID": "Nom ou identifiant Matrix",
|
||||||
"Changes your avatar in this current room only": "Change votre avatar seulement dans le salon actuel",
|
"Changes your avatar in this current room only": "Modifie votre avatar seulement dans le salon actuel",
|
||||||
"Unbans user with given ID": "Révoque le bannissement de l’utilisateur ayant l’identifiant fourni",
|
"Unbans user with given ID": "Révoque le bannissement de l’utilisateur ayant l’identifiant fourni",
|
||||||
"Sends the given message coloured as a rainbow": "Envoie le message coloré aux couleurs de l’arc-en-ciel",
|
"Sends the given message coloured as a rainbow": "Envoie le message coloré aux couleurs de l’arc-en-ciel",
|
||||||
"Sends the given emote coloured as a rainbow": "Envoie la réaction colorée aux couleurs de l’arc-en-ciel",
|
"Sends the given emote coloured as a rainbow": "Envoie la réaction colorée aux couleurs de l’arc-en-ciel",
|
||||||
|
@ -1383,7 +1383,7 @@
|
||||||
"Resend %(unsentCount)s reaction(s)": "Renvoyer %(unsentCount)s réaction(s)",
|
"Resend %(unsentCount)s reaction(s)": "Renvoyer %(unsentCount)s réaction(s)",
|
||||||
"Resend removal": "Renvoyer la suppression",
|
"Resend removal": "Renvoyer la suppression",
|
||||||
"Your homeserver doesn't seem to support this feature.": "Il semble que votre serveur d’accueil ne prenne pas en charge cette fonctionnalité.",
|
"Your homeserver doesn't seem to support this feature.": "Il semble que votre serveur d’accueil ne prenne pas en charge cette fonctionnalité.",
|
||||||
"Changes your avatar in all rooms": "Change votre avatar dans tous les salons",
|
"Changes your avatar in all rooms": "Modifie votre avatar dans tous les salons",
|
||||||
"You're signed out": "Vous êtes déconnecté",
|
"You're signed out": "Vous êtes déconnecté",
|
||||||
"Clear all data": "Supprimer toutes les données",
|
"Clear all data": "Supprimer toutes les données",
|
||||||
"Removing…": "Suppression…",
|
"Removing…": "Suppression…",
|
||||||
|
@ -1504,7 +1504,7 @@
|
||||||
"Find a room…": "Trouver un salon…",
|
"Find a room…": "Trouver un salon…",
|
||||||
"Find a room… (e.g. %(exampleRoom)s)": "Trouver un salon… (par ex. %(exampleRoom)s)",
|
"Find a room… (e.g. %(exampleRoom)s)": "Trouver un salon… (par ex. %(exampleRoom)s)",
|
||||||
"If you can't find the room you're looking for, ask for an invite or <a>Create a new room</a>.": "Si vous ne trouvez pas le salon que vous cherchez, demandez une invitation ou <a>créez un nouveau salon</a>.",
|
"If you can't find the room you're looking for, ask for an invite or <a>Create a new room</a>.": "Si vous ne trouvez pas le salon que vous cherchez, demandez une invitation ou <a>créez un nouveau salon</a>.",
|
||||||
"Explore rooms": "Explorer les salons",
|
"Explore rooms": "Parcourir les salons",
|
||||||
"Verify the link in your inbox": "Vérifiez le lien dans votre boîte de réception",
|
"Verify the link in your inbox": "Vérifiez le lien dans votre boîte de réception",
|
||||||
"Complete": "Terminer",
|
"Complete": "Terminer",
|
||||||
"Please fill why you're reporting.": "Dites-nous pourquoi vous envoyez un signalement.",
|
"Please fill why you're reporting.": "Dites-nous pourquoi vous envoyez un signalement.",
|
||||||
|
@ -1514,7 +1514,7 @@
|
||||||
"Report Content": "Signaler le contenu",
|
"Report Content": "Signaler le contenu",
|
||||||
"Read Marker lifetime (ms)": "Durée de vie du repère de lecture (ms)",
|
"Read Marker lifetime (ms)": "Durée de vie du repère de lecture (ms)",
|
||||||
"Read Marker off-screen lifetime (ms)": "Durée de vie du repère de lecture en dehors de l’écran (ms)",
|
"Read Marker off-screen lifetime (ms)": "Durée de vie du repère de lecture en dehors de l’écran (ms)",
|
||||||
"Changes the avatar of the current room": "Change l’avatar du salon actuel",
|
"Changes the avatar of the current room": "Modifie l’avatar du salon actuel",
|
||||||
"e.g. my-room": "par ex. mon-salon",
|
"e.g. my-room": "par ex. mon-salon",
|
||||||
"Close dialog": "Fermer la boîte de dialogue",
|
"Close dialog": "Fermer la boîte de dialogue",
|
||||||
"Please enter a name for the room": "Veuillez renseigner un nom pour le salon",
|
"Please enter a name for the room": "Veuillez renseigner un nom pour le salon",
|
||||||
|
@ -2003,7 +2003,7 @@
|
||||||
"Remove server": "Supprimer le serveur",
|
"Remove server": "Supprimer le serveur",
|
||||||
"Matrix": "Matrix",
|
"Matrix": "Matrix",
|
||||||
"Add a new server": "Ajouter un nouveau serveur",
|
"Add a new server": "Ajouter un nouveau serveur",
|
||||||
"Enter the name of a new server you want to explore.": "Saisissez le nom du nouveau serveur que vous voulez explorer.",
|
"Enter the name of a new server you want to explore.": "Saisissez le nom du nouveau serveur que vous voulez parcourir.",
|
||||||
"Server name": "Nom du serveur",
|
"Server name": "Nom du serveur",
|
||||||
"Add a new server...": "Ajouter un nouveau serveur…",
|
"Add a new server...": "Ajouter un nouveau serveur…",
|
||||||
"%(networkName)s rooms": "%(networkName)s salons",
|
"%(networkName)s rooms": "%(networkName)s salons",
|
||||||
|
@ -2060,7 +2060,7 @@
|
||||||
"Confirm by comparing the following with the User Settings in your other session:": "Confirmez en comparant ceci avec les paramètres utilisateurs de votre autre session :",
|
"Confirm by comparing the following with the User Settings in your other session:": "Confirmez en comparant ceci avec les paramètres utilisateurs de votre autre session :",
|
||||||
"Confirm this user's session by comparing the following with their User Settings:": "Confirmez la session de cet utilisateur en comparant ceci avec ses paramètres utilisateur :",
|
"Confirm this user's session by comparing the following with their User Settings:": "Confirmez la session de cet utilisateur en comparant ceci avec ses paramètres utilisateur :",
|
||||||
"If they don't match, the security of your communication may be compromised.": "S’ils ne correspondent pas, la sécurité de vos communications est peut-être compromise.",
|
"If they don't match, the security of your communication may be compromised.": "S’ils ne correspondent pas, la sécurité de vos communications est peut-être compromise.",
|
||||||
"Navigate composer history": "Explorer l’historique du compositeur",
|
"Navigate composer history": "Parcourir l’historique du compositeur",
|
||||||
"Previous/next unread room or DM": "Salon ou conversation privée non lu précédent/suivant",
|
"Previous/next unread room or DM": "Salon ou conversation privée non lu précédent/suivant",
|
||||||
"Previous/next room or DM": "Salon ou conversation privée précédent/suivant",
|
"Previous/next room or DM": "Salon ou conversation privée précédent/suivant",
|
||||||
"Toggle right panel": "Afficher/masquer le panneau de droite",
|
"Toggle right panel": "Afficher/masquer le panneau de droite",
|
||||||
|
@ -2129,7 +2129,7 @@
|
||||||
"Delete sessions|one": "Supprimer la session",
|
"Delete sessions|one": "Supprimer la session",
|
||||||
"Enable end-to-end encryption": "Activer le chiffrement de bout en bout",
|
"Enable end-to-end encryption": "Activer le chiffrement de bout en bout",
|
||||||
"You can’t disable this later. Bridges & most bots won’t work yet.": "Vous ne pourrez pas le désactiver plus tard. Les passerelles et la plupart des robots ne fonctionneront pas pour le moment.",
|
"You can’t disable this later. Bridges & most bots won’t work yet.": "Vous ne pourrez pas le désactiver plus tard. Les passerelles et la plupart des robots ne fonctionneront pas pour le moment.",
|
||||||
"Failed to set topic": "Échec du changement de sujet",
|
"Failed to set topic": "Échec de la modification du sujet",
|
||||||
"Command failed": "La commande a échoué",
|
"Command failed": "La commande a échoué",
|
||||||
"Could not find user in room": "Impossible de trouver l’utilisateur dans le salon",
|
"Could not find user in room": "Impossible de trouver l’utilisateur dans le salon",
|
||||||
"Syncing...": "Synchronisation…",
|
"Syncing...": "Synchronisation…",
|
||||||
|
@ -2472,11 +2472,11 @@
|
||||||
"Room Info": "Informations sur le salon",
|
"Room Info": "Informations sur le salon",
|
||||||
"%(count)s results|one": "%(count)s résultat",
|
"%(count)s results|one": "%(count)s résultat",
|
||||||
"%(count)s results|other": "%(count)s résultats",
|
"%(count)s results|other": "%(count)s résultats",
|
||||||
"Explore all public rooms": "Explorer tous les salons publics",
|
"Explore all public rooms": "Parcourir tous les salons publics",
|
||||||
"Can't see what you’re looking for?": "Vous ne trouvez pas ce que vous cherchez ?",
|
"Can't see what you’re looking for?": "Vous ne trouvez pas ce que vous cherchez ?",
|
||||||
"Custom Tag": "Étiquette personnalisée",
|
"Custom Tag": "Étiquette personnalisée",
|
||||||
"Explore public rooms": "Explorer les salons publics",
|
"Explore public rooms": "Parcourir les salons publics",
|
||||||
"Explore community rooms": "Explorer les salons de la communauté",
|
"Explore community rooms": "Parcourir les salons de la communauté",
|
||||||
"Show Widgets": "Afficher les widgets",
|
"Show Widgets": "Afficher les widgets",
|
||||||
"Hide Widgets": "Masquer les widgets",
|
"Hide Widgets": "Masquer les widgets",
|
||||||
"Remove messages sent by others": "Supprimer les messages envoyés par d’autres",
|
"Remove messages sent by others": "Supprimer les messages envoyés par d’autres",
|
||||||
|
@ -2493,7 +2493,7 @@
|
||||||
"Starting camera...": "Allumage de la caméra ...",
|
"Starting camera...": "Allumage de la caméra ...",
|
||||||
"Call connecting...": "Connexion à l'appel …",
|
"Call connecting...": "Connexion à l'appel …",
|
||||||
"Calling...": "Appel en cours …",
|
"Calling...": "Appel en cours …",
|
||||||
"Explore rooms in %(communityName)s": "Explorer les salons dans %(communityName)s",
|
"Explore rooms in %(communityName)s": "Parcourir les salons de %(communityName)s",
|
||||||
"You have no visible notifications in this room.": "Vous n'avez pas de notification visible dans ce salon.",
|
"You have no visible notifications in this room.": "Vous n'avez pas de notification visible dans ce salon.",
|
||||||
"You’re all caught up": "Vous êtes à jour",
|
"You’re all caught up": "Vous êtes à jour",
|
||||||
"You do not have permission to create rooms in this community.": "Vous n’avez pas la permission de créer des salons dans cette communauté.",
|
"You do not have permission to create rooms in this community.": "Vous n’avez pas la permission de créer des salons dans cette communauté.",
|
||||||
|
@ -2897,7 +2897,7 @@
|
||||||
"Messages in this room are end-to-end encrypted. When people join, you can verify them in their profile, just tap on their avatar.": "Les messages ici sont chiffrés de bout en bout. Quand les gens joignent, vous pouvez les vérifier dans leur profil, tapez simplement sur leur avatar.",
|
"Messages in this room are end-to-end encrypted. When people join, you can verify them in their profile, just tap on their avatar.": "Les messages ici sont chiffrés de bout en bout. Quand les gens joignent, vous pouvez les vérifier dans leur profil, tapez simplement sur leur avatar.",
|
||||||
"Messages here are end-to-end encrypted. Verify %(displayName)s in their profile - tap on their avatar.": "Les messages ici sont chiffrés de bout en bout. Vérifiez %(displayName)s dans leur profil - tapez sur leur avatar.",
|
"Messages here are end-to-end encrypted. Verify %(displayName)s in their profile - tap on their avatar.": "Les messages ici sont chiffrés de bout en bout. Vérifiez %(displayName)s dans leur profil - tapez sur leur avatar.",
|
||||||
"Role": "Rôle",
|
"Role": "Rôle",
|
||||||
"Use the + to make a new room or explore existing ones below": "Utilisez le + pour créer un nouveau salon ou explorer ceux existant ci-dessous",
|
"Use the + to make a new room or explore existing ones below": "Utilisez le + pour créer un nouveau salon ou parcourir ceux existant ci-dessous",
|
||||||
"This is the start of <roomName/>.": "C’est le début de <roomName/>.",
|
"This is the start of <roomName/>.": "C’est le début de <roomName/>.",
|
||||||
"Add a photo, so people can easily spot your room.": "Ajoutez une photo afin que les gens repèrent facilement votre salon.",
|
"Add a photo, so people can easily spot your room.": "Ajoutez une photo afin que les gens repèrent facilement votre salon.",
|
||||||
"%(displayName)s created this room.": "%(displayName)s a créé ce salon.",
|
"%(displayName)s created this room.": "%(displayName)s a créé ce salon.",
|
||||||
|
@ -2906,7 +2906,7 @@
|
||||||
"Topic: %(topic)s ": "Sujet : %(topic)s ",
|
"Topic: %(topic)s ": "Sujet : %(topic)s ",
|
||||||
"Topic: %(topic)s (<a>edit</a>)": "Sujet : %(topic)s (<a>modifier</a>)",
|
"Topic: %(topic)s (<a>edit</a>)": "Sujet : %(topic)s (<a>modifier</a>)",
|
||||||
"This is the beginning of your direct message history with <displayName/>.": "C’est le début de votre historique de messages privés avec <displayName/>.",
|
"This is the beginning of your direct message history with <displayName/>.": "C’est le début de votre historique de messages privés avec <displayName/>.",
|
||||||
"Only the two of you are in this conversation, unless either of you invites anyone to join.": "Vous n’êtes que tous les deux dans cette conversation, à moins que l’un de vous invite quelqu’un.",
|
"Only the two of you are in this conversation, unless either of you invites anyone to join.": "Vous n’êtes que tous les deux dans cette conversation, à moins que l’un de vous invite quelqu’un à vous rejoindre.",
|
||||||
"%(name)s on hold": "%(name)s est en attente",
|
"%(name)s on hold": "%(name)s est en attente",
|
||||||
"Return to call": "Revenir à l’appel",
|
"Return to call": "Revenir à l’appel",
|
||||||
"Fill Screen": "Remplir l’écran",
|
"Fill Screen": "Remplir l’écran",
|
||||||
|
@ -3065,5 +3065,118 @@
|
||||||
"Setting ID": "Identifiant de paramètre",
|
"Setting ID": "Identifiant de paramètre",
|
||||||
"Failed to save settings": "Échec lors de la sauvegarde des paramètres",
|
"Failed to save settings": "Échec lors de la sauvegarde des paramètres",
|
||||||
"Settings Explorer": "Explorateur de paramètres",
|
"Settings Explorer": "Explorateur de paramètres",
|
||||||
"Show chat effects (animations when receiving e.g. confetti)": "Afficher les animations de conversation (animations lors de la réception par ex. de confettis)"
|
"Show chat effects (animations when receiving e.g. confetti)": "Afficher les animations de conversation (animations lors de la réception par ex. de confettis)",
|
||||||
|
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.": "Invitez quelqu’un grâce à son nom, nom d’utilisateur (tel que <userId/>) ou <a>partagez cet espace</a>.",
|
||||||
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "Invitez quelqu’un grâce à son nom, adresse e-mail, nom d’utilisateur (tel que <userId/>) ou <a>partagez cet espace</a>.",
|
||||||
|
"Original event source": "Événement source original",
|
||||||
|
"Decrypted event source": "Événement source déchiffré",
|
||||||
|
"We'll create rooms for each of them. You can add existing rooms after setup.": "Nous allons créer un salon pour chacun d’entre eux. Vous pourrez ajouter des salons après l’initialisation.",
|
||||||
|
"What projects are you working on?": "Sur quels projets travaillez vous ?",
|
||||||
|
"We'll create rooms for each topic.": "Nous allons créer un salon pour chaque sujet.",
|
||||||
|
"What are some things you want to discuss?": "De quoi voulez vous discuter ?",
|
||||||
|
"Inviting...": "Invitation…",
|
||||||
|
"Invite by username": "Inviter par nom d’utilisateur",
|
||||||
|
"Invite your teammates": "Invitez votre équipe",
|
||||||
|
"Failed to invite the following users to your space: %(csvUsers)s": "Échec de l’invitation des utilisateurs suivants à votre espace : %(csvUsers)s",
|
||||||
|
"A private space for you and your teammates": "Un espace privé pour vous et votre équipe",
|
||||||
|
"Me and my teammates": "Moi et mon équipe",
|
||||||
|
"A private space just for you": "Un espace privé seulement pour vous",
|
||||||
|
"Just Me": "Seulement moi",
|
||||||
|
"Ensure the right people have access to the space.": "Vérifiez que les bonnes personnes ont accès à cet espace.",
|
||||||
|
"Who are you working with?": "Avec qui travaillez vous ?",
|
||||||
|
"Finish": "Finir",
|
||||||
|
"At the moment only you can see it.": "Pour l’instant vous seul pouvez le voir.",
|
||||||
|
"Creating rooms...": "Création des salons…",
|
||||||
|
"Skip for now": "Passer pour l’instant",
|
||||||
|
"Failed to create initial space rooms": "Échec de la création des salons initiaux de l’espace",
|
||||||
|
"Room name": "Nom du salon",
|
||||||
|
"Support": "Prise en charge",
|
||||||
|
"Random": "Aléatoire",
|
||||||
|
"Welcome to <name/>": "Bienvenue dans <name/>",
|
||||||
|
"Your private space <name/>": "Votre espace privé <name/>",
|
||||||
|
"Your public space <name/>": "Votre espace public <name/>",
|
||||||
|
"You have been invited to <name/>": "Vous avez été invité dans <name/>",
|
||||||
|
"<inviter/> invited you to <name/>": "<inviter/> vous a invité dans <name/>",
|
||||||
|
"%(count)s members|one": "%(count)s membre",
|
||||||
|
"%(count)s members|other": "%(count)s membres",
|
||||||
|
"Your server does not support showing space hierarchies.": "Votre serveur ne prend pas en charge l’affichage des hiérarchies d’espaces.",
|
||||||
|
"Default Rooms": "Salons par défaut",
|
||||||
|
"Add existing rooms & spaces": "Ajouter des salons et espaces existants",
|
||||||
|
"Accept Invite": "Accepter l’invitation",
|
||||||
|
"Find a room...": "Trouver un salon…",
|
||||||
|
"Manage rooms": "Gérer les salons",
|
||||||
|
"Save changes": "Enregistrer les modifications",
|
||||||
|
"You're in this room": "Vous faites partie de ce salon",
|
||||||
|
"You're in this space": "Vous faites partie de cet espace",
|
||||||
|
"No permissions": "Aucune permission",
|
||||||
|
"Remove from Space": "Supprimer de l’espace",
|
||||||
|
"Undo": "Annuler",
|
||||||
|
"Your message wasn't sent because this homeserver has been blocked by it's administrator. Please <a>contact your service administrator</a> to continue using the service.": "Votre message n’a pas été envoyé car ce serveur d’accueil a été banni par son administrateur. Merci de <a>contacter votre administrateur de service</a> pour poursuivre l’usage de ce service.",
|
||||||
|
"Are you sure you want to leave the space '%(spaceName)s'?": "Êtes vous sûr de vouloir quitter l’espace « %(spaceName)s » ?",
|
||||||
|
"This space is not public. You will not be able to rejoin without an invite.": "Cet espace n’est pas public. Vous ne pourrez pas le rejoindre sans invitation.",
|
||||||
|
"Start audio stream": "Démarrer une diffusion audio",
|
||||||
|
"Failed to start livestream": "Échec lors du démarrage de la diffusion en direct",
|
||||||
|
"Unable to start audio streaming.": "Impossible de démarrer la diffusion audio.",
|
||||||
|
"Save Changes": "Enregistrer les modifications",
|
||||||
|
"Saving...": "Enregistrement…",
|
||||||
|
"View dev tools": "Afficher les outils de développement",
|
||||||
|
"Leave Space": "Quitter l’espace",
|
||||||
|
"Make this space private": "Rendre cet espace privé",
|
||||||
|
"Edit settings relating to your space.": "Modifiez les paramètres de votre espace.",
|
||||||
|
"Space settings": "Paramètres de l’espace",
|
||||||
|
"Failed to save space settings.": "Échec de l’enregistrement des paramètres.",
|
||||||
|
"Unnamed Space": "Espace sans nom",
|
||||||
|
"Invite to %(spaceName)s": "Inviter à %(spaceName)s",
|
||||||
|
"Failed to add rooms to space": "Échec de l’ajout des salons à l’espace",
|
||||||
|
"Apply": "Appliquer",
|
||||||
|
"Applying...": "Application…",
|
||||||
|
"Create a new room": "Créer un nouveau salon",
|
||||||
|
"Don't want to add an existing room?": "Vous ne voulez pas ajouter de salon existant ?",
|
||||||
|
"Spaces": "Espaces",
|
||||||
|
"Filter your rooms and spaces": "Filtrez vos salons et espaces",
|
||||||
|
"Add existing spaces/rooms": "Ajouter des espaces/salons existants",
|
||||||
|
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the space it will be impossible to regain privileges.": "Vous ne pourrez pas annuler ce changement puisque vous vous rétrogradez. Si vous êtes le dernier utilisateur a privilèges de cet espace, il deviendra impossible d’en reprendre contrôle.",
|
||||||
|
"Empty room": "Salon vide",
|
||||||
|
"Suggested Rooms": "Salons suggérés",
|
||||||
|
"Explore space rooms": "Parcourir les salons de cet espace",
|
||||||
|
"You do not have permissions to add rooms to this space": "Vous n’avez pas la permission d’ajouter des salons à cet espace",
|
||||||
|
"Add existing room": "Ajouter un salon existant",
|
||||||
|
"You do not have permissions to create new rooms in this space": "Vous n’avez pas la permission de créer de nouveaux salons dans cet espace",
|
||||||
|
"Send message": "Envoyer le message",
|
||||||
|
"Invite to this space": "Inviter dans cet espace",
|
||||||
|
"Your message was sent": "Votre message a été envoyé",
|
||||||
|
"Encrypting your message...": "Chiffrement de votre message…",
|
||||||
|
"Sending your message...": "Envoi de votre message…",
|
||||||
|
"Spell check dictionaries": "Dictionnaires de correction orthographique",
|
||||||
|
"Space options": "Options de l’espace",
|
||||||
|
"Space Home": "Accueil de l’espace",
|
||||||
|
"New room": "Nouveau salon",
|
||||||
|
"Leave space": "Quitter l’espace",
|
||||||
|
"Invite people": "Inviter des personnes",
|
||||||
|
"Share your public space": "Partager votre espace public",
|
||||||
|
"Invite members": "Inviter des membres",
|
||||||
|
"Invite by email or username": "Inviter par e-mail ou nom d’utilisateur",
|
||||||
|
"Share invite link": "Partager le lien d’invitation",
|
||||||
|
"Click to copy": "Cliquez pour copier",
|
||||||
|
"Collapse space panel": "Réduire le panneau de l’espace",
|
||||||
|
"Expand space panel": "Développer le panneau de l’espace",
|
||||||
|
"Creating...": "Création…",
|
||||||
|
"You can change these at any point.": "Vous pouvez les changer à n’importe quel moment.",
|
||||||
|
"Give it a photo, name and description to help you identify it.": "Définissez une photo, un nom et une description pour vous aider à le retrouver.",
|
||||||
|
"Your private space": "Votre espace privé",
|
||||||
|
"Your public space": "Votre espace public",
|
||||||
|
"You can change this later": "Vous pouvez changer ceci plus tard",
|
||||||
|
"Invite only, best for yourself or teams": "Sur invitation, idéal pour vous-même ou les équipes",
|
||||||
|
"Private": "Privé",
|
||||||
|
"Open space for anyone, best for communities": "Espace ouvert à tous, idéal pour les communautés",
|
||||||
|
"Public": "Public",
|
||||||
|
"Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "Les espaces sont un nouveau moyen de grouper les salons et les personnes. Une invitation est nécessaire pour rejoindre un espace existant",
|
||||||
|
"Create a space": "Créer un espace",
|
||||||
|
"Delete": "Supprimer",
|
||||||
|
"Jump to the bottom of the timeline when you send a message": "Sauter en bas du fil de discussion lorsque vous envoyez un message",
|
||||||
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Prototype d’espaces. Incompatible avec les communautés, les communautés v2 et les étiquettes personnalisées. Nécessite un serveur d’accueil compatible pour certaines fonctionnalités.",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "Ce serveur d’accueil a été banni par ses administrateurs.",
|
||||||
|
"This homeserver has been blocked by its administrator.": "Ce serveur d’accueil a été banni par ses administrateurs.",
|
||||||
|
"You're already in a call with this person.": "Vous êtes déjà en cours d’appel avec cette personne.",
|
||||||
|
"Already in call": "Déjà en cours d’appel"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,675 @@
|
||||||
{}
|
{
|
||||||
|
"Sign in with": "Sínigh isteach le",
|
||||||
|
"Signing In...": "ag Síniú Isteach…",
|
||||||
|
"Sign in": "Sínigh Isteach",
|
||||||
|
"Already have an account? <a>Sign in here</a>": "An bhfuil cuntas agat cheana? <a>Sínigh isteach anseo</a>",
|
||||||
|
"Show less": "Taispeáin níos lú",
|
||||||
|
"Show more": "Taispeáin níos mó",
|
||||||
|
"Show %(count)s more|one": "Taispeáin %(count)s níos mó",
|
||||||
|
"Show %(count)s more|other": "Taispeáin %(count)s níos mó",
|
||||||
|
"Switch to dark mode": "Athraigh go mód dorcha",
|
||||||
|
"Switch to light mode": "Athraigh go mód geal",
|
||||||
|
"User settings": "Socruithe úsáideora",
|
||||||
|
"Community settings": "Socruithe pobail",
|
||||||
|
"Notification settings": "Socruithe fógra",
|
||||||
|
"Got an account? <a>Sign in</a>": "An bhfuil cuntas agat? <a>Sínigh isteach</a>",
|
||||||
|
"New here? <a>Create an account</a>": "Céaduaire? <a>Cruthaigh cuntas</a>",
|
||||||
|
"All settings": "Gach Socrú",
|
||||||
|
"Security & Privacy": "Slándáil ⁊ Príobháideachas",
|
||||||
|
"Security & privacy": "Slándáil ⁊ príobháideachas",
|
||||||
|
"A verification email will be sent to your inbox to confirm setting your new password.": "Seolfar ríomhphost fíoraithe chuig do bhosca isteach chun a dhearbhú go bhfuil do phasfhocal nua socraithe.",
|
||||||
|
"Sign in instead": "Sínigh Isteach ina ionad sin",
|
||||||
|
"Send Reset Email": "Seol ríomhphost athshocruithe",
|
||||||
|
"What's new?": "Cad é nua?",
|
||||||
|
"New? <a>Create account</a>": "Céaduaire? <a>Cruthaigh cuntas</a>",
|
||||||
|
"Forgotten your password?": "An nDearna tú dearmad ar do fhocal faire?",
|
||||||
|
"Forgot password?": "An nDearna tú dearmad ar do fhocal faire?",
|
||||||
|
"Sign In or Create Account": "Sínigh Isteach nó Déan cuntas a chruthú",
|
||||||
|
"Autoplay GIFs and videos": "Uathsheinn GIFs agus físeáin",
|
||||||
|
"Are you sure you want to reject the invitation?": "An bhfuil tú cinnte gur mian leat an cuireadh a dhiúltú?",
|
||||||
|
"Are you sure you want to leave the room '%(roomName)s'?": "An bhfuil tú cinnte gur mian leat an seomra '%(roomName)s' a fhágáil?",
|
||||||
|
"Are you sure?": "An bhfuil tú cinnte?",
|
||||||
|
"Anyone who knows the room's link, including guests": "Duine ar bith a bhfuil eolas aige ar nasc an tseomra, aíonna san áireamh",
|
||||||
|
"Anyone who knows the room's link, apart from guests": "Duine ar bith a bhfuil eolas aige ar nasc an tseomra, seachas aíonna",
|
||||||
|
"An error has occurred.": "D’imigh earráid éigin.",
|
||||||
|
"%(senderName)s answered the call.": "D'fhreagair %(senderName)s an glao.",
|
||||||
|
"A new password must be entered.": "Caithfear focal faire nua a iontráil.",
|
||||||
|
"%(items)s and %(lastItem)s": "%(items)s agus %(lastItem)s",
|
||||||
|
"Always show message timestamps": "Taispeáin stampaí ama teachtaireachta i gcónaí",
|
||||||
|
"Alt Gr": "Alt Gr",
|
||||||
|
"Default Device": "Gléas Réamhshocraithe",
|
||||||
|
"No media permissions": "Gan cheadanna meáin",
|
||||||
|
"No Webcams detected": "Níor braitheadh aon ceamara gréasáin",
|
||||||
|
"No Microphones detected": "Níor braitheadh aon micreafón",
|
||||||
|
"Access Token:": "Licín Rochtana:",
|
||||||
|
"%(targetName)s accepted the invitation for %(displayName)s.": "Ghlac %(targetName)s leis an cuireadh ó %(displayName)s.",
|
||||||
|
"%(targetName)s accepted an invitation.": "Ghlac %(targetName)s leis an cuireadh.",
|
||||||
|
"Waiting for answer": "ag Fanacht le freagra",
|
||||||
|
"%(senderName)s started a call": "Thosaigh %(senderName)s an glao",
|
||||||
|
"You started a call": "Thosaigh tú an glao",
|
||||||
|
"Call ended": "Críochnaíodh an glao",
|
||||||
|
"%(senderName)s ended the call": "Chríochnaigh %(senderName)s an glao",
|
||||||
|
"You ended the call": "Chríochnaigh tú an glao",
|
||||||
|
"Call in Progress": "Glaoch ar siúl",
|
||||||
|
"Call in progress": "Glaoch ar siúl",
|
||||||
|
"Unable to access microphone": "Ní féidir rochtain a fháil ar mhicreafón",
|
||||||
|
"Try using turn.matrix.org": "Déan iarracht turn.matrix.org a úsáid",
|
||||||
|
"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.": "De rogha air sin, is féidir leat iarracht a dhéanamh an freastalaí poiblí ag <code>turn.matrix.org</code> a úsáid, ach ní bheidh sé seo chomh iontaofa, agus roinnfidh sé do sheoladh ip leis an freastalaí sin. Is féidir leat é seo a bhainistiú sa socruithe freisin.",
|
||||||
|
"Please ask the administrator of your homeserver (<code>%(homeserverDomain)s</code>) to configure a TURN server in order for calls to work reliably.": "Iarr ar an riarthóir do fhreastalaí baile (<code>%(homeserverDomain)s</code>) freastalaí TURN a chumrú go bhfeidhmeoidh glaonna go hiontaofa.",
|
||||||
|
"Call failed due to misconfigured server": "Theip an glaoch de bharr freastalaí mícumraithe",
|
||||||
|
"Answered Elsewhere": "Tógtha in áit eile",
|
||||||
|
"The call could not be established": "Níor féidir an glaoch a bhunú",
|
||||||
|
"The remote side failed to pick up": "Níor thóg an taobh eile an glaoch",
|
||||||
|
"The other party declined the call.": "Dhiúltaigh an duine eile an glaoch.",
|
||||||
|
"Call Declined": "Glao Diúltaithe",
|
||||||
|
"Unable to load! Check your network connectivity and try again.": "Ní féidir a lódáil! Seiceáil do nascacht líonra agus bain triail eile as.",
|
||||||
|
"Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "As chás go bhfuil eolas inaitheanta ar an leathanach seo, mar shampla ID seomra, úsáideora nó grúpa, baintear na sonraí sin sula seoltar chuig an bhfreastalaí iad.",
|
||||||
|
"The information being sent to us to help make %(brand)s better includes:": "Cuimsíonn an eolas a chuirtear chugainn chun cabhrú le %(brand)s a dhéanamh níos fearr:",
|
||||||
|
"Your device resolution": "Taifeach do gléas",
|
||||||
|
"Your user agent": "Do ghníomhaire úsáideora",
|
||||||
|
"The call was answered on another device.": "Do ghníomhaire úsáideora.",
|
||||||
|
"Every page you use in the app": "Gach leathanach a úsáideann tú san aip",
|
||||||
|
"Whether you're using %(brand)s as an installed Progressive Web App": "Má úsáideann tú %(brand)s mar feidhmchlár gréasáin forásach (PWA) suiteáilte",
|
||||||
|
"Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Má úsáideann tú an gné “grabhróige aráin” (abhatáranna os cionn an liosta seomra)",
|
||||||
|
"Whether you're using %(brand)s on a device where touch is the primary input mechanism": "Má úsáideann tú %(brand)s ar gléas arb é an teagmháil an phríomh-mheicníocht ionchuir",
|
||||||
|
"Your homeserver's URL": "An URL do fhreastalaí baile",
|
||||||
|
"Whether or not you're using the Richtext mode of the Rich Text Editor": "Má tá nó níl tú ag úsáid an modh téacs saibhir an eagarthóra téacs saibhir",
|
||||||
|
"Which officially provided instance you are using, if any": "Cén ásc a chuirtear ar fáil go hoifigiúil atá á úsáid agat, más ann dó",
|
||||||
|
"Your language of choice": "Do theanga roghnaithe",
|
||||||
|
"Whether or not you're logged in (we don't record your username)": "Má logáil nó níor logáil tú isteach (ní thaifeadaimid d'ainm úsáideora)",
|
||||||
|
"Failed to verify email address: make sure you clicked the link in the email": "Níor cinntíodh an seoladh ríomhphoist: déan cinnte gur chliceáil tú an nasc sa ríomhphost",
|
||||||
|
"Reject & Ignore user": "Diúltaigh ⁊ Neamaird do úsáideoir",
|
||||||
|
"Ignore": "Neamhaird",
|
||||||
|
"Ignored users": "Úsáideoirí neamhairde",
|
||||||
|
"Ignored/Blocked": "Neamhairde/Tachta",
|
||||||
|
"Message Pinning": "Ceangal teachtaireachta",
|
||||||
|
"Avoid sequences": "Seachain seicheamh",
|
||||||
|
"Unrecognised address": "Seoladh nár aithníodh",
|
||||||
|
"(no answer)": "(gan freagra)",
|
||||||
|
"Displays action": "Taispeáin gníomh",
|
||||||
|
"Verified key": "Eochair deimhnithe",
|
||||||
|
"Unignored user": "Úsáideoir leis aird",
|
||||||
|
"Ignored user": "Úsáideoir neamhairde",
|
||||||
|
"Unignore": "Stop ag tabhairt neamhaird air",
|
||||||
|
"Leave room": "Fág an seomra",
|
||||||
|
"Missing roomId.": "Comhartha aitheantais seomra ar iarraidh.",
|
||||||
|
"Operation failed": "Chlis an oibríocht",
|
||||||
|
"Unnamed Room": "Seomra gan ainm",
|
||||||
|
"%(weekDayName)s %(time)s": "%(weekDayName)s ar a %(time)s",
|
||||||
|
"Upload Failed": "Chlis an uaslódáil",
|
||||||
|
"Permission Required": "Is Teastáil Cead",
|
||||||
|
"Call Failed": "Chlis an glaoch",
|
||||||
|
"e.g. <CurrentPageURL>": "mar shampla <CurrentPageURL>",
|
||||||
|
"e.g. %(exampleValue)s": "mar shampla %(exampleValue)s",
|
||||||
|
"Inviting...": "ag Tabhairt cuireadh…",
|
||||||
|
"Finish": "Críochnaigh",
|
||||||
|
"Support": "Tacaíocht",
|
||||||
|
"Random": "Randamach",
|
||||||
|
"Undo": "Cuir ar ceal",
|
||||||
|
"Saving...": "ag Sábháil…",
|
||||||
|
"Apply": "Cuir i bhfeidhm",
|
||||||
|
"Applying...": "ag Cur i bhfeidhm…",
|
||||||
|
"Spaces": "Spásanna",
|
||||||
|
"Creating...": "ag Cruthú…",
|
||||||
|
"Private": "Príobháideach",
|
||||||
|
"Public": "Poiblí",
|
||||||
|
"Delete": "Bain amach",
|
||||||
|
"Value:": "Luach:",
|
||||||
|
"Level": "Leibhéal",
|
||||||
|
"Caution:": "Faichill:",
|
||||||
|
"Setting:": "Socrú:",
|
||||||
|
"Value": "Luach",
|
||||||
|
"Abort": "Tobscoir",
|
||||||
|
"Windows": "Fuinneoga",
|
||||||
|
"Screens": "Scáileáin",
|
||||||
|
"Transfer": "Aistrigh",
|
||||||
|
"Hold": "Fan",
|
||||||
|
"Resume": "Tosaigh arís",
|
||||||
|
"Effects": "Tionchair",
|
||||||
|
"Homeserver": "Freastalaí baile",
|
||||||
|
"Approve": "Ceadaigh",
|
||||||
|
"Filter": "Scag",
|
||||||
|
"Role": "Ról",
|
||||||
|
"Zimbabwe": "an tSiombáib",
|
||||||
|
"Zambia": "an tSaimbia",
|
||||||
|
"Yemen": "Éimin",
|
||||||
|
"Vietnam": "Vítneam",
|
||||||
|
"Venezuela": "Veiniséala",
|
||||||
|
"Vanuatu": "Vanuatú",
|
||||||
|
"Uzbekistan": "an Úisbéiceastáin",
|
||||||
|
"Uruguay": "Uragua",
|
||||||
|
"Ukraine": "an Úcráin",
|
||||||
|
"Uganda": "Uganda",
|
||||||
|
"Tuvalu": "Túvalú",
|
||||||
|
"Turkmenistan": "an Tuircméanastáin",
|
||||||
|
"Turkey": "an Tuirc",
|
||||||
|
"Tunisia": "an Túinéis",
|
||||||
|
"Tonga": "Tonga",
|
||||||
|
"Tokelau": "Oileáin Tokelau",
|
||||||
|
"Togo": "Tóga",
|
||||||
|
"Timor-Leste": "Tíomór Thoir",
|
||||||
|
"Thailand": "an Téalainn",
|
||||||
|
"Tanzania": "an Tansáin",
|
||||||
|
"Tajikistan": "an Táidsíceastáin",
|
||||||
|
"Taiwan": "an Téaváin",
|
||||||
|
"Syria": "an tSiria",
|
||||||
|
"Switzerland": "an Eilvéis",
|
||||||
|
"Sweden": "an tSualainn",
|
||||||
|
"Swaziland": "an tSuasalainn",
|
||||||
|
"Suriname": "Suranam",
|
||||||
|
"Sudan": "an tSúdáin",
|
||||||
|
"Spain": "an Spáinn",
|
||||||
|
"Somalia": "an tSomáil",
|
||||||
|
"Slovenia": "an tSlóivéin",
|
||||||
|
"Slovakia": "an tSlóvaic",
|
||||||
|
"Singapore": "Singeapór",
|
||||||
|
"Seychelles": "na Séiséil",
|
||||||
|
"Serbia": "an tSeirbia",
|
||||||
|
"Senegal": "an tSeineagáil",
|
||||||
|
"Samoa": "Samó",
|
||||||
|
"Réunion": "La Réunion",
|
||||||
|
"Rwanda": "Ruanda",
|
||||||
|
"Russia": "an Rúis",
|
||||||
|
"Romania": "an Rómáin",
|
||||||
|
"Qatar": "Catar",
|
||||||
|
"Portugal": "an Phortaingéil",
|
||||||
|
"Poland": "an Pholainn",
|
||||||
|
"Philippines": "na hOileáin Fhilipíneacha",
|
||||||
|
"Peru": "Peiriú",
|
||||||
|
"Paraguay": "Paragua",
|
||||||
|
"Panama": "Panama",
|
||||||
|
"Palestine": "an Phalaistín",
|
||||||
|
"Palau": "Oileáin Palau",
|
||||||
|
"Pakistan": "an Phacastáin",
|
||||||
|
"Oman": "Óman",
|
||||||
|
"Norway": "an Iorua",
|
||||||
|
"Niue": "Niue",
|
||||||
|
"Nigeria": "an Nigéir",
|
||||||
|
"Niger": "an Nígir",
|
||||||
|
"Nicaragua": "Nicearagua",
|
||||||
|
"Netherlands": "an Ísiltír",
|
||||||
|
"Nepal": "Neipeal",
|
||||||
|
"Nauru": "Nárú",
|
||||||
|
"Namibia": "an Namaib",
|
||||||
|
"Myanmar": "Maenmar",
|
||||||
|
"Mozambique": "Mósaimbíc",
|
||||||
|
"Morocco": "Maracó",
|
||||||
|
"Montserrat": "Montsarat",
|
||||||
|
"Montenegro": "Montainéagró",
|
||||||
|
"Mongolia": "an Mhongóil",
|
||||||
|
"Monaco": "Monacó",
|
||||||
|
"Moldova": "an Mholdóiv",
|
||||||
|
"Micronesia": "an Mhicrinéis",
|
||||||
|
"Mexico": "Meicsiceo",
|
||||||
|
"Mayotte": "Mayotte",
|
||||||
|
"Mauritius": "Oileán Mhuirís",
|
||||||
|
"Mauritania": "an Mháratáin",
|
||||||
|
"Martinique": "Martinique",
|
||||||
|
"Malta": "Málta",
|
||||||
|
"Mali": "Mailí",
|
||||||
|
"Maldives": "Oileáin Mhaildíve",
|
||||||
|
"Malaysia": "an Mhalaeisia",
|
||||||
|
"Malawi": "an Mhaláiv",
|
||||||
|
"Madagascar": "Madagascar",
|
||||||
|
"Macedonia": "an Mhacadóin",
|
||||||
|
"Macau": "Macau",
|
||||||
|
"Luxembourg": "Lucsamburg",
|
||||||
|
"Lithuania": "an Liotuáin",
|
||||||
|
"Liechtenstein": "Lichtinstéin",
|
||||||
|
"Libya": "an Libia",
|
||||||
|
"Liberia": "an Libéir",
|
||||||
|
"Lesotho": "Leosóta",
|
||||||
|
"Lebanon": "an Liobáin",
|
||||||
|
"Latvia": "an Laitvia",
|
||||||
|
"Laos": "Laos",
|
||||||
|
"Kyrgyzstan": "an Chirgeastáin",
|
||||||
|
"Kuwait": "Cuáit",
|
||||||
|
"Kosovo": "an Chosaiv",
|
||||||
|
"Kiribati": "Ciribeas",
|
||||||
|
"Kenya": "an Chéinia",
|
||||||
|
"Kazakhstan": "an Chasacstáin",
|
||||||
|
"Jordan": "an Iordáin",
|
||||||
|
"Jersey": "Geirsí",
|
||||||
|
"Japan": "an tSeapáin",
|
||||||
|
"Jamaica": "Iamáice",
|
||||||
|
"Italy": "an Iodáil",
|
||||||
|
"Israel": "Iosrael",
|
||||||
|
"Ireland": "Éire",
|
||||||
|
"Iraq": "an Iaráic",
|
||||||
|
"Iran": "an Iaráin",
|
||||||
|
"Indonesia": "an Indinéis",
|
||||||
|
"India": "an India",
|
||||||
|
"Iceland": "an Íoslainn",
|
||||||
|
"Hungary": "an Ungáir",
|
||||||
|
"Honduras": "Hondúras",
|
||||||
|
"Haiti": "Háití",
|
||||||
|
"Guyana": "an Ghuáin",
|
||||||
|
"Guinea-Bissau": "Guine Bissau",
|
||||||
|
"Guinea": "an Ghuine",
|
||||||
|
"Guernsey": "Geansaí",
|
||||||
|
"Guatemala": "Guatamala",
|
||||||
|
"Guam": "Guam",
|
||||||
|
"Guadeloupe": "Guadalúip",
|
||||||
|
"Grenada": "Greanáda",
|
||||||
|
"Greenland": "an Ghraonlainn",
|
||||||
|
"Greece": "an Ghréig",
|
||||||
|
"Gibraltar": "Giobráltar",
|
||||||
|
"Ghana": "Gána",
|
||||||
|
"Germany": "an Ghearmáin",
|
||||||
|
"Georgia": "an tSeoirsia",
|
||||||
|
"Gambia": "an Ghaimbia",
|
||||||
|
"Gabon": "an Ghabúin",
|
||||||
|
"France": "an Fhrainc",
|
||||||
|
"Finland": "an Fhionlainn",
|
||||||
|
"Fiji": "Fidsí",
|
||||||
|
"Ethiopia": "an Aetóip",
|
||||||
|
"Estonia": "an Eastóin",
|
||||||
|
"Eritrea": "an Eirtré",
|
||||||
|
"Egypt": "an Éigipt",
|
||||||
|
"Ecuador": "Eacuadór",
|
||||||
|
"Dominica": "Doiminice",
|
||||||
|
"Djibouti": "Djibouti",
|
||||||
|
"Denmark": "an Danmhairg",
|
||||||
|
"Cyprus": "an Chipir",
|
||||||
|
"Curaçao": "Curaçao",
|
||||||
|
"Cuba": "Cúba",
|
||||||
|
"Croatia": "an Chróit",
|
||||||
|
"Comoros": "Oileáin Chomóra",
|
||||||
|
"Colombia": "an Cholóim",
|
||||||
|
"China": "an tSín",
|
||||||
|
"Chile": "an tSile",
|
||||||
|
"Chad": "Sead",
|
||||||
|
"Canada": "Ceanada",
|
||||||
|
"Cameroon": "Camarún",
|
||||||
|
"Cambodia": "an Chambóid",
|
||||||
|
"Burundi": "an Bhurúin",
|
||||||
|
"Bulgaria": "an Bhulgáir",
|
||||||
|
"Brunei": "Brúiné",
|
||||||
|
"Brazil": "an Bhrasaíl",
|
||||||
|
"Botswana": "an Bhotsuáin",
|
||||||
|
"Bosnia": "an Bhoisnia agus an Heirseagaivéin",
|
||||||
|
"Bolivia": "an Bholaiv",
|
||||||
|
"Bhutan": "an Bhútáin",
|
||||||
|
"Bermuda": "Beirmiúda",
|
||||||
|
"Benin": "Beinin",
|
||||||
|
"Belize": "an Bheilís",
|
||||||
|
"Belgium": "an Bheilg",
|
||||||
|
"Belarus": "an Bhealarúis",
|
||||||
|
"Barbados": "Barbadós",
|
||||||
|
"Bangladesh": "an Bhanglaidéis",
|
||||||
|
"Bahrain": "Bairéin",
|
||||||
|
"Bahamas": "na Bahámaí",
|
||||||
|
"Azerbaijan": "an Asarbaiseáin",
|
||||||
|
"Austria": "an Ostair",
|
||||||
|
"Australia": "an Astráil",
|
||||||
|
"Aruba": "Arúba",
|
||||||
|
"Armenia": "an Airméin",
|
||||||
|
"Argentina": "an Airgintín",
|
||||||
|
"Antarctica": "Antartaice",
|
||||||
|
"Anguilla": "Angaíle",
|
||||||
|
"Angola": "Angóla",
|
||||||
|
"Andorra": "Andóra",
|
||||||
|
"Algeria": "an Ailgéir",
|
||||||
|
"Albania": "an Albáin",
|
||||||
|
"Afghanistan": "an Afganastáin",
|
||||||
|
"Comment": "Trácht",
|
||||||
|
"Pin": "Biorán",
|
||||||
|
"Widgets": "Giuirléidí",
|
||||||
|
"ready": "réidh",
|
||||||
|
"Algorithm:": "Algartam:",
|
||||||
|
"Unpin": "Neamhceangail",
|
||||||
|
"About": "Faoi",
|
||||||
|
"Privacy": "Príobháideachas",
|
||||||
|
"Show": "Taispeáin",
|
||||||
|
"Information": "Eolas",
|
||||||
|
"Away": "Imithe",
|
||||||
|
"Favourited": "Roghnaithe",
|
||||||
|
"Restore": "Athbhunaigh",
|
||||||
|
"Dark": "Dorcha",
|
||||||
|
"Light": "Geal",
|
||||||
|
"A-Z": "A-Z",
|
||||||
|
"Activity": "Gníomhaíocht",
|
||||||
|
"Feedback": "Aiseolas",
|
||||||
|
"People": "Daoine",
|
||||||
|
"Ok": "Togha",
|
||||||
|
"Categories": "Catagóire",
|
||||||
|
"Appearance": "Cuma",
|
||||||
|
"Syncing...": "ag Sioncrónú...",
|
||||||
|
"Verified": "Deimhnithe",
|
||||||
|
"End": "End",
|
||||||
|
"Space": "Spás",
|
||||||
|
"Enter": "Enter",
|
||||||
|
"Esc": "Esc",
|
||||||
|
"Ctrl": "Ctrl",
|
||||||
|
"Super": "Súpar",
|
||||||
|
"Shift": "Shift",
|
||||||
|
"Alt": "Alt",
|
||||||
|
"Autocomplete": "Uathiomlánaigh",
|
||||||
|
"Calls": "Glaonna",
|
||||||
|
"Navigation": "Nascleanúint",
|
||||||
|
"Matrix": "Matrix",
|
||||||
|
"Accepting…": "ag Glacadh leis…",
|
||||||
|
"Cancelling…": "ag Cealú…",
|
||||||
|
"exists": "a bheith ann",
|
||||||
|
"or": "nó",
|
||||||
|
"Copy": "Cóipeáil",
|
||||||
|
"Mod": "Mod",
|
||||||
|
"Bridges": "Droichid",
|
||||||
|
"Disable": "Cuir as feidhm",
|
||||||
|
"Enable": "Tosaigh",
|
||||||
|
"Manage": "Bainistigh",
|
||||||
|
"Review": "Athbhreithnigh",
|
||||||
|
"Later": "Níos deireanaí",
|
||||||
|
"Done": "Críochnaithe",
|
||||||
|
"Start": "Tosaigh",
|
||||||
|
"Lock": "Glasáil",
|
||||||
|
"Suggestions": "Moltaí",
|
||||||
|
"Go": "Téigh",
|
||||||
|
"Cross-signing": "Cros-síniú",
|
||||||
|
"Reactions": "Freagartha",
|
||||||
|
"Unencrypted": "Gan chriptiú",
|
||||||
|
"Upgrade": "Uasghrádaigh",
|
||||||
|
"Verify": "Cinntigh",
|
||||||
|
"Security": "Slándáil",
|
||||||
|
"Trusted": "Dílis",
|
||||||
|
"Subscribe": "Liostáil",
|
||||||
|
"Unsubscribe": "Díliostáil",
|
||||||
|
"None": "Níl aon cheann",
|
||||||
|
"Trust": "Cuir muinín i",
|
||||||
|
"React": "Freagair",
|
||||||
|
"Flags": "Bratacha",
|
||||||
|
"Symbols": "Siombailí",
|
||||||
|
"Objects": "Rudaí",
|
||||||
|
"Activities": "Gníomhaíochtaí",
|
||||||
|
"Document": "Cáipéis",
|
||||||
|
"Complete": "Críochnaigh",
|
||||||
|
"View": "Amharc",
|
||||||
|
"Preview": "Réamhamharc",
|
||||||
|
"Strikethrough": "Líne a chur trí",
|
||||||
|
"Italics": "Iodálach",
|
||||||
|
"Bold": "Trom",
|
||||||
|
"ID": "Comhartha aitheantais",
|
||||||
|
"Disconnect": "Dícheangail",
|
||||||
|
"Share": "Roinn le",
|
||||||
|
"Revoke": "Cúlghair",
|
||||||
|
"Discovery": "Aimsiú",
|
||||||
|
"Actions": "Gníomhartha",
|
||||||
|
"Messages": "Teachtaireachtaí",
|
||||||
|
"Retry": "Atriail",
|
||||||
|
"Success!": "Rath!",
|
||||||
|
"Download": "Íoslódáil",
|
||||||
|
"Import": "Iompórtáil",
|
||||||
|
"Export": "Easpórtáil",
|
||||||
|
"Name": "Ainm",
|
||||||
|
"Users": "Úsáideoirí",
|
||||||
|
"Emoji": "Straoiseog",
|
||||||
|
"Commands": "Ordú",
|
||||||
|
"Guest": "Cuairteoir",
|
||||||
|
"Room": "Seomra",
|
||||||
|
"Logout": "Logáil amach",
|
||||||
|
"Description": "Cuntas",
|
||||||
|
"Everyone": "Gach duine",
|
||||||
|
"Other": "Eile",
|
||||||
|
"Change": "Athraigh",
|
||||||
|
"Phone": "Guthán",
|
||||||
|
"Username": "Ainm úsáideora",
|
||||||
|
"Email": "Ríomhphost",
|
||||||
|
"Submit": "Cuir isteach",
|
||||||
|
"Code": "Cód",
|
||||||
|
"Home": "Tús",
|
||||||
|
"Hide": "Cuir i bhfolach",
|
||||||
|
"Favourite": "Cuir mar ceanán",
|
||||||
|
"Leave": "Fág",
|
||||||
|
"Quote": "Luaigh",
|
||||||
|
"Resend": "Athsheol",
|
||||||
|
"Upload": "Uaslódáil",
|
||||||
|
"Next": "Ar Aghaidh",
|
||||||
|
"Summary": "Achoimre",
|
||||||
|
"Service": "Seirbhís",
|
||||||
|
"Skip": "Léim",
|
||||||
|
"Refresh": "Athnuaigh",
|
||||||
|
"Toolbox": "Uirlisí",
|
||||||
|
"Back": "Ar Ais",
|
||||||
|
"Create": "Cruthaigh",
|
||||||
|
"example": "sampla",
|
||||||
|
"Example": "Sampla",
|
||||||
|
"Removing…": "ag Baint…",
|
||||||
|
"Changelog": "Loga na n-athruithe",
|
||||||
|
"Unavailable": "Níl sé ar fáil",
|
||||||
|
"Notes": "Nótaí",
|
||||||
|
"expand": "méadaigh",
|
||||||
|
"collapse": "cumaisc",
|
||||||
|
"%(oneUser)sleft %(count)s times|one": "D'fhág %(oneUser)s",
|
||||||
|
"%(severalUsers)sleft %(count)s times|one": "D'fhág %(severalUsers)s",
|
||||||
|
"%(oneUser)sjoined %(count)s times|one": "Tháinig %(oneUser)s isteach",
|
||||||
|
"%(severalUsers)sjoined %(count)s times|one": "Tháinig %(severalUsers)s isteach",
|
||||||
|
"Communities": "Pobail",
|
||||||
|
"Join": "Téigh isteach",
|
||||||
|
"Warning": "Rabhadh",
|
||||||
|
"Update": "Uasdátaigh",
|
||||||
|
"edited": "curtha in eagar",
|
||||||
|
"Copied!": "Cóipeáilte!",
|
||||||
|
"Attachment": "Ceangaltán",
|
||||||
|
"Options": "Roghanna",
|
||||||
|
"Edit": "Cuir in eagar",
|
||||||
|
"Reply": "Freagair",
|
||||||
|
"Yesterday": "Inné",
|
||||||
|
"Today": "Inniu",
|
||||||
|
"Saturday": "Dé Sathairn",
|
||||||
|
"Friday": "Dé hAoine",
|
||||||
|
"Thursday": "Déardaoin",
|
||||||
|
"Wednesday": "Dé Céadaoin",
|
||||||
|
"Tuesday": "Dé Máirt",
|
||||||
|
"Monday": "Dé Luain",
|
||||||
|
"Sunday": "Dé Domhnaigh",
|
||||||
|
"Members": "Baill",
|
||||||
|
"Stickerpack": "Pacáiste greamáin",
|
||||||
|
"Search…": "Cuardaigh…",
|
||||||
|
"Reject": "Diúltaigh",
|
||||||
|
"Re-join": "Téigh ar ais isteach",
|
||||||
|
"Historical": "Stairiúil",
|
||||||
|
"Rooms": "Seomraí",
|
||||||
|
"Favourites": "Ceanáin",
|
||||||
|
"Invites": "Cuirí",
|
||||||
|
"Search": "Cuardaigh",
|
||||||
|
"Settings": "Socruithe",
|
||||||
|
"Replying": "Ag freagairt",
|
||||||
|
"Unknown": "Anaithnid",
|
||||||
|
"Offline": "As líne",
|
||||||
|
"Idle": "Díomhaoin",
|
||||||
|
"Online": "Ar Líne",
|
||||||
|
"%(duration)sd": "%(duration)sl",
|
||||||
|
"%(duration)sh": "%(duration)su",
|
||||||
|
"%(duration)sm": "%(duration)sn",
|
||||||
|
"%(duration)ss": "%(duration)ss",
|
||||||
|
"Delete Backup": "Scrios cúltaca",
|
||||||
|
"Email Address": "Seoladh Ríomhphoist",
|
||||||
|
"Last seen": "Úsáid deireanach",
|
||||||
|
"Change Password": "Athraigh focal faire",
|
||||||
|
"Confirm password": "Deimhnigh focal faire",
|
||||||
|
"New Password": "Focal Faire Nua",
|
||||||
|
"Current password": "Focal faire reatha",
|
||||||
|
"Upload new:": "Uaslódáil nua:",
|
||||||
|
"Light bulb": "Bolgán solais",
|
||||||
|
"Thumbs up": "Ordógí suas",
|
||||||
|
"Got It": "Tuigthe",
|
||||||
|
"Call invitation": "Nuair a fhaighim cuireadh glaoigh",
|
||||||
|
"Collecting logs": "ag Bailiú logaí",
|
||||||
|
"Room Colour": "Dath an tSeomra",
|
||||||
|
"Loading...": "ag Lódáil...",
|
||||||
|
"Invited": "Le cuireadh",
|
||||||
|
"Close": "Dún",
|
||||||
|
"Mute": "Ciúinaigh",
|
||||||
|
"Unmute": "Stop ag ciúnú",
|
||||||
|
"Invite": "Tabhair cuireadh",
|
||||||
|
"Mention": "Luaigh",
|
||||||
|
"Demote": "Bain ceadanna",
|
||||||
|
"Ban": "Coisc",
|
||||||
|
"Kick": "Caith amach",
|
||||||
|
"Disinvite": "Tarraing siar cuireadh",
|
||||||
|
"Encrypted": "Criptithe",
|
||||||
|
"Encryption": "Criptiúchán",
|
||||||
|
"Anyone": "Aon duine",
|
||||||
|
"Permissions": "Ceadanna",
|
||||||
|
"Unban": "Bain an coisc",
|
||||||
|
"Browse": "Brabhsáil",
|
||||||
|
"Reset": "Athshocraigh",
|
||||||
|
"Sounds": "Fuaimeanna",
|
||||||
|
"Camera": "Ceamara",
|
||||||
|
"Microphone": "Micreafón",
|
||||||
|
"Cryptography": "Cripteagrafaíocht",
|
||||||
|
"Timeline": "Amlíne",
|
||||||
|
"Composer": "Eagarthóir",
|
||||||
|
"Preferences": "Roghanna",
|
||||||
|
"Notifications": "Fógraí",
|
||||||
|
"Versions": "Leaganacha",
|
||||||
|
"Labs": "Turgnaimh",
|
||||||
|
"FAQ": "Ceisteanna Coitianta - CC",
|
||||||
|
"Credits": "Creidiúintí",
|
||||||
|
"Legal": "Dlí",
|
||||||
|
"General": "Ginearálta",
|
||||||
|
"Theme": "Téama",
|
||||||
|
"Account": "Cuntas",
|
||||||
|
"Profile": "Próifíl",
|
||||||
|
"Success": "Rath",
|
||||||
|
"Flair": "Suaitheantas",
|
||||||
|
"Save": "Sábháil",
|
||||||
|
"Noisy": "Callánach",
|
||||||
|
"On": "Ar siúl",
|
||||||
|
"Off": "Múchta",
|
||||||
|
"Keywords": "Eochairfhocail",
|
||||||
|
"Advanced": "Forbartha",
|
||||||
|
"Add": "Cuir",
|
||||||
|
"Remove": "Bain",
|
||||||
|
"No": "Níl",
|
||||||
|
"Yes": "Tá",
|
||||||
|
"Authentication": "Fíordheimhniú",
|
||||||
|
"Password": "Pasfhocal",
|
||||||
|
"Warning!": "Aire!",
|
||||||
|
"Folder": "Fillteán",
|
||||||
|
"Headphones": "Cluasáin",
|
||||||
|
"Anchor": "Ancaire",
|
||||||
|
"Bell": "Cloigín",
|
||||||
|
"Trumpet": "Trumpa",
|
||||||
|
"Guitar": "Giotár",
|
||||||
|
"Ball": "Liathróid",
|
||||||
|
"Trophy": "Corn",
|
||||||
|
"Rocket": "Roicéad",
|
||||||
|
"Aeroplane": "Eitleán",
|
||||||
|
"Bicycle": "Rothar",
|
||||||
|
"Train": "Traein",
|
||||||
|
"Flag": "Bratach",
|
||||||
|
"Telephone": "Guthán",
|
||||||
|
"Hammer": "Casúr",
|
||||||
|
"Key": "Eochair",
|
||||||
|
"Scissors": "Siosúr",
|
||||||
|
"Paperclip": "Fáiscín páipéir",
|
||||||
|
"Pencil": "Peann luaidhe",
|
||||||
|
"Book": "Leabhar",
|
||||||
|
"Gift": "Bronntanas",
|
||||||
|
"Clock": "Clog",
|
||||||
|
"Hourglass": "Orláiste",
|
||||||
|
"Umbrella": "Scáth báistí",
|
||||||
|
"Santa": "Daidí na Nollag",
|
||||||
|
"Spanner": "Castaire",
|
||||||
|
"Glasses": "Spéaclaí",
|
||||||
|
"Hat": "Hata",
|
||||||
|
"Robot": "Róbat",
|
||||||
|
"Smiley": "Straoiseog",
|
||||||
|
"Heart": "Croí",
|
||||||
|
"Cake": "Cáca",
|
||||||
|
"Pizza": "Píotsa",
|
||||||
|
"Corn": "Grán buí",
|
||||||
|
"Strawberry": "Sú talún",
|
||||||
|
"Apple": "Úll",
|
||||||
|
"Banana": "Banana",
|
||||||
|
"Fire": "Tine",
|
||||||
|
"Cloud": "Scamall",
|
||||||
|
"Moon": "Gealach",
|
||||||
|
"Globe": "Cruinneog",
|
||||||
|
"Mushroom": "Muisiriún",
|
||||||
|
"Cactus": "Cachtas",
|
||||||
|
"Tree": "Crann",
|
||||||
|
"Flower": "Bláth",
|
||||||
|
"Butterfly": "Féileacán",
|
||||||
|
"Octopus": "Ochtapas",
|
||||||
|
"Fish": "Iasc",
|
||||||
|
"Turtle": "Turtar",
|
||||||
|
"Penguin": "Piongain",
|
||||||
|
"Rooster": "Coileach",
|
||||||
|
"Panda": "Panda",
|
||||||
|
"Rabbit": "Coinín",
|
||||||
|
"Elephant": "Eilifint",
|
||||||
|
"Pig": "Muc",
|
||||||
|
"Unicorn": "Aonbheannach",
|
||||||
|
"Horse": "Capall",
|
||||||
|
"Lion": "Leon",
|
||||||
|
"Cat": "Cat",
|
||||||
|
"Dog": "Madra",
|
||||||
|
"Cancel": "Cuir ar ceal",
|
||||||
|
"Verified!": "Deimhnithe!",
|
||||||
|
"OK": "Togha",
|
||||||
|
"Accept": "Glac",
|
||||||
|
"Decline": "Diúltaigh",
|
||||||
|
"Someone": "Duine éigin",
|
||||||
|
"Reason": "Cúis",
|
||||||
|
"Usage": "Úsáid",
|
||||||
|
"Admin": "Riarthóir",
|
||||||
|
"Moderator": "Modhnóir",
|
||||||
|
"Restricted": "Teoranta",
|
||||||
|
"Default": "Réamhshocrú",
|
||||||
|
"Register": "Cláraigh",
|
||||||
|
"Error": "Earráid",
|
||||||
|
"AM": "RN",
|
||||||
|
"PM": "IN",
|
||||||
|
"Dec": "Nol",
|
||||||
|
"Nov": "Saṁ",
|
||||||
|
"Oct": "DFó",
|
||||||
|
"Sep": "MFó",
|
||||||
|
"Aug": "Lún",
|
||||||
|
"Jul": "Iúil",
|
||||||
|
"Jun": "Meiṫ",
|
||||||
|
"May": "Beal",
|
||||||
|
"Apr": "Aib",
|
||||||
|
"Mar": "Már",
|
||||||
|
"Feb": "Feaḃ",
|
||||||
|
"Jan": "Ean",
|
||||||
|
"Sat": "Saṫ",
|
||||||
|
"Fri": "Aoi",
|
||||||
|
"Thu": "Déa",
|
||||||
|
"Wed": "Céa",
|
||||||
|
"Tue": "Mái",
|
||||||
|
"Mon": "Lua",
|
||||||
|
"Sun": "Doṁ",
|
||||||
|
"Send": "Seol",
|
||||||
|
"Continue": "Lean ar aghaidh",
|
||||||
|
"Analytics": "Anailísiú sonraí",
|
||||||
|
"The version of %(brand)s": "An leagan %(brand)s",
|
||||||
|
"The platform you're on": "An t-ardán ar a bhfuil tú",
|
||||||
|
"Add Phone Number": "Cuir uimhir ghutháin",
|
||||||
|
"Click the button below to confirm adding this phone number.": "Cliceáil an cnaipe thíos chun an uimhir ghutháin nua a dheimhniú.",
|
||||||
|
"Confirm adding phone number": "Deimhnigh an uimhir ghutháin nua",
|
||||||
|
"Confirm adding this phone number by using Single Sign On to prove your identity.": "Deimhnigh an uimhir ghutháin seo le SSO mar cruthúnas céannachta.",
|
||||||
|
"Add Email Address": "Cuir seoladh ríomhphoist",
|
||||||
|
"Confirm": "Deimhnigh",
|
||||||
|
"Click the button below to confirm adding this email address.": "Cliceáil an cnaipe thíos chun an seoladh ríomhphoist nua a dheimhniú.",
|
||||||
|
"Confirm adding email": "Deimhnigh an seoladh ríomhphoist nua",
|
||||||
|
"Single Sign On": "Single Sign On",
|
||||||
|
"Confirm adding this email address by using Single Sign On to prove your identity.": "Deimhnigh an seoladh ríomhphoist seo le SSO mar cruthúnas céannachta.",
|
||||||
|
"Explore rooms": "Breathnaigh thart ar na seomraí",
|
||||||
|
"Create Account": "Déan cuntas a chruthú",
|
||||||
|
"Sign In": "Sínigh Isteach",
|
||||||
|
"Dismiss": "Cuir uait",
|
||||||
|
"Use Single Sign On to continue": "Lean ar aghaidh le SSO",
|
||||||
|
"This phone number is already in use": "Úsáidtear an uimhir ghutháin seo chean féin",
|
||||||
|
"This email address is already in use": "Úsáidtear an seoladh ríomhphoist seo chean féin",
|
||||||
|
"Sign out and remove encryption keys?": "Sínigh amach agus scrios eochracha criptiúcháin?",
|
||||||
|
"Clear Storage and Sign Out": "Scrios Stóras agus Sínigh Amach",
|
||||||
|
"You're signed out": "Tá tú sínithe amach",
|
||||||
|
"Sign out": "Sínigh amach",
|
||||||
|
"Are you sure you want to sign out?": "An bhfuil tú cinnte go dteastaíonn uait sínigh amach?",
|
||||||
|
"Signed Out": "Sínithe Amach",
|
||||||
|
"Unable to query for supported registration methods.": "Ní féidir iarratas a dhéanamh faoi modhanna cláraithe tacaithe.",
|
||||||
|
"Host account on": "Óstáil cuntas ar",
|
||||||
|
"Create account": "Déan cuntas a chruthú"
|
||||||
|
}
|
||||||
|
|
|
@ -3087,5 +3087,120 @@
|
||||||
"Setting ID": "ID do axuste",
|
"Setting ID": "ID do axuste",
|
||||||
"Failed to save settings": "Non se gardaron os axustes",
|
"Failed to save settings": "Non se gardaron os axustes",
|
||||||
"Settings Explorer": "Navegar nos axustes",
|
"Settings Explorer": "Navegar nos axustes",
|
||||||
"Show chat effects (animations when receiving e.g. confetti)": "Mostrar efectos no chat (animacións na recepción, ex. confetti)"
|
"Show chat effects (animations when receiving e.g. confetti)": "Mostrar efectos no chat (animacións na recepción, ex. confetti)",
|
||||||
|
"Original event source": "Fonte orixinal do evento",
|
||||||
|
"Decrypted event source": "Fonte descifrada do evento",
|
||||||
|
"We'll create rooms for each of them. You can add existing rooms after setup.": "Crearemos salas para cada un deles. Podes engadir salas existentes após a configuración.",
|
||||||
|
"What projects are you working on?": "En que proxectos estás a traballar?",
|
||||||
|
"We'll create rooms for each topic.": "Crearemos salas para cada tema.",
|
||||||
|
"What are some things you want to discuss?": "Cales son os temas sobre os que queres debater?",
|
||||||
|
"Inviting...": "Convidando...",
|
||||||
|
"Invite by username": "Convidar por nome de usuaria",
|
||||||
|
"Invite your teammates": "Convida ao teu equipo",
|
||||||
|
"Failed to invite the following users to your space: %(csvUsers)s": "Fallou o convite ao teu espazo para as seguintes usuarias: %(csvUsers)s",
|
||||||
|
"A private space for you and your teammates": "Un espazo privado para ti e o teu equipo",
|
||||||
|
"Me and my teammates": "Eu máis o meu equipo",
|
||||||
|
"A private space just for you": "Un espazo privado só para ti",
|
||||||
|
"Just Me": "Só eu",
|
||||||
|
"Ensure the right people have access to the space.": "Asegúrate de que as persoas correctas teñen acceso ao espazo.",
|
||||||
|
"Who are you working with?": "Con quen estás a traballar?",
|
||||||
|
"Finish": "Rematar",
|
||||||
|
"At the moment only you can see it.": "Por agora só ti podes velo.",
|
||||||
|
"Creating rooms...": "Creando salas...",
|
||||||
|
"Skip for now": "Omitir por agora",
|
||||||
|
"Failed to create initial space rooms": "Fallou a creación inicial das salas do espazo",
|
||||||
|
"Room name": "Nome da sala",
|
||||||
|
"Support": "Axuda",
|
||||||
|
"Random": "Ao chou",
|
||||||
|
"Welcome to <name/>": "Benvida a <name/>",
|
||||||
|
"Your private space <name/>": "O teu espazo privado <name/>",
|
||||||
|
"Your public space <name/>": "O teu espazo público <name/>",
|
||||||
|
"You have been invited to <name/>": "Foches convidada a <name/>",
|
||||||
|
"<inviter/> invited you to <name/>": "<inviter/> convidoute a <name/>",
|
||||||
|
"%(count)s members|one": "%(count)s participante",
|
||||||
|
"%(count)s members|other": "%(count)s participantes",
|
||||||
|
"Your server does not support showing space hierarchies.": "O teu servidor non soporta amosar xerarquías dos espazos.",
|
||||||
|
"Default Rooms": "Salas por defecto",
|
||||||
|
"Add existing rooms & spaces": "Engadir salas e espazos existentes",
|
||||||
|
"Accept Invite": "Aceptar Convite",
|
||||||
|
"Find a room...": "Atopar unha sala...",
|
||||||
|
"Manage rooms": "Xestionar salas",
|
||||||
|
"Promoted to users": "Promovida ás usuarias",
|
||||||
|
"Save changes": "Gardar cambios",
|
||||||
|
"You're in this room": "Estás nesta sala",
|
||||||
|
"You're in this space": "Estas neste espazo",
|
||||||
|
"No permissions": "Sen permiso",
|
||||||
|
"Remove from Space": "Eliminar do Espazo",
|
||||||
|
"Undo": "Desfacer",
|
||||||
|
"Your message wasn't sent because this homeserver has been blocked by it's administrator. Please <a>contact your service administrator</a> to continue using the service.": "A túa mensaxe non se enviou porque o servidor foi bloqueado pola súa administración. Contacta <a>coa administración do servizo</a> para seguir utilizando o servizo.",
|
||||||
|
"Are you sure you want to leave the space '%(spaceName)s'?": "Tes a certeza de querer deixar o espazo '%(spaceName)s'?",
|
||||||
|
"This space is not public. You will not be able to rejoin without an invite.": "Este espazo non é público. Non poderás volver a unirte sen un convite.",
|
||||||
|
"Start audio stream": "Iniciar fluxo de audio",
|
||||||
|
"Failed to start livestream": "Fallou o inicio da emisión en directo",
|
||||||
|
"Unable to start audio streaming.": "Non se puido iniciar a retransmisión de audio.",
|
||||||
|
"Save Changes": "Gardar cambios",
|
||||||
|
"Saving...": "Gardando...",
|
||||||
|
"View dev tools": "Ver ferramentas dev",
|
||||||
|
"Leave Space": "Deixar o Espazo",
|
||||||
|
"Make this space private": "Establecer este espazo como privado",
|
||||||
|
"Edit settings relating to your space.": "Editar os axustes relativos ao teu espazo.",
|
||||||
|
"Space settings": "Axustes do espazo",
|
||||||
|
"Failed to save space settings.": "Fallo ao gardar os axustes do espazo.",
|
||||||
|
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.": "Convida a alguén usando o seu nome, nome de usuaria (como <userId/>) ou <a>comparte este espazo</a>.",
|
||||||
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "Convida a persoas usando o seu nome, enderezo de email, nome de usuaria (como <userId/>) ou <a>comparte este espazo</a>.",
|
||||||
|
"Unnamed Space": "Espazo sen nome",
|
||||||
|
"Invite to %(spaceName)s": "Convidar a %(spaceName)s",
|
||||||
|
"Failed to add rooms to space": "Fallou a adición das salas ao espazo",
|
||||||
|
"Apply": "Aplicar",
|
||||||
|
"Applying...": "Aplicando...",
|
||||||
|
"Create a new room": "Crear unha nova sala",
|
||||||
|
"Don't want to add an existing room?": "Non queres engadir unha sala existente?",
|
||||||
|
"Spaces": "Espazos",
|
||||||
|
"Filter your rooms and spaces": "Filtra as túas salas e espazos",
|
||||||
|
"Space selection": "Selección de Espazos",
|
||||||
|
"Add existing spaces/rooms": "Engadir espazos/salas existentes",
|
||||||
|
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the space it will be impossible to regain privileges.": "Non poderás desfacer este cambio xa que te estás degradando a ti mesma, se es a última usuaria con privilexios no espazo será imposible volver a obter os privilexios.",
|
||||||
|
"Empty room": "Sala baleira",
|
||||||
|
"Suggested Rooms": "Salas suxeridas",
|
||||||
|
"Explore space rooms": "Explorar salas do espazo",
|
||||||
|
"You do not have permissions to add rooms to this space": "Non tes permiso para engadir salas a este espazo",
|
||||||
|
"Add existing room": "Engadir sala existente",
|
||||||
|
"You do not have permissions to create new rooms in this space": "Non tes permiso para crear novas salas neste espazo",
|
||||||
|
"Send message": "Enviar mensaxe",
|
||||||
|
"Invite to this space": "Convidar a este espazo",
|
||||||
|
"Your message was sent": "Enviouse a túa mensaxe",
|
||||||
|
"Encrypting your message...": "Cifrando a túa mensaxe...",
|
||||||
|
"Sending your message...": "Enviando a túa mensaxe...",
|
||||||
|
"Spell check dictionaries": "Dicionarios de ortografía",
|
||||||
|
"Space options": "Opcións do Espazo",
|
||||||
|
"Space Home": "Incio do Espazo",
|
||||||
|
"New room": "Nova sala",
|
||||||
|
"Leave space": "Saír do espazo",
|
||||||
|
"Invite people": "Convidar persoas",
|
||||||
|
"Share your public space": "Comparte o teu espazo público",
|
||||||
|
"Invite members": "Convidar membros",
|
||||||
|
"Invite by email or username": "Convidar por email ou nome de usuaria",
|
||||||
|
"Share invite link": "Compartir ligazón do convite",
|
||||||
|
"Click to copy": "Click para copiar",
|
||||||
|
"Collapse space panel": "Pechar panel do espazo",
|
||||||
|
"Expand space panel": "Despregar panel do espazo",
|
||||||
|
"Creating...": "Creando...",
|
||||||
|
"You can change these at any point.": "Podes cambiar esto en calquera momento.",
|
||||||
|
"Give it a photo, name and description to help you identify it.": "Ponlle unha foto, nome e descrición para axudar a identificalo.",
|
||||||
|
"Your private space": "O teu espazo privado",
|
||||||
|
"Your public space": "O teu espazo público",
|
||||||
|
"You can change this later": "Podes cambiar esto máis tarde",
|
||||||
|
"Invite only, best for yourself or teams": "Só con convite, mellor para ti ou para equipos",
|
||||||
|
"Private": "Privado",
|
||||||
|
"Open space for anyone, best for communities": "Espazo aberto para calquera, mellor para comunidades",
|
||||||
|
"Public": "Público",
|
||||||
|
"Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "Espazos son novos xeitos de agrupar salas e persoas. Para unirse a un espazo existente precisarás un convite",
|
||||||
|
"Create a space": "Crear un espazo",
|
||||||
|
"Delete": "Eliminar",
|
||||||
|
"Jump to the bottom of the timeline when you send a message": "Ir ao final da cronoloxía cando envías unha mensaxe",
|
||||||
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Prototipo de Espazos. Incompatible con Comunidades, Comunidades v2 e Etiquetas Personais. Require un servidor compatible para algunhas características.",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "Este servidor de inicio foi bloqueado pola súa administración.",
|
||||||
|
"This homeserver has been blocked by its administrator.": "O servidor de inicio foi bloqueado pola súa administración.",
|
||||||
|
"You're already in a call with this person.": "Xa estás nunha conversa con esta persoa.",
|
||||||
|
"Already in call": "Xa estás nunha chamada"
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
"Notifications": "Értesítések",
|
"Notifications": "Értesítések",
|
||||||
"Operation failed": "Sikertelen művelet",
|
"Operation failed": "Sikertelen művelet",
|
||||||
"powered by Matrix": "a gépházban: Matrix",
|
"powered by Matrix": "a gépházban: Matrix",
|
||||||
"Remove": "Kitakarás",
|
"Remove": "Eltávolítás",
|
||||||
"Settings": "Beállítások",
|
"Settings": "Beállítások",
|
||||||
"unknown error code": "ismeretlen hibakód",
|
"unknown error code": "ismeretlen hibakód",
|
||||||
"Accept": "Elfogad",
|
"Accept": "Elfogad",
|
||||||
|
@ -1953,7 +1953,7 @@
|
||||||
"Accepting…": "Elfogadás…",
|
"Accepting…": "Elfogadás…",
|
||||||
"Accepting …": "Elfogadás …",
|
"Accepting …": "Elfogadás …",
|
||||||
"Declining …": "Elutasítás …",
|
"Declining …": "Elutasítás …",
|
||||||
"Verification Requests": "Hitelesítés Kérések",
|
"Verification Requests": "Hitelesítéskérések",
|
||||||
"Your account is not secure": "A fiókod nem biztonságos",
|
"Your account is not secure": "A fiókod nem biztonságos",
|
||||||
"Your password": "A jelszavad",
|
"Your password": "A jelszavad",
|
||||||
"This session, or the other session": "Ez vagy másik munkamenet",
|
"This session, or the other session": "Ez vagy másik munkamenet",
|
||||||
|
@ -3079,8 +3079,123 @@
|
||||||
"Setting:": "Beállítás:",
|
"Setting:": "Beállítás:",
|
||||||
"Value in this room": "Érték ebben a szobában",
|
"Value in this room": "Érték ebben a szobában",
|
||||||
"Value": "Érték",
|
"Value": "Érték",
|
||||||
"Setting ID": "Beállítás azon.",
|
"Setting ID": "Beállításazonosító",
|
||||||
"Failed to save settings": "A beállítások elmentése nem sikerült",
|
"Failed to save settings": "A beállítások mentése sikertelen",
|
||||||
"Settings Explorer": "Beállítás Böngésző",
|
"Settings Explorer": "Beállításböngésző",
|
||||||
"Show chat effects (animations when receiving e.g. confetti)": "Csevegés effektek megjelenítése (mint a konfetti animáció)"
|
"Show chat effects (animations when receiving e.g. confetti)": "Csevegés effektek megjelenítése (mint a konfetti animáció)",
|
||||||
|
"Original event source": "Eredeti esemény forráskód",
|
||||||
|
"Decrypted event source": "Visszafejtett esemény forráskód",
|
||||||
|
"We'll create rooms for each of them. You can add existing rooms after setup.": "Mindegyikhez készítünk egy szobát. A beállítás után hozzá tud adni meglévő szobákat.",
|
||||||
|
"What projects are you working on?": "Milyen projekteken dolgozik?",
|
||||||
|
"We'll create rooms for each topic.": "Minden témához készítünk egy szobát.",
|
||||||
|
"What are some things you want to discuss?": "Mik azok amiket meg szeretnének beszélni?",
|
||||||
|
"Inviting...": "Meghívás…",
|
||||||
|
"Invite by username": "Meghívás felhasználónévvel",
|
||||||
|
"Invite your teammates": "Csoporttársak meghívása",
|
||||||
|
"Failed to invite the following users to your space: %(csvUsers)s": "Az alábbi felhasználókat nem sikerült meghívni a térbe: %(csvUsers)s",
|
||||||
|
"A private space for you and your teammates": "Privát tér önnek és a csoporttársainak",
|
||||||
|
"Me and my teammates": "Én és a csoporttársaim",
|
||||||
|
"A private space just for you": "Privát tér csak önnek",
|
||||||
|
"Just Me": "Csak én",
|
||||||
|
"Ensure the right people have access to the space.": "Biztosítsa, hogy a térhez a megfelelő embereknek van hozzáférése.",
|
||||||
|
"Who are you working with?": "Kivel dolgozik együtt?",
|
||||||
|
"Finish": "Befejez",
|
||||||
|
"At the moment only you can see it.": "Jelenleg csak ön láthatja.",
|
||||||
|
"Creating rooms...": "Szobák létrehozása…",
|
||||||
|
"Skip for now": "Kihagy egyenlőre",
|
||||||
|
"Failed to create initial space rooms": "Térhez tartozó kezdő szobákat nem sikerült elkészíteni",
|
||||||
|
"Room name": "Szoba neve",
|
||||||
|
"Support": "Támogatás",
|
||||||
|
"Random": "Véletlen",
|
||||||
|
"Welcome to <name/>": "Üdvözlöm itt: <name/>",
|
||||||
|
"Your private space <name/>": "Privát tere: <name/>",
|
||||||
|
"Your public space <name/>": "Nyilvános tere: <name/>",
|
||||||
|
"You have been invited to <name/>": "Meghívták ide: <name/>",
|
||||||
|
"<inviter/> invited you to <name/>": "<inviter/> meghívta ide: <name/>",
|
||||||
|
"%(count)s members|one": "%(count)s tag",
|
||||||
|
"%(count)s members|other": "%(count)s tag",
|
||||||
|
"Your server does not support showing space hierarchies.": "A szervere nem támogatja a terek hierarchiáinak a megjelenítését.",
|
||||||
|
"Default Rooms": "Alapértelmezett szobák",
|
||||||
|
"Add existing rooms & spaces": "Létező szobák és terek hozzáadása",
|
||||||
|
"Accept Invite": "Meghívó elfogadása",
|
||||||
|
"Find a room...": "Szoba keresése…",
|
||||||
|
"Manage rooms": "Szobák kezelése",
|
||||||
|
"Promoted to users": "A felhasználók figyelmébe ajánlva",
|
||||||
|
"Save changes": "Változások mentése",
|
||||||
|
"You're in this room": "Ebben a szobában van",
|
||||||
|
"You're in this space": "Ebben a térben van",
|
||||||
|
"No permissions": "Nincs jogosultság",
|
||||||
|
"Remove from Space": "Eltávolítás a térből",
|
||||||
|
"Undo": "Visszavon",
|
||||||
|
"Your message wasn't sent because this homeserver has been blocked by it's administrator. Please <a>contact your service administrator</a> to continue using the service.": "Az üzenete nem került elküldésre mert az adminisztrátor megtiltotta ezen a Matrix szerveren. A szolgáltatás további igénybevétele végett kérjük <a>vegye fel a kapcsolatot a szolgáltatás adminisztrátorával</a>.",
|
||||||
|
"Are you sure you want to leave the space '%(spaceName)s'?": "Biztos, hogy elhagyja ezt a teret: %(spaceName)s?",
|
||||||
|
"This space is not public. You will not be able to rejoin without an invite.": "Ez a tér nem nyilvános. Kilépés után csak újabb meghívóval lehet újra belépni.",
|
||||||
|
"Start audio stream": "Hang folyam indítása",
|
||||||
|
"Failed to start livestream": "Az élő adás indítása sikertelen",
|
||||||
|
"Unable to start audio streaming.": "A hang folyam indítása sikertelen.",
|
||||||
|
"Save Changes": "Változások mentése",
|
||||||
|
"Saving...": "Mentés…",
|
||||||
|
"View dev tools": "Fejlesztői eszközök megjelenítése",
|
||||||
|
"Leave Space": "Tér elhagyása",
|
||||||
|
"Make this space private": "Tér beállítása privátnak",
|
||||||
|
"Edit settings relating to your space.": "Tér beállításainak szerkesztése.",
|
||||||
|
"Space settings": "Tér beállítások",
|
||||||
|
"Failed to save space settings.": "A tér beállításának mentése nem sikerült.",
|
||||||
|
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.": "Hívjon meg valakit a nevével, felhasználói nevével (pl. <userId/>) vagy <a>oszd meg ezt a teret</a>.",
|
||||||
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "Hívjon meg valakit a nevét, e-mail címét, vagy felhasználónevét (például <userId/>) megadva, vagy <a>oszd meg ezt a teret</a>.",
|
||||||
|
"Unnamed Space": "Névtelen tér",
|
||||||
|
"Invite to %(spaceName)s": "Meghívás ide: %(spaceName)s",
|
||||||
|
"Failed to add rooms to space": "A szobát nem sikerült hozzáadni a térhez",
|
||||||
|
"Apply": "Alkalmaz",
|
||||||
|
"Applying...": "Alkalmaz…",
|
||||||
|
"Create a new room": "Új szoba készítése",
|
||||||
|
"Don't want to add an existing room?": "Nem szeretne létező szobát hozzáadni?",
|
||||||
|
"Spaces": "Terek",
|
||||||
|
"Filter your rooms and spaces": "Terek és szobák szűrése",
|
||||||
|
"Add existing spaces/rooms": "Létező terek/szobák hozzáadása",
|
||||||
|
"Space selection": "Tér kiválasztása",
|
||||||
|
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the space it will be impossible to regain privileges.": "Nem fogja tudni visszavonni ezt a változtatást, mert lefokozza magát, ha Ön az utolsó privilegizált felhasználó a térben, akkor lehetetlen lesz a jogosultságok visszanyerése.",
|
||||||
|
"Empty room": "Üres szoba",
|
||||||
|
"Suggested Rooms": "Javasolt szobák",
|
||||||
|
"Explore space rooms": "Szobák felderítése ebben a térben",
|
||||||
|
"You do not have permissions to add rooms to this space": "Nincs jogosultsága szobát hozzáadni ehhez a térhez",
|
||||||
|
"Add existing room": "Létező szoba hozzáadása",
|
||||||
|
"You do not have permissions to create new rooms in this space": "Nincs jogosultsága szoba létrehozására ebben a térben",
|
||||||
|
"Send message": "Üzenet küldése",
|
||||||
|
"Invite to this space": "Meghívás a térbe",
|
||||||
|
"Your message was sent": "Üzenet elküldve",
|
||||||
|
"Encrypting your message...": "Üzenet titkosítása…",
|
||||||
|
"Sending your message...": "Üzenet küldése…",
|
||||||
|
"Spell check dictionaries": "Helyesírási szótárak",
|
||||||
|
"Space options": "Tér beállításai",
|
||||||
|
"Space Home": "Tér Otthona",
|
||||||
|
"New room": "Új szoba",
|
||||||
|
"Leave space": "Tér elhagyása",
|
||||||
|
"Invite people": "Személyek meghívása",
|
||||||
|
"Share your public space": "Nyilvános tér megosztása",
|
||||||
|
"Invite members": "Tagok meghívása",
|
||||||
|
"Invite by email or username": "Meghívás e-mail címmel vagy felhasználói névvel",
|
||||||
|
"Share invite link": "Meghívó linkjének megosztása",
|
||||||
|
"Click to copy": "Másolás kattintással",
|
||||||
|
"Collapse space panel": "Tér panel összezárása",
|
||||||
|
"Expand space panel": "Tér panel kiterjesztése",
|
||||||
|
"Creating...": "Készül...",
|
||||||
|
"You can change these at any point.": "Bármikor megváltoztatható.",
|
||||||
|
"Give it a photo, name and description to help you identify it.": "Fotóval, névvel és leírással lehet segíteni az azonosítást.",
|
||||||
|
"Your private space": "Privát tér",
|
||||||
|
"Your public space": "Nyilvános tér",
|
||||||
|
"You can change this later": "Ezt később meg lehet változtatni",
|
||||||
|
"Invite only, best for yourself or teams": "Csak meghívóval, saját célra és csoportoknak ideális",
|
||||||
|
"Private": "Privát",
|
||||||
|
"Open space for anyone, best for communities": "Nyílt tér mindenkinek, a legjobb a közösségeknek",
|
||||||
|
"Public": "Nyilvános",
|
||||||
|
"Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "A terek egy új lehetőség a szobák és emberek csoportosításához. Létező térhez meghívóval lehet csatlakozni",
|
||||||
|
"Create a space": "Tér készítése",
|
||||||
|
"Delete": "Töröl",
|
||||||
|
"Jump to the bottom of the timeline when you send a message": "Üzenetküldés után az idővonal aljára ugrás",
|
||||||
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Terek prototípus. Nem kompatibilis se a Közösségekkel, közösségek v2-vel és az egyedi címkékkel. Kompatibilis matrix szerver kell bizonyos funkciókhoz.",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "Ezt a matrix szervert az adminisztrátor lezárta.",
|
||||||
|
"This homeserver has been blocked by its administrator.": "Ezt a matrix szervert az adminisztrátor lezárta.",
|
||||||
|
"You're already in a call with this person.": "Már hívásban van ezzel a személlyel.",
|
||||||
|
"Already in call": "A hívás már folyamatban van"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3087,5 +3087,120 @@
|
||||||
"Setting ID": "ID impostazione",
|
"Setting ID": "ID impostazione",
|
||||||
"Failed to save settings": "Impossibile salvare le impostazioni",
|
"Failed to save settings": "Impossibile salvare le impostazioni",
|
||||||
"Settings Explorer": "Esploratore di impostazioni",
|
"Settings Explorer": "Esploratore di impostazioni",
|
||||||
"Show chat effects (animations when receiving e.g. confetti)": "Mostra effetti chat (animazioni quando si ricevono ad es. coriandoli)"
|
"Show chat effects (animations when receiving e.g. confetti)": "Mostra effetti chat (animazioni quando si ricevono ad es. coriandoli)",
|
||||||
|
"Original event source": "Fonte dell'evento originale",
|
||||||
|
"Decrypted event source": "Fonte dell'evento decifrato",
|
||||||
|
"We'll create rooms for each of them. You can add existing rooms after setup.": "Creeremo stanze per ognuno di essi. Puoi aggiungere stanze esistenti dopo la configurazione.",
|
||||||
|
"What projects are you working on?": "Su quali progetti stai lavorando?",
|
||||||
|
"We'll create rooms for each topic.": "Creeremo stanze per ogni argomento.",
|
||||||
|
"What are some things you want to discuss?": "Di cosa vuoi discutere?",
|
||||||
|
"Inviting...": "Invito...",
|
||||||
|
"Invite by username": "Invita per nome utente",
|
||||||
|
"Invite your teammates": "Invita la tua squadra",
|
||||||
|
"Failed to invite the following users to your space: %(csvUsers)s": "Impossibile invitare i seguenti utenti nello spazio: %(csvUsers)s",
|
||||||
|
"A private space for you and your teammates": "Uno spazio privato per te e i tuoi compagni",
|
||||||
|
"Me and my teammates": "Io e la mia squadra",
|
||||||
|
"A private space just for you": "Uno spazio privato solo per te",
|
||||||
|
"Just Me": "Solo io",
|
||||||
|
"Ensure the right people have access to the space.": "Assicurati che le persone giuste abbiano accesso allo spazio.",
|
||||||
|
"Who are you working with?": "Con chi stai lavorando?",
|
||||||
|
"Finish": "Fine",
|
||||||
|
"At the moment only you can see it.": "Al momento solo tu puoi vederlo.",
|
||||||
|
"Creating rooms...": "Creazione stanze...",
|
||||||
|
"Skip for now": "Salta per adesso",
|
||||||
|
"Failed to create initial space rooms": "Creazione di stanze iniziali dello spazio fallita",
|
||||||
|
"Room name": "Nome stanza",
|
||||||
|
"Support": "Supporto",
|
||||||
|
"Random": "Casuale",
|
||||||
|
"Welcome to <name/>": "Ti diamo il benvenuto in <name/>",
|
||||||
|
"Your private space <name/>": "Il tuo spazio privato <name/>",
|
||||||
|
"Your public space <name/>": "Il tuo spazio pubblico <name/>",
|
||||||
|
"You have been invited to <name/>": "Sei stato invitato in <name/>",
|
||||||
|
"<inviter/> invited you to <name/>": "<inviter/> ti ha invitato in <name/>",
|
||||||
|
"%(count)s members|one": "%(count)s membro",
|
||||||
|
"%(count)s members|other": "%(count)s membri",
|
||||||
|
"Your server does not support showing space hierarchies.": "Il tuo server non supporta la visualizzazione di gerarchie di spazi.",
|
||||||
|
"Default Rooms": "Stanze predefinite",
|
||||||
|
"Add existing rooms & spaces": "Aggiungi stanze e spazi esistenti",
|
||||||
|
"Accept Invite": "Accetta invito",
|
||||||
|
"Find a room...": "Trova una stanza...",
|
||||||
|
"Manage rooms": "Gestisci stanze",
|
||||||
|
"Promoted to users": "Promosso a utenti",
|
||||||
|
"Save changes": "Salva modifiche",
|
||||||
|
"You're in this room": "Sei in questa stanza",
|
||||||
|
"You're in this space": "Sei in questo spazio",
|
||||||
|
"No permissions": "Nessuna autorizzazione",
|
||||||
|
"Remove from Space": "Rimuovi dallo spazio",
|
||||||
|
"Undo": "Annulla",
|
||||||
|
"Your message wasn't sent because this homeserver has been blocked by it's administrator. Please <a>contact your service administrator</a> to continue using the service.": "Il tuo messaggio non è stato inviato perché questo homeserver è stato bloccato dal suo amministratore. <a>Contatta l'amministratore del servizio</a> per continuare ad usarlo.",
|
||||||
|
"Are you sure you want to leave the space '%(spaceName)s'?": "Vuoi veramente uscire dallo spazio '%(spaceName)s'?",
|
||||||
|
"This space is not public. You will not be able to rejoin without an invite.": "Questo spazio non è pubblico. Non potrai rientrare senza un invito.",
|
||||||
|
"Start audio stream": "Avvia stream audio",
|
||||||
|
"Failed to start livestream": "Impossibile avviare lo stream in diretta",
|
||||||
|
"Unable to start audio streaming.": "Impossibile avviare lo streaming audio.",
|
||||||
|
"Save Changes": "Salva modifiche",
|
||||||
|
"Saving...": "Salvataggio...",
|
||||||
|
"View dev tools": "Vedi strumenti da sviluppatore",
|
||||||
|
"Leave Space": "Esci dallo spazio",
|
||||||
|
"Make this space private": "Rendi privato questo spazio",
|
||||||
|
"Edit settings relating to your space.": "Modifica le impostazioni relative al tuo spazio.",
|
||||||
|
"Space settings": "Impostazioni spazio",
|
||||||
|
"Failed to save space settings.": "Impossibile salvare le impostazioni dello spazio.",
|
||||||
|
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.": "Invita qualcuno usando il suo nome, nome utente (come <userId/>) o <a>condividi questo spazio</a>.",
|
||||||
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "Invita qualcuno usando il suo nome, indirizzo email, nome utente (come <userId/>) o <a>condividi questo spazio</a>.",
|
||||||
|
"Unnamed Space": "Spazio senza nome",
|
||||||
|
"Invite to %(spaceName)s": "Invita in %(spaceName)s",
|
||||||
|
"Failed to add rooms to space": "Aggiunta di stanze allo spazio fallita",
|
||||||
|
"Apply": "Applica",
|
||||||
|
"Applying...": "Applicazione...",
|
||||||
|
"Create a new room": "Crea nuova stanza",
|
||||||
|
"Don't want to add an existing room?": "Non vuoi aggiungere una stanza esistente?",
|
||||||
|
"Spaces": "Spazi",
|
||||||
|
"Filter your rooms and spaces": "Filtra le tue stanze e spazi",
|
||||||
|
"Add existing spaces/rooms": "Aggiungi spazi/stanze esistenti",
|
||||||
|
"Space selection": "Selezione spazio",
|
||||||
|
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the space it will be impossible to regain privileges.": "Non potrai annullare questa modifica dato che ti stai declassando, se sei l'ultimo utente privilegiato nello spazio sarà impossibile riottenere il grado.",
|
||||||
|
"Empty room": "Stanza vuota",
|
||||||
|
"Suggested Rooms": "Stanze suggerite",
|
||||||
|
"Explore space rooms": "Esplora stanze dello spazio",
|
||||||
|
"You do not have permissions to add rooms to this space": "Non hai i permessi per aggiungere stanze a questo spazio",
|
||||||
|
"Add existing room": "Aggiungi stanza esistente",
|
||||||
|
"You do not have permissions to create new rooms in this space": "Non hai i permessi per creare stanze in questo spazio",
|
||||||
|
"Send message": "Invia messaggio",
|
||||||
|
"Invite to this space": "Invita in questo spazio",
|
||||||
|
"Your message was sent": "Il tuo messaggio è stato inviato",
|
||||||
|
"Encrypting your message...": "Crittazione del tuo messaggio...",
|
||||||
|
"Sending your message...": "Invio del tuo messaggio...",
|
||||||
|
"Spell check dictionaries": "Dizionari di controllo ortografia",
|
||||||
|
"Space options": "Opzioni dello spazio",
|
||||||
|
"Space Home": "Pagina iniziale dello spazio",
|
||||||
|
"New room": "Nuova stanza",
|
||||||
|
"Leave space": "Esci dallo spazio",
|
||||||
|
"Invite people": "Invita persone",
|
||||||
|
"Share your public space": "Condividi il tuo spazio pubblico",
|
||||||
|
"Invite members": "Invita membri",
|
||||||
|
"Invite by email or username": "Invita per email o nome utente",
|
||||||
|
"Share invite link": "Condividi collegamento di invito",
|
||||||
|
"Click to copy": "Clicca per copiare",
|
||||||
|
"Collapse space panel": "Riduci pannello dello spazio",
|
||||||
|
"Expand space panel": "Espandi pannello dello spazio",
|
||||||
|
"Creating...": "Creazione...",
|
||||||
|
"You can change these at any point.": "Puoi cambiarli in qualsiasi momento.",
|
||||||
|
"Give it a photo, name and description to help you identify it.": "Dagli una foto, un nome e una descrizione per aiutarti a identificarlo.",
|
||||||
|
"Your private space": "Il tuo spazio privato",
|
||||||
|
"Your public space": "Il tuo spazio pubblico",
|
||||||
|
"You can change this later": "Puoi modificarlo in seguito",
|
||||||
|
"Invite only, best for yourself or teams": "Solo su invito, la scelta migliore per te o i team",
|
||||||
|
"Private": "Privato",
|
||||||
|
"Open space for anyone, best for communities": "Spazio aperto a tutti, la scelta migliore per le comunità",
|
||||||
|
"Public": "Pubblico",
|
||||||
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Prototipo degli spazi. Non compatibile con comunità, comunità v2 ed etichette personalizzate. Richiede un homeserver compatibile per alcune funzioni.",
|
||||||
|
"Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "Gli spazi sono nuovi modi di raggruppare stanze e persone. Per entrare in uno spazio esistente ti serve un invito",
|
||||||
|
"Create a space": "Crea uno spazio",
|
||||||
|
"Delete": "Elimina",
|
||||||
|
"Jump to the bottom of the timeline when you send a message": "Salta in fondo alla linea temporale quando invii un messaggio",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "Questo homeserver è stato bloccato dal suo amministratore.",
|
||||||
|
"This homeserver has been blocked by its administrator.": "Questo homeserver è stato bloccato dal suo amministratore.",
|
||||||
|
"You're already in a call with this person.": "Sei già in una chiamata con questa persona.",
|
||||||
|
"Already in call": "Già in una chiamata"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1484,7 +1484,7 @@
|
||||||
"e.g. my-room": "例: my-room",
|
"e.g. my-room": "例: my-room",
|
||||||
"Room address": "ルームアドレス",
|
"Room address": "ルームアドレス",
|
||||||
"New published address (e.g. #alias:server)": "新しい公開アドレス (例: #alias:server)",
|
"New published address (e.g. #alias:server)": "新しい公開アドレス (例: #alias:server)",
|
||||||
"No other published addresses yet, add one below": "現在、公開アドレスがありません。以下から追加可能です",
|
"No other published addresses yet, add one below": "他の公開アドレスはまだありません。以下から追加できます",
|
||||||
"Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|one": "検索結果を表示させるために、暗号化されたメッセージをローカルに安全にキャッシュしています。現在、%(rooms)s 件の部屋のメッセージの保存に %(size)s を使用中です。",
|
"Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|one": "検索結果を表示させるために、暗号化されたメッセージをローカルに安全にキャッシュしています。現在、%(rooms)s 件の部屋のメッセージの保存に %(size)s を使用中です。",
|
||||||
"Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|other": "検索結果を表示させるために、暗号化されたメッセージをローカルに安全にキャッシュしています。現在、%(rooms)s 件の部屋のメッセージの保存に %(size)s を使用中です。",
|
"Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|other": "検索結果を表示させるために、暗号化されたメッセージをローカルに安全にキャッシュしています。現在、%(rooms)s 件の部屋のメッセージの保存に %(size)s を使用中です。",
|
||||||
"Mentions & Keywords": "メンションとキーワード",
|
"Mentions & Keywords": "メンションとキーワード",
|
||||||
|
@ -2336,5 +2336,113 @@
|
||||||
"Click the button below to confirm adding this phone number.": "下のボタンをクリックして電話番号の追加を確認します。",
|
"Click the button below to confirm adding this phone number.": "下のボタンをクリックして電話番号の追加を確認します。",
|
||||||
"Confirm adding phone number": "電話番号の追加を確認する",
|
"Confirm adding phone number": "電話番号の追加を確認する",
|
||||||
"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.": "シングルサインオンを使用して本人確認を行い、電話番号の追加を承認してください。",
|
||||||
"Click the button below to confirm adding this email address.": "下のボタンを押してこのメールアドレスを確認します。"
|
"Click the button below to confirm adding this email address.": "下のボタンを押してこのメールアドレスを確認します。",
|
||||||
|
"Reactions": "リアクション",
|
||||||
|
"Declining …": "断り中です…",
|
||||||
|
"Accepting …": "受け付け中です…",
|
||||||
|
"%(name)s accepted": "%(name)s は受け付けました",
|
||||||
|
"You accepted": "あなたは受け付けました",
|
||||||
|
"Waiting for you to accept on your other session…": "あなたがサインイン中の他のセッションで受け付けられるのを待ちます…",
|
||||||
|
"%(name)s cancelled": "%(name)s は中止しました",
|
||||||
|
"%(name)s declined": "%(name)sは断りました",
|
||||||
|
"You cancelled": "あなたは中止しました",
|
||||||
|
"You declined": "あなたは断りました",
|
||||||
|
"%(name)s cancelled verifying": "%(name)s は検証を中止しました",
|
||||||
|
"You cancelled verifying %(name)s": "%(name)s の検証を中止しました",
|
||||||
|
"You verified %(name)s": "%(name)s を検証しました",
|
||||||
|
"You have ignored this user, so their message is hidden. <a>Show anyways.</a>": "このユーザを無視しているのでメッセージは隠されます。<a>とにかく表示する</a>",
|
||||||
|
"Video conference started by %(senderName)s": "ビデオ会議は %(senderName)s により開始されました",
|
||||||
|
"Video conference ended by %(senderName)s": "ビデオ会議は %(senderName)s により終了しました",
|
||||||
|
"Video conference updated by %(senderName)s": "ビデオ会議は %(senderName)s により更新されました",
|
||||||
|
"Join the conference from the room information card on the right": "右側の部屋情報カードから会議に参加する",
|
||||||
|
"Join the conference at the top of this room": "この部屋の上部で会議に参加する",
|
||||||
|
"Message Actions": "メッセージのアクション",
|
||||||
|
"Ignored attempt to disable encryption": "暗号化を無効にする試みを無視しました",
|
||||||
|
"Compare emoji": "絵文字を比較",
|
||||||
|
"You cancelled verification on your other session.": "他のセッションで検証を中止しました。",
|
||||||
|
"Verification timed out.": "検証がタイムアウトしました。",
|
||||||
|
"Start verification again from the notification.": "通知から再度検証を開始します。",
|
||||||
|
"Verified": "検証済",
|
||||||
|
"In encrypted rooms, verify all users to ensure it’s secure.": "暗号化された部屋では、安全確認のために全てのユーザーを検証します。",
|
||||||
|
"Almost there! Is %(displayName)s showing the same shield?": "あと少しです! %(displayName)s は同じ盾マークを表示していますか?",
|
||||||
|
"Almost there! Is your other session showing the same shield?": "あと少しです! あなたの他のセッションは同じ盾マークを表示していますか?",
|
||||||
|
"Verify by emoji": "絵文字で検証",
|
||||||
|
"Verify by comparing unique emoji.": "絵文字の並びを比較して検証。",
|
||||||
|
"If you can't scan the code above, verify by comparing unique emoji.": "上記のコードをスキャンできない場合は、絵文字による確認を行ってください。",
|
||||||
|
"Ask %(displayName)s to scan your code:": "%(displayName)s にQRコードをスキャンするよう問い合わせてください:",
|
||||||
|
"Verify by scanning": "QRコードスキャンで検証",
|
||||||
|
"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.": "検証しようとしているセッションは %(brand)s で利用できる QRコードのスキャンまたは絵文字認証をサポートしていません。 別のクライアントで試してください。",
|
||||||
|
"This client does not support end-to-end encryption.": "このクライアントはエンドツーエンド暗号化に対応していません。",
|
||||||
|
"Failed to deactivate user": "ユーザーの非アクティブ化に失敗しました",
|
||||||
|
"Deactivate user": "ユーザーを非アクティブ化する",
|
||||||
|
"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?": "このユーザーを非アクティブ化するとユーザーはログアウトされて再度ログインできなくなります。さらにユーザーは現在参加中の部屋すべてから離れます。このアクションを元に戻すことはできません。 このユーザーを非アクティブ化してもよろしいですか?",
|
||||||
|
"Deactivate user?": "ユーザーを非アクティブ化しますか?",
|
||||||
|
"Remove %(count)s messages|one": "1件のメッセージを削除する",
|
||||||
|
"Remove %(count)s messages|other": "%(count)s 件のメッセージを削除する",
|
||||||
|
"For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "大量のメッセージだと時間がかかるかもしれません。その間はクライアントをリロードしないでください。",
|
||||||
|
"You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|one": "%(user)s からのメッセージ 1 件を削除しようとしています。 これは元に戻せません。続けますか?",
|
||||||
|
"You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|other": "%(user)s からの %(count)s 件のメッセージを削除しようとしています。これは元に戻せません。続けますか?",
|
||||||
|
"Remove recent messages by %(user)s": "%(user)s からの最近のメッセージを削除する",
|
||||||
|
"Try scrolling up in the timeline to see if there are any earlier ones.": "タイムラインを上にスクロールして、以前のものがあるかどうかを確認してください。",
|
||||||
|
"No recent messages by %(user)s found": "%(user)s からの最近のメッセージが見つかりません",
|
||||||
|
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the space it will be impossible to regain privileges.": "自分自身を降格しているため、この変更を元に戻すことはできません。スペース内の最後の特権ユーザーである場合、特権を取り戻すことはできません。",
|
||||||
|
"Not encrypted": "暗号化されていません",
|
||||||
|
"Edit widgets, bridges & bots": "ウィジェット、ブリッジ、ボットを編集する",
|
||||||
|
"Set my room layout for everyone": "私の部屋のレイアウトをみんな用に設定します",
|
||||||
|
"Unpin a widget to view it in this panel": "ウィジェットのピン留めを外して、このパネルに表示します",
|
||||||
|
"Unpin": "ピン留めを外す",
|
||||||
|
"You can only pin up to %(count)s widgets|other": "ウィジェットのピン留めは %(count)s 件までです",
|
||||||
|
"Yours, or the other users’ session": "あなたまたは他のユーザーのセッション",
|
||||||
|
"Yours, or the other users’ internet connection": "あなたまたは他のユーザーのインターネット接続",
|
||||||
|
"The homeserver the user you’re verifying is connected to": "あなたが検証しているユーザーが接続するホームサーバー",
|
||||||
|
"One of the following may be compromised:": "次のいずれかが危険にさらされる可能性があります:",
|
||||||
|
"Your messages are not secure": "あなたのメッセージは暗号化されません",
|
||||||
|
"In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.": "暗号化された部屋ではメッセージは保護されます。メッセージをアンロックするためのキーはあなたと受信者だけが持っています。",
|
||||||
|
"Other published addresses:": "他の公開アドレス:",
|
||||||
|
"Error removing address": "アドレスの削除のエラー",
|
||||||
|
"There was an error removing that address. It may no longer exist or a temporary error occurred.": "アドレスの削除中にエラーがありました。既に存在しない部屋か、一時的なエラーが発生したか。",
|
||||||
|
"You don't have permission to delete the address.": "アドレスを削除する権限がありません。",
|
||||||
|
"Empty room": "空の部屋",
|
||||||
|
"Suggested Rooms": "おすすめの部屋",
|
||||||
|
"Explore space rooms": "スペース内の部屋を探索します",
|
||||||
|
"You do not have permissions to add rooms to this space": "このスペースに部屋を追加する権限がありません",
|
||||||
|
"Add existing room": "既存の部屋を追加します",
|
||||||
|
"You do not have permissions to create new rooms in this space": "このスペースに新しい部屋を作成する権限がありません",
|
||||||
|
"Send message": "メッセージを送ります",
|
||||||
|
"Invite to this space": "このスペースに招待します",
|
||||||
|
"Your message was sent": "メッセージは送信されました",
|
||||||
|
"Encrypting your message...": "メッセージの暗号化中…",
|
||||||
|
"Sending your message...": "メッセージの送信中…",
|
||||||
|
"Spell check dictionaries": "スペルチェック辞書",
|
||||||
|
"Space options": "スペースのオプション",
|
||||||
|
"Space Home": "スペースのホーム",
|
||||||
|
"New room": "新しい部屋",
|
||||||
|
"Leave space": "スペースを離れる",
|
||||||
|
"Invite people": "人々を招待する",
|
||||||
|
"Share your public space": "公開スペースを共有する",
|
||||||
|
"Invite members": "参加者を招待する",
|
||||||
|
"Invite by email or username": "メールまたはユーザー名で招待する",
|
||||||
|
"Share invite link": "招待リンクを共有する",
|
||||||
|
"Click to copy": "クリックでコピーします",
|
||||||
|
"Collapse space panel": "スペースパネルを畳む",
|
||||||
|
"Expand space panel": "スペースパネルを展開",
|
||||||
|
"Creating...": "作成中…",
|
||||||
|
"You can change these at any point.": "これらはいつでも変更できます。",
|
||||||
|
"Give it a photo, name and description to help you identify it.": "写真、名前、説明を追加して識別しやすくします。",
|
||||||
|
"Your private space": "あなたの非公開スペース",
|
||||||
|
"Your public space": "あなたの公開スペース",
|
||||||
|
"You can change this later": "これは後から変更できます",
|
||||||
|
"Invite only, best for yourself or teams": "招待のみ。チームや個人での使用に適しています",
|
||||||
|
"Private": "非公開",
|
||||||
|
"Open space for anyone, best for communities": "誰もが利用できるオープンスペース、コミュニティに最適",
|
||||||
|
"Public": "公開",
|
||||||
|
"Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "スペースは部屋や人をグループ化する新しい方法です。 既存のスペースに参加するには招待状が必要です",
|
||||||
|
"Create a space": "スペースを作成する",
|
||||||
|
"Delete": "削除",
|
||||||
|
"Jump to the bottom of the timeline when you send a message": "メッセージを送信する際にタイムライン最下部に移動します",
|
||||||
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Spacesはプロトタイプです。 コミュニティ、コミュニティv2、カスタムタグとは互換性がありません。 一部の機能には互換性のあるホームサーバーが必要です。",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "このホームサーバーは管理者によりブロックされています。",
|
||||||
|
"This homeserver has been blocked by its administrator.": "このホームサーバーは管理者によりブロックされています。",
|
||||||
|
"You're already in a call with this person.": "あなたは既にこの人と通話中です。",
|
||||||
|
"Already in call": "既に電話中です"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2749,5 +2749,10 @@
|
||||||
"Prepends (╯°□°)╯︵ ┻━┻ to a plain-text message": "Yerna (╯°□°)╯︵ ┻━┻ ɣer tazwara n yizen",
|
"Prepends (╯°□°)╯︵ ┻━┻ to a plain-text message": "Yerna (╯°□°)╯︵ ┻━┻ ɣer tazwara n yizen",
|
||||||
"This will end the conference for everyone. Continue?": "Aya ad yeḥbes asarag i yal yiwen. Kemmel?",
|
"This will end the conference for everyone. Continue?": "Aya ad yeḥbes asarag i yal yiwen. Kemmel?",
|
||||||
"End conference": "Kfu asarag",
|
"End conference": "Kfu asarag",
|
||||||
"Call failed because microphone could not be accessed. Check that a microphone is plugged in and set up correctly.": "Tawuri tecceḍ acku asawaḍ ur yessaweḍ ara ad yekcem. Senqed ma yella usawaḍ yeqqnen yerna yettusbadu akken iwata."
|
"Call failed because microphone could not be accessed. Check that a microphone is plugged in and set up correctly.": "Tawuri tecceḍ acku asawaḍ ur yessaweḍ ara ad yekcem. Senqed ma yella usawaḍ yeqqnen yerna yettusbadu akken iwata.",
|
||||||
|
"%(senderName)s declined the call.": "%(senderName)s yugi asiwel.",
|
||||||
|
"(an error occurred)": "(tella-d tuccḍa)",
|
||||||
|
"(connection failed)": "(tuqqna ur teddi ara)",
|
||||||
|
"🎉 All servers are banned from participating! This room can no longer be used.": "🎉 Iqeddcen akk ttwagedlen seg uttekki! Taxxamt-a dayen ur tettuseqdac ara.",
|
||||||
|
"Try again": "Ɛreḍ tikkelt-nniḍen"
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@
|
||||||
"%(brand)s uses many advanced browser features, some of which are not available or experimental in your current browser.": "%(brand)s naudoja daug išplėstinių naršyklės funkcijų, kai kurios iš jų yra neprieinamos arba eksperimentinės jūsų esamoje naršyklėje.",
|
"%(brand)s uses many advanced browser features, some of which are not available or experimental in your current browser.": "%(brand)s naudoja daug išplėstinių naršyklės funkcijų, kai kurios iš jų yra neprieinamos arba eksperimentinės jūsų esamoje naršyklėje.",
|
||||||
"Event sent!": "Įvykis išsiųstas!",
|
"Event sent!": "Įvykis išsiųstas!",
|
||||||
"Unnamed room": "Kambarys be pavadinimo",
|
"Unnamed room": "Kambarys be pavadinimo",
|
||||||
"Dismiss": "Atsisakyti",
|
"Dismiss": "Atmesti",
|
||||||
"Explore Account Data": "Peržiūrėti paskyros duomenis",
|
"Explore Account Data": "Peržiūrėti paskyros duomenis",
|
||||||
"Remove from Directory": "Pašalinti iš Katalogo",
|
"Remove from Directory": "Pašalinti iš Katalogo",
|
||||||
"Download this file": "Atsisiųsti šį failą",
|
"Download this file": "Atsisiųsti šį failą",
|
||||||
|
|
|
@ -130,7 +130,7 @@
|
||||||
"%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s heeft de gespreksnaam verwijderd.",
|
"%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s heeft de gespreksnaam verwijderd.",
|
||||||
"Create Room": "Gesprek aanmaken",
|
"Create Room": "Gesprek aanmaken",
|
||||||
"/ddg is not a command": "/ddg is geen opdracht",
|
"/ddg is not a command": "/ddg is geen opdracht",
|
||||||
"Deactivate Account": "Account sluiten",
|
"Deactivate Account": "Account Sluiten",
|
||||||
"Decline": "Weigeren",
|
"Decline": "Weigeren",
|
||||||
"Decrypt %(text)s": "%(text)s ontsleutelen",
|
"Decrypt %(text)s": "%(text)s ontsleutelen",
|
||||||
"Disinvite": "Uitnodiging intrekken",
|
"Disinvite": "Uitnodiging intrekken",
|
||||||
|
@ -422,7 +422,7 @@
|
||||||
"Delete Widget": "Widget verwijderen",
|
"Delete Widget": "Widget verwijderen",
|
||||||
"Who would you like to add to this community?": "Wie wil je toevoegen aan deze gemeenschap?",
|
"Who would you like to add to this community?": "Wie wil je toevoegen aan deze gemeenschap?",
|
||||||
"Invite to Community": "Uitnodigen tot gemeenschap",
|
"Invite to Community": "Uitnodigen tot gemeenschap",
|
||||||
"Show these rooms to non-members on the community page and room list?": "Deze gesprekken tonen aan niet-leden op de gemeenschapspagina en gesprekslijst?",
|
"Show these rooms to non-members on the community page and room list?": "Deze gesprekken tonen aan niet-leden op de gemeenschapspagina en openbare gesprekkenlijst?",
|
||||||
"Add rooms to the community": "Voeg gesprekken toe aan de gemeenschap",
|
"Add rooms to the community": "Voeg gesprekken toe aan de gemeenschap",
|
||||||
"Add to community": "Toevoegen aan gemeenschap",
|
"Add to community": "Toevoegen aan gemeenschap",
|
||||||
"Failed to invite the following users to %(groupId)s:": "Uitnodigen van volgende gebruikers tot %(groupId)s is mislukt:",
|
"Failed to invite the following users to %(groupId)s:": "Uitnodigen van volgende gebruikers tot %(groupId)s is mislukt:",
|
||||||
|
@ -640,7 +640,7 @@
|
||||||
"%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s heeft %(displayName)s als weergavenaam aangenomen.",
|
"%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s heeft %(displayName)s als weergavenaam aangenomen.",
|
||||||
"Key request sent.": "Sleutelverzoek verstuurd.",
|
"Key request sent.": "Sleutelverzoek verstuurd.",
|
||||||
"Did you know: you can use communities to filter your %(brand)s experience!": "Tip: u kunt gemeenschappen gebruiken om uw %(brand)s-beleving te filteren!",
|
"Did you know: you can use communities to filter your %(brand)s experience!": "Tip: u kunt gemeenschappen gebruiken om uw %(brand)s-beleving te filteren!",
|
||||||
"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.": "Versleep een gemeenschapsavatar naar het filterpaneel helemaal links op het scherm om een filter in te stellen. Daarna kunt u op de avatar in het filterpaneel klikken wanneer u zich wilt beperken tot de gesprekken en mensen uit die gemeenschap.",
|
"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.": "Versleep een gemeenschapsavatar naar het filterpaneel helemaal links op het scherm om een filter in te stellen. Daarna kunt u op de avatar in het filterpaneel klikken wanneer u zich wilt beperken tot de gesprekken en personen uit die gemeenschap.",
|
||||||
"Clear filter": "Filter wissen",
|
"Clear filter": "Filter wissen",
|
||||||
"Failed to set direct chat tag": "Instellen van direct gespreklabel is mislukt",
|
"Failed to set direct chat tag": "Instellen van direct gespreklabel is mislukt",
|
||||||
"Failed to remove tag %(tagName)s from room": "Verwijderen van %(tagName)s-label van gesprek is mislukt",
|
"Failed to remove tag %(tagName)s from room": "Verwijderen van %(tagName)s-label van gesprek is mislukt",
|
||||||
|
@ -794,9 +794,9 @@
|
||||||
"Popout widget": "Widget in nieuw venster openen",
|
"Popout widget": "Widget in nieuw venster openen",
|
||||||
"Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Kan de gebeurtenis waarop gereageerd was niet laden. Wellicht bestaat die niet, of u heeft geen toestemming die te bekijken.",
|
"Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Kan de gebeurtenis waarop gereageerd was niet laden. Wellicht bestaat die niet, of u heeft geen toestemming die te bekijken.",
|
||||||
"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>": "Dit zal uw account voorgoed onbruikbaar maken. U zult niet meer kunnen inloggen, en niemand anders zal zich met dezelfde gebruikers-ID kunnen registreren. Hierdoor zal uw account alle gesprekken waaraan u deelneemt verlaten, en worden de accountgegevens verwijderd van de identiteitsserver. <b>Deze stap is onomkeerbaar.</b>",
|
"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>": "Dit zal uw account voorgoed onbruikbaar maken. U zult niet meer kunnen inloggen, en niemand anders zal zich met dezelfde gebruikers-ID kunnen registreren. Hierdoor zal uw account alle gesprekken waaraan u deelneemt verlaten, en worden de accountgegevens verwijderd van de identiteitsserver. <b>Deze stap is onomkeerbaar.</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.": "Het sluiten van uw account <b>maakt op zich niet dat wij de door u verstuurde berichten vergeten.</b> Als u wilt dat wij uw berichten vergeten, vink dan het vakje hieronder aan.",
|
"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.": "Het sluiten van uw account <b>maakt standaard niet dat wij de door u verstuurde berichten vergeten.</b> Als u wilt dat wij uw berichten vergeten, vink dan het vakje hieronder aan.",
|
||||||
"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.": "De zichtbaarheid van berichten in Matrix is zoals bij e-mails. Het vergeten van uw berichten betekent dat berichten die u heeft verstuurd niet meer gedeeld worden met nieuwe of ongeregistreerde gebruikers, maar geregistreerde gebruikers die al toegang hebben tot deze berichten zullen alsnog toegang hebben tot hun eigen kopie ervan.",
|
"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.": "De zichtbaarheid van berichten in Matrix is zoals bij e-mails. Het vergeten van uw berichten betekent dat berichten die u heeft verstuurd niet meer gedeeld worden met nieuwe of ongeregistreerde gebruikers, maar geregistreerde gebruikers die al toegang hebben tot deze berichten zullen alsnog toegang hebben tot hun eigen kopie ervan.",
|
||||||
"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)": "Vergeet bij het sluiten van mijn account alle door mij verstuurde berichten (<b>Let op:</b> hierdoor zullen gebruikers een onvolledig beeld krijgen van gesprekken)",
|
"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)": "Vergeet bij het sluiten van mijn account alle door mij verstuurde berichten (<b>Let op:</b> hierdoor zullen personen een onvolledig beeld krijgen van gesprekken)",
|
||||||
"To continue, please enter your password:": "Voer uw wachtwoord in om verder te gaan:",
|
"To continue, please enter your password:": "Voer uw wachtwoord in om verder te gaan:",
|
||||||
"Clear Storage and Sign Out": "Opslag wissen en afmelden",
|
"Clear Storage and Sign Out": "Opslag wissen en afmelden",
|
||||||
"Send Logs": "Logboek versturen",
|
"Send Logs": "Logboek versturen",
|
||||||
|
@ -847,7 +847,7 @@
|
||||||
"Unable to load! Check your network connectivity and try again.": "Laden mislukt! Controleer je netwerktoegang en probeer het nogmaals.",
|
"Unable to load! Check your network connectivity and try again.": "Laden mislukt! Controleer je netwerktoegang en probeer het nogmaals.",
|
||||||
"Failed to invite users to the room:": "Kon de volgende gebruikers hier niet uitnodigen:",
|
"Failed to invite users to the room:": "Kon de volgende gebruikers hier niet uitnodigen:",
|
||||||
"Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Plakt ¯\\_(ツ)_/¯ vóór een bericht zonder opmaak",
|
"Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Plakt ¯\\_(ツ)_/¯ vóór een bericht zonder opmaak",
|
||||||
"Upgrades a room to a new version": "Actualiseert het gesprek tot een nieuwe versie",
|
"Upgrades a room to a new version": "Upgrade het gesprek naar de nieuwe versie",
|
||||||
"Changes your display nickname in the current room only": "Stelt uw weergavenaam alleen in het huidige gesprek in",
|
"Changes your display nickname in the current room only": "Stelt uw weergavenaam alleen in het huidige gesprek in",
|
||||||
"Gets or sets the room topic": "Verkrijgt het onderwerp van het gesprek of stelt het in",
|
"Gets or sets the room topic": "Verkrijgt het onderwerp van het gesprek of stelt het in",
|
||||||
"This room has no topic.": "Dit gesprek heeft geen onderwerp.",
|
"This room has no topic.": "Dit gesprek heeft geen onderwerp.",
|
||||||
|
@ -1021,7 +1021,7 @@
|
||||||
"Verification code": "Verificatiecode",
|
"Verification code": "Verificatiecode",
|
||||||
"Phone Number": "Telefoonnummer",
|
"Phone Number": "Telefoonnummer",
|
||||||
"Profile picture": "Profielfoto",
|
"Profile picture": "Profielfoto",
|
||||||
"<a>Upgrade</a> to your own domain": "<a>Waardeer op</a> naar uw eigen domein",
|
"<a>Upgrade</a> to your own domain": "<a>Upgrade</a> naar uw eigen domein",
|
||||||
"Display Name": "Weergavenaam",
|
"Display Name": "Weergavenaam",
|
||||||
"Set a new account password...": "Stel een nieuw accountwachtwoord in…",
|
"Set a new account password...": "Stel een nieuw accountwachtwoord in…",
|
||||||
"Email addresses": "E-mailadressen",
|
"Email addresses": "E-mailadressen",
|
||||||
|
@ -1131,10 +1131,10 @@
|
||||||
"Report bugs & give feedback": "Fouten melden & feedback geven",
|
"Report bugs & give feedback": "Fouten melden & feedback geven",
|
||||||
"Go back": "Terug",
|
"Go back": "Terug",
|
||||||
"Room Settings - %(roomName)s": "Gespreksinstellingen - %(roomName)s",
|
"Room Settings - %(roomName)s": "Gespreksinstellingen - %(roomName)s",
|
||||||
"Failed to upgrade room": "Gesprek bijwerken mislukt",
|
"Failed to upgrade room": "Gesprek upgraden mislukt",
|
||||||
"The room upgrade could not be completed": "Het bijwerken van het gesprek kon niet voltooid worden",
|
"The room upgrade could not be completed": "Het upgraden van het gesprek kon niet voltooid worden",
|
||||||
"Upgrade this room to version %(version)s": "Werk dit gesprek bij tot versie %(version)s",
|
"Upgrade this room to version %(version)s": "Upgrade dit gesprek tot versie %(version)s",
|
||||||
"Upgrade Room Version": "Gespreksversie bijwerken",
|
"Upgrade Room Version": "Gespreksversie upgraden",
|
||||||
"Create a new room with the same name, description and avatar": "Een nieuw gesprek aanmaken met dezelfde naam, beschrijving en avatar",
|
"Create a new room with the same name, description and avatar": "Een nieuw gesprek aanmaken met dezelfde naam, beschrijving en avatar",
|
||||||
"Update any local room aliases to point to the new room": "Alle lokale gespreksbijnamen naar het nieuwe gesprek laten verwijzen",
|
"Update any local room aliases to point to the new room": "Alle lokale gespreksbijnamen naar het nieuwe gesprek laten verwijzen",
|
||||||
"Stop users from speaking in the old version of the room, and post a message advising users to move to the new room": "Gebruikers verhinderen aan de oude versie van het gesprek bij te dragen, en daar een bericht plaatsen dat de gebruikers verwijst naar het nieuwe gesprek",
|
"Stop users from speaking in the old version of the room, and post a message advising users to move to the new room": "Gebruikers verhinderen aan de oude versie van het gesprek bij te dragen, en daar een bericht plaatsen dat de gebruikers verwijst naar het nieuwe gesprek",
|
||||||
|
@ -1196,8 +1196,8 @@
|
||||||
"Sign in instead": "Aanmelden",
|
"Sign in instead": "Aanmelden",
|
||||||
"Your password has been reset.": "Uw wachtwoord is opnieuw ingesteld.",
|
"Your password has been reset.": "Uw wachtwoord is opnieuw ingesteld.",
|
||||||
"Set a new password": "Stel een nieuw wachtwoord in",
|
"Set a new password": "Stel een nieuw wachtwoord in",
|
||||||
"Invalid homeserver discovery response": "Ongeldig homeserver-ontdekkingsantwoord",
|
"Invalid homeserver discovery response": "Ongeldig homeserver-vindbaarheids-antwoord",
|
||||||
"Invalid identity server discovery response": "Ongeldig identiteitsserverontdekkingsantwoord",
|
"Invalid identity server discovery response": "Ongeldig identiteitsserver-vindbaarheidsantwoord",
|
||||||
"General failure": "Algemene fout",
|
"General failure": "Algemene fout",
|
||||||
"This homeserver does not support login using email address.": "Deze homeserver biedt geen ondersteuning voor inloggen met e-mailadres.",
|
"This homeserver does not support login using email address.": "Deze homeserver biedt geen ondersteuning voor inloggen met e-mailadres.",
|
||||||
"Please <a>contact your service administrator</a> to continue using this service.": "Gelieve <a>contact op te nemen met uw dienstbeheerder</a> om deze dienst te blijven gebruiken.",
|
"Please <a>contact your service administrator</a> to continue using this service.": "Gelieve <a>contact op te nemen met uw dienstbeheerder</a> om deze dienst te blijven gebruiken.",
|
||||||
|
@ -1238,7 +1238,7 @@
|
||||||
"Please supply a https:// or http:// widget URL": "Voer een https://- of http://-widget-URL in",
|
"Please supply a https:// or http:// widget URL": "Voer een https://- of http://-widget-URL in",
|
||||||
"You cannot modify widgets in this room.": "U kunt de widgets in dit gesprek niet aanpassen.",
|
"You cannot modify widgets in this room.": "U kunt de widgets in dit gesprek niet aanpassen.",
|
||||||
"%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s heeft de uitnodiging aan %(targetDisplayName)s toe te treden tot het gesprek ingetrokken.",
|
"%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s heeft de uitnodiging aan %(targetDisplayName)s toe te treden tot het gesprek ingetrokken.",
|
||||||
"Upgrade this room to the recommended room version": "Werk dit gesprek bij tot de aanbevolen versie",
|
"Upgrade this room to the recommended room version": "Upgrade dit gesprek naar de aanbevolen gespreksversie",
|
||||||
"This room is running room version <roomVersion />, which this homeserver has marked as <i>unstable</i>.": "Dit gesprek draait op groepsgespreksversie <roomVersion />, die door deze homeserver als <i>onstabiel</i> is gemarkeerd.",
|
"This room is running room version <roomVersion />, which this homeserver has marked as <i>unstable</i>.": "Dit gesprek draait op groepsgespreksversie <roomVersion />, die door deze homeserver als <i>onstabiel</i> is gemarkeerd.",
|
||||||
"Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Upgraden zal de huidige versie van dit gesprek sluiten, en onder dezelfde naam een geüpgraded versie starten.",
|
"Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Upgraden zal de huidige versie van dit gesprek sluiten, en onder dezelfde naam een geüpgraded versie starten.",
|
||||||
"Failed to revoke invite": "Intrekken van uitnodiging is mislukt",
|
"Failed to revoke invite": "Intrekken van uitnodiging is mislukt",
|
||||||
|
@ -1341,7 +1341,7 @@
|
||||||
"Add room": "Gesprek toevoegen",
|
"Add room": "Gesprek toevoegen",
|
||||||
"Your profile": "Uw profiel",
|
"Your profile": "Uw profiel",
|
||||||
"Your Matrix account on <underlinedServerName />": "Uw Matrix-account op <underlinedServerName />",
|
"Your Matrix account on <underlinedServerName />": "Uw Matrix-account op <underlinedServerName />",
|
||||||
"Failed to get autodiscovery configuration from server": "Ophalen van auto-ontdekkingsconfiguratie van server is mislukt",
|
"Failed to get autodiscovery configuration from server": "Ophalen van auto-vindbaarheidsconfiguratie van server is mislukt",
|
||||||
"Invalid base_url for m.homeserver": "Ongeldige base_url voor m.homeserver",
|
"Invalid base_url for m.homeserver": "Ongeldige base_url voor m.homeserver",
|
||||||
"Homeserver URL does not appear to be a valid Matrix homeserver": "De homeserver-URL lijkt geen geldige Matrix-homeserver",
|
"Homeserver URL does not appear to be a valid Matrix homeserver": "De homeserver-URL lijkt geen geldige Matrix-homeserver",
|
||||||
"Invalid base_url for m.identity_server": "Ongeldige base_url voor m.identity_server",
|
"Invalid base_url for m.identity_server": "Ongeldige base_url voor m.identity_server",
|
||||||
|
@ -1413,22 +1413,22 @@
|
||||||
"Disconnect from the identity server <idserver />?": "Wilt u de verbinding met de identiteitsserver <idserver /> verbreken?",
|
"Disconnect from the identity server <idserver />?": "Wilt u de verbinding met de identiteitsserver <idserver /> verbreken?",
|
||||||
"Disconnect": "Verbinding verbreken",
|
"Disconnect": "Verbinding verbreken",
|
||||||
"Identity Server (%(server)s)": "Identiteitsserver (%(server)s)",
|
"Identity Server (%(server)s)": "Identiteitsserver (%(server)s)",
|
||||||
"You are currently using <server></server> to discover and be discoverable by existing contacts you know. You can change your identity server below.": "Om bekenden te kunnen vinden en door hen vindbaar te zijn gebruikt u momenteel <server></server>. U kunt die identiteitsserver hieronder wijzigen.",
|
"You are currently using <server></server> to discover and be discoverable by existing contacts you know. You can change your identity server below.": "Om bekenden te kunnen vinden en voor hen vindbaar te zijn gebruikt u momenteel <server></server>. U kunt die identiteitsserver hieronder wijzigen.",
|
||||||
"You are not currently using an identity server. To discover and be discoverable by existing contacts you know, add one below.": "U gebruikt momenteel geen identiteitsserver. Voeg er hieronder één toe om bekenden te kunnen vinden en voor hen vindbaar te zijn.",
|
"You are not currently using an identity server. To discover and be discoverable by existing contacts you know, add one below.": "U gebruikt momenteel geen identiteitsserver. Voeg er hieronder één toe om bekenden te kunnen vinden en voor hen vindbaar te zijn.",
|
||||||
"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.": "De verbinding met uw identiteitsserver verbreken zal ertoe leiden dat u niet door andere gebruikers gevonden zal kunnen worden, en dat u anderen niet via e-mail of telefoon zal kunnen uitnodigen.",
|
"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.": "Als u de verbinding met uw identiteitsserver verbreekt zal u niet door andere personen gevonden kunnen worden, en dat u anderen niet via e-mail of telefoon zal kunnen uitnodigen.",
|
||||||
"Integration Manager": "Integratiebeheerder",
|
"Integration Manager": "Integratiebeheerder",
|
||||||
"Discovery": "Ontdekking",
|
"Discovery": "Vindbaarheid",
|
||||||
"Deactivate account": "Account sluiten",
|
"Deactivate account": "Account sluiten",
|
||||||
"Always show the window menu bar": "De venstermenubalk altijd tonen",
|
"Always show the window menu bar": "De venstermenubalk altijd tonen",
|
||||||
"Unable to revoke sharing for email address": "Kan delen voor dit e-mailadres niet intrekken",
|
"Unable to revoke sharing for email address": "Kan delen voor dit e-mailadres niet intrekken",
|
||||||
"Unable to share email address": "Kan e-mailadres niet delen",
|
"Unable to share email address": "Kan e-mailadres niet delen",
|
||||||
"Revoke": "Intrekken",
|
"Revoke": "Intrekken",
|
||||||
"Share": "Delen",
|
"Share": "Delen",
|
||||||
"Discovery options will appear once you have added an email above.": "Ontdekkingsopties zullen verschijnen wanneer u een e-mailadres hebt toegevoegd.",
|
"Discovery options will appear once you have added an email above.": "Vindbaarheidopties zullen verschijnen wanneer u een e-mailadres hebt toegevoegd.",
|
||||||
"Unable to revoke sharing for phone number": "Kan delen voor dit telefoonnummer niet intrekken",
|
"Unable to revoke sharing for phone number": "Kan delen voor dit telefoonnummer niet intrekken",
|
||||||
"Unable to share phone number": "Kan telefoonnummer niet delen",
|
"Unable to share phone number": "Kan telefoonnummer niet delen",
|
||||||
"Please enter verification code sent via text.": "Voer de verificatiecode in die werd verstuurd via sms.",
|
"Please enter verification code sent via text.": "Voer de verificatiecode in die werd verstuurd via sms.",
|
||||||
"Discovery options will appear once you have added a phone number above.": "Ontdekkingsopties zullen verschijnen wanneer u een telefoonnummer hebt toegevoegd.",
|
"Discovery options will appear once you have added a phone number above.": "Vindbaarheidopties zullen verschijnen wanneer u een telefoonnummer hebt toegevoegd.",
|
||||||
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "Er is een sms verstuurd naar +%(msisdn)s. Voor de verificatiecode in die in het bericht staat.",
|
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "Er is een sms verstuurd naar +%(msisdn)s. Voor de verificatiecode in die in het bericht staat.",
|
||||||
"Command Help": "Hulp bij opdrachten",
|
"Command Help": "Hulp bij opdrachten",
|
||||||
"No identity server is configured: add one in server settings to reset your password.": "Er is geen identiteitsserver geconfigureerd: voeg er één toe in de serverinstellingen om uw wachtwoord opnieuw in te stellen.",
|
"No identity server is configured: add one in server settings to reset your password.": "Er is geen identiteitsserver geconfigureerd: voeg er één toe in de serverinstellingen om uw wachtwoord opnieuw in te stellen.",
|
||||||
|
@ -1467,7 +1467,7 @@
|
||||||
"Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Aanvaard de gebruiksvoorwaarden van de identiteitsserver (%(serverName)s) om vindbaar te zijn op e-mailadres of telefoonnummer.",
|
"Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Aanvaard de gebruiksvoorwaarden van de identiteitsserver (%(serverName)s) om vindbaar te zijn op e-mailadres of telefoonnummer.",
|
||||||
"Read Marker lifetime (ms)": "Levensduur van leesbevestigingen (ms)",
|
"Read Marker lifetime (ms)": "Levensduur van leesbevestigingen (ms)",
|
||||||
"Read Marker off-screen lifetime (ms)": "Levensduur van levensbevestigingen, niet op scherm (ms)",
|
"Read Marker off-screen lifetime (ms)": "Levensduur van levensbevestigingen, niet op scherm (ms)",
|
||||||
"Upgrade the room": "Werk het gesprek bij",
|
"Upgrade the room": "Upgrade het gesprek",
|
||||||
"Enable room encryption": "Gespreksversleuteling inschakelen",
|
"Enable room encryption": "Gespreksversleuteling inschakelen",
|
||||||
"Error changing power level requirement": "Fout bij wijzigen van machtsniveauvereiste",
|
"Error changing power level requirement": "Fout bij wijzigen van machtsniveauvereiste",
|
||||||
"An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.": "Er is een fout opgetreden bij het wijzigen van de machtsniveauvereisten van het gesprek. Zorg ervoor dat u over voldoende machtigingen beschikt en probeer het opnieuw.",
|
"An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.": "Er is een fout opgetreden bij het wijzigen van de machtsniveauvereisten van het gesprek. Zorg ervoor dat u over voldoende machtigingen beschikt en probeer het opnieuw.",
|
||||||
|
@ -1550,7 +1550,7 @@
|
||||||
"%(creator)s created and configured the room.": "Gesprek gestart en ingesteld door %(creator)s.",
|
"%(creator)s created and configured the room.": "Gesprek gestart en ingesteld door %(creator)s.",
|
||||||
"Setting up keys": "Sleutelconfiguratie",
|
"Setting up keys": "Sleutelconfiguratie",
|
||||||
"Verify this session": "Deze sessie verifiëren",
|
"Verify this session": "Deze sessie verifiëren",
|
||||||
"Encryption upgrade available": "Er is een bijgewerkte versleuteling beschikbaar",
|
"Encryption upgrade available": "Versleutelingsupgrade beschikbaar",
|
||||||
"You can use <code>/help</code> to list available commands. Did you mean to send this as a message?": "Typ <code>/help</code> om alle opdrachten te zien. Was het uw bedoeling dit als bericht te sturen?",
|
"You can use <code>/help</code> to list available commands. Did you mean to send this as a message?": "Typ <code>/help</code> om alle opdrachten te zien. Was het uw bedoeling dit als bericht te sturen?",
|
||||||
"Help": "Hulp",
|
"Help": "Hulp",
|
||||||
"Set up encryption": "Versleuteling instellen",
|
"Set up encryption": "Versleuteling instellen",
|
||||||
|
@ -1588,11 +1588,11 @@
|
||||||
"%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s heeft het patroon van een banregel wegens %(reason)s aangepast van %(oldGlob)s tot %(newGlob)s",
|
"%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s heeft het patroon van een banregel wegens %(reason)s aangepast van %(oldGlob)s tot %(newGlob)s",
|
||||||
"The message you are trying to send is too large.": "Uw bericht is te lang om te versturen.",
|
"The message you are trying to send is too large.": "Uw bericht is te lang om te versturen.",
|
||||||
"a few seconds ago": "enige tellen geleden",
|
"a few seconds ago": "enige tellen geleden",
|
||||||
"about a minute ago": "een minuut of zo geleden",
|
"about a minute ago": "ongeveer een minuut geleden",
|
||||||
"%(num)s minutes ago": "%(num)s minuten geleden",
|
"%(num)s minutes ago": "%(num)s minuten geleden",
|
||||||
"about an hour ago": "een uur of zo geleden",
|
"about an hour ago": "ongeveer een uur geleden",
|
||||||
"%(num)s hours ago": "%(num)s uur geleden",
|
"%(num)s hours ago": "%(num)s uur geleden",
|
||||||
"about a day ago": "een dag of zo geleden",
|
"about a day ago": "ongeveer een dag geleden",
|
||||||
"%(num)s days ago": "%(num)s dagen geleden",
|
"%(num)s days ago": "%(num)s dagen geleden",
|
||||||
"a few seconds from now": "over een paar tellen",
|
"a few seconds from now": "over een paar tellen",
|
||||||
"about a minute from now": "over een minuut of zo",
|
"about a minute from now": "over een minuut of zo",
|
||||||
|
@ -1602,7 +1602,7 @@
|
||||||
"about a day from now": "over een dag of zo",
|
"about a day from now": "over een dag of zo",
|
||||||
"%(num)s days from now": "over %(num)s dagen",
|
"%(num)s days from now": "over %(num)s dagen",
|
||||||
"%(name)s (%(userId)s)": "%(name)s (%(userId)s)",
|
"%(name)s (%(userId)s)": "%(name)s (%(userId)s)",
|
||||||
"Try out new ways to ignore people (experimental)": "Nieuwe manieren om mensen te negeren uitproberen (nog in ontwikkeling)",
|
"Try out new ways to ignore people (experimental)": "Nieuwe manieren om personen te negeren uitproberen (nog in ontwikkeling)",
|
||||||
"Show info about bridges in room settings": "Toon bruginformatie in gespreksinstellingen",
|
"Show info about bridges in room settings": "Toon bruginformatie in gespreksinstellingen",
|
||||||
"Match system theme": "Aanpassen aan systeemthema",
|
"Match system theme": "Aanpassen aan systeemthema",
|
||||||
"Never send encrypted messages to unverified sessions from this session": "Vanaf deze sessie nooit versleutelde berichten naar ongeverifieerde sessies versturen",
|
"Never send encrypted messages to unverified sessions from this session": "Vanaf deze sessie nooit versleutelde berichten naar ongeverifieerde sessies versturen",
|
||||||
|
@ -1629,7 +1629,7 @@
|
||||||
"Channel: %(channelName)s": "Kanaal: %(channelName)s",
|
"Channel: %(channelName)s": "Kanaal: %(channelName)s",
|
||||||
"Show less": "Minder tonen",
|
"Show less": "Minder tonen",
|
||||||
"Show more": "Meer tonen",
|
"Show more": "Meer tonen",
|
||||||
"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.": "Momenteel stelt een wachtwoordswijziging alle berichtsleutels in alle sessies opnieuw in, en maakt zo oude versleutelde berichten onleesbaar - tenzij u uw sleutels eerst wegschrijft, en na afloop weer inleest. Dit zal verbeterd worden.",
|
"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.": "Momenteel stelt een wachtwoordswijziging alle versleutelingssleutels in alle sessies opnieuw in, en maakt zo oude versleutelde berichten onleesbaar - tenzij u uw gesprekssleutels eerst opslaat, en na afloop weer inleest. Dit zal in de toekomst verbeterd worden.",
|
||||||
"in memory": "in het geheugen",
|
"in memory": "in het geheugen",
|
||||||
"not found": "niet gevonden",
|
"not found": "niet gevonden",
|
||||||
"Your homeserver does not support session management.": "Uw homeserver ondersteunt geen sessiebeheer.",
|
"Your homeserver does not support session management.": "Uw homeserver ondersteunt geen sessiebeheer.",
|
||||||
|
@ -1698,7 +1698,7 @@
|
||||||
"Session ID:": "Sessie-ID:",
|
"Session ID:": "Sessie-ID:",
|
||||||
"Session key:": "Sessiesleutel:",
|
"Session key:": "Sessiesleutel:",
|
||||||
"Message search": "Berichten zoeken",
|
"Message search": "Berichten zoeken",
|
||||||
"A session's public name is visible to people you communicate with": "De publieke naam van een sessie is zichtbaar voor de mensen waarmee u communiceert",
|
"A session's public name is visible to people you communicate with": "De openbare naam van een sessie is zichtbaar voor de personen waarmee u communiceert",
|
||||||
"This room is bridging messages to the following platforms. <a>Learn more.</a>": "Dit gesprek wordt overbrugd naar de volgende platformen. <a>Lees meer</a>",
|
"This room is bridging messages to the following platforms. <a>Learn more.</a>": "Dit gesprek wordt overbrugd naar de volgende platformen. <a>Lees meer</a>",
|
||||||
"This room isn’t bridging messages to any platforms. <a>Learn more.</a>": "Dit gesprek wordt niet overbrugd naar andere platformen. <a>Lees meer.</a>",
|
"This room isn’t bridging messages to any platforms. <a>Learn more.</a>": "Dit gesprek wordt niet overbrugd naar andere platformen. <a>Lees meer.</a>",
|
||||||
"Bridges": "Bruggen",
|
"Bridges": "Bruggen",
|
||||||
|
@ -1846,7 +1846,7 @@
|
||||||
"Reactions": "Reacties",
|
"Reactions": "Reacties",
|
||||||
"<reactors/><reactedWith> reacted with %(content)s</reactedWith>": "<reactors/><reactedWith> heeft gereageerd met %(content)s</reactedWith>",
|
"<reactors/><reactedWith> reacted with %(content)s</reactedWith>": "<reactors/><reactedWith> heeft gereageerd met %(content)s</reactedWith>",
|
||||||
"Frequently Used": "Vaak gebruikt",
|
"Frequently Used": "Vaak gebruikt",
|
||||||
"Smileys & People": "Smileys & mensen",
|
"Smileys & People": "Smileys & Personen",
|
||||||
"Animals & Nature": "Dieren en natuur",
|
"Animals & Nature": "Dieren en natuur",
|
||||||
"Food & Drink": "Eten en drinken",
|
"Food & Drink": "Eten en drinken",
|
||||||
"Activities": "Activiteiten",
|
"Activities": "Activiteiten",
|
||||||
|
@ -1907,11 +1907,11 @@
|
||||||
"If you didn’t sign in to this session, your account may be compromised.": "Als u zich niet heeft aangemeld bij deze sessie, is uw account wellicht geschonden.",
|
"If you didn’t sign in to this session, your account may be compromised.": "Als u zich niet heeft aangemeld bij deze sessie, is uw account wellicht geschonden.",
|
||||||
"This wasn't me": "Dat was ik niet",
|
"This wasn't me": "Dat was ik niet",
|
||||||
"Automatically invite users": "Gebruikers automatisch uitnodigen",
|
"Automatically invite users": "Gebruikers automatisch uitnodigen",
|
||||||
"Upgrade private room": "Privégesprek bijwerken",
|
"Upgrade private room": "Privégesprek upgraden",
|
||||||
"Upgrade public room": "Openbaar gesprek bijwerken",
|
"Upgrade public room": "Openbaar gesprek upgraden",
|
||||||
"Upgrading a room is an advanced action and is usually recommended when a room is unstable due to bugs, missing features or security vulnerabilities.": "Het bijwerken van een gesprek is een gevorderde actie en wordt meestal aanbevolen wanneer een gesprek onstabiel is door fouten, ontbrekende functies of problemen met de beveiliging.",
|
"Upgrading a room is an advanced action and is usually recommended when a room is unstable due to bugs, missing features or security vulnerabilities.": "Het bijwerken van een gesprek is een gevorderde actie en wordt meestal aanbevolen wanneer een gesprek onstabiel is door fouten, ontbrekende functies of problemen met de beveiliging.",
|
||||||
"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>.": "Dit heeft meestal enkel een invloed op de manier waarop het gesprek door de server verwerkt wordt. Als u problemen met uw %(brand)s ondervindt, <a>dien dan een foutmelding in</a>.",
|
"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>.": "Dit heeft meestal enkel een invloed op de manier waarop het gesprek door de server verwerkt wordt. Als u problemen met uw %(brand)s ondervindt, <a>dien dan een foutmelding in</a>.",
|
||||||
"You'll upgrade this room from <oldVersion /> to <newVersion />.": "U werkt dit gesprek bij van <oldVersion /> naar <newVersion />.",
|
"You'll upgrade this room from <oldVersion /> to <newVersion />.": "U upgrade dit gesprek van <oldVersion /> naar <newVersion />.",
|
||||||
"This will allow you to return to your account after signing out, and sign in on other sessions.": "Daardoor kunt u na afmelding terugkeren tot uw account, en u bij andere sessies aanmelden.",
|
"This will allow you to return to your account after signing out, and sign in on other sessions.": "Daardoor kunt u na afmelding terugkeren tot uw account, en u bij andere sessies aanmelden.",
|
||||||
"Verification Request": "Verificatieverzoek",
|
"Verification Request": "Verificatieverzoek",
|
||||||
"Recovery key mismatch": "Herstelsleutel komt niet overeen",
|
"Recovery key mismatch": "Herstelsleutel komt niet overeen",
|
||||||
|
@ -1936,24 +1936,24 @@
|
||||||
"Your new session is now verified. Other users will see it as trusted.": "Uw nieuwe sessie is nu geverifieerd. Ze zal voor andere gebruikers als vertrouwd gemarkeerd worden.",
|
"Your new session is now verified. Other users will see it as trusted.": "Uw nieuwe sessie is nu geverifieerd. Ze zal voor andere gebruikers als vertrouwd gemarkeerd worden.",
|
||||||
"Without completing security on this session, it won’t have access to encrypted messages.": "Als u de beveiliging van deze sessie niet vervolledigt, zal ze geen toegang hebben tot uw versleutelde berichten.",
|
"Without completing security on this session, it won’t have access to encrypted messages.": "Als u de beveiliging van deze sessie niet vervolledigt, zal ze geen toegang hebben tot uw versleutelde berichten.",
|
||||||
"Go Back": "Terugkeren",
|
"Go Back": "Terugkeren",
|
||||||
"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.": "Door uw wachtwoord te wijzigen stelt u alle eind-tot-eind-versleutelingssleutels op al uw sessies opnieuw in, waardoor uw versleutelde gespreksgeschiedenis onleesbaar wordt. Stel sleutelback-up in of schrijf uw gesprekssleutels van een andere sessie weg vooraleer u een nieuw wachtwoord instelt.",
|
"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.": "Door uw wachtwoord te wijzigen stelt u alle eind-tot-eind-versleutelingssleutels op al uw sessies opnieuw in, waardoor uw versleutelde gespreksgeschiedenis onleesbaar wordt. Stel uw sleutelback-up in of sla uw gesprekssleutels van een andere sessie op voor u een nieuw wachtwoord instelt.",
|
||||||
"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.": "U bent uitgelogd bij al uw sessies en zult geen pushberichten meer ontvangen. Meld u op elk apparaat opnieuw aan om meldingen opnieuw in te schakelen.",
|
"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.": "U bent uitgelogd bij al uw sessies en zult geen pushberichten meer ontvangen. Meld u op elk apparaat opnieuw aan om meldingen opnieuw in te schakelen.",
|
||||||
"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.": "Herwin toegang tot uw account en herstel de tijdens deze sessie opgeslagen versleutelingssleutels, zonder welke sommige van uw beveiligde berichten in al uw sessies onleesbaar zijn.",
|
"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.": "Ontvang toegang tot uw account en herstel de tijdens deze sessie opgeslagen versleutelingssleutels, zonder deze sleutels zijn sommige van uw versleutelde berichten in uw sessies onleesbaar.",
|
||||||
"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.": "Let op: uw persoonlijke gegevens (waaronder versleutelingssleutels) zijn nog steeds opgeslagen in deze sessie. Wis ze wanneer u klaar bent met deze sessie, of wanneer u zich wilt aanmelden met een andere account.",
|
"Warning: Your personal data (including encryption keys) is still stored in this session. Clear it if you're finished using this session, or want to sign in to another account.": "Let op: uw persoonlijke gegevens (waaronder versleutelingssleutels) zijn nog steeds opgeslagen in deze sessie. Wis ze wanneer u klaar bent met deze sessie, of wanneer u zich wilt aanmelden met een andere account.",
|
||||||
"Command Autocomplete": "Opdrachten autoaanvullen",
|
"Command Autocomplete": "Opdrachten autoaanvullen",
|
||||||
"DuckDuckGo Results": "DuckDuckGo-resultaten",
|
"DuckDuckGo Results": "DuckDuckGo-resultaten",
|
||||||
"Enter your account password to confirm the upgrade:": "Voer uw accountwachtwoord in om het bijwerken te bevestigen:",
|
"Enter your account password to confirm the upgrade:": "Voer uw accountwachtwoord in om het upgraden te bevestigen:",
|
||||||
"Restore your key backup to upgrade your encryption": "Herstel uw sleutelback-up om uw versleuteling bij te werken",
|
"Restore your key backup to upgrade your encryption": "Herstel uw sleutelback-up om uw versleuteling te upgraden",
|
||||||
"Restore": "Herstellen",
|
"Restore": "Herstellen",
|
||||||
"You'll need to authenticate with the server to confirm the upgrade.": "U zult zich moeten aanmelden bij de server om het bijwerken te bevestigen.",
|
"You'll need to authenticate with the server to confirm the upgrade.": "U zult zich moeten aanmelden bij de server om het upgraden te bevestigen.",
|
||||||
"Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Werk deze sessie bij om er andere sessies mee te verifiëren, waardoor deze ook de toegang verkrijgen tot uw versleutelde berichten en voor andere gebruikers als vertrouwd gemarkeerd worden.",
|
"Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Upgrade deze sessie om er andere sessies mee te verifiëren, waardoor deze ook de toegang verkrijgen tot uw versleutelde berichten en deze voor andere gebruikers als vertrouwd gemarkeerd worden.",
|
||||||
"Set up with a recovery key": "Instellen met een herstelsleutel",
|
"Set up with a recovery key": "Instellen met een herstelsleutel",
|
||||||
"Keep a copy of it somewhere secure, like a password manager or even a safe.": "Bewaar een kopie op een veilige plaats, zoals in een wachtwoordbeheerder of een kluis.",
|
"Keep a copy of it somewhere secure, like a password manager or even a safe.": "Bewaar een kopie op een veilige plaats, zoals in een wachtwoordbeheerder of een kluis.",
|
||||||
"Your recovery key": "Uw herstelsleutel",
|
"Your recovery key": "Uw herstelsleutel",
|
||||||
"Copy": "Kopiëren",
|
"Copy": "Kopiëren",
|
||||||
"Your recovery key has been <b>copied to your clipboard</b>, paste it to:": "Uw herstelsleutel is <b>gekopieerd naar uw klembord</b>, plak hem en:",
|
"Your recovery key has been <b>copied to your clipboard</b>, paste it to:": "Uw herstelsleutel is <b>gekopieerd naar uw klembord</b>, plak hem en:",
|
||||||
"Your recovery key is in your <b>Downloads</b> folder.": "Uw herstelsleutel bevindt zich in uw <b>Downloads</b>-map.",
|
"Your recovery key is in your <b>Downloads</b> folder.": "Uw herstelsleutel bevindt zich in uw <b>Downloads</b>-map.",
|
||||||
"Upgrade your encryption": "Werk uw versleuteling bij",
|
"Upgrade your encryption": "Upgrade uw versleuteling",
|
||||||
"Make a copy of your recovery key": "Maak een kopie van uw herstelsleutel",
|
"Make a copy of your recovery key": "Maak een kopie van uw herstelsleutel",
|
||||||
"Unable to set up secret storage": "Kan sleutelopslag niet instellen",
|
"Unable to set up secret storage": "Kan sleutelopslag niet instellen",
|
||||||
"Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "Zonder veilig berichtherstel in te stellen zult u uw versleutelde berichtgeschiedenis niet kunnen herstellen als u uitlogt of een andere sessie gebruikt.",
|
"Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "Zonder veilig berichtherstel in te stellen zult u uw versleutelde berichtgeschiedenis niet kunnen herstellen als u uitlogt of een andere sessie gebruikt.",
|
||||||
|
@ -2465,7 +2465,7 @@
|
||||||
"Send %(count)s invites|one": "Stuur %(count)s uitnodiging",
|
"Send %(count)s invites|one": "Stuur %(count)s uitnodiging",
|
||||||
"Send %(count)s invites|other": "Stuur %(count)s uitnodigingen",
|
"Send %(count)s invites|other": "Stuur %(count)s uitnodigingen",
|
||||||
"Show": "Toon",
|
"Show": "Toon",
|
||||||
"People you know on %(brand)s": "Mensen die u kent van %(brand)s",
|
"People you know on %(brand)s": "Personen die u kent van %(brand)s",
|
||||||
"Add another email": "Nog een e-mailadres toevoegen",
|
"Add another email": "Nog een e-mailadres toevoegen",
|
||||||
"Download logs": "Download logboeken",
|
"Download logs": "Download logboeken",
|
||||||
"Add a new server...": "Een nieuwe server toevoegen…",
|
"Add a new server...": "Een nieuwe server toevoegen…",
|
||||||
|
@ -2508,7 +2508,7 @@
|
||||||
"Role": "Rol",
|
"Role": "Rol",
|
||||||
"Room settings": "Gespreksinstellingen",
|
"Room settings": "Gespreksinstellingen",
|
||||||
"Show files": "Bestanden tonen",
|
"Show files": "Bestanden tonen",
|
||||||
"%(count)s people|other": "%(count)s mensen",
|
"%(count)s people|other": "%(count)s personen",
|
||||||
"About": "Over",
|
"About": "Over",
|
||||||
"Not encrypted": "Niet versleuteld",
|
"Not encrypted": "Niet versleuteld",
|
||||||
"Widgets": "Widgets",
|
"Widgets": "Widgets",
|
||||||
|
@ -2533,7 +2533,7 @@
|
||||||
"Signature upload failed": "Versturen van ondertekening mislukt",
|
"Signature upload failed": "Versturen van ondertekening mislukt",
|
||||||
"Signature upload success": "Ondertekening succesvol verstuurd",
|
"Signature upload success": "Ondertekening succesvol verstuurd",
|
||||||
"Unable to upload": "Versturen niet mogelijk",
|
"Unable to upload": "Versturen niet mogelijk",
|
||||||
"Transfer": "Overdragen",
|
"Transfer": "Doorschakelen",
|
||||||
"Start a conversation with someone using their name or username (like <userId/>).": "Start een gesprek met iemand door hun naam of gebruikersnaam (zoals <userId/>) te typen.",
|
"Start a conversation with someone using their name or username (like <userId/>).": "Start een gesprek met iemand door hun naam of gebruikersnaam (zoals <userId/>) te typen.",
|
||||||
"May include members not in %(communityName)s": "Mag deelnemers bevatten die geen deel uitmaken van %(communityName)s",
|
"May include members not in %(communityName)s": "Mag deelnemers bevatten die geen deel uitmaken van %(communityName)s",
|
||||||
"Invite by email": "Via e-mail uitnodigen",
|
"Invite by email": "Via e-mail uitnodigen",
|
||||||
|
@ -2697,37 +2697,37 @@
|
||||||
"Navigation": "Navigatie",
|
"Navigation": "Navigatie",
|
||||||
"Currently indexing: %(currentRoom)s": "Momenteel indexeren: %(currentRoom)s",
|
"Currently indexing: %(currentRoom)s": "Momenteel indexeren: %(currentRoom)s",
|
||||||
"Enter your recovery passphrase a second time to confirm it.": "Voer uw Herstelwachtwoord een tweede keer in om te bevestigen.",
|
"Enter your recovery passphrase a second time to confirm it.": "Voer uw Herstelwachtwoord een tweede keer in om te bevestigen.",
|
||||||
"This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Deze sessie heeft ontdekt dat uw veiligheidszin en sleutel voor versleutelde berichten zijn verwijderd.",
|
"This session has detected that your Security Phrase and key for Secure Messages have been removed.": "Deze sessie heeft ontdekt dat uw veiligheidswachtwoord en -sleutel voor versleutelde berichten zijn verwijderd.",
|
||||||
"A new Security Phrase and key for Secure Messages have been detected.": "Er is een nieuwe veiligheidszin en sleutel voor versleutelde berichten gedetecteerd.",
|
"A new Security Phrase and key for Secure Messages have been detected.": "Er is een nieuwe veiligheidswachtwoord en -sleutel voor versleutelde berichten gedetecteerd.",
|
||||||
"Save your Security Key": "Uw veiligheidssleutel opslaan",
|
"Save your Security Key": "Uw veiligheidssleutel opslaan",
|
||||||
"Confirm Security Phrase": "Veiligheidszin bevestigen",
|
"Confirm Security Phrase": "Veiligheidswachtwoord bevestigen",
|
||||||
"Set a Security Phrase": "Een veiligheidszin instellen",
|
"Set a Security Phrase": "Een veiligheidswachtwoord instellen",
|
||||||
"You can also set up Secure Backup & manage your keys in Settings.": "U kunt ook een beveiligde back-up instellen en uw sleutels beheren via instellingen.",
|
"You can also set up Secure Backup & manage your keys in Settings.": "U kunt ook een beveiligde back-up instellen en uw sleutels beheren via instellingen.",
|
||||||
"Secure Backup": "Beveiligde back-up",
|
"Secure Backup": "Beveiligde back-up",
|
||||||
"Unable to access secret storage. Please verify that you entered the correct Security Phrase.": "Geen toegang tot sleutelopslag. Controleer of u de juiste veiligheidszin hebt ingevoerd.",
|
"Unable to access secret storage. Please verify that you entered the correct Security Phrase.": "Geen toegang tot geheime opslag. Controleer of u het juiste veiligheidswachtwoord hebt ingevoerd.",
|
||||||
"Secret storage:": "Sleutelopslag:",
|
"Secret storage:": "Sleutelopslag:",
|
||||||
"Unable to query secret storage status": "Kan status sleutelopslag niet opvragen",
|
"Unable to query secret storage status": "Kan status sleutelopslag niet opvragen",
|
||||||
"Store your Security Key somewhere safe, like a password manager or a safe, as it’s used to safeguard your encrypted data.": "Bewaar uw veiligheidssleutel op een veilige plaats, zoals in een wachtwoordmanager of een kluis, aangezien deze wordt gebruikt om uw versleutelde gegevens te beveiligen.",
|
"Store your Security Key somewhere safe, like a password manager or a safe, as it’s used to safeguard your encrypted data.": "Bewaar uw veiligheidssleutel op een veilige plaats, zoals in een wachtwoordmanager of een kluis, aangezien deze wordt gebruikt om uw versleutelde gegevens te beveiligen.",
|
||||||
"Confirm your recovery passphrase": "Bevestig uw Herstelwachtwoord",
|
"Confirm your recovery passphrase": "Bevestig uw Herstelwachtwoord",
|
||||||
"Use a different passphrase?": "Gebruik een ander wachtwoord?",
|
"Use a different passphrase?": "Gebruik een ander wachtwoord?",
|
||||||
"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.": "Voer een veiligheidszin in die alleen u kent, aangezien deze wordt gebruikt om uw gegevens te versleutelen. Om veilig te zijn, moet u het wachtwoord van uw account niet opnieuw gebruiken.",
|
"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.": "Voer een veiligheidswachtwoord in die alleen u kent, aangezien deze wordt gebruikt om uw gegevens te versleutelen. Om veilig te zijn, moet u het wachtwoord van uw account niet opnieuw gebruiken.",
|
||||||
"Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.": "Bescherm uw server tegen toegangsverlies tot versleutelde berichten en gegevens door een back-up te maken van de versleutelingssleutels.",
|
"Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.": "Bescherm uw server tegen toegangsverlies tot versleutelde berichten en gegevens door een back-up te maken van de versleutelingssleutels.",
|
||||||
"Use a secret phrase only you know, and optionally save a Security Key to use for backup.": "Gebruik een veiligheidszin die alleen u kent, en sla optioneel een veiligheidssleutel op om te gebruiken als back-up.",
|
"Use a secret phrase only you know, and optionally save a Security Key to use for backup.": "Gebruik een veiligheidswachtwoord die alleen u kent, en sla optioneel een veiligheidssleutel op om te gebruiken als back-up.",
|
||||||
"We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.": "Wij maken een veiligheidssleutel voor u aan die u ergens veilig kunt opbergen, zoals in een wachtwoordmanager of een kluis.",
|
"We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.": "Wij maken een veiligheidssleutel voor u aan die u ergens veilig kunt opbergen, zoals in een wachtwoordmanager of een kluis.",
|
||||||
"Generate a Security Key": "Genereer een veiligheidssleutel",
|
"Generate a Security Key": "Genereer een veiligheidssleutel",
|
||||||
"Make a copy of your Security Key": "Maak een kopie van uw veiligheidssleutel",
|
"Make a copy of your Security Key": "Maak een kopie van uw veiligheidssleutel",
|
||||||
"Confirm your Security Phrase": "Bevestig uw veiligheidszin",
|
"Confirm your Security Phrase": "Bevestig uw veiligheidswachtwoord",
|
||||||
"Secure your backup with a Security Phrase": "Beveilig uw back-up met een veiligheidszin",
|
"Secure your backup with a Security Phrase": "Beveilig uw back-up met een veiligheidswachtwoord",
|
||||||
"Your Security Key is in your <b>Downloads</b> folder.": "Uw veiligheidssleutel staat in uw <b>Downloads</b>-map.",
|
"Your Security Key is in your <b>Downloads</b> folder.": "Uw veiligheidssleutel staat in uw <b>Downloads</b>-map.",
|
||||||
"Your Security Key has been <b>copied to your clipboard</b>, paste it to:": "Uw veiligheidssleutel is <b>gekopieerd naar uw klembord</b>, plak het in:",
|
"Your Security Key has been <b>copied to your clipboard</b>, paste it to:": "Uw veiligheidssleutel is <b>gekopieerd naar uw klembord</b>, plak het in:",
|
||||||
"Your Security Key": "Uw veiligheidssleutel",
|
"Your Security Key": "Uw veiligheidssleutel",
|
||||||
"Your Security Key is a safety net - you can use it to restore access to your encrypted messages if you forget your Security Phrase.": "Uw veiligheidssleutel is een vangnet - u kunt hem gebruiken om de toegang tot uw versleutelde berichten te herstellen als u uw veiligheidszin bent vergeten.",
|
"Your Security Key is a safety net - you can use it to restore access to your encrypted messages if you forget your Security Phrase.": "Uw veiligheidssleutel is een vangnet - u kunt hem gebruiken om de toegang tot uw versleutelde berichten te herstellen als u uw veiligheidswachtwoord bent vergeten.",
|
||||||
"Repeat your Security Phrase...": "Herhaal uw veiligheidszin...",
|
"Repeat your Security Phrase...": "Herhaal uw veiligheidswachtwoord...",
|
||||||
"Please enter your Security Phrase a second time to confirm.": "Voer uw veiligheidszin een tweede keer in om te bevestigen.",
|
"Please enter your Security Phrase a second time to confirm.": "Voer uw veiligheidswachtwoord een tweede keer in om deze te bevestigen.",
|
||||||
"Set up with a Security Key": "Instellen met een veiligheidssleutel",
|
"Set up with a Security Key": "Instellen met een veiligheidssleutel",
|
||||||
"Great! This Security Phrase looks strong enough.": "Geweldig. Deze veiligheidszin ziet er sterk genoeg uit.",
|
"Great! This Security Phrase looks strong enough.": "Geweldig. Dit veiligheidswachtwoord ziet er sterk genoeg uit.",
|
||||||
"Enter a Security Phrase": "Veiligheidszin invoeren",
|
"Enter a Security Phrase": "Veiligheidswachtwoord invoeren",
|
||||||
"We'll store an encrypted copy of your keys on our server. Secure your backup with a Security Phrase.": "Wij bewaren een versleutelde kopie van uw sleutels op onze server. Beveilig uw back-up met een veiligheidszin.",
|
"We'll store an encrypted copy of your keys on our server. Secure your backup with a Security Phrase.": "Wij bewaren een versleutelde kopie van uw sleutels op onze server. Beveilig uw back-up met een veiligheidswachtwoord.",
|
||||||
"or another cross-signing capable Matrix client": "of een andere Matrix-client die kruislings kan ondertekenen",
|
"or another cross-signing capable Matrix client": "of een andere Matrix-client die kruislings kan ondertekenen",
|
||||||
"%(brand)s Android": "%(brand)s Android",
|
"%(brand)s Android": "%(brand)s Android",
|
||||||
"%(brand)s iOS": "%(brand)s iOS",
|
"%(brand)s iOS": "%(brand)s iOS",
|
||||||
|
@ -2735,7 +2735,7 @@
|
||||||
"%(brand)s Web": "%(brand)s Web",
|
"%(brand)s Web": "%(brand)s Web",
|
||||||
"This requires the latest %(brand)s on your other devices:": "Dit vereist de nieuwste %(brand)s op uw andere toestellen:",
|
"This requires the latest %(brand)s on your other devices:": "Dit vereist de nieuwste %(brand)s op uw andere toestellen:",
|
||||||
"Use Security Key": "Gebruik veiligheidssleutel",
|
"Use Security Key": "Gebruik veiligheidssleutel",
|
||||||
"Use Security Key or Phrase": "Gebruik veiligheidssleutel of -zin",
|
"Use Security Key or Phrase": "Gebruik veiligheidssleutel of -wachtwoord",
|
||||||
"Decide where your account is hosted": "Kies waar uw account wordt gehost",
|
"Decide where your account is hosted": "Kies waar uw account wordt gehost",
|
||||||
"Host account on": "Host uw account op",
|
"Host account on": "Host uw account op",
|
||||||
"Already have an account? <a>Sign in here</a>": "Heeft u al een account? <a>Aanmelden</a>",
|
"Already have an account? <a>Sign in here</a>": "Heeft u al een account? <a>Aanmelden</a>",
|
||||||
|
@ -2768,8 +2768,8 @@
|
||||||
"Upgrade to pro": "Upgrade naar pro",
|
"Upgrade to pro": "Upgrade naar pro",
|
||||||
"Now, let's help you get started": "Laten we u helpen om te beginnen",
|
"Now, let's help you get started": "Laten we u helpen om te beginnen",
|
||||||
"Welcome %(name)s": "Welkom %(name)s",
|
"Welcome %(name)s": "Welkom %(name)s",
|
||||||
"Add a photo so people know it's you.": "Voeg een foto toe zodat mensen weten dat u het bent.",
|
"Add a photo so people know it's you.": "Voeg een foto toe zodat personen weten dat u het bent.",
|
||||||
"Great, that'll help people know it's you": "Geweldig, dat zal mensen helpen te weten dat u het bent",
|
"Great, that'll help people know it's you": "Geweldig, dan zullen personen weten dat u het bent",
|
||||||
"<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 add images with Matrix URLs <img src=\"mxc://url\" />\n</p>\n": "<h1>HTML voor de pagina van uw gemeenschap</h1>\n<p>\nGebruik de lange beschrijving om nieuwe deelnemers voor te stellen aan de gemeenschap, of verspreid enkele belangrijke <a href=\"foo\">links</a>\n</p>\n<p>\nU kunt zelfs afbeeldingen toevoegen met Matrix URL's <img src=\"mxc://url\" />\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 add images with Matrix URLs <img src=\"mxc://url\" />\n</p>\n": "<h1>HTML voor de pagina van uw gemeenschap</h1>\n<p>\nGebruik de lange beschrijving om nieuwe deelnemers voor te stellen aan de gemeenschap, of verspreid enkele belangrijke <a href=\"foo\">links</a>\n</p>\n<p>\nU kunt zelfs afbeeldingen toevoegen met Matrix URL's <img src=\"mxc://url\" />\n</p>\n",
|
||||||
"Create community": "Gemeenschap aanmaken",
|
"Create community": "Gemeenschap aanmaken",
|
||||||
"Attach files from chat or just drag and drop them anywhere in a room.": "Voeg bestanden toe vanuit het gesprek of sleep ze in een gesprek.",
|
"Attach files from chat or just drag and drop them anywhere in a room.": "Voeg bestanden toe vanuit het gesprek of sleep ze in een gesprek.",
|
||||||
|
@ -2797,13 +2797,13 @@
|
||||||
"Not a valid Security Key": "Geen geldige veiligheidssleutel",
|
"Not a valid Security Key": "Geen geldige veiligheidssleutel",
|
||||||
"This looks like a valid Security Key!": "Dit lijkt op een geldige veiligheidssleutel!",
|
"This looks like a valid Security Key!": "Dit lijkt op een geldige veiligheidssleutel!",
|
||||||
"Enter Security Key": "Veiligheidssleutel invoeren",
|
"Enter Security Key": "Veiligheidssleutel invoeren",
|
||||||
"If you've forgotten your Security Phrase you can <button1>use your Security Key</button1> or <button2>set up new recovery options</button2>": "Als u uw Herstelwachtwoord bent vergeten, kunt u <button1>uw Herstelsleutel gebruiken</button1> of <button2>nieuwe herstelopties instellen</button2>",
|
"If you've forgotten your Security Phrase you can <button1>use your Security Key</button1> or <button2>set up new recovery options</button2>": "Als u uw veiligheidswachtwoord bent vergeten, kunt u <button1>uw veiligheidssleutel gebruiken</button1> of <button2>nieuwe herstelopties instellen</button2>",
|
||||||
"Access your secure message history and set up secure messaging by entering your Security Phrase.": "Ga naar uw veilige berichtengeschiedenis en stel veilige berichten in door uw veiligheidszin in te voeren.",
|
"Access your secure message history and set up secure messaging by entering your Security Phrase.": "Ga naar uw versleutelde berichtengeschiedenis en stel versleutelde berichten in door uw veiligheidswachtwoord in te voeren.",
|
||||||
"Enter Security Phrase": "Voer veiligheidszin in",
|
"Enter Security Phrase": "Veiligheidswachtwoord invoeren",
|
||||||
"Successfully restored %(sessionCount)s keys": "Succesvol %(sessionCount)s sleutels hersteld",
|
"Successfully restored %(sessionCount)s keys": "Succesvol %(sessionCount)s sleutels hersteld",
|
||||||
"Keys restored": "Sleutels hersteld",
|
"Keys restored": "Sleutels hersteld",
|
||||||
"Backup could not be decrypted with this Security Phrase: please verify that you entered the correct Security Phrase.": "Back-up kon niet worden gedecodeerd met deze veiligheidszin: controleer of u de juiste veiligheidszin hebt ingevoerd.",
|
"Backup could not be decrypted with this Security Phrase: please verify that you entered the correct Security Phrase.": "Back-up kon niet worden ontsleuteld met dit veiligheidswachtwoord: controleer of u het juiste veiligheidswachtwoord hebt ingevoerd.",
|
||||||
"Incorrect Security Phrase": "Onjuiste veiligheidszin",
|
"Incorrect Security Phrase": "Onjuist Veiligheidswachtwoord",
|
||||||
"Backup could not be decrypted with this Security Key: please verify that you entered the correct Security Key.": "Back-up kon niet worden ontcijferd met deze veiligheidssleutel: controleer of u de juiste veiligheidssleutel hebt ingevoerd.",
|
"Backup could not be decrypted with this Security Key: please verify that you entered the correct Security Key.": "Back-up kon niet worden ontcijferd met deze veiligheidssleutel: controleer of u de juiste veiligheidssleutel hebt ingevoerd.",
|
||||||
"Security Key mismatch": "Verkeerde veiligheidssleutel",
|
"Security Key mismatch": "Verkeerde veiligheidssleutel",
|
||||||
"%(completed)s of %(total)s keys restored": "%(completed)s van %(total)s sleutels hersteld",
|
"%(completed)s of %(total)s keys restored": "%(completed)s van %(total)s sleutels hersteld",
|
||||||
|
@ -2814,8 +2814,8 @@
|
||||||
"Confirm encryption setup": "Bevestig versleuting instelling",
|
"Confirm encryption setup": "Bevestig versleuting instelling",
|
||||||
"Use your Security Key to continue.": "Gebruik uw veiligheidssleutel om verder te gaan.",
|
"Use your Security Key to continue.": "Gebruik uw veiligheidssleutel om verder te gaan.",
|
||||||
"Security Key": "Veiligheidssleutel",
|
"Security Key": "Veiligheidssleutel",
|
||||||
"Enter your Security Phrase or <button>Use your Security Key</button> to continue.": "Voer uw veiligheidszin in of <button>gebruik uw veiligheidssleutel</button> om verder te gaan.",
|
"Enter your Security Phrase or <button>Use your Security Key</button> to continue.": "Voer uw veiligheidswachtwoord in of <button>gebruik uw veiligheidssleutel</button> om verder te gaan.",
|
||||||
"Security Phrase": "Veiligheidszin",
|
"Security Phrase": "Veiligheidswachtwoord",
|
||||||
"Invalid Security Key": "Ongeldige veiligheidssleutel",
|
"Invalid Security Key": "Ongeldige veiligheidssleutel",
|
||||||
"Wrong Security Key": "Verkeerde veiligheidssleutel",
|
"Wrong Security Key": "Verkeerde veiligheidssleutel",
|
||||||
"Looks good!": "Ziet er goed uit!",
|
"Looks good!": "Ziet er goed uit!",
|
||||||
|
@ -2869,11 +2869,11 @@
|
||||||
"Upload completed": "Upload voltooid",
|
"Upload completed": "Upload voltooid",
|
||||||
"Maximize dialog": "Maximaliseer dialoog",
|
"Maximize dialog": "Maximaliseer dialoog",
|
||||||
"%(hostSignupBrand)s Setup": "%(hostSignupBrand)s Installatie",
|
"%(hostSignupBrand)s Setup": "%(hostSignupBrand)s Installatie",
|
||||||
"You should know": "U moet weten",
|
"You should know": "Dit moet u weten",
|
||||||
"Privacy Policy": "Privacystatement",
|
"Privacy Policy": "Privacystatement",
|
||||||
"Cookie Policy": "Cookiebeleid",
|
"Cookie Policy": "Cookiebeleid",
|
||||||
"Abort": "Annuleren",
|
"Abort": "Afbreken",
|
||||||
"Confirm abort of host creation": "Bevestig het annuleren van de host creatie",
|
"Confirm abort of host creation": "Bevestig het afbreken van host creatie",
|
||||||
"You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "U zou dit kunnen aanzetten als dit gesprek alleen gebruikt zal worden voor samenwerking met interne teams op uw homeserver. Dit kan later niet meer veranderd worden.",
|
"You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "U zou dit kunnen aanzetten als dit gesprek alleen gebruikt zal worden voor samenwerking met interne teams op uw homeserver. Dit kan later niet meer veranderd worden.",
|
||||||
"You can’t disable this later. Bridges & most bots won’t work yet.": "U kunt dit later niet uitschakelen. Bruggen en de meeste bots zullen nog niet werken.",
|
"You can’t disable this later. Bridges & most bots won’t work yet.": "U kunt dit later niet uitschakelen. Bruggen en de meeste bots zullen nog niet werken.",
|
||||||
"There was an error creating your community. The name may be taken or the server is unable to process your request.": "Er is een fout opgetreden bij het aanmaken van uw gemeenschap. De naam kan bezet zijn of de server is niet in staat om uw aanvraag te verwerken.",
|
"There was an error creating your community. The name may be taken or the server is unable to process your request.": "Er is een fout opgetreden bij het aanmaken van uw gemeenschap. De naam kan bezet zijn of de server is niet in staat om uw aanvraag te verwerken.",
|
||||||
|
@ -2887,7 +2887,7 @@
|
||||||
"Screens": "Schermen",
|
"Screens": "Schermen",
|
||||||
"Share your screen": "Uw scherm delen",
|
"Share your screen": "Uw scherm delen",
|
||||||
"Submit logs": "Logs versturen",
|
"Submit logs": "Logs versturen",
|
||||||
"Messages in this room are end-to-end encrypted. When people join, you can verify them in their profile, just tap on their avatar.": "Berichten in dit gesprek zijn eind-tot-eind-versleuteld. Als mensen deelnemen, kan u ze verifiëren in hun profiel, tik gewoon op hun avatar.",
|
"Messages in this room are end-to-end encrypted. When people join, you can verify them in their profile, just tap on their avatar.": "Berichten in dit gesprek zijn eind-tot-eind-versleuteld. Als personen deelnemen, kan u ze verifiëren in hun profiel, tik hiervoor op hun avatar.",
|
||||||
"In encrypted rooms, verify all users to ensure it’s secure.": "Controleer alle gebruikers in versleutelde gesprekken om er zeker van te zijn dat het veilig is.",
|
"In encrypted rooms, verify all users to ensure it’s secure.": "Controleer alle gebruikers in versleutelde gesprekken om er zeker van te zijn dat het veilig is.",
|
||||||
"Verify all users in a room to ensure it's secure.": "Controleer alle gebruikers in een gesprek om er zeker van te zijn dat hij veilig is.",
|
"Verify all users in a room to ensure it's secure.": "Controleer alle gebruikers in een gesprek om er zeker van te zijn dat hij veilig is.",
|
||||||
"%(count)s people|one": "%(count)s persoon",
|
"%(count)s people|one": "%(count)s persoon",
|
||||||
|
@ -2903,7 +2903,7 @@
|
||||||
"Use the + to make a new room or explore existing ones below": "Gebruik de + om een nieuw gesprek te starten of ontdek de bestaande groepen hieronder",
|
"Use the + to make a new room or explore existing ones below": "Gebruik de + om een nieuw gesprek te starten of ontdek de bestaande groepen hieronder",
|
||||||
"Open dial pad": "Kiestoetsen openen",
|
"Open dial pad": "Kiestoetsen openen",
|
||||||
"Recently visited rooms": "Onlangs geopende gesprekken",
|
"Recently visited rooms": "Onlangs geopende gesprekken",
|
||||||
"Add a photo, so people can easily spot your room.": "Voeg een foto toe, zodat mensen je gemakkelijk kunnen herkennen in het gesprek.",
|
"Add a photo, so people can easily spot your room.": "Voeg een foto toe, zodat personen u gemakkelijk kunnen herkennen in het gesprek.",
|
||||||
"Only the two of you are in this conversation, unless either of you invites anyone to join.": "Alleen u beiden nemen deel aan dit gesprek, tenzij een van u beiden iemand uitnodigt om deel te nemen.",
|
"Only the two of you are in this conversation, unless either of you invites anyone to join.": "Alleen u beiden nemen deel aan dit gesprek, tenzij een van u beiden iemand uitnodigt om deel te nemen.",
|
||||||
"Emoji picker": "Emoji kiezer",
|
"Emoji picker": "Emoji kiezer",
|
||||||
"Room ID or address of ban list": "Gesprek-ID of het adres van de banlijst",
|
"Room ID or address of ban list": "Gesprek-ID of het adres van de banlijst",
|
||||||
|
@ -2916,7 +2916,7 @@
|
||||||
"Hey you. You're the best!": "Hey. U bent de beste!",
|
"Hey you. You're the best!": "Hey. U bent de beste!",
|
||||||
"Backup key cached:": "Back-up sleutel cached:",
|
"Backup key cached:": "Back-up sleutel cached:",
|
||||||
"Backup key stored:": "Back-up sleutel bewaard:",
|
"Backup key stored:": "Back-up sleutel bewaard:",
|
||||||
"Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.": "Maak een back-up van uw encryptiesleutels met uw accountgegevens voor het geval u de toegang tot uw sessies verliest. Uw sleutels worden beveiligd met een unieke veiligheidssleutel.",
|
"Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.": "Maak een back-up van uw versleutelingssleutels met uw accountgegevens voor het geval u de toegang tot uw sessies verliest. Uw sleutels worden beveiligd met een unieke veiligheidssleutel.",
|
||||||
"well formed": "goed gevormd",
|
"well formed": "goed gevormd",
|
||||||
"%(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 kan versleutelde berichten niet veilig lokaal opslaan in een webbrowser. Gebruik <desktopLink>%(brand)s Desktop</desktopLink> om versleutelde berichten in zoekresultaten te laten verschijnen.",
|
"%(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 kan versleutelde berichten niet veilig lokaal opslaan in een webbrowser. Gebruik <desktopLink>%(brand)s Desktop</desktopLink> om versleutelde berichten in zoekresultaten te laten verschijnen.",
|
||||||
"Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|one": "Veilig lokaal opslaan van versleutelde berichten zodat ze in de zoekresultaten verschijnen, gebruik %(size)s voor het opslaan van berichten uit %(rooms)s gesprek.",
|
"Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|one": "Veilig lokaal opslaan van versleutelde berichten zodat ze in de zoekresultaten verschijnen, gebruik %(size)s voor het opslaan van berichten uit %(rooms)s gesprek.",
|
||||||
|
@ -2950,7 +2950,7 @@
|
||||||
"Create a Group Chat": "Maak een groepsgesprek aan",
|
"Create a Group Chat": "Maak een groepsgesprek aan",
|
||||||
"Send a Direct Message": "Start een direct gesprek",
|
"Send a Direct Message": "Start een direct gesprek",
|
||||||
"Welcome to %(appName)s": "Welkom bij %(appName)s",
|
"Welcome to %(appName)s": "Welkom bij %(appName)s",
|
||||||
"<a>Add a topic</a> to help people know what it is about.": "<a>Stel een gespreksonderwerp in</a> zodat mensen weten waar het over gaat.",
|
"<a>Add a topic</a> to help people know what it is about.": "<a>Stel een gespreksonderwerp in</a> zodat de personen weten waar het over gaat.",
|
||||||
"Upgrade to %(hostSignupBrand)s": "Upgrade naar %(hostSignupBrand)s",
|
"Upgrade to %(hostSignupBrand)s": "Upgrade naar %(hostSignupBrand)s",
|
||||||
"Edit Values": "Waarde wijzigen",
|
"Edit Values": "Waarde wijzigen",
|
||||||
"Values at explicit levels in this room:": "Waarde op expliciete niveaus in dit gesprek:",
|
"Values at explicit levels in this room:": "Waarde op expliciete niveaus in dit gesprek:",
|
||||||
|
@ -2972,5 +2972,120 @@
|
||||||
"Setting ID": "Instellingen-ID",
|
"Setting ID": "Instellingen-ID",
|
||||||
"Failed to save settings": "Kan geen instellingen opslaan",
|
"Failed to save settings": "Kan geen instellingen opslaan",
|
||||||
"Settings Explorer": "Instellingen Ontdekken",
|
"Settings Explorer": "Instellingen Ontdekken",
|
||||||
"Show chat effects (animations when receiving e.g. confetti)": "Effecten tonen (animaties bij ontvangst bijv. confetti)"
|
"Show chat effects (animations when receiving e.g. confetti)": "Effecten tonen (animaties bij ontvangst bijv. confetti)",
|
||||||
|
"Jump to the bottom of the timeline when you send a message": "Naar de onderkant van de tijdlijn springen wanneer u een bericht verstuurd",
|
||||||
|
"Original event source": "Originele gebeurtenisbron",
|
||||||
|
"Decrypted event source": "Ontsleutel de gebeurtenisbron",
|
||||||
|
"We'll create rooms for each of them. You can add existing rooms after setup.": "We maken gesprekken voor elk van hen. U kunt bestaande gesprekken toevoegen na het instellen.",
|
||||||
|
"What projects are you working on?": "Aan welke projecten werkt u?",
|
||||||
|
"We'll create rooms for each topic.": "We maken gesprekken voor elk onderwerp.",
|
||||||
|
"What are some things you want to discuss?": "Wat zijn dingen die u wilt bespreken?",
|
||||||
|
"Inviting...": "Uitnodigen...",
|
||||||
|
"Invite by username": "Op gebruikersnaam uitnodigen",
|
||||||
|
"Invite your teammates": "Uw teamgenoten uitnodigen",
|
||||||
|
"Failed to invite the following users to your space: %(csvUsers)s": "Het uitnodigen van de volgende gebruikers voor uw space is mislukt: %(csvUsers)s",
|
||||||
|
"A private space for you and your teammates": "Een privé space voor u en uw teamgenoten",
|
||||||
|
"Me and my teammates": "Ik en mijn teamgenoten",
|
||||||
|
"A private space just for you": "Een privé space alleen voor u",
|
||||||
|
"Just Me": "Alleen Ik",
|
||||||
|
"Ensure the right people have access to the space.": "Zorg ervoor dat de juiste personen toegang hebben tot deze space.",
|
||||||
|
"Who are you working with?": "Met wie werkt u samen?",
|
||||||
|
"Finish": "Voltooien",
|
||||||
|
"At the moment only you can see it.": "Op dit moment kan u deze alleen zien.",
|
||||||
|
"Creating rooms...": "Gesprekken aanmaken...",
|
||||||
|
"Skip for now": "Voorlopig overslaan",
|
||||||
|
"Failed to create initial space rooms": "Het maken van de space gesprekken is mislukt",
|
||||||
|
"Room name": "Gespreksnaam",
|
||||||
|
"Support": "Ondersteuning",
|
||||||
|
"Random": "Willekeurig",
|
||||||
|
"Welcome to <name/>": "Welkom in <name/>",
|
||||||
|
"Your private space <name/>": "Uw privé space <name/>",
|
||||||
|
"Your public space <name/>": "Uw openbare space <name/>",
|
||||||
|
"You have been invited to <name/>": "U bent uitgenodigd voor <name/>",
|
||||||
|
"<inviter/> invited you to <name/>": "<inviter/> heeft u uitgenodigd voor <name/>",
|
||||||
|
"%(count)s members|other": "%(count)s personen",
|
||||||
|
"%(count)s members|one": "%(count)s persoon",
|
||||||
|
"Your server does not support showing space hierarchies.": "Uw server heeft geen ondersteuning voor het weergeven van space indelingen.",
|
||||||
|
"Default Rooms": "Standaard Gesprekken",
|
||||||
|
"Add existing rooms & spaces": "Bestaande gesprekken en spaces toevoegen",
|
||||||
|
"Accept Invite": "Uitnodiging Accepteren",
|
||||||
|
"Find a room...": "Vind een gesprek...",
|
||||||
|
"Manage rooms": "Gesprekken beheren",
|
||||||
|
"Promoted to users": "Gepromoot aan gebruikers",
|
||||||
|
"Save changes": "Wijzigingen opslaan",
|
||||||
|
"You're in this room": "U bent in dit gesprek",
|
||||||
|
"You're in this space": "U bent in deze space",
|
||||||
|
"No permissions": "Geen rechten",
|
||||||
|
"Remove from Space": "Van space verwijderen",
|
||||||
|
"Undo": "Ongedaan maken",
|
||||||
|
"Your message wasn't sent because this homeserver has been blocked by it's administrator. Please <a>contact your service administrator</a> to continue using the service.": "Uw bericht is niet verstuurd, omdat deze homeserver is geblokkeerd door zijn beheerder. Gelieve <a>contact op te nemen met uw beheerder</a> om de dienst te blijven gebruiken.",
|
||||||
|
"Are you sure you want to leave the space '%(spaceName)s'?": "Weet u zeker dat u de space '%(spaceName)s' wilt verlaten?",
|
||||||
|
"This space is not public. You will not be able to rejoin without an invite.": "Deze space is niet openbaar. Zonder uitnodiging zult u niet opnieuw kunnen toetreden.",
|
||||||
|
"Start audio stream": "Audio-stream starten",
|
||||||
|
"Failed to start livestream": "Starten van livestream is mislukt",
|
||||||
|
"Unable to start audio streaming.": "Kan audio-streaming niet starten.",
|
||||||
|
"Save Changes": "Wijzigingen Opslaan",
|
||||||
|
"Saving...": "Opslaan...",
|
||||||
|
"View dev tools": "Bekijk dev tools",
|
||||||
|
"Leave Space": "Space verlaten",
|
||||||
|
"Make this space private": "Maak deze space privé",
|
||||||
|
"Failed to save space settings.": "Het opslaan van de space-instellingen is mislukt.",
|
||||||
|
"Space settings": "Space-instellingen",
|
||||||
|
"Edit settings relating to your space.": "Bewerk instellingen gerelateerd aan uw space.",
|
||||||
|
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.": "Nodig iemand uit per naam, gebruikersnaam (zoals <userId/>) of <a>deel deze space</a>.",
|
||||||
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "Nodig iemand uit per naam, e-mailadres, gebruikersnaam (zoals <userId/>) of <a>deel deze space</a>.",
|
||||||
|
"Unnamed Space": "Naamloze Space",
|
||||||
|
"Invite to %(spaceName)s": "Voor %(spaceName)s uitnodigen",
|
||||||
|
"Failed to add rooms to space": "Het toevoegen van gesprekken aan de space is mislukt",
|
||||||
|
"Apply": "Toepassen",
|
||||||
|
"Applying...": "Toepassen...",
|
||||||
|
"Create a new room": "Een nieuw gesprek aanmaken",
|
||||||
|
"Don't want to add an existing room?": "Wilt u geen bestaand gesprek toevoegen?",
|
||||||
|
"Spaces": "Spaces",
|
||||||
|
"Filter your rooms and spaces": "Gesprekken en spaces filteren",
|
||||||
|
"Add existing spaces/rooms": "Bestaande spaces/gesprekken toevoegen",
|
||||||
|
"Space selection": "Space-selectie",
|
||||||
|
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the space it will be impossible to regain privileges.": "U kunt deze wijziging niet ongedaan maken omdat u uzelf rechten ontneemt, als u de laatste bevoegde gebruiker in de ruimte bent zal het onmogelijk zijn om weer rechten te krijgen.",
|
||||||
|
"Empty room": "Leeg gesprek",
|
||||||
|
"Suggested Rooms": "Gespreksuggesties",
|
||||||
|
"Explore space rooms": "Space-gesprekken ontdekken",
|
||||||
|
"You do not have permissions to add rooms to this space": "U hebt geen toestemming om gesprekken toe te voegen in deze space",
|
||||||
|
"Add existing room": "Bestaande gesprekken toevoegen",
|
||||||
|
"You do not have permissions to create new rooms in this space": "U hebt geen toestemming om gesprekken te maken in deze space",
|
||||||
|
"Send message": "Bericht versturen",
|
||||||
|
"Invite to this space": "Uitnodigen voor deze space",
|
||||||
|
"Your message was sent": "Uw bericht is verstuurd",
|
||||||
|
"Encrypting your message...": "Uw bericht versleutelen...",
|
||||||
|
"Sending your message...": "Uw bericht versturen...",
|
||||||
|
"Spell check dictionaries": "Spellingscontrole woordenboeken",
|
||||||
|
"Space options": "Space-opties",
|
||||||
|
"Space Home": "Space Thuis",
|
||||||
|
"New room": "Nieuw gesprek",
|
||||||
|
"Leave space": "Space verlaten",
|
||||||
|
"Invite people": "Personen uitnodigen",
|
||||||
|
"Share your public space": "Deel uw publieke space",
|
||||||
|
"Invite members": "Leden uitnodigen",
|
||||||
|
"Invite by email or username": "Uitnodigen per e-mail of gebruikersnaam",
|
||||||
|
"Share invite link": "Deel uitnodigingskoppeling",
|
||||||
|
"Click to copy": "Klik om te kopiëren",
|
||||||
|
"Collapse space panel": "Space-paneel invouwen",
|
||||||
|
"Expand space panel": "Space-paneel uitvouwen",
|
||||||
|
"Creating...": "Aanmaken...",
|
||||||
|
"You can change these at any point.": "U kan dit op elk moment aanpassen.",
|
||||||
|
"Give it a photo, name and description to help you identify it.": "Geef het een foto, naam en omschrijving om u te helpen het te herkennen.",
|
||||||
|
"Your private space": "Uw privé space",
|
||||||
|
"Your public space": "Uw openbare space",
|
||||||
|
"You can change this later": "U kan dit later aanpassen",
|
||||||
|
"Invite only, best for yourself or teams": "Alleen op uitnodiging, geschikt voor uzelf of teams",
|
||||||
|
"Private": "Privé",
|
||||||
|
"Open space for anyone, best for communities": "Openbare space voor iedereen, geschikt voor gemeenschappen",
|
||||||
|
"Public": "Openbaar",
|
||||||
|
"Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "Spaces is een nieuwe manier van groeperen van gesprekken en personen. Om deel te nemen aan een bestaande space heeft u een uitnodiging nodig",
|
||||||
|
"Create a space": "Space aanmaken",
|
||||||
|
"Delete": "Verwijderen",
|
||||||
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Spaces prototype. Niet compatibel met Gemeenschappen, Gemeenschappen v2 en Aangepaste Labels. Vereist een geschikte homeserver voor sommige functies.",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "Deze homeserver is geblokkeerd door zijn beheerder.",
|
||||||
|
"This homeserver has been blocked by its administrator.": "Deze homeserver is geblokkeerd door uw beheerder.",
|
||||||
|
"Already in call": "Al in gesprek",
|
||||||
|
"You're already in a call with this person.": "U bent al in gesprek met deze persoon."
|
||||||
}
|
}
|
||||||
|
|
|
@ -3019,5 +3019,96 @@
|
||||||
"Value": "Valor",
|
"Value": "Valor",
|
||||||
"Failed to save settings": "Falha ao salvar as configurações",
|
"Failed to save settings": "Falha ao salvar as configurações",
|
||||||
"Show chat effects (animations when receiving e.g. confetti)": "Mostrar efeitos na conversa (por exemplo: animações ao receber confetes)",
|
"Show chat effects (animations when receiving e.g. confetti)": "Mostrar efeitos na conversa (por exemplo: animações ao receber confetes)",
|
||||||
"Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "O Element Web é experimental para dispositivos móveis. Para uma melhor experiência e os recursos mais recentes, use nosso aplicativo gratuito."
|
"Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "O Element Web é experimental para dispositivos móveis. Para uma melhor experiência e os recursos mais recentes, use nosso aplicativo gratuito.",
|
||||||
|
"Empty room": "Sala vazia",
|
||||||
|
"Suggested Rooms": "Salas sugeridas",
|
||||||
|
"Add existing room": "Adicionar sala existente",
|
||||||
|
"Send message": "Enviar mensagem",
|
||||||
|
"Just Me": "Somente eu",
|
||||||
|
"Finish": "Concluir",
|
||||||
|
"Creating rooms...": "Criando salas...",
|
||||||
|
"Skip for now": "Ignorar por enquanto",
|
||||||
|
"Room name": "Nome da sala",
|
||||||
|
"Random": "Aleatório",
|
||||||
|
"Welcome to <name/>": "Boas-vindas ao <name/>",
|
||||||
|
"Creating...": "Criando...",
|
||||||
|
"Private": "Privado",
|
||||||
|
"Public": "Público",
|
||||||
|
"Delete": "Excluir",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "Este servidor local foi bloqueado pelo seu administrador.",
|
||||||
|
"This homeserver has been blocked by its administrator.": "Este servidor local foi bloqueado pelo seu administrador.",
|
||||||
|
"You're already in a call with this person.": "Você já está em uma chamada com essa pessoa.",
|
||||||
|
"At the moment only you can see it.": "No momento, só você pode ver.",
|
||||||
|
"Failed to create initial space rooms": "Falha ao criar salas de espaço iniciais",
|
||||||
|
"Your private space <name/>": "Seu espaço privado <name/>",
|
||||||
|
"Your public space <name/>": "Seu espaço público <name/>",
|
||||||
|
"You have been invited to <name/>": "Você foi convidado para <name/>",
|
||||||
|
"<inviter/> invited you to <name/>": "<inviter/> convidou você para <name/>",
|
||||||
|
"%(count)s members|one": "%(count)s integrante",
|
||||||
|
"%(count)s members|other": "%(count)s integrantes",
|
||||||
|
"Add existing rooms & spaces": "Adicionar salas & espaços já existentes",
|
||||||
|
"Accept Invite": "Aceitar o convite",
|
||||||
|
"Save changes": "Salvar alterações",
|
||||||
|
"You're in this room": "Você está nesta sala",
|
||||||
|
"You're in this space": "Você está neste espaço",
|
||||||
|
"No permissions": "Sem permissões",
|
||||||
|
"Undo": "Desfazer",
|
||||||
|
"Your message wasn't sent because this homeserver has been blocked by it's administrator. Please <a>contact your service administrator</a> to continue using the service.": "A sua mensagem não foi enviada porque este servidor local foi bloqueado pelo seu administrador. <a>Entre em contato com o administrador do serviço</a> para continuar usando o serviço.",
|
||||||
|
"Are you sure you want to leave the space '%(spaceName)s'?": "Tem certeza de que deseja sair desse espaço '%(spaceName)s'?",
|
||||||
|
"This space is not public. You will not be able to rejoin without an invite.": "Este espaço não é público. Você não poderá entrar novamente sem um convite.",
|
||||||
|
"Save Changes": "Salvar alterações",
|
||||||
|
"Saving...": "Salvando...",
|
||||||
|
"View dev tools": "Ver ferramentas de desenvolvimento",
|
||||||
|
"Leave space": "Sair desse espaço",
|
||||||
|
"Leave Space": "Sair desse espaço",
|
||||||
|
"Make this space private": "Tornar este espaço privado",
|
||||||
|
"Edit settings relating to your space.": "Editar configurações relacionadas ao seu espaço.",
|
||||||
|
"Space settings": "Configurações desse espaço",
|
||||||
|
"Failed to save space settings.": "Falha ao salvar as configurações desse espaço.",
|
||||||
|
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.": "Convide alguém a partir do nome, nome de usuário (como <userId/>) ou <a>compartilhe este espaço</a>.",
|
||||||
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "Convide alguém a partir do nome, endereço de e-mail, nome de usuário (como <userId/>) ou <a>compartilhe este espaço</a>.",
|
||||||
|
"Unnamed Space": "Espaço sem nome",
|
||||||
|
"Invite to %(spaceName)s": "Convidar para %(spaceName)s",
|
||||||
|
"Failed to add rooms to space": "Falha ao adicionar salas ao espaço",
|
||||||
|
"Create a new room": "Criar uma nova sala",
|
||||||
|
"Don't want to add an existing room?": "Não deseja adicionar uma sala já existente?",
|
||||||
|
"Spaces": "Espaços",
|
||||||
|
"Filter your rooms and spaces": "Pesquisar suas salas e espaços",
|
||||||
|
"Add existing spaces/rooms": "Adicionar espaços/salas já existentes",
|
||||||
|
"Explore space rooms": "Explorar as salas deste espaço",
|
||||||
|
"You do not have permissions to add rooms to this space": "Você não tem permissão para adicionar salas neste espaço",
|
||||||
|
"You do not have permissions to create new rooms in this space": "Você não tem permissão para criar novas salas neste espaço",
|
||||||
|
"Invite to this space": "Convidar para este espaço",
|
||||||
|
"Your message was sent": "A sua mensagem foi enviada",
|
||||||
|
"Encrypting your message...": "Criptografando a sua mensagem...",
|
||||||
|
"Sending your message...": "Enviando a sua mensagem...",
|
||||||
|
"Spell check dictionaries": "Dicionários de verificação ortográfica",
|
||||||
|
"Space options": "Opções do espaço",
|
||||||
|
"New room": "Nova sala",
|
||||||
|
"Invite people": "Convidar pessoas",
|
||||||
|
"Share your public space": "Compartilhar o seu espaço público",
|
||||||
|
"Invite members": "Convidar integrantes",
|
||||||
|
"Invite by email or username": "Convidar por e-mail ou nome de usuário",
|
||||||
|
"Share invite link": "Compartilhar link de convite",
|
||||||
|
"Click to copy": "Clique para copiar",
|
||||||
|
"Collapse space panel": "Fechar o painel do espaço",
|
||||||
|
"Expand space panel": "Expandir o painel do espaço",
|
||||||
|
"You can change these at any point.": "Você pode alterar esses dados a qualquer momento.",
|
||||||
|
"Give it a photo, name and description to help you identify it.": "Insira uma foto, nome e descrição para ajudar a identificar o espaço.",
|
||||||
|
"Your private space": "O seu espaço privado",
|
||||||
|
"Your public space": "O seu espaço público",
|
||||||
|
"You can change this later": "Você pode mudar isso depois",
|
||||||
|
"Open space for anyone, best for communities": "Abra espaços para todos, especialmente para comunidades",
|
||||||
|
"Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "Espaços são novas formas de agrupar salas e pessoas. Para entrar em um espaço existente, você precisará de um convite",
|
||||||
|
"Create a space": "Criar um espaço",
|
||||||
|
"Jump to the bottom of the timeline when you send a message": "Vá para o final da linha do tempo ao enviar uma mensagem",
|
||||||
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Protótipo de Espaços. Incompatível com Comunidades, Comunidades v2 e tags personalizadas. Requer um servidor compatível com os recursos necessários.",
|
||||||
|
"Decrypted event source": "Fonte de evento descriptografada",
|
||||||
|
"We'll create rooms for each of them. You can add existing rooms after setup.": "Criaremos salas para cada um deles. Você pode adicionar salas já existentes após a configuração.",
|
||||||
|
"What projects are you working on?": "Em quais projetos você trabalha no momento?",
|
||||||
|
"We'll create rooms for each topic.": "Nós criaremos salas para cada tópico.",
|
||||||
|
"Inviting...": "Convidando...",
|
||||||
|
"Invite by username": "Convidar por nome de usuário",
|
||||||
|
"Support": "Suporte",
|
||||||
|
"Original event source": "Fonte do evento original"
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@
|
||||||
"Failure to create room": "Не удалось создать комнату",
|
"Failure to create room": "Не удалось создать комнату",
|
||||||
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "для %(userId)s с %(fromPowerLevel)s на %(toPowerLevel)s",
|
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "для %(userId)s с %(fromPowerLevel)s на %(toPowerLevel)s",
|
||||||
"click to reveal": "нажмите для открытия",
|
"click to reveal": "нажмите для открытия",
|
||||||
"%(senderName)s invited %(targetName)s.": "%(senderName)s пригласил %(targetName)s.",
|
"%(senderName)s invited %(targetName)s.": "%(senderName)s пригласил(а) %(targetName)s.",
|
||||||
"%(targetName)s joined the room.": "%(targetName)s вошёл в комнату.",
|
"%(targetName)s joined the room.": "%(targetName)s вошёл в комнату.",
|
||||||
"%(senderName)s kicked %(targetName)s.": "%(senderName)s исключил(а) %(targetName)s.",
|
"%(senderName)s kicked %(targetName)s.": "%(senderName)s исключил(а) %(targetName)s.",
|
||||||
"%(targetName)s left the room.": "%(targetName)s покинул(а) комнату.",
|
"%(targetName)s left the room.": "%(targetName)s покинул(а) комнату.",
|
||||||
|
@ -2064,7 +2064,7 @@
|
||||||
"You changed your avatar": "Вы поменяли свой аватар",
|
"You changed your avatar": "Вы поменяли свой аватар",
|
||||||
"%(targetName)s changed their avatar": "%(targetName)s поменял(а) свой аватар",
|
"%(targetName)s changed their avatar": "%(targetName)s поменял(а) свой аватар",
|
||||||
"You changed the room name": "Вы поменяли имя комнаты",
|
"You changed the room name": "Вы поменяли имя комнаты",
|
||||||
"Enable experimental, compact IRC style layout": "Включите экспериментальный, компактный стиль IRC",
|
"Enable experimental, compact IRC style layout": "Включить экспериментальный, компактный стиль IRC",
|
||||||
"Unknown caller": "Неизвестный абонент",
|
"Unknown caller": "Неизвестный абонент",
|
||||||
"Incoming call": "Входящий звонок",
|
"Incoming call": "Входящий звонок",
|
||||||
"Waiting for your other session to verify…": "Ожидание вашей другой сессии для начала подтверждения…",
|
"Waiting for your other session to verify…": "Ожидание вашей другой сессии для начала подтверждения…",
|
||||||
|
@ -2613,7 +2613,7 @@
|
||||||
"Unable to validate homeserver": "Невозможно проверить домашний сервер",
|
"Unable to validate homeserver": "Невозможно проверить домашний сервер",
|
||||||
"Sign into your homeserver": "Войдите на свой домашний сервер",
|
"Sign into your homeserver": "Войдите на свой домашний сервер",
|
||||||
"with state key %(stateKey)s": "с ключом состояния %(stateKey)s",
|
"with state key %(stateKey)s": "с ключом состояния %(stateKey)s",
|
||||||
"%(creator)s created this DM.": "%(creator)s начал этот чат.",
|
"%(creator)s created this DM.": "%(creator)s начал(а) этот чат.",
|
||||||
"Show chat effects": "Показать эффекты чата",
|
"Show chat effects": "Показать эффекты чата",
|
||||||
"Host account on": "Ваша учётная запись обслуживается",
|
"Host account on": "Ваша учётная запись обслуживается",
|
||||||
"%(ssoButtons)s Or %(usernamePassword)s": "%(ssoButtons)s или %(usernamePassword)s",
|
"%(ssoButtons)s Or %(usernamePassword)s": "%(ssoButtons)s или %(usernamePassword)s",
|
||||||
|
|
|
@ -3076,5 +3076,120 @@
|
||||||
"Value": "Vlerë",
|
"Value": "Vlerë",
|
||||||
"Failed to save settings": "S’u arrit të ruhen rregullimet",
|
"Failed to save settings": "S’u arrit të ruhen rregullimet",
|
||||||
"Settings Explorer": "Eksplorues Rregullimesh",
|
"Settings Explorer": "Eksplorues Rregullimesh",
|
||||||
"Show chat effects (animations when receiving e.g. confetti)": "Shfaq efekte fjalosjeje (animacione kur merren bonbone, për shembull)"
|
"Show chat effects (animations when receiving e.g. confetti)": "Shfaq efekte fjalosjeje (animacione kur merren bonbone, për shembull)",
|
||||||
|
"Original event source": "Burim i veprimtarisë origjinale",
|
||||||
|
"Decrypted event source": "U shfshehtëzua burim veprimtarie",
|
||||||
|
"We'll create rooms for each of them. You can add existing rooms after setup.": "Do të krijojmë dhoma për çdo një prej tyre. Pas ujdisjes mund të shtoni dhoma ekzistuese.",
|
||||||
|
"What projects are you working on?": "Me çfarë projektesh po merreni?",
|
||||||
|
"We'll create rooms for each topic.": "Do të krijojmë dhoma për çdo temë.",
|
||||||
|
"What are some things you want to discuss?": "Cilat janë disa nga gjërat që doni të diskutoni?",
|
||||||
|
"Inviting...": "Po ftohen…",
|
||||||
|
"Invite by username": "Ftoni përmes emri përdoruesi",
|
||||||
|
"Invite your teammates": "Ftoni anëtarët e ekipit tuaj",
|
||||||
|
"Failed to invite the following users to your space: %(csvUsers)s": "S’u arrit të ftoheshin te hapësira juaj përdoruesit vijues: %(csvUsers)s",
|
||||||
|
"A private space for you and your teammates": "Një hapësirë private për ju dhe anëtarët e ekipit tuaj",
|
||||||
|
"Me and my teammates": "Unë dhe anëtarët e ekipit tim",
|
||||||
|
"A private space just for you": "Një hapësirë private vetëm për ju",
|
||||||
|
"Just Me": "Vetëm Unë",
|
||||||
|
"Ensure the right people have access to the space.": "Siguroni që personat e duhur të mund të hyjnë te hapësira",
|
||||||
|
"Who are you working with?": "Me cilët po punoni?",
|
||||||
|
"Finish": "Përfundoje",
|
||||||
|
"At the moment only you can see it.": "Hëpërhë mund ta shihni vetëm ju.",
|
||||||
|
"Creating rooms...": "Po krijohen dhoma…",
|
||||||
|
"Skip for now": "Hëpërhë anashkaloje",
|
||||||
|
"Failed to create initial space rooms": "S’u arrit të krijohen dhomat fillestare të hapësirës",
|
||||||
|
"Room name": "Emër dhome",
|
||||||
|
"Support": "Asistencë",
|
||||||
|
"Random": "Kuturu",
|
||||||
|
"Welcome to <name/>": "Mirë se vini te <name/>",
|
||||||
|
"Your private space <name/>": "Hapësira juaj private <name/>",
|
||||||
|
"Your public space <name/>": "Hapësira juaj publike <name/>",
|
||||||
|
"You have been invited to <name/>": "Jeni ftuar te <name/>",
|
||||||
|
"<inviter/> invited you to <name/>": "<inviter/> ju ftoi te <name/>",
|
||||||
|
"%(count)s members|one": "%(count)s anëtar",
|
||||||
|
"%(count)s members|other": "%(count)s anëtarë",
|
||||||
|
"Your server does not support showing space hierarchies.": "Shërbyesi juaj nuk mbulon shfaqje hierarkish hapësire.",
|
||||||
|
"Default Rooms": "Dhoma Parazgjedhje",
|
||||||
|
"Add existing rooms & spaces": "Shtoni dhoma & hapësira ekzistuese",
|
||||||
|
"Accept Invite": "Pranoje Ftesën",
|
||||||
|
"Find a room...": "Gjeni një dhomë…",
|
||||||
|
"Manage rooms": "Administroni dhoma",
|
||||||
|
"Save changes": "Ruaji ndryshimet",
|
||||||
|
"You're in this room": "Gjendeni në këtë dhomë",
|
||||||
|
"You're in this space": "Gjendeni në këtë hapësirë",
|
||||||
|
"No permissions": "S’ka leje",
|
||||||
|
"Remove from Space": "Hiqe prej Hapësire",
|
||||||
|
"Undo": "Zhbëje",
|
||||||
|
"Your message wasn't sent because this homeserver has been blocked by it's administrator. Please <a>contact your service administrator</a> to continue using the service.": "Mesazhi juaj s’u dërgua, ngaqë ky shërbyes Home është bllokuar nga përgjegjësi i tij. Ju lutemi, që të vazhdoni ta përdorni këtë shërbim, <a>lidhuni me përgjegjësin e shërbimit tuaj</a>.",
|
||||||
|
"Are you sure you want to leave the space '%(spaceName)s'?": "Jeni i sigurt se doni të dilni nga hapësira '%(spaceName)s'?",
|
||||||
|
"This space is not public. You will not be able to rejoin without an invite.": "Kjo hapësirë s’është publike. S’do të jeni në gjendje të rihyni në të pa një ftesë.",
|
||||||
|
"Start audio stream": "Nisni transmetim audio",
|
||||||
|
"Unable to start audio streaming.": "S’arrihet të niset transmetim audio.",
|
||||||
|
"Save Changes": "Ruaji Ndryshimet",
|
||||||
|
"Saving...": "Po ruhet…",
|
||||||
|
"View dev tools": "Shihni mjete zhvilluesi",
|
||||||
|
"Leave Space": "Braktiseni Hapësirën",
|
||||||
|
"Make this space private": "Bëje këtë hapësirë private",
|
||||||
|
"Edit settings relating to your space.": "Përpunoni rregullime që lidhen me hapësirën tuaj",
|
||||||
|
"Space settings": "Rregullime hapësire",
|
||||||
|
"Failed to save space settings.": "S’u arrit të ruhen rregullime hapësire.",
|
||||||
|
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.": "Ftoni dikë duke përdorur emrin e tij, emrin e tij të përdoruesit (bie fjala, <userId/>) ose <a>ndani me të këtë hapësirë</a>.",
|
||||||
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "Ftoni dikë duke përdorur emrin e tij, adresën email, emrin e përdoruesit (bie fjala, <userId/>) ose <a>ndani me të këtë hapësirë</a>.",
|
||||||
|
"Unnamed Space": "Hapësirë e Paemërtuar",
|
||||||
|
"Invite to %(spaceName)s": "Ftojeni te %(spaceName)s",
|
||||||
|
"Caution:": "Kujdes:",
|
||||||
|
"Setting ID": "ID Rregullimi",
|
||||||
|
"Failed to add rooms to space": "S’u arrit të shtoheshin dhomat te hapësira",
|
||||||
|
"Apply": "Aplikoje",
|
||||||
|
"Applying...": "Po aplikohet …",
|
||||||
|
"Create a new room": "Krijoni dhomë të re",
|
||||||
|
"Don't want to add an existing room?": "S’doni të shtoni një dhomë ekzistuese?",
|
||||||
|
"Spaces": "Hapësira",
|
||||||
|
"Filter your rooms and spaces": "Filtroni dhomat dhe hapësirat tuaja",
|
||||||
|
"Add existing spaces/rooms": "Shtoni hapësira/dhoma ekzistuese",
|
||||||
|
"Space selection": "Përzgjedhje hapësire",
|
||||||
|
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the space it will be impossible to regain privileges.": "S’do të jeni në gjendje ta zhbëni këtë ndryshim, teksa zhgradoni veten, nëse jeni përdoruesi i fundit i privilegjuar te hapësira, s’do të jetë e mundur të rifitoni privilegjet.",
|
||||||
|
"Empty room": "Dhomë e zbrazët",
|
||||||
|
"Suggested Rooms": "Roma të Këshilluara",
|
||||||
|
"Explore space rooms": "Eksploroni dhoma hapësire",
|
||||||
|
"You do not have permissions to add rooms to this space": "S’keni leje të shtoni dhoma në këtë hapësirë",
|
||||||
|
"Add existing room": "Shtoni dhomë ekzistuese",
|
||||||
|
"You do not have permissions to create new rooms in this space": "S’keni leje të krijoni dhoma të reja në këtë hapësirë",
|
||||||
|
"Send message": "Dërgoje mesazhin",
|
||||||
|
"Invite to this space": "Ftoni në këtë hapësirë",
|
||||||
|
"Your message was sent": "Mesazhi juaj u dërgua",
|
||||||
|
"Encrypting your message...": "Po fshehtëzohet meszhi juaj…",
|
||||||
|
"Sending your message...": "Po dërgohet mesazhi juaj…",
|
||||||
|
"Spell check dictionaries": "Fjalorë kontrolli drejtshkrimi",
|
||||||
|
"Space options": "Mundësi Hapësire",
|
||||||
|
"Space Home": "Shtëpi Hapësire",
|
||||||
|
"New room": "Dhomë e re",
|
||||||
|
"Leave space": "Braktiseni hapësirën",
|
||||||
|
"Invite people": "Ftoni njerëz",
|
||||||
|
"Share your public space": "Ndani me të tjerët hapësirën tuaj publike",
|
||||||
|
"Invite members": "Ftoni anëtarë",
|
||||||
|
"Invite by email or username": "Ftoni përmes email-i ose emri përdoruesi",
|
||||||
|
"Share invite link": "Jepuni lidhje ftese",
|
||||||
|
"Click to copy": "Klikoni që të kopjohet",
|
||||||
|
"Collapse space panel": "Tkurre panelin e hapësirave",
|
||||||
|
"Expand space panel": "Zgjeroje panelin e hapësirave",
|
||||||
|
"Creating...": "Po krijohet…",
|
||||||
|
"You can change these at any point.": "Këto mund ti ndryshoni kur të doni.",
|
||||||
|
"Give it a photo, name and description to help you identify it.": "Jepini një foto, emër dhe përshkrim, për t’ju ndihmuar ta indentifikoni.",
|
||||||
|
"Your private space": "Hapësira juaj private",
|
||||||
|
"Your public space": "Hapësira juaj publike",
|
||||||
|
"You can change this later": "Këtë mund ta ndryshoni më vonë",
|
||||||
|
"Invite only, best for yourself or teams": "Vetëm me ftesa, më e mira për ju dhe ekipe",
|
||||||
|
"Private": "Private",
|
||||||
|
"Open space for anyone, best for communities": "Hapësirë e hapur për këdo, më e mira për bashkësi",
|
||||||
|
"Public": "Publike",
|
||||||
|
"Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "Hapësirat janë rrugë e re për të grupuar dhoma dhe njerëz. Për t’u bërë pjesë e një hapësire ekzistuese, do t’ju duhet një ftesë",
|
||||||
|
"Create a space": "Krijoni një hapësirë",
|
||||||
|
"Delete": "Fshije",
|
||||||
|
"Jump to the bottom of the timeline when you send a message": "Kalo te fundi i rrjedhës kohore, kur dërgoni një mesazh",
|
||||||
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Prototip hapësirash. I papërputhshëm me Bashkësi, Bashkësi v2 dhe Etiketa Vetjake. Për disa nga veçoritë, lyp shërbyes Home të përputhshëm.",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "Ky shërbyes Home është bllokuar nga përgjegjësi i tij.",
|
||||||
|
"This homeserver has been blocked by its administrator.": "Ky shërbyes Home është bllokuar nga përgjegjësit e tij.",
|
||||||
|
"You're already in a call with this person.": "Gjendeni tashmë në thirrje me këtë person.",
|
||||||
|
"Already in call": "Tashmë në thirrje"
|
||||||
}
|
}
|
||||||
|
|
|
@ -3018,5 +3018,120 @@
|
||||||
"Setting ID": "Inställnings-ID",
|
"Setting ID": "Inställnings-ID",
|
||||||
"Failed to save settings": "Misslyckades att spara inställningar",
|
"Failed to save settings": "Misslyckades att spara inställningar",
|
||||||
"Settings Explorer": "Inställningsutforskare",
|
"Settings Explorer": "Inställningsutforskare",
|
||||||
"Show chat effects (animations when receiving e.g. confetti)": "Visa chatteffekter (animeringar när du tar emot t.ex. konfetti)"
|
"Show chat effects (animations when receiving e.g. confetti)": "Visa chatteffekter (animeringar när du tar emot t.ex. konfetti)",
|
||||||
|
"Original event source": "Ursprunglig händelsekällkod",
|
||||||
|
"Decrypted event source": "Avkrypterad händelsekällkod",
|
||||||
|
"We'll create rooms for each of them. You can add existing rooms after setup.": "Vi kommer att skapa rum för varje. Du kan lägga till existerande rum efter inställningen.",
|
||||||
|
"What projects are you working on?": "Vilka projekt jobbar du på?",
|
||||||
|
"We'll create rooms for each topic.": "Vi kommer att skapa rum för varje ämne.",
|
||||||
|
"What are some things you want to discuss?": "Vad är exempel på saker du vill diskutera?",
|
||||||
|
"Inviting...": "Bjuder in…",
|
||||||
|
"Invite by username": "Bjud in med användarnamn",
|
||||||
|
"Invite your teammates": "Bjud in dina teamkamrater",
|
||||||
|
"Failed to invite the following users to your space: %(csvUsers)s": "Misslyckades att bjuda in följande användare till ditt utrymme: %(csvUsers)s",
|
||||||
|
"A private space for you and your teammates": "Ett privat utrymme för dig och dina teamkamrater",
|
||||||
|
"Me and my teammates": "Jag och mina teamkamrater",
|
||||||
|
"A private space just for you": "Ett personligt utrymme för bara dig",
|
||||||
|
"Just Me": "Bara jag",
|
||||||
|
"Ensure the right people have access to the space.": "Försäkra att rätt personer har tillgång till utrymmet.",
|
||||||
|
"Who are you working with?": "Vem arbetar du med?",
|
||||||
|
"Finish": "Färdigställ",
|
||||||
|
"At the moment only you can see it.": "För tillfället så kan bara du se det.",
|
||||||
|
"Creating rooms...": "Skapar rum…",
|
||||||
|
"Skip for now": "Hoppa över för tillfället",
|
||||||
|
"Failed to create initial space rooms": "Misslyckades att skapa initiala utrymmesrum",
|
||||||
|
"Room name": "Rumsnamn",
|
||||||
|
"Support": "Hjälp",
|
||||||
|
"Random": "Slumpmässig",
|
||||||
|
"Welcome to <name/>": "Välkommen till <name/>",
|
||||||
|
"Your private space <name/>": "Ditt privata utrymme <name/>",
|
||||||
|
"Your public space <name/>": "Ditt offentliga utrymme <name/>",
|
||||||
|
"You have been invited to <name/>": "Du har blivit inbjuden till <name/>",
|
||||||
|
"<inviter/> invited you to <name/>": "<inviter/> bjöd in dig till <name/>",
|
||||||
|
"%(count)s members|one": "%(count)s medlem",
|
||||||
|
"%(count)s members|other": "%(count)s medlemmar",
|
||||||
|
"Your server does not support showing space hierarchies.": "Din server stöder inte att visa utrymmeshierarkier.",
|
||||||
|
"Default Rooms": "Förvalda rum",
|
||||||
|
"Add existing rooms & spaces": "Lägg till existerande rum och utrymmen",
|
||||||
|
"Accept Invite": "Acceptera inbjudan",
|
||||||
|
"Find a room...": "Hitta ett rum…",
|
||||||
|
"Manage rooms": "Hantera rum",
|
||||||
|
"Promoted to users": "Befordrad till användare",
|
||||||
|
"Save changes": "Spara ändringar",
|
||||||
|
"You're in this room": "Du är i det här rummet",
|
||||||
|
"You're in this space": "Du är i det här utrymmet",
|
||||||
|
"No permissions": "Inga behörigheter",
|
||||||
|
"Remove from Space": "Ta bort från utrymmet",
|
||||||
|
"Undo": "Ångra",
|
||||||
|
"Your message wasn't sent because this homeserver has been blocked by it's administrator. Please <a>contact your service administrator</a> to continue using the service.": "Ditt meddelande skickades inte eftersom att hemservern har blockerats av sin administratör. Vänligen <a>kontakta din tjänsteadministratör</a> för att fortsätta använda tjänsten.",
|
||||||
|
"Are you sure you want to leave the space '%(spaceName)s'?": "Är du säker på att du vill lämna utrymmet '%(spaceName)s'?",
|
||||||
|
"This space is not public. You will not be able to rejoin without an invite.": "Det här utrymmet är inte offentligt. Du kommer inte kunna gå med igen utan en inbjudan.",
|
||||||
|
"Start audio stream": "Starta ljudström",
|
||||||
|
"Failed to start livestream": "Misslyckades att starta livestream",
|
||||||
|
"Unable to start audio streaming.": "Kunde inte starta ljudströmning.",
|
||||||
|
"Save Changes": "Spara inställningar",
|
||||||
|
"Saving...": "Sparar…",
|
||||||
|
"View dev tools": "Visa utvecklingsverktyg",
|
||||||
|
"Leave Space": "Lämna utrymmet",
|
||||||
|
"Make this space private": "Gör det här utrymmet privat",
|
||||||
|
"Edit settings relating to your space.": "Redigera inställningar relaterat till ditt utrymme.",
|
||||||
|
"Space settings": "Utrymmesinställningar",
|
||||||
|
"Failed to save space settings.": "Misslyckades att spara utrymmesinställningar.",
|
||||||
|
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.": "Bjud in någon med deras namn eller användarnamn (som <userId/>), eller <a>dela det här utrymmet</a>.",
|
||||||
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "Bjud in någon med deras namn, e-postadress eller användarnamn (som <userId/>), eller <a>dela det här rummet</a>.",
|
||||||
|
"Unnamed Space": "Namnlöst utrymme",
|
||||||
|
"Invite to %(spaceName)s": "Bjud in till %(spaceName)s",
|
||||||
|
"Failed to add rooms to space": "Misslyckades att lägga till rum till utrymmet",
|
||||||
|
"Apply": "Verkställ",
|
||||||
|
"Applying...": "Verkställer…",
|
||||||
|
"Create a new room": "Skapa ett nytt rum",
|
||||||
|
"Don't want to add an existing room?": "Vill du inte lägga till ett existerande rum?",
|
||||||
|
"Spaces": "Utrymmen",
|
||||||
|
"Filter your rooms and spaces": "Filtrera dina rum och utrymmen",
|
||||||
|
"Add existing spaces/rooms": "Lägg till existerande utrymmen/rum",
|
||||||
|
"Space selection": "Utrymmesval",
|
||||||
|
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the space it will be impossible to regain privileges.": "Du kommer inte kunna ångra den här ändringen eftersom du degraderar dig själv, och om du är den sista privilegierade användaren i utrymmet så kommer det att vara omöjligt att återfå utrymmet.",
|
||||||
|
"Empty room": "Tomt rum",
|
||||||
|
"Suggested Rooms": "Föreslagna rum",
|
||||||
|
"Explore space rooms": "Utforska rum i utrymmet",
|
||||||
|
"You do not have permissions to add rooms to this space": "Du är inte behörig att lägga till rum till det här utrymmet",
|
||||||
|
"Add existing room": "Lägg till existerande rum",
|
||||||
|
"You do not have permissions to create new rooms in this space": "Du är inte behörig att skapa nya rum i det här utrymmet",
|
||||||
|
"Send message": "Skicka meddelande",
|
||||||
|
"Invite to this space": "Bjud in till det här utrymmet",
|
||||||
|
"Your message was sent": "Ditt meddelande skickades",
|
||||||
|
"Encrypting your message...": "Krypterar ditt meddelande…",
|
||||||
|
"Sending your message...": "Skickar dina meddelanden…",
|
||||||
|
"Spell check dictionaries": "Rättstavningsordböcker",
|
||||||
|
"Space options": "Utrymmesalternativ",
|
||||||
|
"Space Home": "Utrymmeshem",
|
||||||
|
"New room": "Nytt rum",
|
||||||
|
"Leave space": "Lämna utrymmet",
|
||||||
|
"Invite people": "Bjud in folk",
|
||||||
|
"Share your public space": "Dela ditt offentliga utrymme",
|
||||||
|
"Invite members": "Bjud in medlemmar",
|
||||||
|
"Invite by email or username": "Bjud in med e-post eller användarnamn",
|
||||||
|
"Share invite link": "Skapa inbjudningslänk",
|
||||||
|
"Click to copy": "Klicka för att kopiera",
|
||||||
|
"Collapse space panel": "Kollapsa utrymmespanelen",
|
||||||
|
"Expand space panel": "Expandera utrymmespanelen",
|
||||||
|
"Creating...": "Skapar…",
|
||||||
|
"You can change these at any point.": "Du kan ändra dessa när som helst.",
|
||||||
|
"Give it a photo, name and description to help you identify it.": "Ge den en bild, ett namn och en beskrivning för att hjälpa dig att identifiera den.",
|
||||||
|
"Your private space": "Ditt privata utrymme",
|
||||||
|
"Your public space": "Ditt offentliga utrymme",
|
||||||
|
"You can change this later": "Du kan ändra detta senare",
|
||||||
|
"Invite only, best for yourself or teams": "Endast inbjudan, bäst för dig själv eller team",
|
||||||
|
"Private": "Privat",
|
||||||
|
"Open space for anyone, best for communities": "Öppna utrymmet för alla, bäst för gemenskaper",
|
||||||
|
"Public": "Offentligt",
|
||||||
|
"Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "Utrymmen är nya sätt att gruppera rum och personer. För att gå med i ett existerande utrymme så behöver du en inbjudan",
|
||||||
|
"Create a space": "Skapa ett utrymme",
|
||||||
|
"Delete": "Radera",
|
||||||
|
"Jump to the bottom of the timeline when you send a message": "Hoppa till botten av tidslinjen när du skickar ett meddelande",
|
||||||
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "Prototyp för utrymmen. Inkompatibel med gemenskaper, gemenskaper v2 och anpassade taggar. Kräver en kompatibel hemserver för viss funktionalitet.",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "Den här hemservern har blockerats av sin administratör.",
|
||||||
|
"This homeserver has been blocked by its administrator.": "Hemservern har blockerats av sin administratör.",
|
||||||
|
"You're already in a call with this person.": "Du är redan i ett samtal med den här personen.",
|
||||||
|
"Already in call": "Redan i samtal"
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,7 +166,7 @@
|
||||||
"New passwords don't match": "两次输入的新密码不符",
|
"New passwords don't match": "两次输入的新密码不符",
|
||||||
"not specified": "未指定",
|
"not specified": "未指定",
|
||||||
"Notifications": "通知",
|
"Notifications": "通知",
|
||||||
"(not supported by this browser)": "(未被此浏览器支持)",
|
"(not supported by this browser)": "(此浏览器不支持)",
|
||||||
"<not supported>": "<不支持>",
|
"<not supported>": "<不支持>",
|
||||||
"No display name": "无昵称",
|
"No display name": "无昵称",
|
||||||
"No results": "没有更多结果",
|
"No results": "没有更多结果",
|
||||||
|
@ -910,10 +910,10 @@
|
||||||
"%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s 将此聊天室对知道此聊天室链接的人公开。",
|
"%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s 将此聊天室对知道此聊天室链接的人公开。",
|
||||||
"%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s 将此聊天室改为仅限邀请。",
|
"%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s 将此聊天室改为仅限邀请。",
|
||||||
"%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s 将加入规则改为 %(rule)s",
|
"%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s 将加入规则改为 %(rule)s",
|
||||||
"%(displayName)s is typing …": "%(displayName)s 正在打字…",
|
"%(displayName)s is typing …": "%(displayName)s 正在输入…",
|
||||||
"%(names)s and %(count)s others are typing …|other": "%(names)s 与其他 %(count)s 位正在打字…",
|
"%(names)s and %(count)s others are typing …|other": "%(names)s 与其他 %(count)s 位正在输入…",
|
||||||
"%(names)s and %(count)s others are typing …|one": "%(names)s 与另一位正在打字…",
|
"%(names)s and %(count)s others are typing …|one": "%(names)s 与另一位正在输入…",
|
||||||
"%(names)s and %(lastPerson)s are typing …": "%(names)s 和 %(lastPerson)s正在打字…",
|
"%(names)s and %(lastPerson)s are typing …": "%(names)s 和 %(lastPerson)s 正在输入…",
|
||||||
"Unrecognised address": "无法识别地址",
|
"Unrecognised address": "无法识别地址",
|
||||||
"User %(user_id)s may or may not exist": "用户 %(user_id)s 不一定存在",
|
"User %(user_id)s may or may not exist": "用户 %(user_id)s 不一定存在",
|
||||||
"Predictable substitutions like '@' instead of 'a' don't help very much": "可预见的替换如将 '@' 替换为 'a' 并不会有太大效果",
|
"Predictable substitutions like '@' instead of 'a' don't help very much": "可预见的替换如将 '@' 替换为 'a' 并不会有太大效果",
|
||||||
|
@ -942,7 +942,7 @@
|
||||||
"Short keyboard patterns are easy to guess": "键位短序列很容易被猜到",
|
"Short keyboard patterns are easy to guess": "键位短序列很容易被猜到",
|
||||||
"Group & filter rooms by custom tags (refresh to apply changes)": "按自定义标签分组和过滤聊天室(刷新以应用更改)",
|
"Group & filter rooms by custom tags (refresh to apply changes)": "按自定义标签分组和过滤聊天室(刷新以应用更改)",
|
||||||
"Render simple counters in room header": "在聊天室标题中显示简单计数",
|
"Render simple counters in room header": "在聊天室标题中显示简单计数",
|
||||||
"Enable Emoji suggestions while typing": "键入时启用表情符号建议",
|
"Enable Emoji suggestions while typing": "启用实时表情符号建议",
|
||||||
"Show a placeholder for removed messages": "已移除的消息显示为一个占位符",
|
"Show a placeholder for removed messages": "已移除的消息显示为一个占位符",
|
||||||
"Show join/leave messages (invites/kicks/bans unaffected)": "显示 加入/离开 信息(邀请/踢出/禁止 不受影响)",
|
"Show join/leave messages (invites/kicks/bans unaffected)": "显示 加入/离开 信息(邀请/踢出/禁止 不受影响)",
|
||||||
"Show avatar changes": "显示头像更改",
|
"Show avatar changes": "显示头像更改",
|
||||||
|
@ -951,7 +951,7 @@
|
||||||
"Show a reminder to enable Secure Message Recovery in encrypted rooms": "在加密聊天室中显示一条允许恢复安全消息的提醒",
|
"Show a reminder to enable Secure Message Recovery in encrypted rooms": "在加密聊天室中显示一条允许恢复安全消息的提醒",
|
||||||
"Show avatars in user and room mentions": "在用户和聊天室提及中显示头像",
|
"Show avatars in user and room mentions": "在用户和聊天室提及中显示头像",
|
||||||
"Enable big emoji in chat": "在聊天中启用大型表情符号",
|
"Enable big emoji in chat": "在聊天中启用大型表情符号",
|
||||||
"Send typing notifications": "发送键入状态通知",
|
"Send typing notifications": "发送正在输入通知",
|
||||||
"Enable Community Filter Panel": "启用社区筛选器面板",
|
"Enable Community Filter Panel": "启用社区筛选器面板",
|
||||||
"Allow Peer-to-Peer for 1:1 calls": "允许一对一通话使用 P2P",
|
"Allow Peer-to-Peer for 1:1 calls": "允许一对一通话使用 P2P",
|
||||||
"Prompt before sending invites to potentially invalid matrix IDs": "在发送邀请之前提示可能无效的 Matrix ID",
|
"Prompt before sending invites to potentially invalid matrix IDs": "在发送邀请之前提示可能无效的 Matrix ID",
|
||||||
|
@ -1259,14 +1259,14 @@
|
||||||
"Alternatively, you can try to use the public server at <code>turn.matrix.org</code>, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "您也可以尝试使用<code>turn.matrix.org</code>公共服务器,但通话质量稍差,并且其将会得知您的 IP。您可以在设置中更改此选项。",
|
"Alternatively, you can try to use the public server at <code>turn.matrix.org</code>, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "您也可以尝试使用<code>turn.matrix.org</code>公共服务器,但通话质量稍差,并且其将会得知您的 IP。您可以在设置中更改此选项。",
|
||||||
"Try using turn.matrix.org": "尝试使用 turn.matrix.org",
|
"Try using turn.matrix.org": "尝试使用 turn.matrix.org",
|
||||||
"Your %(brand)s is misconfigured": "您的 %(brand)s 配置有错误",
|
"Your %(brand)s is misconfigured": "您的 %(brand)s 配置有错误",
|
||||||
"Use Single Sign On to continue": "使用单点登陆继续",
|
"Use Single Sign On to continue": "使用单点登录继续",
|
||||||
"Confirm adding this email address by using Single Sign On to prove your identity.": "通过使用单点登陆来证明您的身份,并确认添加此邮件地址。",
|
"Confirm adding this email address by using Single Sign On to prove your identity.": "通过使用单点登录来证明您的身份,并确认添加此邮件地址。",
|
||||||
"Single Sign On": "单点登陆",
|
"Single Sign On": "单点登录",
|
||||||
"Confirm adding email": "确认使用邮件",
|
"Confirm adding email": "确认使用邮件",
|
||||||
"Click the button below to confirm adding this email address.": "点击下面的按钮,添加此邮箱地址。",
|
"Click the button below to confirm adding this 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.": "点击下面的按钮以确认添加此电话号码。",
|
||||||
"Whether you're using %(brand)s on a device where touch is the primary input mechanism": "是否在触屏设备上使用 %(brand)s",
|
"Whether you're using %(brand)s on a device where touch is the primary input mechanism": "是否在触屏设备上使用 %(brand)s",
|
||||||
"Whether you're using %(brand)s as an installed Progressive Web App": "您是否已经安装 %(brand)s 作为一种渐进式的 Web 应用",
|
"Whether you're using %(brand)s as an installed Progressive Web App": "您是否已经安装 %(brand)s 作为一种渐进式的 Web 应用",
|
||||||
"Your user agent": "您的代理用户",
|
"Your user agent": "您的代理用户",
|
||||||
|
@ -1282,14 +1282,14 @@
|
||||||
"Verify this session": "验证此会话",
|
"Verify this session": "验证此会话",
|
||||||
"Encryption upgrade available": "提供加密升级",
|
"Encryption upgrade available": "提供加密升级",
|
||||||
"Set up encryption": "设置加密",
|
"Set up encryption": "设置加密",
|
||||||
"Review where you’re logged in": "查看您的登陆位置",
|
"Review where you’re logged in": "查看您的登录位置",
|
||||||
"New login. Was this you?": "现在登陆。请问是您本人吗?",
|
"New login. Was this you?": "现在登录。请问是您本人吗?",
|
||||||
"Name or Matrix ID": "姓名或Matrix账号",
|
"Name or Matrix ID": "姓名或 Matrix ID",
|
||||||
"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.": "此操作需要访问默认的身份服务器<server/>以验证电子邮件地址或电话号码,但是此服务器无任何服务条款。",
|
"This action requires accessing the default identity server <server /> to validate an email address or phone number, but the server does not have any terms of service.": "此操作需要访问默认的身份服务器 <server/> 以验证邮箱地址或电话号码,但是此服务器无任何服务条款。",
|
||||||
"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请求验证",
|
"%(name)s is requesting verification": "%(name)s 正在请求验证",
|
||||||
"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": "创建账户",
|
||||||
|
@ -1301,7 +1301,7 @@
|
||||||
"Sends a message as html, without interpreting it as markdown": "以html格式发送消息,而不是markdown",
|
"Sends a message as html, without interpreting it as markdown": "以html格式发送消息,而不是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 this current room only": "仅改变您在当前聊天室的头像",
|
"Changes your avatar in this current room only": "仅改变您在当前聊天室的头像",
|
||||||
"Changes your avatar in all rooms": "改变您在所有聊天室的头像",
|
"Changes your avatar in all rooms": "改变您在所有聊天室的头像",
|
||||||
|
@ -1351,14 +1351,14 @@
|
||||||
"%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s 创建了因为%(reason)s而禁止用户匹配%(glob)s的规则",
|
"%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s 创建了因为%(reason)s而禁止用户匹配%(glob)s的规则",
|
||||||
"%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s 创建了由于%(reason)s而禁止聊天室匹配%(glob)s的规则",
|
"%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s 创建了由于%(reason)s而禁止聊天室匹配%(glob)s的规则",
|
||||||
"%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s 创建了由于%(reason)s而禁止服务器匹配%(glob)s的规则",
|
"%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s 创建了由于%(reason)s而禁止服务器匹配%(glob)s的规则",
|
||||||
"%(senderName)s created a ban rule matching %(glob)s for %(reason)s": "%(senderName)s 创建了由于%(reason)s而禁止匹配%(glob)s的股则",
|
"%(senderName)s created a ban rule matching %(glob)s for %(reason)s": "%(senderName)s 创建了由于%(reason)s而禁止匹配%(glob)s的规则",
|
||||||
"%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s 更改了一个由于%(reason)s而禁止用户%(oldGlob)s跟%(newGlob)s匹配的规则",
|
"%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s 更改了一个由于%(reason)s而禁止用户%(oldGlob)s跟%(newGlob)s匹配的规则",
|
||||||
"%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s更改了一个由于%(reason)s而禁止聊天室%(oldGlob)s跟%(newGlob)s匹配的规则",
|
"%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s更改了一个由于%(reason)s而禁止聊天室%(oldGlob)s跟%(newGlob)s匹配的规则",
|
||||||
"%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s 更新了一个由于%(reason)s而禁止服务器%(oldGlob)s跟%(newGlob)s匹配的规则",
|
"%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s 更新了一个由于%(reason)s而禁止服务器%(oldGlob)s跟%(newGlob)s匹配的规则",
|
||||||
"%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s 更新了一个由于%(reason)s而禁止%(oldGlob)s跟%(newGlob)s匹配的规则",
|
"%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s 更新了一个由于%(reason)s而禁止%(oldGlob)s跟%(newGlob)s匹配的规则",
|
||||||
"You signed in to a new session without verifying it:": "您登陆了未经过验证的新会话:",
|
"You signed in to a new session without verifying it:": "您登录了未经过验证的新会话:",
|
||||||
"Verify your other session using one of the options below.": "使用以下选项之一验证您的其他会话。",
|
"Verify your other session using one of the options below.": "使用以下选项之一验证您的其他会话。",
|
||||||
"%(name)s (%(userId)s) signed in to a new session without verifying it:": "%(name)s(%(userId)s)登陆到未验证的新会话:",
|
"%(name)s (%(userId)s) signed in to a new session without verifying it:": "%(name)s(%(userId)s)登录到未验证的新会话:",
|
||||||
"Ask this user to verify their session, or manually verify it below.": "要求该用户验证其会话,或在下面手动进行验证。",
|
"Ask this user to verify their session, or manually verify it below.": "要求该用户验证其会话,或在下面手动进行验证。",
|
||||||
"Not Trusted": "不可信任",
|
"Not Trusted": "不可信任",
|
||||||
"Manually Verify by Text": "手动验证文字",
|
"Manually Verify by Text": "手动验证文字",
|
||||||
|
@ -1404,7 +1404,7 @@
|
||||||
"about a day from now": "从现在开始约一天",
|
"about a day from now": "从现在开始约一天",
|
||||||
"%(num)s days from now": "从现在开始%(num)s天",
|
"%(num)s days from now": "从现在开始%(num)s天",
|
||||||
"%(name)s (%(userId)s)": "%(name)s%(userId)s",
|
"%(name)s (%(userId)s)": "%(name)s%(userId)s",
|
||||||
"Your browser does not support the required cryptography extensions": "您的浏览器不支持必需的加密插件",
|
"Your browser does not support the required cryptography extensions": "您的浏览器不支持所需的密码学扩展",
|
||||||
"The user's homeserver does not support the version of the room.": "用户的主服务器不支持该聊天室版本。",
|
"The user's homeserver does not support the version of the room.": "用户的主服务器不支持该聊天室版本。",
|
||||||
"Help us improve %(brand)s": "请协助我们改进%(brand)s",
|
"Help us improve %(brand)s": "请协助我们改进%(brand)s",
|
||||||
"Send <UsageDataLink>anonymous usage data</UsageDataLink> which helps us improve %(brand)s. This will use a <PolicyLink>cookie</PolicyLink>.": "发送<UsageDataLink>匿名使用情况数据</UsageDataLink>,以协助我们改进%(brand)s。这将使用<PolicyLink>cookie</PolicyLink>。",
|
"Send <UsageDataLink>anonymous usage data</UsageDataLink> which helps us improve %(brand)s. This will use a <PolicyLink>cookie</PolicyLink>.": "发送<UsageDataLink>匿名使用情况数据</UsageDataLink>,以协助我们改进%(brand)s。这将使用<PolicyLink>cookie</PolicyLink>。",
|
||||||
|
@ -1666,7 +1666,7 @@
|
||||||
"Enable advanced debugging for the room list": "为此聊天室列表启用高级调试",
|
"Enable advanced debugging for the room list": "为此聊天室列表启用高级调试",
|
||||||
"Show info about bridges in room settings": "在聊天室设置中显示桥接信息",
|
"Show info about bridges in room settings": "在聊天室设置中显示桥接信息",
|
||||||
"Use a more compact ‘Modern’ layout": "使用更紧凑的「现代」布局",
|
"Use a more compact ‘Modern’ layout": "使用更紧凑的「现代」布局",
|
||||||
"Show typing notifications": "显示输入通知",
|
"Show typing notifications": "显示正在输入通知",
|
||||||
"Show shortcuts to recently viewed rooms above the room list": "在聊天室列表上方显示最近浏览过的聊天室的快捷方式",
|
"Show shortcuts to recently viewed rooms above the room list": "在聊天室列表上方显示最近浏览过的聊天室的快捷方式",
|
||||||
"Show hidden events in timeline": "显示时间线中的隐藏事件",
|
"Show hidden events in timeline": "显示时间线中的隐藏事件",
|
||||||
"Low bandwidth mode": "低带宽模式",
|
"Low bandwidth mode": "低带宽模式",
|
||||||
|
@ -2416,17 +2416,17 @@
|
||||||
"%(senderDisplayName)s set the server ACLs for this room.": "%(senderDisplayName)s 为此聊天室设置了服务器 ACL。",
|
"%(senderDisplayName)s set the server ACLs for this room.": "%(senderDisplayName)s 为此聊天室设置了服务器 ACL。",
|
||||||
"Hong Kong": "香港",
|
"Hong Kong": "香港",
|
||||||
"Cook Islands": "库克群岛",
|
"Cook Islands": "库克群岛",
|
||||||
"Congo - Kinshasa": "刚果金",
|
"Congo - Kinshasa": "刚果 - 金沙萨",
|
||||||
"Congo - Brazzaville": "刚果布拉柴维尔",
|
"Congo - Brazzaville": "刚果 - 布拉柴维尔",
|
||||||
"Comoros": "科摩罗",
|
"Comoros": "科摩罗",
|
||||||
"Colombia": "哥伦比亚",
|
"Colombia": "哥伦比亚",
|
||||||
"Cocos (Keeling) Islands": "科科斯基林群岛",
|
"Cocos (Keeling) Islands": "科科斯(基林)群岛",
|
||||||
"Christmas Island": "圣诞岛",
|
"Christmas Island": "圣诞岛",
|
||||||
"China": "中国",
|
"China": "中国",
|
||||||
"Chile": "智利",
|
"Chile": "智利",
|
||||||
"Chad": "乍得",
|
"Chad": "乍得",
|
||||||
"Central African Republic": "中非共和国",
|
"Central African Republic": "中非共和国",
|
||||||
"Cayman Islands": "开曼群岛(英)",
|
"Cayman Islands": "开曼群岛",
|
||||||
"Caribbean Netherlands": "荷兰加勒比区",
|
"Caribbean Netherlands": "荷兰加勒比区",
|
||||||
"Cape Verde": "佛得角",
|
"Cape Verde": "佛得角",
|
||||||
"Canada": "加拿大",
|
"Canada": "加拿大",
|
||||||
|
@ -2472,7 +2472,7 @@
|
||||||
"United States": "美国",
|
"United States": "美国",
|
||||||
"United Kingdom": "英国",
|
"United Kingdom": "英国",
|
||||||
"Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "您的主服务器已拒绝您的登入尝试。请重试。如果此情况持续发生,请联系您的主服务器管理员。",
|
"Your homeserver rejected your log in attempt. This could be due to things just taking too long. Please try again. If this continues, please contact your homeserver administrator.": "您的主服务器已拒绝您的登入尝试。请重试。如果此情况持续发生,请联系您的主服务器管理员。",
|
||||||
"Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "您的主服务器不可达,无法使您登入。请重试。如果此情况持续发生,请联系您的主服务器管理员。",
|
"Your homeserver was unreachable and was not able to log you in. Please try again. If this continues, please contact your homeserver administrator.": "无法访问您的主服务器,因而无法登入。请重试。如果此情况持续发生,请联系您的主服务器管理员。",
|
||||||
"Try again": "重试",
|
"Try again": "重试",
|
||||||
"We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "我们已要求浏览器记住您使用的主服务器,但不幸的是您的浏览器已忘记。请前往登录页面重试。",
|
"We asked the browser to remember which homeserver you use to let you sign in, but unfortunately your browser has forgotten it. Go to the sign in page and try again.": "我们已要求浏览器记住您使用的主服务器,但不幸的是您的浏览器已忘记。请前往登录页面重试。",
|
||||||
"We couldn't log you in": "我们无法使您登入",
|
"We couldn't log you in": "我们无法使您登入",
|
||||||
|
@ -2482,5 +2482,263 @@
|
||||||
"Too Many Calls": "太多呼叫",
|
"Too Many Calls": "太多呼叫",
|
||||||
"Call failed because webcam or microphone could not be accessed. Check that:": "通话失败,因为无法访问网络摄像头或麦克风。请检查:",
|
"Call failed because webcam or microphone could not be accessed. Check that:": "通话失败,因为无法访问网络摄像头或麦克风。请检查:",
|
||||||
"Call failed because microphone could not be accessed. Check that a microphone is plugged in and set up correctly.": "呼叫失败,因为无法访问任何麦克风。 检查是否已插入麦克风并正确设置。",
|
"Call failed because microphone could not be accessed. Check that a microphone is plugged in and set up correctly.": "呼叫失败,因为无法访问任何麦克风。 检查是否已插入麦克风并正确设置。",
|
||||||
"Answered Elsewhere": "在其他地方已回答"
|
"Answered Elsewhere": "在其他地方已回答",
|
||||||
|
"Use the + to make a new room or explore existing ones below": "使用 + 创建新的聊天室或通过下面列出的方式探索已有聊天室",
|
||||||
|
"Start a new chat": "开始新会话",
|
||||||
|
"Room settings": "聊天室设置",
|
||||||
|
"%(count)s people|one": "%(count)s 位成员",
|
||||||
|
"Show files": "显示已发送的文件",
|
||||||
|
"About homeservers": "关于 homeservers",
|
||||||
|
"About": "关于",
|
||||||
|
"Invite members": "邀请成员",
|
||||||
|
"Invite by email or username": "通过电子邮件或用户名邀请",
|
||||||
|
"Share invite link": "分享邀请链接",
|
||||||
|
"Click to copy": "点击复制",
|
||||||
|
"Creating...": "创建中……",
|
||||||
|
"You can change these at any point.": "您可随时更改这些。",
|
||||||
|
"Give it a photo, name and description to help you identify it.": "为它添加一张照片、姓名与描述来帮助您辨认它。",
|
||||||
|
"Your private space": "您的私有空间",
|
||||||
|
"Your public space": "您的公共空间",
|
||||||
|
"You can change this later": "您可稍后更改此项",
|
||||||
|
"Invite only, best for yourself or teams": "仅邀请,适合您自己或团队",
|
||||||
|
"Private": "私有",
|
||||||
|
"Public": "公共",
|
||||||
|
"Delete": "删除",
|
||||||
|
"Dial pad": "拨号盘",
|
||||||
|
"There was an error looking up the phone number": "查询电话号码的过程中发生错误",
|
||||||
|
"Unable to look up phone number": "无法查询电话号码",
|
||||||
|
"Return to call": "返回通话",
|
||||||
|
"Voice Call": "语音通话",
|
||||||
|
"Video Call": "视频通话",
|
||||||
|
"%(peerName)s held the call": "%(peerName)s 挂起了通话",
|
||||||
|
"You held the call <a>Resume</a>": "您挂起了通话 <a>恢复</a>",
|
||||||
|
"You held the call <a>Switch</a>": "您挂起了通话 <a>切换</a>",
|
||||||
|
"Takes the call in the current room off hold": "解除挂起当前聊天室的通话",
|
||||||
|
"Places the call in the current room on hold": "挂起当前聊天室的通话",
|
||||||
|
"Show chat effects (animations when receiving e.g. confetti)": "显示聊天特效(如收到五彩纸屑时的动画效果)",
|
||||||
|
"Use Ctrl + Enter to send a message": "使用 Ctrl + Enter 发送信息",
|
||||||
|
"Use Command + Enter to send a message": "使用 Command + Enter 发送消息",
|
||||||
|
"Use Ctrl + F to search": "使用 Ctrl + F 搜索",
|
||||||
|
"Use Command + F to search": "使用 Command + F 搜索",
|
||||||
|
"Jump to the bottom of the timeline when you send a message": "发送信息时跳转到时间线底部",
|
||||||
|
"Show line numbers in code blocks": "在代码块中显示行号",
|
||||||
|
"Expand code blocks by default": "默认展开代码块",
|
||||||
|
"Show stickers button": "显示贴纸按钮",
|
||||||
|
"Render LaTeX maths in messages": "在信息中渲染 LaTeX 数学",
|
||||||
|
"%(senderName)s ended the call": "%(senderName)s 结束了通话",
|
||||||
|
"You ended the call": "您结束了通话",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "此 homeserver 已被其管理员屏蔽。",
|
||||||
|
"Use app": "使用 app",
|
||||||
|
"Element Web is experimental on mobile. For a better experience and the latest features, use our free native app.": "Element 网页版在移动设备上仍处于试验阶段。使用免费的原生 app 以获得更好的体验与最新的功能。",
|
||||||
|
"Use app for a better experience": "使用 app 以获得更好的体验",
|
||||||
|
"Enable desktop notifications": "开启桌面通知",
|
||||||
|
"Don't miss a reply": "不要错过任何回复",
|
||||||
|
"This homeserver has been blocked by its administrator.": "此 homeserver 已被其管理员屏蔽。",
|
||||||
|
"Send stickers to this room as you": "以您的身份发送贴纸到此聊天室",
|
||||||
|
"Change the avatar of your active room": "更改活跃聊天室的头像",
|
||||||
|
"Change the avatar of this room": "更改当前聊天室的头像",
|
||||||
|
"Change the name of your active room": "更改活跃聊天室的名称",
|
||||||
|
"Change the name of this room": "更改当前聊天室的名称",
|
||||||
|
"Change the topic of your active room": "更改当前活跃聊天室的讨论主题",
|
||||||
|
"Change the topic of this room": "更改当前聊天室的讨论主题",
|
||||||
|
"Change which room, message, or user you're viewing": "更改当前正在查看哪个聊天室、消息或用户",
|
||||||
|
"Change which room you're viewing": "更改当前正在查看哪个聊天室",
|
||||||
|
"Send stickers into your active room": "发送贴纸到您的活跃聊天室",
|
||||||
|
"Send stickers into this room": "发送贴纸到此聊天室",
|
||||||
|
"Remain on your screen while running": "运行时始终保留在您的屏幕上",
|
||||||
|
"Remain on your screen when viewing another room, when running": "运行时始终保留在您的屏幕上,即使您在浏览其它聊天室",
|
||||||
|
"%(senderName)s declined the call.": "%(senderName)s 拒绝了通话。",
|
||||||
|
"(an error occurred)": "(发生了一个错误)",
|
||||||
|
"(their device couldn't start the camera / microphone)": "(对方的设备无法开启摄像头/麦克风)",
|
||||||
|
"Converts the room to a DM": "将此聊天室会话转化为私聊会话",
|
||||||
|
"Converts the DM to a room": "将此私聊会话转化为聊天室会话",
|
||||||
|
"Prepends ┬──┬ ノ( ゜-゜ノ) to a plain-text message": "在纯文字信息前添加 ┬──┬ ノ( ゜-゜ノ)",
|
||||||
|
"Prepends (╯°□°)╯︵ ┻━┻ to a plain-text message": "在纯文字信息前添加 (╯°□°)╯︵ ┻━┻",
|
||||||
|
"You're already in a call with this person.": "您与此人已处在通话中。",
|
||||||
|
"Already in call": "已在通话中",
|
||||||
|
"Navigate composer history": "浏览编辑区历史",
|
||||||
|
"Go to Home View": "转到主视图",
|
||||||
|
"Search (must be enabled)": "搜索(必须启用)",
|
||||||
|
"Your Security Key": "您的安全密钥",
|
||||||
|
"Use Security Key": "使用安全密钥",
|
||||||
|
"%(ssoButtons)s Or %(usernamePassword)s": "%(ssoButtons)s 或 %(usernamePassword)s",
|
||||||
|
"User settings": "用户设置",
|
||||||
|
"Creating rooms...": "正在创建聊天室…",
|
||||||
|
"Room name": "聊天室名称",
|
||||||
|
"Random": "随机",
|
||||||
|
"%(count)s members|one": "%(count)s 位成员",
|
||||||
|
"%(count)s members|other": "%(count)s 位成员",
|
||||||
|
"Default Rooms": "默认聊天室",
|
||||||
|
"Accept Invite": "接受邀请",
|
||||||
|
"Manage rooms": "管理聊天室",
|
||||||
|
"Save changes": "保存修改",
|
||||||
|
"Remove from Space": "从空间中移除",
|
||||||
|
"Undo": "撤销",
|
||||||
|
"Welcome %(name)s": "欢迎 %(name)s",
|
||||||
|
"Create community": "创建社区",
|
||||||
|
"Forgot password?": "忘记密码?",
|
||||||
|
"Enter Security Key": "输入安全密钥",
|
||||||
|
"Invalid Security Key": "安全密钥无效",
|
||||||
|
"Wrong Security Key": "安全密钥错误",
|
||||||
|
"Save Changes": "保存修改",
|
||||||
|
"Saving...": "正在保存…",
|
||||||
|
"View dev tools": "查看开发者工具",
|
||||||
|
"Leave Space": "离开空间",
|
||||||
|
"Space settings": "空间设置",
|
||||||
|
"Learn more": "了解更多",
|
||||||
|
"Other homeserver": "其他主服务器",
|
||||||
|
"Specify a homeserver": "指定主服务器",
|
||||||
|
"Transfer": "传输",
|
||||||
|
"Unnamed Space": "未命名空间",
|
||||||
|
"Cookie Policy": "Cookie 政策",
|
||||||
|
"Privacy Policy": "隐私政策",
|
||||||
|
"Abort": "放弃",
|
||||||
|
"Send feedback": "发送反馈",
|
||||||
|
"Report a bug": "反馈问题",
|
||||||
|
"Edit Values": "编辑值",
|
||||||
|
"Value:": "值:",
|
||||||
|
"Setting definition:": "设置定义:",
|
||||||
|
"Caution:": "警告:",
|
||||||
|
"Setting:": "设置:",
|
||||||
|
"Value": "值",
|
||||||
|
"Setting ID": "设置 ID",
|
||||||
|
"Enter name": "输入名称",
|
||||||
|
"Community ID: +<localpart />:%(domain)s": "社区 ID:+<localpart />:%(domain)s",
|
||||||
|
"Reason (optional)": "理由(可选)",
|
||||||
|
"Show": "显示",
|
||||||
|
"Apply": "应用",
|
||||||
|
"Applying...": "正在应用…",
|
||||||
|
"Create a new room": "创建新聊天室",
|
||||||
|
"Spaces": "空间",
|
||||||
|
"Continue with %(provider)s": "使用 %(provider)s 继续",
|
||||||
|
"Homeserver": "主服务器",
|
||||||
|
"Server Options": "服务器选项",
|
||||||
|
"Information": "信息",
|
||||||
|
"Windows": "窗口",
|
||||||
|
"Screens": "屏幕",
|
||||||
|
"Share your screen": "共享屏幕",
|
||||||
|
"Role": "角色",
|
||||||
|
"Not encrypted": "未加密",
|
||||||
|
"Unpin": "取消置顶",
|
||||||
|
"Empty room": "空聊天室",
|
||||||
|
"Add existing room": "添加现有的聊天室",
|
||||||
|
"Open dial pad": "打开拨号键盘",
|
||||||
|
"Start a Conversation": "开始对话",
|
||||||
|
"Show Widgets": "显示小挂件",
|
||||||
|
"Hide Widgets": "隐藏小挂件",
|
||||||
|
"%(displayName)s created this room.": "%(displayName)s 创建了此聊天室。",
|
||||||
|
"You created this room.": "你创建了此聊天室。",
|
||||||
|
"Remove messages sent by others": "移除其他人的消息",
|
||||||
|
"Sending your message...": "正在发送消息…",
|
||||||
|
"Encrypting your message...": "正在加密消息…",
|
||||||
|
"Send message": "发送消息",
|
||||||
|
"Invite to this space": "邀请至此空间",
|
||||||
|
"Your message was sent": "消息已发送",
|
||||||
|
"Back up your encryption keys with your account data in case you lose access to your sessions. Your keys will be secured with a unique Security Key.": "请使用您的帐户数据备份加密密钥,以免您无法访问您的会话。密钥将通过一个唯一的安全密钥进行保护。",
|
||||||
|
"Spell check dictionaries": "拼写检查字典",
|
||||||
|
"Failed to save your profile": "个人资料保存失败",
|
||||||
|
"The operation could not be completed": "操作无法完成",
|
||||||
|
"Space options": "空间选项",
|
||||||
|
"Space Home": "空间首页",
|
||||||
|
"New room": "新建聊天室",
|
||||||
|
"Leave space": "离开空间",
|
||||||
|
"Share your public space": "分享你的公共空间",
|
||||||
|
"Collapse space panel": "收起空间面板",
|
||||||
|
"Expand space panel": "展开空间面板",
|
||||||
|
"Create a space": "创建空间",
|
||||||
|
"Fill Screen": "填充屏幕",
|
||||||
|
"sends snowfall": "发送雪球",
|
||||||
|
"Sends the given message with snowfall": "附加雪球发送",
|
||||||
|
"sends confetti": "发送五彩纸屑",
|
||||||
|
"Sends the given message with confetti": "附加五彩纸屑发送",
|
||||||
|
"Sends the given message with fireworks": "附加烟火发送",
|
||||||
|
"sends fireworks": "发送烟火",
|
||||||
|
"Offline encrypted messaging using dehydrated devices": "需要离线设备(dehydrated devices)的加密消息离线传递",
|
||||||
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "正在开发的空间功能的原型。与社区、社区 V2 和自定义标签功能不兼容。需要主服务器兼容才能使用某些功能。",
|
||||||
|
"The <b>%(capability)s</b> capability": "<b>%(capability)s</b> 容量",
|
||||||
|
"%(senderName)s has updated the widget layout": "%(senderName)s 已更新小挂件布局",
|
||||||
|
"Support": "支持",
|
||||||
|
"Your server does not support showing space hierarchies.": "您的服务器不支持显示空间层次结构。",
|
||||||
|
"This version of %(brand)s does not support searching encrypted messages": "当前版本的 %(brand)s 不支持搜索加密消息",
|
||||||
|
"This version of %(brand)s does not support viewing some encrypted files": "当前版本的 %(brand)s 不支持查看某些加密文件",
|
||||||
|
"Effects": "效果",
|
||||||
|
"Pakistan": "巴基斯坦",
|
||||||
|
"United Arab Emirates": "阿拉伯联合酋长国",
|
||||||
|
"Yemen": "也门",
|
||||||
|
"Ukraine": "乌克兰",
|
||||||
|
"Turkmenistan": "土库曼斯坦",
|
||||||
|
"Uganda": "乌干达",
|
||||||
|
"Turkey": "土耳其",
|
||||||
|
"U.S. Virgin Islands": "美属维尔京群岛",
|
||||||
|
"Taiwan": "台湾",
|
||||||
|
"Sweden": "瑞典",
|
||||||
|
"Spain": "西班牙",
|
||||||
|
"South Korea": "韩国",
|
||||||
|
"South Africa": "南非",
|
||||||
|
"Russia": "俄罗斯",
|
||||||
|
"Romania": "罗马尼亚",
|
||||||
|
"Philippines": "菲律宾",
|
||||||
|
"North Korea": "朝鲜",
|
||||||
|
"Norway": "挪威",
|
||||||
|
"New Zealand": "新西兰",
|
||||||
|
"Netherlands": "荷兰",
|
||||||
|
"Mexico": "墨西哥",
|
||||||
|
"Malaysia": "马来西亚",
|
||||||
|
"Macau": "澳门",
|
||||||
|
"Luxembourg": "卢森堡",
|
||||||
|
"Lebanon": "黎巴嫩",
|
||||||
|
"Lithuania": "立陶宛",
|
||||||
|
"Latvia": "拉脱维亚",
|
||||||
|
"Liechtenstein": "列支敦士登",
|
||||||
|
"Laos": "老挝",
|
||||||
|
"Libya": "利比亚",
|
||||||
|
"Liberia": "利比里亚",
|
||||||
|
"Japan": "日本",
|
||||||
|
"Jamaica": "牙买加",
|
||||||
|
"Italy": "意大利",
|
||||||
|
"Israel": "以色列",
|
||||||
|
"Ireland": "爱尔兰",
|
||||||
|
"Iraq": "伊拉克",
|
||||||
|
"Indonesia": "印度尼西亚",
|
||||||
|
"India": "印度",
|
||||||
|
"Iceland": "冰岛",
|
||||||
|
"Iran": "伊朗",
|
||||||
|
"Guatemala": "危地马拉",
|
||||||
|
"Guam": "关岛",
|
||||||
|
"Guadeloupe": "瓜德罗普",
|
||||||
|
"Grenada": "格林纳达",
|
||||||
|
"Greenland": "格陵兰",
|
||||||
|
"Greece": "希腊",
|
||||||
|
"Gibraltar": "直布罗陀",
|
||||||
|
"Ghana": "加纳",
|
||||||
|
"Germany": "德国",
|
||||||
|
"Georgia": "格鲁吉亚",
|
||||||
|
"Gambia": "冈比亚",
|
||||||
|
"Gabon": "加蓬",
|
||||||
|
"French Southern Territories": "法属南部领地",
|
||||||
|
"French Polynesia": "法属波利尼西亚",
|
||||||
|
"French Guiana": "法属圭亚那",
|
||||||
|
"France": "法国",
|
||||||
|
"Finland": "芬兰",
|
||||||
|
"Fiji": "斐济",
|
||||||
|
"Faroe Islands": "法罗群岛",
|
||||||
|
"Falkland Islands": "福克兰群岛",
|
||||||
|
"Ethiopia": "埃塞俄比亚",
|
||||||
|
"Estonia": "爱沙尼亚",
|
||||||
|
"Eritrea": "厄立特里亚",
|
||||||
|
"Equatorial Guinea": "赤道几内亚",
|
||||||
|
"El Salvador": "萨尔瓦多",
|
||||||
|
"Egypt": "埃及",
|
||||||
|
"Ecuador": "厄瓜多尔",
|
||||||
|
"Dominican Republic": "多明尼加共和国",
|
||||||
|
"Dominica": "多米尼加",
|
||||||
|
"Djibouti": "吉布提",
|
||||||
|
"Denmark": "丹麦",
|
||||||
|
"Côte d’Ivoire": "科特迪瓦",
|
||||||
|
"Czech Republic": "捷克共和国",
|
||||||
|
"Cyprus": "塞浦路斯",
|
||||||
|
"Curaçao": "库拉索",
|
||||||
|
"Cuba": "古巴",
|
||||||
|
"Croatia": "克罗地亚",
|
||||||
|
"Costa Rica": "哥斯达黎加"
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
"Click here to fix": "點擊這里修復",
|
"Click here to fix": "點擊這里修復",
|
||||||
"Confirm password": "確認密碼",
|
"Confirm password": "確認密碼",
|
||||||
"Continue": "繼續",
|
"Continue": "繼續",
|
||||||
"Create Room": "創建聊天室",
|
"Create Room": "建立聊天室",
|
||||||
"Cryptography": "加密",
|
"Cryptography": "加密",
|
||||||
"Current password": "當前密碼",
|
"Current password": "當前密碼",
|
||||||
"/ddg is not a command": "/ddg 不是一個命令",
|
"/ddg is not a command": "/ddg 不是一個命令",
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
"Someone": "某人",
|
"Someone": "某人",
|
||||||
"Submit": "提交",
|
"Submit": "提交",
|
||||||
"Success": "成功",
|
"Success": "成功",
|
||||||
"This email address is already in use": "這個電子郵件地址已被使用",
|
"This email address is already in use": "該電子郵件位址已被使用",
|
||||||
"This email address was not found": "未找到此電子郵件地址",
|
"This email address was not found": "未找到此電子郵件地址",
|
||||||
"The email address linked to your account must be entered.": "必須輸入和你帳號關聯的電子郵件地址。",
|
"The email address linked to your account must be entered.": "必須輸入和你帳號關聯的電子郵件地址。",
|
||||||
"Unable to add email address": "無法新增電郵地址",
|
"Unable to add email address": "無法新增電郵地址",
|
||||||
|
@ -259,7 +259,7 @@
|
||||||
"This room has no local addresses": "此房間沒有本機地址",
|
"This room has no local addresses": "此房間沒有本機地址",
|
||||||
"This room is not recognised.": "此聊天室不被認可。",
|
"This room is not recognised.": "此聊天室不被認可。",
|
||||||
"This doesn't appear to be a valid email address": "這似乎不是有效的電子郵件地址",
|
"This doesn't appear to be a valid email address": "這似乎不是有效的電子郵件地址",
|
||||||
"This phone number is already in use": "這個電話號碼已在使用中",
|
"This phone number is already in use": "該電話號碼已被使用",
|
||||||
"This room": "此房間",
|
"This room": "此房間",
|
||||||
"This room is not accessible by remote Matrix servers": "此房間無法被遠端的 Matrix 伺服器存取",
|
"This room is not accessible by remote Matrix servers": "此房間無法被遠端的 Matrix 伺服器存取",
|
||||||
"To use it, just wait for autocomplete results to load and tab through them.": "要使用它,只要等待自動完成的結果載入並在它們上面按 Tab。",
|
"To use it, just wait for autocomplete results to load and tab through them.": "要使用它,只要等待自動完成的結果載入並在它們上面按 Tab。",
|
||||||
|
@ -625,7 +625,7 @@
|
||||||
"Room Notification": "聊天室通知",
|
"Room Notification": "聊天室通知",
|
||||||
"The information being sent to us to help make %(brand)s better includes:": "傳送給我們以協助改進 %(brand)s 的資訊包含了:",
|
"The information being sent to us to help make %(brand)s better includes:": "傳送給我們以協助改進 %(brand)s 的資訊包含了:",
|
||||||
"Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "這個頁面包含了可識別的資訊,如聊天室、使用者或群組 ID,這些資料會在傳到伺服器前被刪除。",
|
"Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "這個頁面包含了可識別的資訊,如聊天室、使用者或群組 ID,這些資料會在傳到伺服器前被刪除。",
|
||||||
"The platform you're on": "您使用的平臺是",
|
"The platform you're on": "您使用的平台是",
|
||||||
"The version of %(brand)s": "%(brand)s 版本",
|
"The version of %(brand)s": "%(brand)s 版本",
|
||||||
"Your language of choice": "您選擇的語言",
|
"Your language of choice": "您選擇的語言",
|
||||||
"Which officially provided instance you are using, if any": "您正在使用的任何官方實體,如果有的話",
|
"Which officially provided instance you are using, if any": "您正在使用的任何官方實體,如果有的話",
|
||||||
|
@ -1520,8 +1520,8 @@
|
||||||
"Create a private room": "建立私人聊天室",
|
"Create a private room": "建立私人聊天室",
|
||||||
"Topic (optional)": "主題(選擇性)",
|
"Topic (optional)": "主題(選擇性)",
|
||||||
"Make this room public": "讓聊天室公開",
|
"Make this room public": "讓聊天室公開",
|
||||||
"Hide advanced": "隱藏進階的",
|
"Hide advanced": "隱藏進階",
|
||||||
"Show advanced": "顯示進階的",
|
"Show advanced": "顯示進階",
|
||||||
"Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "阻擋其他 matrix 伺服器上的使用加入此聊天室(此設定無法在之後變更!)",
|
"Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "阻擋其他 matrix 伺服器上的使用加入此聊天室(此設定無法在之後變更!)",
|
||||||
"Close dialog": "關閉對話框",
|
"Close dialog": "關閉對話框",
|
||||||
"To continue you need to accept the terms of this service.": "要繼續,您必須同意本服務的條款。",
|
"To continue you need to accept the terms of this service.": "要繼續,您必須同意本服務的條款。",
|
||||||
|
@ -1543,7 +1543,7 @@
|
||||||
"Click the link in the email you received to verify and then click continue again.": "點擊您收到的電子郵件中的連結以驗證然後再次點擊繼續。",
|
"Click the link in the email you received to verify and then click continue again.": "點擊您收到的電子郵件中的連結以驗證然後再次點擊繼續。",
|
||||||
"You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|one": "您將要移除 %(user)s 的 1 則訊息。這無法復原。您想要繼續嗎?",
|
"You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|one": "您將要移除 %(user)s 的 1 則訊息。這無法復原。您想要繼續嗎?",
|
||||||
"Remove %(count)s messages|one": "移除 1 則訊息",
|
"Remove %(count)s messages|one": "移除 1 則訊息",
|
||||||
"Add Email Address": "新增電子郵件地址",
|
"Add Email Address": "新增電子郵件位址",
|
||||||
"Add Phone Number": "新增電話號碼",
|
"Add Phone Number": "新增電話號碼",
|
||||||
"%(creator)s created and configured the room.": "%(creator)s 建立並設定了聊天室。",
|
"%(creator)s created and configured the room.": "%(creator)s 建立並設定了聊天室。",
|
||||||
"You should <b>remove your personal data</b> from identity server <idserver /> before disconnecting. Unfortunately, identity server <idserver /> is currently offline or cannot be reached.": "您應該在斷線前從身份識別伺服器 <idserver /> 上<b>移除您的個人資料</b>。不幸的是,身份識別伺服器 <idserver /> 目前離線中或無法連線。",
|
"You should <b>remove your personal data</b> from identity server <idserver /> before disconnecting. Unfortunately, identity server <idserver /> is currently offline or cannot be reached.": "您應該在斷線前從身份識別伺服器 <idserver /> 上<b>移除您的個人資料</b>。不幸的是,身份識別伺服器 <idserver /> 目前離線中或無法連線。",
|
||||||
|
@ -1847,7 +1847,7 @@
|
||||||
"Bridges": "橋接",
|
"Bridges": "橋接",
|
||||||
"This user has not verified all of their sessions.": "此使用者尚未驗證他們的所有工作階段。",
|
"This user has not verified all of their sessions.": "此使用者尚未驗證他們的所有工作階段。",
|
||||||
"You have verified this user. This user has verified all of their sessions.": "您已驗證此使用者。此使用者已驗證他們所有的工作階段。",
|
"You have verified this user. This user has verified all of their sessions.": "您已驗證此使用者。此使用者已驗證他們所有的工作階段。",
|
||||||
"Someone is using an unknown session": "某人正仔使用未知的工作階段",
|
"Someone is using an unknown session": "某人正在使用未知的工作階段",
|
||||||
"Your key share request has been sent - please check your other sessions for key share requests.": "您的金鑰分享請求已傳送,請檢查您其他的工作階段以取得金鑰分享請求。",
|
"Your key share request has been sent - please check your other sessions for key share requests.": "您的金鑰分享請求已傳送,請檢查您其他的工作階段以取得金鑰分享請求。",
|
||||||
"Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "金鑰分享請求已自動傳送到您其他的工作階段。如果您在您其他的工作階段上拒絕或忽略金鑰分享請求,點擊此處以再此請求此工作階段的金鑰。",
|
"Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "金鑰分享請求已自動傳送到您其他的工作階段。如果您在您其他的工作階段上拒絕或忽略金鑰分享請求,點擊此處以再此請求此工作階段的金鑰。",
|
||||||
"If your other sessions do not have the key for this message you will not be able to decrypt them.": "如果您的其他工作階段沒有此訊息的金鑰,您就無法解密它們。",
|
"If your other sessions do not have the key for this message you will not be able to decrypt them.": "如果您的其他工作階段沒有此訊息的金鑰,您就無法解密它們。",
|
||||||
|
@ -2079,11 +2079,11 @@
|
||||||
"Sends a message as html, without interpreting it as markdown": "以 html 形式傳送訊息,不將其翻譯為 markdown",
|
"Sends a message as html, without interpreting it as markdown": "以 html 形式傳送訊息,不將其翻譯為 markdown",
|
||||||
"Cancel replying to a message": "取消回覆訊息",
|
"Cancel replying to a message": "取消回覆訊息",
|
||||||
"Sign in with SSO": "使用單一登入系統登入",
|
"Sign in with SSO": "使用單一登入系統登入",
|
||||||
"Use Single Sign On to continue": "使用單一登入繼續",
|
"Use Single Sign On to continue": "使用單一登入來繼續",
|
||||||
"Confirm adding this email address by using Single Sign On to prove your identity.": "透過使用單一登入來證明您的身份以確認新增此電子郵件地址。",
|
"Confirm adding this email address by using Single Sign On to prove your identity.": "使用單一登入來證明身份,以確認新增該電子郵件位址。",
|
||||||
"Single Sign On": "單一登入",
|
"Single Sign On": "單一登入",
|
||||||
"Confirm adding email": "確任新增電子郵件",
|
"Confirm adding email": "確任新增電子郵件",
|
||||||
"Click the button below to confirm adding this email address.": "點擊下方按鈕以確認新增此電子郵件地址。",
|
"Click the button below to confirm adding this 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.": "點擊下方按鈕以確認新增此電話號碼。",
|
||||||
|
@ -2742,7 +2742,7 @@
|
||||||
"Gibraltar": "直布羅陀",
|
"Gibraltar": "直布羅陀",
|
||||||
"Ghana": "迦納",
|
"Ghana": "迦納",
|
||||||
"Germany": "德國",
|
"Germany": "德國",
|
||||||
"Georgia": "喬治亞",
|
"Georgia": "格魯吉亞",
|
||||||
"Gambia": "甘比亞",
|
"Gambia": "甘比亞",
|
||||||
"Gabon": "加彭",
|
"Gabon": "加彭",
|
||||||
"French Southern Territories": "法屬南部領地",
|
"French Southern Territories": "法屬南部領地",
|
||||||
|
@ -2760,11 +2760,11 @@
|
||||||
"El Salvador": "薩爾瓦多",
|
"El Salvador": "薩爾瓦多",
|
||||||
"Egypt": "埃及",
|
"Egypt": "埃及",
|
||||||
"Ecuador": "厄瓜多",
|
"Ecuador": "厄瓜多",
|
||||||
"Dominican Republic": "多明尼加",
|
"Dominican Republic": "多明尼加共和國",
|
||||||
"Dominica": "多米尼克",
|
"Dominica": "多米尼克",
|
||||||
"Djibouti": "吉布地",
|
"Djibouti": "吉布地",
|
||||||
"Denmark": "丹麥",
|
"Denmark": "丹麥",
|
||||||
"Côte d’Ivoire": "象牙海岸",
|
"Côte d’Ivoire": "科特迪瓦",
|
||||||
"Czech Republic": "捷克",
|
"Czech Republic": "捷克",
|
||||||
"Cyprus": "賽普勒斯",
|
"Cyprus": "賽普勒斯",
|
||||||
"Curaçao": "古拉索",
|
"Curaçao": "古拉索",
|
||||||
|
@ -3090,5 +3090,120 @@
|
||||||
"Setting ID": "設定 ID",
|
"Setting ID": "設定 ID",
|
||||||
"Failed to save settings": "儲存設定失敗",
|
"Failed to save settings": "儲存設定失敗",
|
||||||
"Settings Explorer": "設定瀏覽程式",
|
"Settings Explorer": "設定瀏覽程式",
|
||||||
"Show chat effects (animations when receiving e.g. confetti)": "顯示聊天效果(當收到如五彩紙屑時顯示動畫)"
|
"Show chat effects (animations when receiving e.g. confetti)": "顯示聊天效果(當收到如五彩紙屑時顯示動畫)",
|
||||||
|
"Original event source": "原始活動來源",
|
||||||
|
"Decrypted event source": "解密活動來源",
|
||||||
|
"We'll create rooms for each of them. You can add existing rooms after setup.": "我們將為每個專案建立聊天室。您可以在設定完成後新增既有的聊天室。",
|
||||||
|
"What projects are you working on?": "您正在從事哪些專案?",
|
||||||
|
"We'll create rooms for each topic.": "我們將為每個主題建立聊天室。",
|
||||||
|
"What are some things you want to discuss?": "您想討論什麼?",
|
||||||
|
"Inviting...": "邀請……",
|
||||||
|
"Invite by username": "透過使用者名稱邀請",
|
||||||
|
"Invite your teammates": "邀請您的隊友",
|
||||||
|
"Failed to invite the following users to your space: %(csvUsers)s": "無法邀請以下使用者加入您的空間:%(csvUsers)s",
|
||||||
|
"A private space for you and your teammates": "專為您與您的隊友設計的私人空間",
|
||||||
|
"Me and my teammates": "我與我的隊友",
|
||||||
|
"A private space just for you": "專為您設計的私人空間",
|
||||||
|
"Just Me": "只有我",
|
||||||
|
"Ensure the right people have access to the space.": "確定適合的人才能存取空間。",
|
||||||
|
"Who are you working with?": "您與誰一起工作?",
|
||||||
|
"Finish": "結束",
|
||||||
|
"At the moment only you can see it.": "目前只有您可以看見它。",
|
||||||
|
"Creating rooms...": "正在建立聊天室……",
|
||||||
|
"Skip for now": "現在跳過",
|
||||||
|
"Failed to create initial space rooms": "建立初始空間聊天室失敗",
|
||||||
|
"Room name": "聊天室名稱",
|
||||||
|
"Support": "支援",
|
||||||
|
"Random": "隨機",
|
||||||
|
"Welcome to <name/>": "歡迎加入 <name/>",
|
||||||
|
"Your private space <name/>": "您的私人空間 <name/>",
|
||||||
|
"Your public space <name/>": "您的公開空間 <name/>",
|
||||||
|
"You have been invited to <name/>": "您被邀請到 <name/>",
|
||||||
|
"<inviter/> invited you to <name/>": "<inviter/> 邀請您到 <name/>",
|
||||||
|
"%(count)s members|one": "%(count)s 位成員",
|
||||||
|
"%(count)s members|other": "%(count)s 位成員",
|
||||||
|
"Your server does not support showing space hierarchies.": "您的伺服器不支援顯示空間的層次結構。",
|
||||||
|
"Default Rooms": "預設聊天室",
|
||||||
|
"Add existing rooms & spaces": "新增既有聊天室與空間",
|
||||||
|
"Accept Invite": "接受邀請",
|
||||||
|
"Find a room...": "尋找聊天室……",
|
||||||
|
"Manage rooms": "管理聊天室",
|
||||||
|
"Promoted to users": "升級為使用者",
|
||||||
|
"Save changes": "儲存變更",
|
||||||
|
"You're in this room": "您在此聊天室中",
|
||||||
|
"You're in this space": "您在此空間中",
|
||||||
|
"No permissions": "無權限",
|
||||||
|
"Remove from Space": "從空間移除",
|
||||||
|
"Undo": "復原",
|
||||||
|
"Your message wasn't sent because this homeserver has been blocked by it's administrator. Please <a>contact your service administrator</a> to continue using the service.": "未傳送您的訊息,因為此家伺服器已被其管理員封鎖。請<a>聯絡您的服務管理員</a>以繼續使用服務。",
|
||||||
|
"Are you sure you want to leave the space '%(spaceName)s'?": "您確定您要離開空間「%(spaceName)s」?",
|
||||||
|
"This space is not public. You will not be able to rejoin without an invite.": "此空間並非公開。在無邀請的情況下,您將無法重新加入。",
|
||||||
|
"Start audio stream": "開始音訊串流",
|
||||||
|
"Failed to start livestream": "開始直播串流失敗",
|
||||||
|
"Unable to start audio streaming.": "無法開始音訊串流。",
|
||||||
|
"Save Changes": "儲存變更",
|
||||||
|
"Saving...": "正在儲存……",
|
||||||
|
"View dev tools": "檢視開發者工具",
|
||||||
|
"Leave Space": "離開空間",
|
||||||
|
"Make this space private": "將此空間設為私人",
|
||||||
|
"Edit settings relating to your space.": "編輯關於您空間的設定。",
|
||||||
|
"Space settings": "空間設定",
|
||||||
|
"Failed to save space settings.": "無法儲存空間設定。",
|
||||||
|
"Invite someone using their name, username (like <userId/>) or <a>share this space</a>.": "使用某人的名字、使用者名稱(如 <userId/>)邀請他們,或<a>分享此空間</a>。",
|
||||||
|
"Invite someone using their name, email address, username (like <userId/>) or <a>share this space</a>.": "使用某人的名字、電子郵件地址、使用者名稱(如 <userId/>)邀請他們,或<a>分享此空間</a>。",
|
||||||
|
"Unnamed Space": "未命名空間",
|
||||||
|
"Invite to %(spaceName)s": "邀請至 %(spaceName)s",
|
||||||
|
"Failed to add rooms to space": "新增聊天室到空間失敗",
|
||||||
|
"Apply": "套用",
|
||||||
|
"Applying...": "正在套用……",
|
||||||
|
"Create a new room": "建立新聊天室",
|
||||||
|
"Don't want to add an existing room?": "不想新增既有的聊天室?",
|
||||||
|
"Spaces": "空間",
|
||||||
|
"Filter your rooms and spaces": "過濾您的聊天室與空間",
|
||||||
|
"Add existing spaces/rooms": "新增既有空間/聊天室",
|
||||||
|
"Space selection": "空間選取",
|
||||||
|
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the space it will be impossible to regain privileges.": "如果您將自己降級,您將無法撤銷此變更,而且如果您是空間中的最後一個高權限使用者,將無法再取得這類權限。",
|
||||||
|
"Empty room": "空聊天室",
|
||||||
|
"Suggested Rooms": "建議的聊天室",
|
||||||
|
"Explore space rooms": "探索空間聊天室",
|
||||||
|
"You do not have permissions to add rooms to this space": "您無權在此空間中新增聊天室",
|
||||||
|
"Add existing room": "新增既有的聊天室",
|
||||||
|
"You do not have permissions to create new rooms in this space": "您無權在此空間中建立新聊天室",
|
||||||
|
"Send message": "傳送訊息",
|
||||||
|
"Invite to this space": "邀請至此空間",
|
||||||
|
"Your message was sent": "您的訊息已傳送",
|
||||||
|
"Encrypting your message...": "正在加密的您訊息……",
|
||||||
|
"Sending your message...": "正在傳送您的訊息……",
|
||||||
|
"Spell check dictionaries": "拼字檢查字典",
|
||||||
|
"Space options": "空間選項",
|
||||||
|
"Space Home": "空間首頁",
|
||||||
|
"New room": "新聊天室",
|
||||||
|
"Leave space": "離開空間",
|
||||||
|
"Invite people": "邀請夥伴",
|
||||||
|
"Share your public space": "分享您的公開空間",
|
||||||
|
"Invite members": "邀請成員",
|
||||||
|
"Invite by email or username": "透過電子郵件或使用者名稱邀請",
|
||||||
|
"Share invite link": "分享邀請連結",
|
||||||
|
"Click to copy": "點擊複製",
|
||||||
|
"Collapse space panel": "折疊空間面板",
|
||||||
|
"Expand space panel": "展開空間面板",
|
||||||
|
"Creating...": "正在建立……",
|
||||||
|
"You can change these at any point.": "您隨時可以更改它們。",
|
||||||
|
"Give it a photo, name and description to help you identify it.": "給它一張照片、名字與描述來協助您識別它。",
|
||||||
|
"Your private space": "您的私人空間",
|
||||||
|
"Your public space": "您的公開空間",
|
||||||
|
"You can change this later": "您之後仍可變更",
|
||||||
|
"Invite only, best for yourself or teams": "僅邀請,最適合您自己或團隊",
|
||||||
|
"Private": "私人",
|
||||||
|
"Open space for anyone, best for communities": "對所有人開放的空間,最適合社群",
|
||||||
|
"Public": "公開",
|
||||||
|
"Spaces are new ways to group rooms and people. To join an existing space you’ll need an invite": "空間是將聊天室與人們分組的新方法。要加入既有的空間,您需要邀請",
|
||||||
|
"Create a space": "建立空間",
|
||||||
|
"Delete": "刪除",
|
||||||
|
"Jump to the bottom of the timeline when you send a message": "傳送訊息時,跳到時間軸底部",
|
||||||
|
"Spaces prototype. Incompatible with Communities, Communities v2 and Custom Tags. Requires compatible homeserver for some features.": "空間原型。與社群、社群 v2 以及自訂標籤不相容。需要相容的家伺服器才能使用某些功能。",
|
||||||
|
"This homeserver has been blocked by it's administrator.": "此家伺服器已被其管理員封鎖。",
|
||||||
|
"This homeserver has been blocked by its administrator.": "此家伺服器已被其管理員封鎖。",
|
||||||
|
"You're already in a call with this person.": "您已與此人通話。",
|
||||||
|
"Already in call": "已在通話中"
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ class EventIndexPeg {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.index = null;
|
this.index = null;
|
||||||
this._supportIsInstalled = false;
|
this._supportIsInstalled = false;
|
||||||
|
this.error = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,6 +97,7 @@ class EventIndexPeg {
|
||||||
await index.init();
|
await index.init();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("EventIndex: Error initializing the event index", e);
|
console.log("EventIndex: Error initializing the event index", e);
|
||||||
|
this.error = e;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,12 @@ export const SETTINGS: {[setting: string]: ISetting} = {
|
||||||
default: false,
|
default: false,
|
||||||
controller: new ReloadOnChangeController(),
|
controller: new ReloadOnChangeController(),
|
||||||
},
|
},
|
||||||
|
"feature_voice_messages": {
|
||||||
|
isFeature: true,
|
||||||
|
displayName: _td("Send and receive voice messages (in development)"),
|
||||||
|
supportedLevels: LEVELS_FEATURE,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
"feature_latex_maths": {
|
"feature_latex_maths": {
|
||||||
isFeature: true,
|
isFeature: true,
|
||||||
displayName: _td("Render LaTeX maths in messages"),
|
displayName: _td("Render LaTeX maths in messages"),
|
||||||
|
@ -214,6 +220,12 @@ export const SETTINGS: {[setting: string]: ISetting} = {
|
||||||
supportedLevels: LEVELS_FEATURE,
|
supportedLevels: LEVELS_FEATURE,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
"feature_room_history_key_sharing": {
|
||||||
|
isFeature: true,
|
||||||
|
displayName: _td("Share decryption keys for room history when inviting users"),
|
||||||
|
supportedLevels: LEVELS_FEATURE,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
"advancedRoomListLogging": {
|
"advancedRoomListLogging": {
|
||||||
// TODO: Remove flag before launch: https://github.com/vector-im/element-web/issues/14231
|
// TODO: Remove flag before launch: https://github.com/vector-im/element-web/issues/14231
|
||||||
displayName: _td("Enable advanced debugging for the room list"),
|
displayName: _td("Enable advanced debugging for the room list"),
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue