diff --git a/CHANGELOG.md b/CHANGELOG.md index 22b35b7c59..73b383d76d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,152 @@ +Changes in [3.26.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.26.0) (2021-07-19) +===================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.26.0-rc.1...v3.26.0) + + * Fix 'User' type import + [\#6376](https://github.com/matrix-org/matrix-react-sdk/pull/6376) + +Changes in [3.26.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.26.0-rc.1) (2021-07-14) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.25.0...v3.26.0-rc.1) + + * Fix voice messages in right panels + [\#6370](https://github.com/matrix-org/matrix-react-sdk/pull/6370) + * Use TileShape enum more universally + [\#6369](https://github.com/matrix-org/matrix-react-sdk/pull/6369) + * Translations update from Weblate + [\#6373](https://github.com/matrix-org/matrix-react-sdk/pull/6373) + * Hide world readable history option in encrypted rooms + [\#5947](https://github.com/matrix-org/matrix-react-sdk/pull/5947) + * Make the Image View buttons easier to hit + [\#6372](https://github.com/matrix-org/matrix-react-sdk/pull/6372) + * Reorder buttons in the Image View + [\#6368](https://github.com/matrix-org/matrix-react-sdk/pull/6368) + * Add VS Code to gitignore + [\#6367](https://github.com/matrix-org/matrix-react-sdk/pull/6367) + * Fix inviter exploding due to member being null + [\#6362](https://github.com/matrix-org/matrix-react-sdk/pull/6362) + * Increase sample count in voice message thumbnail + [\#6359](https://github.com/matrix-org/matrix-react-sdk/pull/6359) + * Improve arraySeed utility + [\#6360](https://github.com/matrix-org/matrix-react-sdk/pull/6360) + * Convert FontManager to TS and stub it out for tests + [\#6358](https://github.com/matrix-org/matrix-react-sdk/pull/6358) + * Adjust recording waveform behaviour for voice messages + [\#6357](https://github.com/matrix-org/matrix-react-sdk/pull/6357) + * Do not honor string power levels + [\#6245](https://github.com/matrix-org/matrix-react-sdk/pull/6245) + * Add alias and directory customisation points + [\#6343](https://github.com/matrix-org/matrix-react-sdk/pull/6343) + * Fix multiinviter user already in room and clean up code + [\#6354](https://github.com/matrix-org/matrix-react-sdk/pull/6354) + * Fix right panel not closing user info when changing rooms + [\#6341](https://github.com/matrix-org/matrix-react-sdk/pull/6341) + * Quit sticker picker on m.sticker + [\#5679](https://github.com/matrix-org/matrix-react-sdk/pull/5679) + * Don't autodetect language in inline code blocks + [\#6350](https://github.com/matrix-org/matrix-react-sdk/pull/6350) + * Make ghost button background transparent + [\#6331](https://github.com/matrix-org/matrix-react-sdk/pull/6331) + * only consider valid & loaded url previews for show N more prompt + [\#6346](https://github.com/matrix-org/matrix-react-sdk/pull/6346) + * Extract MXCs from _matrix/media/r0/ URLs for inline images in messages + [\#6335](https://github.com/matrix-org/matrix-react-sdk/pull/6335) + * Fix small visual regression with the site name on url previews + [\#6342](https://github.com/matrix-org/matrix-react-sdk/pull/6342) + * Make PIP CallView draggable/movable + [\#5952](https://github.com/matrix-org/matrix-react-sdk/pull/5952) + * Convert VoiceUserSettingsTab to TS + [\#6340](https://github.com/matrix-org/matrix-react-sdk/pull/6340) + * Simplify typescript definition for Modernizr + [\#6339](https://github.com/matrix-org/matrix-react-sdk/pull/6339) + * Remember the last used server for room directory searches + [\#6322](https://github.com/matrix-org/matrix-react-sdk/pull/6322) + * Focus composer after reacting + [\#6332](https://github.com/matrix-org/matrix-react-sdk/pull/6332) + * Fix bug which prevented more than one event getting pinned + [\#6336](https://github.com/matrix-org/matrix-react-sdk/pull/6336) + * Make DeviceListener also update on megolm key in SSSS + [\#6337](https://github.com/matrix-org/matrix-react-sdk/pull/6337) + * Improve URL previews + [\#6326](https://github.com/matrix-org/matrix-react-sdk/pull/6326) + * Don't close settings dialog when opening spaces feedback prompt + [\#6334](https://github.com/matrix-org/matrix-react-sdk/pull/6334) + * Update import location for types + [\#6330](https://github.com/matrix-org/matrix-react-sdk/pull/6330) + * Improve blurhash rendering performance + [\#6329](https://github.com/matrix-org/matrix-react-sdk/pull/6329) + * Use a proper color scheme for codeblocks + [\#6320](https://github.com/matrix-org/matrix-react-sdk/pull/6320) + * Burn `sdk.getComponent()` with 🔥 + [\#6308](https://github.com/matrix-org/matrix-react-sdk/pull/6308) + * Fix instances of the Edit Message Composer's save button being wrongly + disabled + [\#6307](https://github.com/matrix-org/matrix-react-sdk/pull/6307) + * Do not generate a lockfile when running in CI + [\#6327](https://github.com/matrix-org/matrix-react-sdk/pull/6327) + * Update lockfile with correct dependencies + [\#6324](https://github.com/matrix-org/matrix-react-sdk/pull/6324) + * Clarify the keys we use when submitting rageshakes + [\#6321](https://github.com/matrix-org/matrix-react-sdk/pull/6321) + * Fix ImageView context menu + [\#6318](https://github.com/matrix-org/matrix-react-sdk/pull/6318) + * TypeScript migration + [\#6315](https://github.com/matrix-org/matrix-react-sdk/pull/6315) + * Move animation to compositor + [\#6310](https://github.com/matrix-org/matrix-react-sdk/pull/6310) + * Reorganize preferences + [\#5742](https://github.com/matrix-org/matrix-react-sdk/pull/5742) + * Fix being able to un-rotate images + [\#6313](https://github.com/matrix-org/matrix-react-sdk/pull/6313) + * Fix icon size in passphrase prompt + [\#6312](https://github.com/matrix-org/matrix-react-sdk/pull/6312) + * Use sleep & defer from js-sdk instead of duplicating it + [\#6305](https://github.com/matrix-org/matrix-react-sdk/pull/6305) + * Convert EventTimeline, EventTimelineSet and TimelineWindow to TS + [\#6295](https://github.com/matrix-org/matrix-react-sdk/pull/6295) + * Comply with new member-delimiter-style rule + [\#6306](https://github.com/matrix-org/matrix-react-sdk/pull/6306) + * Fix Test Linting + [\#6304](https://github.com/matrix-org/matrix-react-sdk/pull/6304) + * Convert Markdown to TypeScript + [\#6303](https://github.com/matrix-org/matrix-react-sdk/pull/6303) + * Convert RoomHeader to TS + [\#6302](https://github.com/matrix-org/matrix-react-sdk/pull/6302) + * Prevent RoomDirectory from exploding when filterString is wrongly nulled + [\#6296](https://github.com/matrix-org/matrix-react-sdk/pull/6296) + * Add support for blurhash (MSC2448) + [\#5099](https://github.com/matrix-org/matrix-react-sdk/pull/5099) + * Remove rateLimitedFunc + [\#6300](https://github.com/matrix-org/matrix-react-sdk/pull/6300) + * Convert some Key Verification classes to TypeScript + [\#6299](https://github.com/matrix-org/matrix-react-sdk/pull/6299) + * Typescript conversion of Composer components and more + [\#6292](https://github.com/matrix-org/matrix-react-sdk/pull/6292) + * Upgrade browserlist target versions + [\#6298](https://github.com/matrix-org/matrix-react-sdk/pull/6298) + * Fix browser crashing when searching for a malformed HTML tag + [\#6297](https://github.com/matrix-org/matrix-react-sdk/pull/6297) + * Add custom audio player + [\#6264](https://github.com/matrix-org/matrix-react-sdk/pull/6264) + * Lint MXC APIs to centralise access + [\#6293](https://github.com/matrix-org/matrix-react-sdk/pull/6293) + * Remove reminescent references to the tinter + [\#6290](https://github.com/matrix-org/matrix-react-sdk/pull/6290) + * More js-sdk type consolidation + [\#6263](https://github.com/matrix-org/matrix-react-sdk/pull/6263) + * Convert MessagePanel, TimelinePanel, ScrollPanel, and more to Typescript + [\#6243](https://github.com/matrix-org/matrix-react-sdk/pull/6243) + * Migrate to `eslint-plugin-matrix-org` + [\#6285](https://github.com/matrix-org/matrix-react-sdk/pull/6285) + * Avoid cyclic dependencies by moving watchers out of constructor + [\#6287](https://github.com/matrix-org/matrix-react-sdk/pull/6287) + * Add spacing between toast buttons with cross browser support in mind + [\#6284](https://github.com/matrix-org/matrix-react-sdk/pull/6284) + * Deprecate Tinter and TintableSVG + [\#6279](https://github.com/matrix-org/matrix-react-sdk/pull/6279) + * Migrate FilePanel to TypeScript + [\#6283](https://github.com/matrix-org/matrix-react-sdk/pull/6283) + Changes in [3.25.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.25.0) (2021-07-05) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.25.0-rc.1...v3.25.0) diff --git a/package.json b/package.json index e80ed8dd5a..4e2e933a52 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "3.25.0", + "version": "3.26.0", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { @@ -46,6 +46,7 @@ "start:build": "babel src -w -s -d lib --verbose --extensions \".ts,.js\"", "lint": "yarn lint:types && yarn lint:js && yarn lint:style", "lint:js": "eslint --max-warnings 0 src test", + "lint:js-fix": "eslint --fix src test", "lint:types": "tsc --noEmit --jsx react", "lint:style": "stylelint 'res/css/**/*.scss'", "test": "jest", @@ -79,7 +80,7 @@ "katex": "^0.12.0", "linkifyjs": "^2.1.9", "lodash": "^4.17.20", - "matrix-js-sdk": "12.0.1", + "matrix-js-sdk": "12.1.0", "matrix-widget-api": "^0.1.0-beta.15", "minimist": "^1.2.5", "opus-recorder": "^8.0.3", diff --git a/res/css/_components.scss b/res/css/_components.scss index 8f26cb32d7..bc7d4fc85f 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -202,6 +202,7 @@ @import "./views/rooms/_EditMessageComposer.scss"; @import "./views/rooms/_EntityTile.scss"; @import "./views/rooms/_EventTile.scss"; +@import "./views/rooms/_EventBubbleTile.scss"; @import "./views/rooms/_GroupLayout.scss"; @import "./views/rooms/_IRCLayout.scss"; @import "./views/rooms/_JumpToBottomButton.scss"; diff --git a/res/css/views/avatars/_BaseAvatar.scss b/res/css/views/avatars/_BaseAvatar.scss index cbddd97e18..65e4493f19 100644 --- a/res/css/views/avatars/_BaseAvatar.scss +++ b/res/css/views/avatars/_BaseAvatar.scss @@ -27,6 +27,7 @@ limitations under the License. // https://bugzilla.mozilla.org/show_bug.cgi?id=255139 display: inline-block; user-select: none; + line-height: 1; } .mx_BaseAvatar_initial { diff --git a/res/css/views/elements/_ReplyThread.scss b/res/css/views/elements/_ReplyThread.scss index af8ca956ba..44532ea6a7 100644 --- a/res/css/views/elements/_ReplyThread.scss +++ b/res/css/views/elements/_ReplyThread.scss @@ -16,19 +16,16 @@ limitations under the License. .mx_ReplyThread { margin-top: 0; -} - -.mx_ReplyThread_show { - cursor: pointer; -} - -blockquote.mx_ReplyThread { margin-left: 0; margin-right: 0; margin-bottom: 8px; padding-left: 10px; border-left: 4px solid $button-bg-color; + .mx_ReplyThread_show { + cursor: pointer; + } + &.mx_ReplyThread_color1 { border-left-color: $username-variant1-color; } diff --git a/res/css/views/elements/_StyledRadioButton.scss b/res/css/views/elements/_StyledRadioButton.scss index 62fb5c5512..1ae787dfc2 100644 --- a/res/css/views/elements/_StyledRadioButton.scss +++ b/res/css/views/elements/_StyledRadioButton.scss @@ -46,7 +46,7 @@ limitations under the License. width: $font-16px; } - > input[type=radio] { + input[type=radio] { // Remove the OS's representation margin: 0; padding: 0; @@ -112,6 +112,12 @@ limitations under the License. } } } + + .mx_RadioButton_innerLabel { + display: flex; + position: relative; + top: 4px; + } } .mx_RadioButton_outlined { diff --git a/res/css/views/messages/_MImageBody.scss b/res/css/views/messages/_MImageBody.scss index 878a4154cd..0a199c1f45 100644 --- a/res/css/views/messages/_MImageBody.scss +++ b/res/css/views/messages/_MImageBody.scss @@ -18,7 +18,6 @@ $timelineImageBorderRadius: 4px; .mx_MImageBody { display: block; - margin-right: 34px; } .mx_MImageBody_thumbnail { @@ -29,6 +28,10 @@ $timelineImageBorderRadius: 4px; top: 0; border-radius: $timelineImageBorderRadius; + display: flex; + justify-content: center; + align-items: center; + > canvas { border-radius: $timelineImageBorderRadius; } @@ -43,17 +46,6 @@ $timelineImageBorderRadius: 4px; position: relative; } -.mx_MImageBody_thumbnail_spinner { - position: absolute; - left: 50%; - top: 50%; -} - -// Inner img should be centered around 0, 0 -.mx_MImageBody_thumbnail_spinner > * { - transform: translate(-50%, -50%); -} - .mx_MImageBody_gifLabel { position: absolute; display: block; diff --git a/res/css/views/messages/_ReactionsRow.scss b/res/css/views/messages/_ReactionsRow.scss index e05065eb02..b2bca6dfb3 100644 --- a/res/css/views/messages/_ReactionsRow.scss +++ b/res/css/views/messages/_ReactionsRow.scss @@ -26,6 +26,7 @@ limitations under the License. height: 24px; vertical-align: middle; margin-left: 4px; + margin-right: 4px; &::before { content: ''; diff --git a/res/css/views/rooms/_EventBubbleTile.scss b/res/css/views/rooms/_EventBubbleTile.scss new file mode 100644 index 0000000000..c66f635ffe --- /dev/null +++ b/res/css/views/rooms/_EventBubbleTile.scss @@ -0,0 +1,323 @@ +/* +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_EventTile[data-layout=bubble], +.mx_EventTile[data-layout=bubble] ~ .mx_EventListSummary { + --avatarSize: 32px; + --gutterSize: 11px; + --cornerRadius: 12px; + --maxWidth: 70%; +} + +.mx_EventTile[data-layout=bubble] { + + position: relative; + margin-top: var(--gutterSize); + margin-left: 50px; + margin-right: 100px; + + &.mx_EventTile_continuation { + margin-top: 2px; + } + + /* For replies */ + .mx_EventTile { + padding-top: 0; + } + + &:hover { + &::before { + content: ''; + position: absolute; + top: -1px; + bottom: -1px; + left: -60px; + right: -60px; + z-index: -1; + background: $eventbubble-bg-hover; + border-radius: 4px; + } + + .mx_EventTile_avatar { + img { + box-shadow: 0 0 0 3px $eventbubble-bg-hover; + } + } + } + + .mx_SenderProfile, + .mx_EventTile_line { + width: fit-content; + max-width: 70%; + } + + .mx_SenderProfile { + position: relative; + top: -2px; + left: 2px; + } + + &[data-self=false] { + .mx_EventTile_line { + border-bottom-right-radius: var(--cornerRadius); + } + .mx_EventTile_avatar { + left: -34px; + } + + .mx_MessageActionBar { + right: 0; + transform: translate3d(50%, 50%, 0); + } + + --backgroundColor: $eventbubble-others-bg; + } + &[data-self=true] { + .mx_EventTile_line { + border-bottom-left-radius: var(--cornerRadius); + float: right; + > a { + left: auto; + right: -48px; + } + } + .mx_SenderProfile { + display: none; + } + .mx_ReactionsRow { + float: right; + clear: right; + display: flex; + + /* Moving the "add reaction button" before the reactions */ + > :last-child { + order: -1; + } + } + .mx_EventTile_avatar { + top: -19px; // height of the sender block + right: -35px; + } + + --backgroundColor: $eventbubble-self-bg; + } + + .mx_EventTile_line { + position: relative; + padding: var(--gutterSize); + border-top-left-radius: var(--cornerRadius); + border-top-right-radius: var(--cornerRadius); + background: var(--backgroundColor); + display: flex; + gap: 5px; + margin: 0 -12px 0 -9px; + > a { + position: absolute; + left: -48px; + } + } + + &.mx_EventTile_continuation[data-self=false] .mx_EventTile_line { + border-top-left-radius: 0; + } + &.mx_EventTile_lastInSection[data-self=false] .mx_EventTile_line { + border-bottom-left-radius: var(--cornerRadius); + } + + &.mx_EventTile_continuation[data-self=true] .mx_EventTile_line { + border-top-right-radius: 0; + } + &.mx_EventTile_lastInSection[data-self=true] .mx_EventTile_line { + border-bottom-right-radius: var(--cornerRadius); + } + + .mx_EventTile_avatar { + position: absolute; + top: 0; + line-height: 1; + img { + box-shadow: 0 0 0 3px $eventbubble-avatar-outline; + border-radius: 50%; + } + } + + &[data-has-reply=true] { + > .mx_EventTile_line { + flex-direction: column; + } + + .mx_ReplyThread_show { + order: 99999; + } + + .mx_ReplyThread { + margin: 0 calc(-1 * var(--gutterSize)); + + .mx_EventTile_reply { + max-width: 90%; + padding: 0; + > a { + display: none !important; + } + } + + .mx_EventTile { + display: flex; + gap: var(--gutterSize); + .mx_EventTile_avatar { + position: static; + } + .mx_SenderProfile { + display: none; + } + } + } + } + + .mx_EditMessageComposer_buttons { + position: static; + padding: 0; + margin: 0; + background: transparent; + } + + .mx_ReactionsRow { + margin-right: -18px; + margin-left: -9px; + } + + .mx_ReplyThread { + border-left-width: 2px; + border-left-color: $eventbubble-reply-color; + } + + &.mx_EventTile_bubbleContainer, + &.mx_EventTile_info, + & ~ .mx_EventListSummary[data-expanded=false] { + --backgroundColor: transparent; + --gutterSize: 0; + + display: flex; + align-items: center; + justify-content: center; + + .mx_EventTile_avatar { + position: static; + order: -1; + margin-right: 5px; + } + } + + & ~ .mx_EventListSummary { + --maxWidth: 80%; + margin-left: calc(var(--avatarSize) + var(--gutterSize)); + margin-right: calc(var(--gutterSize) + var(--avatarSize)); + .mx_EventListSummary_toggle { + float: none; + margin: 0; + order: 9; + margin-left: 5px; + } + .mx_EventListSummary_avatars { + padding-top: 0; + } + + &::after { + content: ""; + clear: both; + } + + .mx_EventTile { + margin: 0 6px; + } + + .mx_EventTile_line { + margin: 0 5px; + > a { + left: auto; + right: 0; + transform: translateX(calc(100% + 5px)); + } + } + + .mx_MessageActionBar { + transform: translate3d(50%, 0, 0); + } + } + + & ~ .mx_EventListSummary[data-expanded=false] { + padding: 0 34px; + } + + /* events that do not require bubble layout */ + & ~ .mx_EventListSummary, + &.mx_EventTile_bad { + .mx_EventTile_line { + background: transparent; + } + + &:hover { + &::before { + background: transparent; + } + } + } + + & + .mx_EventListSummary { + .mx_EventTile { + margin-top: 0; + padding: 0; + } + } + + .mx_EventListSummary_toggle { + margin-right: 55px; + } + + /* Special layout scenario for "Unable To Decrypt (UTD)" events */ + &.mx_EventTile_bad > .mx_EventTile_line { + display: grid; + grid-template: + "reply reply" auto + "shield body" auto + "shield link" auto + / auto 1fr; + .mx_EventTile_e2eIcon { + grid-area: shield; + } + .mx_UnknownBody { + grid-area: body; + } + .mx_EventTile_keyRequestInfo { + grid-area: link; + } + .mx_ReplyThread_wrapper { + grid-area: reply; + } + } + + + .mx_EventTile_readAvatars { + position: absolute; + right: -110px; + bottom: 0; + top: auto; + } + + .mx_MTextBody { + max-width: 100%; + } +} diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 95b5472530..489db615a0 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -1,6 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd -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"); you may not use this file except in compliance with the License. @@ -18,102 +18,313 @@ limitations under the License. $left-gutter: 64px; $hover-select-border: 4px; -.mx_EventTile { +.mx_EventTile:not([data-layout=bubble]) { max-width: 100%; clear: both; padding-top: 18px; font-size: $font-14px; position: relative; -} -.mx_EventTile.mx_EventTile_info { - padding-top: 1px; -} + &.mx_EventTile_info { + padding-top: 1px; + } -.mx_EventTile_avatar { - top: 14px; - left: 8px; - cursor: pointer; - user-select: none; -} + .mx_EventTile_avatar { + top: 14px; + left: 8px; + cursor: pointer; + user-select: none; + } -.mx_EventTile.mx_EventTile_info .mx_EventTile_avatar { - top: $font-6px; - left: $left-gutter; -} + &.mx_EventTile_info .mx_EventTile_avatar { + top: $font-6px; + left: $left-gutter; + } -.mx_EventTile_continuation { - padding-top: 0px !important; + &.mx_EventTile_continuation { + padding-top: 0px !important; + + &.mx_EventTile_isEditing { + padding-top: 5px !important; + margin-top: -5px; + } + } &.mx_EventTile_isEditing { - padding-top: 5px !important; - margin-top: -5px; + background-color: $header-panel-bg-color; } -} -.mx_EventTile_isEditing { - background-color: $header-panel-bg-color; -} + .mx_SenderProfile { + color: $primary-fg-color; + font-size: $font-14px; + display: inline-block; /* anti-zalgo, with overflow hidden */ + overflow: hidden; + cursor: pointer; + padding-bottom: 0px; + padding-top: 0px; + margin: 0px; + /* the next three lines, along with overflow hidden, truncate long display names */ + white-space: nowrap; + text-overflow: ellipsis; + max-width: calc(100% - $left-gutter); + } -.mx_EventTile .mx_SenderProfile { - color: $primary-fg-color; - font-size: $font-14px; - display: inline-block; /* anti-zalgo, with overflow hidden */ - overflow: hidden; - cursor: pointer; - padding-bottom: 0px; - padding-top: 0px; - margin: 0px; - /* the next three lines, along with overflow hidden, truncate long display names */ - white-space: nowrap; - text-overflow: ellipsis; - max-width: calc(100% - $left-gutter); -} + .mx_SenderProfile .mx_Flair { + opacity: 0.7; + margin-left: 5px; + display: inline-block; + vertical-align: top; + overflow: hidden; + user-select: none; -.mx_EventTile .mx_SenderProfile .mx_Flair { - opacity: 0.7; - margin-left: 5px; - display: inline-block; - vertical-align: top; - overflow: hidden; - user-select: none; + img { + vertical-align: -2px; + margin-right: 2px; + border-radius: 8px; + } + } - img { - vertical-align: -2px; - margin-right: 2px; + &.mx_EventTile_isEditing .mx_MessageTimestamp { + visibility: hidden; + } + + .mx_MessageTimestamp { + display: block; + white-space: nowrap; + left: 0px; + text-align: center; + user-select: none; + } + + &.mx_EventTile_continuation .mx_EventTile_line { + clear: both; + } + + .mx_EventTile_line, .mx_EventTile_reply { + position: relative; + padding-left: $left-gutter; border-radius: 8px; } -} -.mx_EventTile_isEditing .mx_MessageTimestamp { - visibility: hidden; -} - -.mx_EventTile .mx_MessageTimestamp { - display: block; - white-space: nowrap; - left: 0px; - text-align: center; - user-select: none; -} - -.mx_EventTile_continuation .mx_EventTile_line { - clear: both; -} - -.mx_EventTile_line, .mx_EventTile_reply { - position: relative; - padding-left: $left-gutter; - border-radius: 8px; -} - -.mx_RoomView_timeline_rr_enabled, -// on ELS we need the margin to allow interaction with the expand/collapse button which is normally in the RR gutter -.mx_EventListSummary { - .mx_EventTile_line { - /* ideally should be 100px, but 95px gives us a max thumbnail size of 800x600, which is nice */ - margin-right: 110px; + .mx_EventTile_reply { + margin-right: 10px; } + + &.mx_EventTile_selected > div > a > .mx_MessageTimestamp { + left: calc(-$hover-select-border); + } + + /* this is used for the tile for the event which is selected via the URL. + * TODO: ultimately we probably want some transition on here. + */ + &.mx_EventTile_selected > .mx_EventTile_line { + border-left: $accent-color 4px solid; + padding-left: calc($left-gutter - $hover-select-border); + background-color: $event-selected-color; + } + + &.mx_EventTile_highlight, + &.mx_EventTile_highlight .markdown-body { + color: $event-highlight-fg-color; + + .mx_EventTile_line { + background-color: $event-highlight-bg-color; + } + } + + &.mx_EventTile_info .mx_EventTile_line { + padding-left: calc($left-gutter + 18px); + } + + &.mx_EventTile_selected.mx_EventTile_info .mx_EventTile_line { + padding-left: calc($left-gutter + 18px - $hover-select-border); + } + + &.mx_EventTile:hover .mx_EventTile_line, + &.mx_EventTile.mx_EventTile_actionBarFocused .mx_EventTile_line, + &.mx_EventTile.focus-visible:focus-within .mx_EventTile_line { + background-color: $event-selected-color; + } + + .mx_EventTile_searchHighlight { + background-color: $accent-color; + color: $accent-fg-color; + border-radius: 5px; + padding-left: 2px; + padding-right: 2px; + cursor: pointer; + } + + .mx_EventTile_searchHighlight a { + background-color: $accent-color; + color: $accent-fg-color; + } + + .mx_EventTile_receiptSent, + .mx_EventTile_receiptSending { + // We don't use `position: relative` on the element because then it won't line + // up with the other read receipts + + &::before { + background-color: $tertiary-fg-color; + mask-repeat: no-repeat; + mask-position: center; + mask-size: 14px; + width: 14px; + height: 14px; + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + } + } + .mx_EventTile_receiptSent::before { + mask-image: url('$(res)/img/element-icons/circle-sent.svg'); + } + .mx_EventTile_receiptSending::before { + mask-image: url('$(res)/img/element-icons/circle-sending.svg'); + } + + &.mx_EventTile_contextual { + opacity: 0.4; + } + + .mx_EventTile_msgOption { + float: right; + text-align: right; + position: relative; + width: 90px; + + /* Hack to stop the height of this pushing the messages apart. + Replaces margin-top: -6px. This interacts better with a read + marker being in between. Content overflows. */ + height: 1px; + + margin-right: 10px; + } + + &:hover { + .mx_EventTile_line { + // To avoid bubble events being highlighted + background-color: inherit !important; + } + } + + + .mx_EventTile_msgOption a { + text-decoration: none; + } + + /* all the overflow-y: hidden; are to trap Zalgos - + but they introduce an implicit overflow-x: auto. + so make that explicitly hidden too to avoid random + horizontal scrollbars occasionally appearing, like in + https://github.com/vector-im/vector-web/issues/1154 + */ + .mx_EventTile_content { + display: block; + overflow-y: hidden; + overflow-x: hidden; + margin-right: 34px; + } + + /* De-zalgoing */ + .mx_EventTile_body { + overflow-y: hidden; + } + + /* Spoiler stuff */ + .mx_EventTile_spoiler { + cursor: pointer; + } + + .mx_EventTile_spoiler_reason { + color: $event-timestamp-color; + font-size: $font-11px; + } + + .mx_EventTile_spoiler_content { + filter: blur(5px) saturate(0.1) sepia(1); + transition-duration: 0.5s; + } + + .mx_EventTile_spoiler.visible > .mx_EventTile_spoiler_content { + filter: none; + } + + &:hover.mx_EventTile_verified .mx_EventTile_line, + &:hover.mx_EventTile_unverified .mx_EventTile_line, + &:hover.mx_EventTile_unknown .mx_EventTile_line { + padding-left: calc($left-gutter - $hover-select-border); + } + + &:hover.mx_EventTile_verified .mx_EventTile_line { + border-left: $e2e-verified-color $EventTile_e2e_state_indicator_width solid; + } + + &:hover.mx_EventTile_unverified .mx_EventTile_line { + border-left: $e2e-unverified-color $EventTile_e2e_state_indicator_width solid; + } + + &:hover.mx_EventTile_unknown .mx_EventTile_line { + border-left: $e2e-unknown-color $EventTile_e2e_state_indicator_width solid; + } + + &:hover.mx_EventTile_verified.mx_EventTile_info .mx_EventTile_line, + &:hover.mx_EventTile_unverified.mx_EventTile_info .mx_EventTile_line, + &:hover.mx_EventTile_unknown.mx_EventTile_info .mx_EventTile_line { + padding-left: calc($left-gutter + 18px - $hover-select-border); + } + + /* End to end encryption stuff */ + &:hover .mx_EventTile_e2eIcon { + opacity: 1; + } + + // Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies) + &:hover.mx_EventTile_verified .mx_EventTile_line > a > .mx_MessageTimestamp, + &:hover.mx_EventTile_unverified .mx_EventTile_line > a > .mx_MessageTimestamp, + &:hover.mx_EventTile_unknown .mx_EventTile_line > a > .mx_MessageTimestamp { + left: calc(-$hover-select-border); + } + + // Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies) + &:hover.mx_EventTile_verified .mx_EventTile_line > .mx_EventTile_e2eIcon, + &:hover.mx_EventTile_unverified .mx_EventTile_line > .mx_EventTile_e2eIcon, + &:hover.mx_EventTile_unknown .mx_EventTile_line > .mx_EventTile_e2eIcon { + display: block; + left: 41px; + } + + .mx_MImageBody { + margin-right: 34px; + } + + .mx_EventTile_e2eIcon { + position: absolute; + top: 6px; + left: 44px; + bottom: 0; + right: 0; + } + + .mx_ReactionsRow { + margin: 0; + padding: 6px 60px; + } +} + +.mx_RoomView_timeline_rr_enabled { + + .mx_EventTile:not([data-layout=bubble]) { + .mx_EventTile_line { + /* ideally should be 100px, but 95px gives us a max thumbnail size of 800x600, which is nice */ + margin-right: 110px; + } + } + + // on ELS we need the margin to allow interaction with the expand/collapse button which is normally in the RR gutter } .mx_EventTile_bubbleContainer { @@ -130,128 +341,6 @@ $hover-select-border: 4px; .mx_EventTile_msgOption { grid-column: 2; } - - &:hover { - .mx_EventTile_line { - // To avoid bubble events being highlighted - background-color: inherit !important; - } - } -} - -.mx_EventTile_reply { - margin-right: 10px; -} - -/* HACK to override line-height which is already marked important elsewhere */ -.mx_EventTile_bigEmoji.mx_EventTile_bigEmoji { - font-size: 48px !important; - line-height: 57px !important; -} - -.mx_EventTile_selected > div > a > .mx_MessageTimestamp { - left: calc(-$hover-select-border); -} - -.mx_EventTile:hover .mx_MessageActionBar, -.mx_EventTile.mx_EventTile_actionBarFocused .mx_MessageActionBar, -[data-whatinput='keyboard'] .mx_EventTile:focus-within .mx_MessageActionBar, -.mx_EventTile.focus-visible:focus-within .mx_MessageActionBar { - visibility: visible; -} - -/* this is used for the tile for the event which is selected via the URL. - * TODO: ultimately we probably want some transition on here. - */ -.mx_EventTile_selected > .mx_EventTile_line { - border-left: $accent-color 4px solid; - padding-left: calc($left-gutter - $hover-select-border); - background-color: $event-selected-color; -} - -.mx_EventTile_highlight, -.mx_EventTile_highlight .markdown-body { - color: $event-highlight-fg-color; - - .mx_EventTile_line { - background-color: $event-highlight-bg-color; - } -} - -.mx_EventTile_info .mx_EventTile_line { - padding-left: calc($left-gutter + 18px); -} - -.mx_EventTile_selected.mx_EventTile_info .mx_EventTile_line { - padding-left: calc($left-gutter + 18px - $hover-select-border); -} - -.mx_EventTile:hover .mx_EventTile_line, -.mx_EventTile.mx_EventTile_actionBarFocused .mx_EventTile_line, -.mx_EventTile.focus-visible:focus-within .mx_EventTile_line { - background-color: $event-selected-color; -} - -.mx_EventTile_searchHighlight { - background-color: $accent-color; - color: $accent-fg-color; - border-radius: 5px; - padding-left: 2px; - padding-right: 2px; - cursor: pointer; -} - -.mx_EventTile_searchHighlight a { - background-color: $accent-color; - color: $accent-fg-color; -} - -.mx_EventTile_receiptSent, -.mx_EventTile_receiptSending { - // We don't use `position: relative` on the element because then it won't line - // up with the other read receipts - - &::before { - background-color: $tertiary-fg-color; - mask-repeat: no-repeat; - mask-position: center; - mask-size: 14px; - width: 14px; - height: 14px; - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - } -} -.mx_EventTile_receiptSent::before { - mask-image: url('$(res)/img/element-icons/circle-sent.svg'); -} -.mx_EventTile_receiptSending::before { - mask-image: url('$(res)/img/element-icons/circle-sending.svg'); -} - -.mx_EventTile_contextual { - opacity: 0.4; -} - -.mx_EventTile_msgOption { - float: right; - text-align: right; - position: relative; - width: 90px; - - /* Hack to stop the height of this pushing the messages apart. - Replaces margin-top: -6px. This interacts better with a read - marker being in between. Content overflows. */ - height: 1px; - - margin-right: 10px; -} - -.mx_EventTile_msgOption a { - text-decoration: none; } .mx_EventTile_readAvatars { @@ -284,52 +373,27 @@ $hover-select-border: 4px; position: absolute; } -/* all the overflow-y: hidden; are to trap Zalgos - - but they introduce an implicit overflow-x: auto. - so make that explicitly hidden too to avoid random - horizontal scrollbars occasionally appearing, like in - https://github.com/vector-im/vector-web/issues/1154 - */ -.mx_EventTile_content { - display: block; - overflow-y: hidden; - overflow-x: hidden; - margin-right: 34px; +/* HACK to override line-height which is already marked important elsewhere */ +.mx_EventTile_bigEmoji.mx_EventTile_bigEmoji { + font-size: 48px !important; + line-height: 57px !important; } -/* De-zalgoing */ -.mx_EventTile_body { - overflow-y: hidden; -} - -/* Spoiler stuff */ -.mx_EventTile_spoiler { +.mx_EventTile_content .mx_EventTile_edited { + user-select: none; + font-size: $font-12px; + color: $roomtopic-color; + display: inline-block; + margin-left: 9px; cursor: pointer; } -.mx_EventTile_spoiler_reason { - color: $event-timestamp-color; - font-size: $font-11px; -} - -.mx_EventTile_spoiler_content { - filter: blur(5px) saturate(0.1) sepia(1); - transition-duration: 0.5s; -} - -.mx_EventTile_spoiler.visible > .mx_EventTile_spoiler_content { - filter: none; -} .mx_EventTile_e2eIcon { - position: absolute; - top: 6px; - left: 44px; + position: relative; width: 14px; height: 14px; display: block; - bottom: 0; - right: 0; opacity: 0.2; background-repeat: no-repeat; background-size: contain; @@ -388,87 +452,6 @@ $hover-select-border: 4px; opacity: 1; } -.mx_EventTile_keyRequestInfo { - font-size: $font-12px; -} - -.mx_EventTile_keyRequestInfo_text { - opacity: 0.5; -} - -.mx_EventTile_keyRequestInfo_text a { - color: $primary-fg-color; - text-decoration: underline; - cursor: pointer; -} - -.mx_EventTile_keyRequestInfo_tooltip_contents p { - text-align: auto; - margin-left: 3px; - margin-right: 3px; -} - -.mx_EventTile_keyRequestInfo_tooltip_contents p:first-child { - margin-top: 0px; -} - -.mx_EventTile_keyRequestInfo_tooltip_contents p:last-child { - margin-bottom: 0px; -} - -.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line, -.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line, -.mx_EventTile:hover.mx_EventTile_unknown .mx_EventTile_line { - padding-left: calc($left-gutter - $hover-select-border); -} - -.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line { - border-left: $e2e-verified-color $EventTile_e2e_state_indicator_width solid; -} - -.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line { - border-left: $e2e-unverified-color $EventTile_e2e_state_indicator_width solid; -} - -.mx_EventTile:hover.mx_EventTile_unknown .mx_EventTile_line { - border-left: $e2e-unknown-color $EventTile_e2e_state_indicator_width solid; -} - -.mx_EventTile:hover.mx_EventTile_verified.mx_EventTile_info .mx_EventTile_line, -.mx_EventTile:hover.mx_EventTile_unverified.mx_EventTile_info .mx_EventTile_line, -.mx_EventTile:hover.mx_EventTile_unknown.mx_EventTile_info .mx_EventTile_line { - padding-left: calc($left-gutter + 18px - $hover-select-border); -} - -/* End to end encryption stuff */ -.mx_EventTile:hover .mx_EventTile_e2eIcon { - opacity: 1; -} - -// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies) -.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > a > .mx_MessageTimestamp, -.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > a > .mx_MessageTimestamp, -.mx_EventTile:hover.mx_EventTile_unknown .mx_EventTile_line > a > .mx_MessageTimestamp { - left: calc(-$hover-select-border); -} - -// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies) -.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > .mx_EventTile_e2eIcon, -.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > .mx_EventTile_e2eIcon, -.mx_EventTile:hover.mx_EventTile_unknown .mx_EventTile_line > .mx_EventTile_e2eIcon { - display: block; - left: 41px; -} - -.mx_EventTile_content .mx_EventTile_edited { - user-select: none; - font-size: $font-12px; - color: $roomtopic-color; - display: inline-block; - margin-left: 9px; - cursor: pointer; -} - /* Various markdown overrides */ .mx_EventTile_body pre { @@ -602,6 +585,35 @@ $hover-select-border: 4px; /* end of overrides */ + +.mx_EventTile_keyRequestInfo { + font-size: $font-12px; +} + +.mx_EventTile_keyRequestInfo_text { + opacity: 0.5; +} + +.mx_EventTile_keyRequestInfo_text a { + color: $primary-fg-color; + text-decoration: underline; + cursor: pointer; +} + +.mx_EventTile_keyRequestInfo_tooltip_contents p { + text-align: auto; + margin-left: 3px; + margin-right: 3px; +} + +.mx_EventTile_keyRequestInfo_tooltip_contents p:first-child { + margin-top: 0px; +} + +.mx_EventTile_keyRequestInfo_tooltip_contents p:last-child { + margin-bottom: 0px; +} + .mx_EventTile_tileError { color: red; text-align: center; @@ -622,6 +634,13 @@ $hover-select-border: 4px; } } +.mx_EventTile:hover .mx_MessageActionBar, +.mx_EventTile.mx_EventTile_actionBarFocused .mx_MessageActionBar, +[data-whatinput='keyboard'] .mx_EventTile:focus-within .mx_MessageActionBar, +.mx_EventTile.focus-visible:focus-within .mx_MessageActionBar { + visibility: visible; +} + @media only screen and (max-width: 480px) { .mx_EventTile_line, .mx_EventTile_reply { padding-left: 0; diff --git a/res/css/views/rooms/_ReplyPreview.scss b/res/css/views/rooms/_ReplyPreview.scss index c1fe1d9a8b..60feb39d11 100644 --- a/res/css/views/rooms/_ReplyPreview.scss +++ b/res/css/views/rooms/_ReplyPreview.scss @@ -22,33 +22,34 @@ limitations under the License. max-height: 50vh; overflow: auto; box-shadow: 0px -16px 32px $composer-shadow-color; + + .mx_ReplyPreview_section { + border-bottom: 1px solid $primary-hairline-color; + + .mx_ReplyPreview_header { + margin: 8px; + color: $primary-fg-color; + font-weight: 400; + opacity: 0.4; + } + + .mx_ReplyPreview_tile { + margin: 0 8px; + } + + .mx_ReplyPreview_title { + float: left; + } + + .mx_ReplyPreview_cancel { + float: right; + cursor: pointer; + display: flex; + } + + .mx_ReplyPreview_clear { + clear: both; + } + } } -.mx_ReplyPreview_section { - border-bottom: 1px solid $primary-hairline-color; -} - -.mx_ReplyPreview_header { - margin: 8px; - color: $primary-fg-color; - font-weight: 400; - opacity: 0.4; -} - -.mx_ReplyPreview_tile { - margin: 0 8px; -} - -.mx_ReplyPreview_title { - float: left; -} - -.mx_ReplyPreview_cancel { - float: right; - cursor: pointer; - display: flex; -} - -.mx_ReplyPreview_clear { - clear: both; -} diff --git a/res/css/views/rooms/_ReplyTile.scss b/res/css/views/rooms/_ReplyTile.scss index c8f76ee995..f3e204e415 100644 --- a/res/css/views/rooms/_ReplyTile.scss +++ b/res/css/views/rooms/_ReplyTile.scss @@ -15,10 +15,9 @@ limitations under the License. */ .mx_ReplyTile { - padding-top: 2px; - padding-bottom: 2px; - font-size: $font-14px; position: relative; + padding: 2px 0; + font-size: $font-14px; line-height: $font-16px; &.mx_ReplyTile_audio .mx_MFileBody_info_icon::before { @@ -38,86 +37,83 @@ limitations under the License. display: none; } } -} -.mx_ReplyTile > a { - display: flex; - flex-direction: column; - text-decoration: none; - color: $primary-fg-color; -} - -.mx_ReplyTile .mx_RedactedBody { - padding: 4px 0 2px 20px; - - &::before { - height: 13px; - width: 13px; - top: 5px; - } -} - -// We do reply size limiting with CSS to avoid duplicating the TextualBody component. -.mx_ReplyTile .mx_EventTile_content { - $reply-lines: 2; - $line-height: $font-22px; - - pointer-events: none; - - text-overflow: ellipsis; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: $reply-lines; - line-height: $line-height; - - .mx_EventTile_body.mx_EventTile_bigEmoji { - line-height: $line-height !important; - // Override the big emoji override - font-size: $font-14px !important; + > a { + display: flex; + flex-direction: column; + text-decoration: none; + color: $primary-fg-color; } - // Hide line numbers - .mx_EventTile_lineNumbers { - display: none; + .mx_RedactedBody { + padding: 4px 0 2px 20px; + + &::before { + height: 13px; + width: 13px; + top: 5px; + } } - // Hack to cut content in
tags too
- .mx_EventTile_pre_container > pre {
- overflow: hidden;
+ // We do reply size limiting with CSS to avoid duplicating the TextualBody component.
+ .mx_EventTile_content {
+ $reply-lines: 2;
+ $line-height: $font-22px;
+
+ pointer-events: none;
+
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: $reply-lines;
- padding: 4px;
+ line-height: $line-height;
+
+ .mx_EventTile_body.mx_EventTile_bigEmoji {
+ line-height: $line-height !important;
+ font-size: $font-14px !important; // Override the big emoji override
+ }
+
+ // Hide line numbers
+ .mx_EventTile_lineNumbers {
+ display: none;
+ }
+
+ // Hack to cut content in tags too
+ .mx_EventTile_pre_container > pre {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: $reply-lines;
+ padding: 4px;
+ }
+
+ .markdown-body blockquote,
+ .markdown-body dl,
+ .markdown-body ol,
+ .markdown-body p,
+ .markdown-body pre,
+ .markdown-body table,
+ .markdown-body ul {
+ margin-bottom: 4px;
+ }
}
- .markdown-body blockquote,
- .markdown-body dl,
- .markdown-body ol,
- .markdown-body p,
- .markdown-body pre,
- .markdown-body table,
- .markdown-body ul {
- margin-bottom: 4px;
+ &.mx_ReplyTile_info {
+ padding-top: 0;
+ }
+
+ .mx_SenderProfile {
+ font-size: $font-14px;
+ line-height: $font-17px;
+
+ display: inline-block; // anti-zalgo, with overflow hidden
+ padding: 0;
+ margin: 0;
+
+ // truncate long display names
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
}
}
-
-.mx_ReplyTile.mx_ReplyTile_info {
- padding-top: 0;
-}
-
-.mx_ReplyTile .mx_SenderProfile {
- color: $primary-fg-color;
- font-size: $font-14px;
- display: inline-block; /* anti-zalgo, with overflow hidden */
- overflow: hidden;
- cursor: pointer;
- padding-left: 0; /* left gutter */
- padding-bottom: 0;
- padding-top: 0;
- margin: 0;
- line-height: $font-17px;
- /* the next three lines, along with overflow hidden, truncate long display names */
- white-space: nowrap;
- text-overflow: ellipsis;
-}
diff --git a/res/themes/dark/css/_dark.scss b/res/themes/dark/css/_dark.scss
index 74b33fbd02..2a4ebff034 100644
--- a/res/themes/dark/css/_dark.scss
+++ b/res/themes/dark/css/_dark.scss
@@ -227,6 +227,13 @@ $groupFilterPanel-background-blur-amount: 30px;
$composer-shadow-color: rgba(0, 0, 0, 0.28);
+// Bubble tiles
+$eventbubble-self-bg: #143A34;
+$eventbubble-others-bg: #394049;
+$eventbubble-bg-hover: #433C23;
+$eventbubble-avatar-outline: $bg-color;
+$eventbubble-reply-color: #C1C6CD;
+
// ***** Mixins! *****
@define-mixin mx_DialogButton {
diff --git a/res/themes/legacy-light/css/_legacy-light.scss b/res/themes/legacy-light/css/_legacy-light.scss
index c7debcdabe..f349a804a8 100644
--- a/res/themes/legacy-light/css/_legacy-light.scss
+++ b/res/themes/legacy-light/css/_legacy-light.scss
@@ -347,6 +347,13 @@ $appearance-tab-border-color: $input-darker-bg-color;
$composer-shadow-color: tranparent;
+// Bubble tiles
+$eventbubble-self-bg: #F8FDFC;
+$eventbubble-others-bg: #F7F8F9;
+$eventbubble-bg-hover: rgb(242, 242, 242);
+$eventbubble-avatar-outline: #fff;
+$eventbubble-reply-color: #C1C6CD;
+
// ***** Mixins! *****
@define-mixin mx_DialogButton {
diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss
index 7e958c2af6..ef5f4d8c86 100644
--- a/res/themes/light/css/_light.scss
+++ b/res/themes/light/css/_light.scss
@@ -349,6 +349,13 @@ $groupFilterPanel-background-blur-amount: 20px;
$composer-shadow-color: rgba(0, 0, 0, 0.04);
+// Bubble tiles
+$eventbubble-self-bg: #F8FDFC;
+$eventbubble-others-bg: #F7F8F9;
+$eventbubble-bg-hover: #FEFCF5;
+$eventbubble-avatar-outline: $primary-bg-color;
+$eventbubble-reply-color: #C1C6CD;
+
// ***** Mixins! *****
@define-mixin mx_DialogButton {
diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts
index 7192eb81cc..051e865464 100644
--- a/src/@types/global.d.ts
+++ b/src/@types/global.d.ts
@@ -50,6 +50,8 @@ import UIStore from "../stores/UIStore";
import { SetupEncryptionStore } from "../stores/SetupEncryptionStore";
import { RoomScrollStateStore } from "../stores/RoomScrollStateStore";
+/* eslint-disable @typescript-eslint/naming-convention */
+
declare global {
interface Window {
matrixChat: ReturnType;
@@ -186,3 +188,5 @@ declare global {
}
);
}
+
+/* eslint-enable @typescript-eslint/naming-convention */
diff --git a/src/ActiveRoomObserver.ts b/src/ActiveRoomObserver.ts
index 1126dc9496..0be49a24ea 100644
--- a/src/ActiveRoomObserver.ts
+++ b/src/ActiveRoomObserver.ts
@@ -15,6 +15,7 @@ limitations under the License.
*/
import RoomViewStore from './stores/RoomViewStore';
+import { EventSubscription } from 'fbemitter';
type Listener = (isActive: boolean) => void;
@@ -30,7 +31,7 @@ type Listener = (isActive: boolean) => void;
export class ActiveRoomObserver {
private listeners: {[key: string]: Listener[]} = {};
private _activeRoomId = RoomViewStore.getRoomId();
- private readonly roomStoreToken: string;
+ private readonly roomStoreToken: EventSubscription;
constructor() {
// TODO: We could self-destruct when the last listener goes away, or at least stop listening.
diff --git a/src/Analytics.tsx b/src/Analytics.tsx
index ce8287de56..fc4664039f 100644
--- a/src/Analytics.tsx
+++ b/src/Analytics.tsx
@@ -270,7 +270,7 @@ export class Analytics {
localStorage.removeItem(LAST_VISIT_TS_KEY);
}
- private async _track(data: IData) {
+ private async track(data: IData) {
if (this.disabled) return;
const now = new Date();
@@ -304,7 +304,7 @@ export class Analytics {
}
public ping() {
- this._track({
+ this.track({
ping: "1",
});
localStorage.setItem(LAST_VISIT_TS_KEY, String(new Date().getTime())); // update last visit ts
@@ -324,14 +324,14 @@ export class Analytics {
// But continue anyway because we still want to track the change
}
- this._track({
+ this.track({
gt_ms: String(generationTimeMs),
});
}
public trackEvent(category: string, action: string, name?: string, value?: string) {
if (this.disabled) return;
- this._track({
+ this.track({
e_c: category,
e_a: action,
e_n: name,
@@ -395,17 +395,17 @@ export class Analytics {
Modal.createTrackedDialog('Analytics Details', '', ErrorDialog, {
title: _t('Analytics'),
description:
- {_t('The information being sent to us to help make %(brand)s better includes:', {
+ { _t('The information being sent to us to help make %(brand)s better includes:', {
brand: SdkConfig.get().brand,
- })}
+ }) }
{ rows.map((row) =>
- {_t(
+ { _t(
customVariables[row[0]].expl,
customVariables[row[0]].getTextVariables ?
customVariables[row[0]].getTextVariables() :
null,
- )}
+ ) }
{ row[1] !== undefined && { row[1] } }
) }
{ otherVariables.map((item, index) =>
diff --git a/src/Avatar.ts b/src/Avatar.ts
index 198d4162a0..c0ecb19eaf 100644
--- a/src/Avatar.ts
+++ b/src/Avatar.ts
@@ -18,6 +18,7 @@ import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { User } from "matrix-js-sdk/src/models/user";
import { Room } from "matrix-js-sdk/src/models/room";
import { ResizeMethod } from "matrix-js-sdk/src/@types/partials";
+import { split } from "lodash";
import DMRoomMap from './utils/DMRoomMap';
import { mediaFromMxc } from "./customisations/Media";
@@ -122,27 +123,13 @@ export function getInitialLetter(name: string): string {
return undefined;
}
- let idx = 0;
const initial = name[0];
if ((initial === '@' || initial === '#' || initial === '+') && name[1]) {
- idx++;
+ name = name.substring(1);
}
- // string.codePointAt(0) would do this, but that isn't supported by
- // some browsers (notably PhantomJS).
- let chars = 1;
- const first = name.charCodeAt(idx);
-
- // check if it’s the start of a surrogate pair
- if (first >= 0xD800 && first <= 0xDBFF && name[idx+1]) {
- const second = name.charCodeAt(idx+1);
- if (second >= 0xDC00 && second <= 0xDFFF) {
- chars++;
- }
- }
-
- const firstChar = name.substring(idx, idx+chars);
- return firstChar.toUpperCase();
+ // rely on the grapheme cluster splitter in lodash so that we don't break apart compound emojis
+ return split(name, "", 1)[0].toUpperCase();
}
export function avatarUrlForRoom(room: Room, width: number, height: number, resizeMethod?: ResizeMethod) {
diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx
index 942e259b67..e7ba1aa9fb 100644
--- a/src/CallHandler.tsx
+++ b/src/CallHandler.tsx
@@ -656,23 +656,23 @@ export default class CallHandler extends EventEmitter {
private showICEFallbackPrompt() {
const cli = MatrixClientPeg.get();
- const code = sub => {sub};
+ const code = sub => { sub };
Modal.createTrackedDialog('No TURN servers', '', QuestionDialog, {
title: _t("Call failed due to misconfigured server"),
description:
- {_t(
+
{ _t(
"Please ask the administrator of your homeserver " +
"(%(homeserverDomain)s) to configure a TURN server in " +
"order for calls to work reliably.",
{ homeserverDomain: cli.getDomain() }, { code },
- )}
- {_t(
+ ) }
+ { _t(
"Alternatively, you can try to use the public server at " +
"turn.matrix.org, but this will not be as reliable, and " +
"it will share your IP address with that server. You can also manage " +
"this in Settings.",
null, { code },
- )}
+ ) }
,
button: _t('Try using turn.matrix.org'),
cancelButton: _t('OK'),
@@ -690,19 +690,19 @@ export default class CallHandler extends EventEmitter {
if (call.type === CallType.Voice) {
title = _t("Unable to access microphone");
description =
- {_t(
+ { _t(
"Call failed because microphone could not be accessed. " +
"Check that a microphone is plugged in and set up correctly.",
- )}
+ ) }
;
} else if (call.type === CallType.Video) {
title = _t("Unable to access webcam / microphone");
description =
- {_t("Call failed because webcam or microphone could not be accessed. Check that:")}
+ { _t("Call failed because webcam or microphone could not be accessed. Check that:") }
- - {_t("A microphone and webcam are plugged in and set up correctly")}
- - {_t("Permission is granted to use the webcam")}
- - {_t("No other application is using the webcam")}
+ - { _t("A microphone and webcam are plugged in and set up correctly") }
+ - { _t("Permission is granted to use the webcam") }
+ - { _t("No other application is using the webcam") }
;
}
diff --git a/src/ContentMessages.tsx b/src/ContentMessages.tsx
index 0c65a7bd35..c5bcb226ff 100644
--- a/src/ContentMessages.tsx
+++ b/src/ContentMessages.tsx
@@ -425,10 +425,10 @@ export default class ContentMessages {
const { finished } = Modal.createTrackedDialog<[boolean]>('Upload Reply Warning', '', QuestionDialog, {
title: _t('Replying With Files'),
description: (
- {_t(
+ { _t(
'At this time it is not possible to reply with a file. ' +
'Would you like to upload this file without replying?',
- )}
+ ) }
),
hasCancelButton: true,
button: _t("Continue"),
diff --git a/src/DeviceListener.ts b/src/DeviceListener.ts
index d033063677..51c624e3c3 100644
--- a/src/DeviceListener.ts
+++ b/src/DeviceListener.ts
@@ -33,6 +33,7 @@ import { isSecretStorageBeingAccessed, accessSecretStorage } from "./SecurityMan
import { isSecureBackupRequired } from './utils/WellKnownUtils';
import { isLoggedIn } from './components/structures/MatrixChat';
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
+import { ActionPayload } from "./dispatcher/payloads";
const KEY_BACKUP_POLL_INTERVAL = 5 * 60 * 1000;
@@ -58,28 +59,28 @@ export default class DeviceListener {
}
start() {
- MatrixClientPeg.get().on('crypto.willUpdateDevices', this._onWillUpdateDevices);
- MatrixClientPeg.get().on('crypto.devicesUpdated', this._onDevicesUpdated);
- MatrixClientPeg.get().on('deviceVerificationChanged', this._onDeviceVerificationChanged);
- MatrixClientPeg.get().on('userTrustStatusChanged', this._onUserTrustStatusChanged);
- MatrixClientPeg.get().on('crossSigning.keysChanged', this._onCrossSingingKeysChanged);
- MatrixClientPeg.get().on('accountData', this._onAccountData);
- MatrixClientPeg.get().on('sync', this._onSync);
- MatrixClientPeg.get().on('RoomState.events', this._onRoomStateEvents);
- this.dispatcherRef = dis.register(this._onAction);
- this._recheck();
+ MatrixClientPeg.get().on('crypto.willUpdateDevices', this.onWillUpdateDevices);
+ MatrixClientPeg.get().on('crypto.devicesUpdated', this.onDevicesUpdated);
+ MatrixClientPeg.get().on('deviceVerificationChanged', this.onDeviceVerificationChanged);
+ MatrixClientPeg.get().on('userTrustStatusChanged', this.onUserTrustStatusChanged);
+ MatrixClientPeg.get().on('crossSigning.keysChanged', this.onCrossSingingKeysChanged);
+ MatrixClientPeg.get().on('accountData', this.onAccountData);
+ MatrixClientPeg.get().on('sync', this.onSync);
+ MatrixClientPeg.get().on('RoomState.events', this.onRoomStateEvents);
+ this.dispatcherRef = dis.register(this.onAction);
+ this.recheck();
}
stop() {
if (MatrixClientPeg.get()) {
- MatrixClientPeg.get().removeListener('crypto.willUpdateDevices', this._onWillUpdateDevices);
- MatrixClientPeg.get().removeListener('crypto.devicesUpdated', this._onDevicesUpdated);
- MatrixClientPeg.get().removeListener('deviceVerificationChanged', this._onDeviceVerificationChanged);
- MatrixClientPeg.get().removeListener('userTrustStatusChanged', this._onUserTrustStatusChanged);
- MatrixClientPeg.get().removeListener('crossSigning.keysChanged', this._onCrossSingingKeysChanged);
- MatrixClientPeg.get().removeListener('accountData', this._onAccountData);
- MatrixClientPeg.get().removeListener('sync', this._onSync);
- MatrixClientPeg.get().removeListener('RoomState.events', this._onRoomStateEvents);
+ MatrixClientPeg.get().removeListener('crypto.willUpdateDevices', this.onWillUpdateDevices);
+ MatrixClientPeg.get().removeListener('crypto.devicesUpdated', this.onDevicesUpdated);
+ MatrixClientPeg.get().removeListener('deviceVerificationChanged', this.onDeviceVerificationChanged);
+ MatrixClientPeg.get().removeListener('userTrustStatusChanged', this.onUserTrustStatusChanged);
+ MatrixClientPeg.get().removeListener('crossSigning.keysChanged', this.onCrossSingingKeysChanged);
+ MatrixClientPeg.get().removeListener('accountData', this.onAccountData);
+ MatrixClientPeg.get().removeListener('sync', this.onSync);
+ MatrixClientPeg.get().removeListener('RoomState.events', this.onRoomStateEvents);
}
if (this.dispatcherRef) {
dis.unregister(this.dispatcherRef);
@@ -103,15 +104,15 @@ export default class DeviceListener {
this.dismissed.add(d);
}
- this._recheck();
+ this.recheck();
}
dismissEncryptionSetup() {
this.dismissedThisDeviceToast = true;
- this._recheck();
+ this.recheck();
}
- _ensureDeviceIdsAtStartPopulated() {
+ private ensureDeviceIdsAtStartPopulated() {
if (this.ourDeviceIdsAtStart === null) {
const cli = MatrixClientPeg.get();
this.ourDeviceIdsAtStart = new Set(
@@ -120,39 +121,39 @@ export default class DeviceListener {
}
}
- _onWillUpdateDevices = async (users: string[], initialFetch?: boolean) => {
+ private onWillUpdateDevices = async (users: string[], initialFetch?: boolean) => {
// If we didn't know about *any* devices before (ie. it's fresh login),
// then they are all pre-existing devices, so ignore this and set the
// devicesAtStart list to the devices that we see after the fetch.
if (initialFetch) return;
const myUserId = MatrixClientPeg.get().getUserId();
- if (users.includes(myUserId)) this._ensureDeviceIdsAtStartPopulated();
+ if (users.includes(myUserId)) this.ensureDeviceIdsAtStartPopulated();
// No need to do a recheck here: we just need to get a snapshot of our devices
// before we download any new ones.
};
- _onDevicesUpdated = (users: string[]) => {
+ private onDevicesUpdated = (users: string[]) => {
if (!users.includes(MatrixClientPeg.get().getUserId())) return;
- this._recheck();
+ this.recheck();
};
- _onDeviceVerificationChanged = (userId: string) => {
+ private onDeviceVerificationChanged = (userId: string) => {
if (userId !== MatrixClientPeg.get().getUserId()) return;
- this._recheck();
+ this.recheck();
};
- _onUserTrustStatusChanged = (userId: string) => {
+ private onUserTrustStatusChanged = (userId: string) => {
if (userId !== MatrixClientPeg.get().getUserId()) return;
- this._recheck();
+ this.recheck();
};
- _onCrossSingingKeysChanged = () => {
- this._recheck();
+ private onCrossSingingKeysChanged = () => {
+ this.recheck();
};
- _onAccountData = (ev) => {
+ private onAccountData = (ev: MatrixEvent) => {
// User may have:
// * migrated SSSS to symmetric
// * uploaded keys to secret storage
@@ -163,32 +164,32 @@ export default class DeviceListener {
ev.getType().startsWith('m.cross_signing.') ||
ev.getType() === 'm.megolm_backup.v1'
) {
- this._recheck();
+ this.recheck();
}
};
- _onSync = (state, prevState) => {
- if (state === 'PREPARED' && prevState === null) this._recheck();
+ private onSync = (state, prevState) => {
+ if (state === 'PREPARED' && prevState === null) this.recheck();
};
- _onRoomStateEvents = (ev: MatrixEvent) => {
+ private onRoomStateEvents = (ev: MatrixEvent) => {
if (ev.getType() !== "m.room.encryption") {
return;
}
// If a room changes to encrypted, re-check as it may be our first
// encrypted room. This also catches encrypted room creation as well.
- this._recheck();
+ this.recheck();
};
- _onAction = ({ action }) => {
+ private onAction = ({ action }: ActionPayload) => {
if (action !== "on_logged_in") return;
- this._recheck();
+ this.recheck();
};
// The server doesn't tell us when key backup is set up, so we poll
// & cache the result
- async _getKeyBackupInfo() {
+ private async getKeyBackupInfo() {
const now = (new Date()).getTime();
if (!this.keyBackupInfo || this.keyBackupFetchedAt < now - KEY_BACKUP_POLL_INTERVAL) {
this.keyBackupInfo = await MatrixClientPeg.get().getKeyBackupVersion();
@@ -206,7 +207,7 @@ export default class DeviceListener {
return cli && cli.getRooms().some(r => cli.isRoomEncrypted(r.roomId));
}
- async _recheck() {
+ private async recheck() {
const cli = MatrixClientPeg.get();
if (!await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")) return;
@@ -235,7 +236,7 @@ export default class DeviceListener {
// Cross-signing on account but this device doesn't trust the master key (verify this session)
showSetupEncryptionToast(SetupKind.VERIFY_THIS_SESSION);
} else {
- const backupInfo = await this._getKeyBackupInfo();
+ const backupInfo = await this.getKeyBackupInfo();
if (backupInfo) {
// No cross-signing on account but key backup available (upgrade encryption)
showSetupEncryptionToast(SetupKind.UPGRADE_ENCRYPTION);
@@ -256,7 +257,7 @@ export default class DeviceListener {
// This needs to be done after awaiting on downloadKeys() above, so
// we make sure we get the devices after the fetch is done.
- this._ensureDeviceIdsAtStartPopulated();
+ this.ensureDeviceIdsAtStartPopulated();
// Unverified devices that were there last time the app ran
// (technically could just be a boolean: we don't actually
diff --git a/src/IdentityAuthClient.js b/src/IdentityAuthClient.js
index 447c5edd30..e91e1d72cf 100644
--- a/src/IdentityAuthClient.js
+++ b/src/IdentityAuthClient.js
@@ -149,17 +149,17 @@ export default class IdentityAuthClient {
title: _t("Identity server has no terms of service"),
description: (
- {_t(
+
{ _t(
"This action requires accessing the default identity server " +
" to validate an email address or phone number, " +
"but the server does not have any terms of service.", {},
{
- server: () => {abbreviateUrl(identityServerUrl)},
+ server: () => { abbreviateUrl(identityServerUrl) },
},
- )}
- {_t(
+ ) }
+ { _t(
"Only continue if you trust the owner of the server.",
- )}
+ ) }
),
button: _t("Trust"),
diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts
index e9364b1b47..f43351aab2 100644
--- a/src/MatrixClientPeg.ts
+++ b/src/MatrixClientPeg.ts
@@ -105,7 +105,7 @@ export interface IMatrixClientPeg {
* This module provides a singleton instance of this class so the 'current'
* Matrix Client object is available easily.
*/
-class _MatrixClientPeg implements IMatrixClientPeg {
+class MatrixClientPegClass implements IMatrixClientPeg {
// These are the default options used when when the
// client is started in 'start'. These can be altered
// at any time up to after the 'will_start_client'
@@ -300,7 +300,7 @@ class _MatrixClientPeg implements IMatrixClientPeg {
}
if (!window.mxMatrixClientPeg) {
- window.mxMatrixClientPeg = new _MatrixClientPeg();
+ window.mxMatrixClientPeg = new MatrixClientPegClass();
}
export const MatrixClientPeg = window.mxMatrixClientPeg;
diff --git a/src/Modal.tsx b/src/Modal.tsx
index 55fc871d67..1e84078ddb 100644
--- a/src/Modal.tsx
+++ b/src/Modal.tsx
@@ -378,7 +378,7 @@ export class ModalManager {
const dialog = (
- {modal.elem}
+ { modal.elem }
diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx
index 7753ff6f75..9f5ac83a56 100644
--- a/src/SlashCommands.tsx
+++ b/src/SlashCommands.tsx
@@ -480,14 +480,14 @@ export const Commands = [
'Identity server',
QuestionDialog, {
title: _t("Use an identity server"),
- description: {_t(
+ description:
{ _t(
"Use an identity server to invite by email. " +
"Click continue to use the default identity server " +
"(%(defaultIdentityServerName)s) or manage in Settings.",
{
defaultIdentityServerName: abbreviateUrl(defaultIdentityServerUrl),
},
- )}
,
+ ) },
button: _t("Continue"),
},
);
@@ -522,7 +522,7 @@ export const Commands = [
aliases: ['j', 'goto'],
args: '',
description: _td('Joins room with given address'),
- runFn: function(_, args) {
+ runFn: function(roomId, args) {
if (args) {
// Note: we support 2 versions of this command. The first is
// the public-facing one for most users and the other is a
@@ -1069,7 +1069,7 @@ export const Commands = [
command: "msg",
description: _td("Sends a message to the given user"),
args: " ",
- runFn: function(_, args) {
+ runFn: function(roomId, args) {
if (args) {
// matches the first whitespace delimited group and then the rest of the string
const matches = args.match(/^(\S+?)(?: +(.*))?$/s);
diff --git a/src/accessibility/KeyboardShortcuts.tsx b/src/accessibility/KeyboardShortcuts.tsx
index c5cf85facd..9cc7b60c99 100644
--- a/src/accessibility/KeyboardShortcuts.tsx
+++ b/src/accessibility/KeyboardShortcuts.tsx
@@ -370,8 +370,8 @@ export const toggleDialog = () => {
const sections = categoryOrder.map(category => {
const list = shortcuts[category];
return
- {_t(category)}
- {list.map(shortcut => )}
+ { _t(category) }
+ { list.map(shortcut => ) }
;
});
diff --git a/src/accessibility/Toolbar.tsx b/src/accessibility/Toolbar.tsx
index 8d882fadea..90538760bb 100644
--- a/src/accessibility/Toolbar.tsx
+++ b/src/accessibility/Toolbar.tsx
@@ -62,9 +62,9 @@ const Toolbar: React.FC = ({ children, ...props }) => {
};
return
- {({ onKeyDownHandler }) =>
+ { ({ onKeyDownHandler }) =>
{ children }
- }
+ }
;
};
diff --git a/src/async-components/views/dialogs/eventindex/DisableEventIndexDialog.js b/src/async-components/views/dialogs/eventindex/DisableEventIndexDialog.js
index a19494c753..e1c2b7b202 100644
--- a/src/async-components/views/dialogs/eventindex/DisableEventIndexDialog.js
+++ b/src/async-components/views/dialogs/eventindex/DisableEventIndexDialog.js
@@ -59,8 +59,8 @@ export default class DisableEventIndexDialog extends React.Component {
return (
- {_t("If disabled, messages from encrypted rooms won't appear in search results.")}
- {this.state.disabling ? : }
+ { _t("If disabled, messages from encrypted rooms won't appear in search results.") }
+ { this.state.disabling ? : }
- {_t(
+ { _t(
"%(brand)s is securely caching encrypted messages locally for them " +
"to appear in search results:",
{ brand },
- )}
+ ) }
- {crawlerState}
- {_t("Space used:")} {formatBytes(this.state.eventIndexSize, 0)}
- {_t("Indexed messages:")} {formatCountLong(this.state.eventCount)}
- {_t("Indexed rooms:")} {_t("%(doneRooms)s out of %(totalRooms)s", {
+ { crawlerState }
+ { _t("Space used:") } { formatBytes(this.state.eventIndexSize, 0) }
+ { _t("Indexed messages:") } { formatCountLong(this.state.eventCount) }
+ { _t("Indexed rooms:") } { _t("%(doneRooms)s out of %(totalRooms)s", {
doneRooms: formatCountLong(doneRooms),
totalRooms: formatCountLong(this.state.roomCount),
- })}
+ }) }
- {eventIndexingSettings}
+ { eventIndexingSettings }
- {_t(
+
{ _t(
"Warning: You should only set up key backup from a trusted computer.", {},
- { b: sub => {sub} },
- )}
- {_t(
+ { b: sub => { sub } },
+ ) }
+ { _t(
"We'll store an encrypted copy of your keys on our server. " +
"Secure your backup with a Security Phrase.",
- )}
- {_t("For maximum security, this should be different from your account password.")}
+ ) }
+ { _t("For maximum security, this should be different from your account password.") }
@@ -268,9 +268,9 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
/>
- {_t("Advanced")}
+ { _t("Advanced") }
- {_t("Set up with a Security Key")}
+ { _t("Set up with a Security Key") }
;
@@ -299,19 +299,19 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
let passPhraseMatch = null;
if (matchText) {
passPhraseMatch =
- {matchText}
+ { matchText }
- {changeText}
+ { changeText }
;
}
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return
);
}
diff --git a/src/components/views/auth/PasswordLogin.tsx b/src/components/views/auth/PasswordLogin.tsx
index a77dd0b683..587d7f2453 100644
--- a/src/components/views/auth/PasswordLogin.tsx
+++ b/src/components/views/auth/PasswordLogin.tsx
@@ -416,7 +416,7 @@ export default class PasswordLogin extends React.PureComponent {
kind="link"
onClick={this.onForgotPasswordClick}
>
- {_t("Forgot password?")}
+ { _t("Forgot password?") }
;
}
@@ -441,16 +441,16 @@ export default class PasswordLogin extends React.PureComponent {
disabled={this.props.disableSubmit}
>
@@ -460,8 +460,8 @@ export default class PasswordLogin extends React.PureComponent {
return (
- {loginType}
- {loginField}
+ { loginType }
+ { loginField }
{
onValidate={this.onPasswordValidate}
ref={field => this[LoginField.Password] = field}
/>
- {forgotPasswordJsx}
+ { forgotPasswordJsx }
{ !this.props.busy &&
- {this.renderUsername()}
+ { this.renderUsername() }
- {this.renderPassword()}
- {this.renderPasswordConfirm()}
+ { this.renderPassword() }
+ { this.renderPasswordConfirm() }
- {this.renderEmail()}
- {this.renderPhoneNumber()}
+ { this.renderEmail() }
+ { this.renderPhoneNumber() }
{ emailHelperText }
{ registerButton }
diff --git a/src/components/views/avatars/DecoratedRoomAvatar.tsx b/src/components/views/avatars/DecoratedRoomAvatar.tsx
index 5e6bf45f07..99f2b70efc 100644
--- a/src/components/views/avatars/DecoratedRoomAvatar.tsx
+++ b/src/components/views/avatars/DecoratedRoomAvatar.tsx
@@ -205,8 +205,8 @@ export default class DecoratedRoomAvatar extends React.PureComponent
- {icon}
- {badge}
+ { icon }
+ { badge }
;
}
}
diff --git a/src/components/views/avatars/MemberStatusMessageAvatar.js b/src/components/views/avatars/MemberStatusMessageAvatar.js
index b8b23dc33e..82b7b8e400 100644
--- a/src/components/views/avatars/MemberStatusMessageAvatar.js
+++ b/src/components/views/avatars/MemberStatusMessageAvatar.js
@@ -145,7 +145,7 @@ export default class MemberStatusMessageAvatar extends React.Component {
isExpanded={this.state.menuDisplayed}
label={_t("User Status")}
>
- {avatar}
+ { avatar }
{ contextMenu }
diff --git a/src/components/views/avatars/RoomAvatar.tsx b/src/components/views/avatars/RoomAvatar.tsx
index 8ac8de8233..a07990c3bb 100644
--- a/src/components/views/avatars/RoomAvatar.tsx
+++ b/src/components/views/avatars/RoomAvatar.tsx
@@ -22,6 +22,7 @@ import ImageView from '../elements/ImageView';
import { MatrixClientPeg } from '../../../MatrixClientPeg';
import Modal from '../../../Modal';
import * as Avatar from '../../../Avatar';
+import DMRoomMap from "../../../utils/DMRoomMap";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import { mediaFromMxc } from "../../../customisations/Media";
import { IOOBData } from '../../../stores/ThreepidInviteStore';
@@ -131,11 +132,14 @@ export default class RoomAvatar extends React.Component {
const { room, oobData, viewAvatarOnClick, onClick, ...otherProps } = this.props;
const roomName = room ? room.name : oobData.name;
+ // If the room is a DM, we use the other user's ID for the color hash
+ // in order to match the room avatar with their avatar
+ const idName = room ? (DMRoomMap.shared().getUserIdForRoomId(room.roomId) ?? room.roomId) : null;
return (
diff --git a/src/components/views/context_menus/CallContextMenu.tsx b/src/components/views/context_menus/CallContextMenu.tsx
index 76e1670669..a61cdeedd3 100644
--- a/src/components/views/context_menus/CallContextMenu.tsx
+++ b/src/components/views/context_menus/CallContextMenu.tsx
@@ -65,15 +65,15 @@ export default class CallContextMenu extends React.Component {
let transferItem;
if (this.props.call.opponentCanBeTransferred()) {
transferItem = ;
}
return
- {transferItem}
+ { transferItem }
;
}
}
diff --git a/src/components/views/context_menus/IconizedContextMenu.tsx b/src/components/views/context_menus/IconizedContextMenu.tsx
index a9c75bf3ba..1d822fd246 100644
--- a/src/components/views/context_menus/IconizedContextMenu.tsx
+++ b/src/components/views/context_menus/IconizedContextMenu.tsx
@@ -64,8 +64,8 @@ export const IconizedContextMenuRadio: React.FC = ({
label={label}
>
- {label}
- {active && }
+ { label }
+ { active && }
;
};
@@ -85,15 +85,15 @@ export const IconizedContextMenuCheckbox: React.FC = ({
label={label}
>
- {label}
- {active && }
+ { label }
+ { active && }
;
};
export const IconizedContextMenuOption: React.FC = ({ label, iconClassName, ...props }) => {
return ;
};
@@ -104,7 +104,7 @@ export const IconizedContextMenuOptionList: React.FC = ({ firs
});
return
- {children}
+ { children }
;
};
diff --git a/src/components/views/context_menus/MessageContextMenu.tsx b/src/components/views/context_menus/MessageContextMenu.tsx
index 999e98f4ad..bf171353e8 100644
--- a/src/components/views/context_menus/MessageContextMenu.tsx
+++ b/src/components/views/context_menus/MessageContextMenu.tsx
@@ -268,7 +268,7 @@ export default class MessageContextMenu extends React.Component
resendReactionsButton = (
);
@@ -298,7 +298,7 @@ export default class MessageContextMenu extends React.Component
pinButton = (
);
@@ -333,7 +333,7 @@ export default class MessageContextMenu extends React.Component
- {_t("Clear status")}
+ { _t("Clear status") }
;
} else {
actionButton =
- {_t("Update status")}
+ { _t("Update status") }
;
}
} else {
actionButton =
- {_t("Set status")}
+ { _t("Set status") }
;
}
@@ -130,8 +130,8 @@ export default class StatusMessageContextMenu extends React.Component {
onChange={this._onStatusChange}
/>
- {actionButton}
- {spinner}
+ { actionButton }
+ { spinner }
;
diff --git a/src/components/views/dialogs/AddExistingToSpaceDialog.tsx b/src/components/views/dialogs/AddExistingToSpaceDialog.tsx
index 5024b98def..0f78b971eb 100644
--- a/src/components/views/dialogs/AddExistingToSpaceDialog.tsx
+++ b/src/components/views/dialogs/AddExistingToSpaceDialog.tsx
@@ -221,7 +221,7 @@ export const AddExistingToSpace: React.FC = ({
return
-
+
;
}
@@ -690,7 +690,7 @@ export default class AddressPickerDialog extends React.Component {
&& this.props.validAddressTypes.includes('email')) {
const defaultIdentityServerUrl = getDefaultIdentityServerUrl();
if (defaultIdentityServerUrl) {
- identityServer = {_t(
+ identityServer = { _t(
"Use an identity server to invite by email. " +
"Use the default (%(defaultIdentityServerName)s) " +
"or manage in Settings .",
@@ -698,25 +698,25 @@ export default class AddressPickerDialog extends React.Component {
defaultIdentityServerName: abbreviateUrl(defaultIdentityServerUrl),
},
{
- default: sub => {sub},
- settings: sub => {sub},
+ default: sub => { sub },
+ settings: sub => { sub },
},
- )};
+ ) };
} else {
- identityServer = {_t(
+ identityServer = ;
+ ) };
}
}
return (
- {inputLabel}
+ { inputLabel }
{ query }
{ error }
diff --git a/src/components/views/dialogs/AskInviteAnywayDialog.tsx b/src/components/views/dialogs/AskInviteAnywayDialog.tsx
index 26fad0c724..3ae82f1026 100644
--- a/src/components/views/dialogs/AskInviteAnywayDialog.tsx
+++ b/src/components/views/dialogs/AskInviteAnywayDialog.tsx
@@ -51,7 +51,7 @@ export default class AskInviteAnywayDialog extends React.Component {
public render() {
const errorList = this.props.unknownProfileUsers
- .map(address => {address.userId}: {address.errorText} );
+ .map(address => { address.userId }: { address.errorText } );
return (
{
contentId='mx_Dialog_content'
>
- {/* eslint-disable-next-line */}
- {_t("Unable to find profiles for the Matrix IDs listed below - would you like to invite them anyway?")}
+ { _t("Unable to find profiles for the Matrix IDs listed below - " +
+ "would you like to invite them anyway?") }
{ errorList }
diff --git a/src/components/views/dialogs/BaseDialog.js b/src/components/views/dialogs/BaseDialog.js
index e92bd6315e..8ccc485d7c 100644
--- a/src/components/views/dialogs/BaseDialog.js
+++ b/src/components/views/dialogs/BaseDialog.js
@@ -149,7 +149,7 @@ export default class BaseDialog extends React.Component {
'mx_Dialog_headerWithCancel': !!cancelButton,
})}>
- {headerImage}
+ { headerImage }
{ this.props.title }
{ this.props.headerButton }
diff --git a/src/components/views/dialogs/BetaFeedbackDialog.tsx b/src/components/views/dialogs/BetaFeedbackDialog.tsx
index 5a2f16f169..917004dbc7 100644
--- a/src/components/views/dialogs/BetaFeedbackDialog.tsx
+++ b/src/components/views/dialogs/BetaFeedbackDialog.tsx
@@ -69,7 +69,7 @@ const BetaFeedbackDialog: React.FC = ({ featureId, onFinished }) => {
{ _t(info.feedbackSubheading) }
- { _t("Your platform and username will be noted to help us use your feedback as much as we can.")}
+ { _t("Your platform and username will be noted to help us use your feedback as much as we can.") }
{
onFinished(false);
diff --git a/src/components/views/dialogs/BugReportDialog.tsx b/src/components/views/dialogs/BugReportDialog.tsx
index 6baf24f797..64e984fe20 100644
--- a/src/components/views/dialogs/BugReportDialog.tsx
+++ b/src/components/views/dialogs/BugReportDialog.tsx
@@ -166,7 +166,7 @@ export default class BugReportDialog extends React.Component {
let error = null;
if (this.state.err) {
error =
- {this.state.err}
+ { this.state.err }
;
}
@@ -175,7 +175,7 @@ export default class BugReportDialog extends React.Component {
progress = (
- {this.state.progress} ...
+ { this.state.progress } ...
);
}
@@ -221,7 +221,7 @@ export default class BugReportDialog extends React.Component {
{ _t("Download logs") }
- {this.state.downloadProgress && {this.state.downloadProgress} ...}
+ { this.state.downloadProgress && { this.state.downloadProgress } ... }
{
"please include those things here.",
)}
/>
- {progress}
- {error}
+ { progress }
+ { error }
{
return (
- {commit.commit.message.split('\n')[0]}
+ { commit.commit.message.split('\n')[0] }
);
@@ -79,15 +79,15 @@ export default class ChangelogDialog extends React.Component {
}
return (
- {repo}
- {content}
+ { repo }
+ { content }
);
});
const content = (
- {this.props.version == null || this.props.newVersion == null ? {_t("Unavailable")}
: logs}
+ { this.props.version == null || this.props.newVersion == null ? { _t("Unavailable") }
: logs }
);
diff --git a/src/components/views/dialogs/CommunityPrototypeInviteDialog.tsx b/src/components/views/dialogs/CommunityPrototypeInviteDialog.tsx
index 7627489deb..73fd4def25 100644
--- a/src/components/views/dialogs/CommunityPrototypeInviteDialog.tsx
+++ b/src/components/views/dialogs/CommunityPrototypeInviteDialog.tsx
@@ -156,8 +156,8 @@ export default class CommunityPrototypeInviteDialog extends React.PureComponent<
height={avatarSize}
/>
- {person.user.name}
- {person.userId}
+ { person.user.name }
+ { person.userId }
this.setPersonToggle(person, e.target.checked)} />
@@ -187,7 +187,7 @@ export default class CommunityPrototypeInviteDialog extends React.PureComponent<
emailAddresses.push((
this.onAddressChange(e, emailAddresses.length)}
label={emailAddresses.length > 0 ? _t("Add another email") : _t("Email address")}
placeholder={emailAddresses.length > 0 ? _t("Add another email") : _t("Email address")}
@@ -207,16 +207,16 @@ export default class CommunityPrototypeInviteDialog extends React.PureComponent<
onClick={this.onShowMorePeople}
kind="link" key="more"
className="mx_CommunityPrototypeInviteDialog_morePeople"
- >{_t("Show more")}
+ >{ _t("Show more") }
));
}
}
if (this.state.people.length > 0) {
peopleIntro = (
- {_t("People you know on %(brand)s", { brand: SdkConfig.get().brand })}
+ { _t("People you know on %(brand)s", { brand: SdkConfig.get().brand }) }
- {this.state.showPeople ? _t("Hide") : _t("Show")}
+ { this.state.showPeople ? _t("Hide") : _t("Show") }
);
@@ -236,14 +236,14 @@ export default class CommunityPrototypeInviteDialog extends React.PureComponent<
>
- {emailAddresses}
- {peopleIntro}
- {people}
+ { emailAddresses }
+ { peopleIntro }
+ { people }
{buttonText}
+ >{ buttonText }
diff --git a/src/components/views/dialogs/ConfirmWipeDeviceDialog.tsx b/src/components/views/dialogs/ConfirmWipeDeviceDialog.tsx
index 544d0df1c9..2577d5456d 100644
--- a/src/components/views/dialogs/ConfirmWipeDeviceDialog.tsx
+++ b/src/components/views/dialogs/ConfirmWipeDeviceDialog.tsx
@@ -44,10 +44,10 @@ export default class ConfirmWipeDeviceDialog extends React.Component {
>
- {_t(
+ { _t(
"Clearing all data from this session is permanent. Encrypted messages will be lost " +
"unless their keys have been backed up.",
- )}
+ ) }
- {_t("Community ID: + :%(domain)s", {
+ { _t("Community ID: + :%(domain)s", {
domain: MatrixClientPeg.getHomeserverName(),
}, {
- localpart: () => {this.state.localpart},
- })}
+ localpart: () => { this.state.localpart },
+ }) }
- {_t("You can change this later if needed.")}
+ { _t("You can change this later if needed.") }
);
if (this.state.error) {
const classes = "mx_CreateCommunityPrototypeDialog_subtext mx_CreateCommunityPrototypeDialog_subtext_error";
helpText = (
- {this.state.error}
+ { this.state.error }
);
}
@@ -193,13 +193,13 @@ export default class CreateCommunityPrototypeDialog extends React.PureComponent<
placeholder={_t("Enter name")}
label={_t("Enter name")}
/>
- {helpText}
+ { helpText }
- {/*nbsp is to reserve the height of this element when there's nothing*/}
- {communityId}
+ { /*nbsp is to reserve the height of this element when there's nothing*/ }
+ { communityId }
- {_t("Create")}
+ { _t("Create") }
@@ -212,12 +212,12 @@ export default class CreateCommunityPrototypeDialog extends React.PureComponent<
onClick={this.onChangeAvatar}
className="mx_CreateCommunityPrototypeDialog_avatarContainer"
>
- {preview}
+ { preview }
- {_t("Add image (optional)")}
+ { _t("Add image (optional)") }
- {_t("An image will help people identify your community.")}
+ { _t("An image will help people identify your community.") }
diff --git a/src/components/views/dialogs/CreateGroupDialog.tsx b/src/components/views/dialogs/CreateGroupDialog.tsx
index d6bb582079..88ae801441 100644
--- a/src/components/views/dialogs/CreateGroupDialog.tsx
+++ b/src/components/views/dialogs/CreateGroupDialog.tsx
@@ -102,7 +102,7 @@ export default class CreateGroupDialog extends React.Component {
});
};
- _onCancel = () => {
+ private onCancel = () => {
this.props.onFinished(false);
};
@@ -167,7 +167,7 @@ export default class CreateGroupDialog extends React.Component {
-
diff --git a/src/components/views/dialogs/CreateRoomDialog.tsx b/src/components/views/dialogs/CreateRoomDialog.tsx
index b5c0096771..6d75b94c70 100644
--- a/src/components/views/dialogs/CreateRoomDialog.tsx
+++ b/src/components/views/dialogs/CreateRoomDialog.tsx
@@ -224,15 +224,15 @@ export default class CreateRoomDialog extends React.Component {
);
}
- let publicPrivateLabel = {_t(
+ let publicPrivateLabel =
{ _t(
"Private rooms can be found and joined by invitation only. Public rooms can be " +
"found and joined by anyone.",
- )}
;
+ ) };
if (CommunityPrototypeStore.instance.getSelectedCommunityId()) {
- publicPrivateLabel = {_t(
+ publicPrivateLabel =
{ _t(
"Private rooms can be found and joined by invitation only. Public rooms can be " +
"found and joined by anyone in this community.",
- )}
;
+ ) };
}
let e2eeSection;
@@ -250,7 +250,7 @@ export default class CreateRoomDialog extends React.Component {
}
e2eeSection =
{
onChange={this.onNoFederateChange}
value={this.state.noFederate}
/>
- {federateLabel}
+ { federateLabel }
diff --git a/src/components/views/dialogs/DeactivateAccountDialog.tsx b/src/components/views/dialogs/DeactivateAccountDialog.tsx
index b2ac849314..7221df222f 100644
--- a/src/components/views/dialogs/DeactivateAccountDialog.tsx
+++ b/src/components/views/dialogs/DeactivateAccountDialog.tsx
@@ -172,11 +172,11 @@ export default class DeactivateAccountDialog extends React.Component;
}
- let auth = {_t("Loading...")};
+ let auth = { _t("Loading...") };
if (this.state.authData && this.state.authEnabled) {
auth = (
- {this.state.bodyText}
+ { this.state.bodyText }
- {_t(
+ { _t(
"Please forget all messages I have sent when my account is deactivated " +
"(Warning: this will cause future users to see an incomplete view " +
"of conversations)",
{},
{ b: (sub) => { sub } },
- )}
+ ) }
- {error}
- {auth}
+ { error }
+ { auth }
diff --git a/src/components/views/dialogs/DevtoolsDialog.tsx b/src/components/views/dialogs/DevtoolsDialog.tsx
index 86b8f93d7b..61cda796ee 100644
--- a/src/components/views/dialogs/DevtoolsDialog.tsx
+++ b/src/components/views/dialogs/DevtoolsDialog.tsx
@@ -337,7 +337,7 @@ class FilteredList extends React.PureComponent
- {eventType}
+ { eventType }
;
})
}
@@ -726,17 +726,17 @@ const VerificationRequestExplorer: React.FC<{
return (
- Transaction
- - {txnId}
+ - { txnId }
- Phase
- - {PHASE_MAP[request.phase] || request.phase}
+ - { PHASE_MAP[request.phase] || request.phase }
- Timeout
- - {Math.floor(timeout / 1000)}
+ - { Math.floor(timeout / 1000) }
- Methods
- - {request.methods && request.methods.join(", ")}
+ - { request.methods && request.methods.join(", ") }
- requestingUserId
- - {request.requestingUserId}
+ - { request.requestingUserId }
- observeOnly
- - {JSON.stringify(request.observeOnly)}
+ - { JSON.stringify(request.observeOnly) }
);
};
@@ -771,12 +771,12 @@ class VerificationExplorer extends React.PureComponent {
return (
- {Array.from(inRoomRequests.entries()).reverse().map(([txnId, request]) =>
+ { Array.from(inRoomRequests.entries()).reverse().map(([txnId, request]) =>
,
- )}
+ ) }
- {_t("Back")}
+ { _t("Back") }
);
}
@@ -844,9 +844,9 @@ class WidgetExplorer extends React.Component ev.getId() === editWidget.eventId);
if (!stateEv) { // "should never happen"
return
- {_t("There was an error finding this widget.")}
+ { _t("There was an error finding this widget.") }
- {_t("Back")}
+ { _t("Back") }
;
}
@@ -865,17 +865,17 @@ class WidgetExplorer extends React.Component
- {widgets.map(w => {
+ { widgets.map(w => {
return this.onEditWidget(w)}
- >{w.url} ;
- })}
+ >{ w.url };
+ }) }
- {_t("Back")}
+ { _t("Back") }
);
}
@@ -1007,7 +1007,7 @@ class SettingsExplorer extends React.PureComponent{canEdit.toString()};
+ return { canEdit.toString() } ;
}
render() {
@@ -1028,17 +1028,17 @@ class SettingsExplorer extends React.PureComponent
- {_t("Setting ID")}
- {_t("Value")}
- {_t("Value in this room")}
+ { _t("Setting ID") }
+ { _t("Value") }
+ { _t("Value in this room") }
- {allSettings.map(i => (
+ { allSettings.map(i => (
this.onViewClick(e, i)}>
- {i}
+ { i }
this.onEditClick(e, i)}
className='mx_DevTools_SettingsExplorer_edit'
@@ -1047,20 +1047,20 @@ class SettingsExplorer extends React.PureComponent
- {this.renderSettingValue(SettingsStore.getValue(i))}
+ { this.renderSettingValue(SettingsStore.getValue(i)) }
- {this.renderSettingValue(SettingsStore.getValue(i, room.roomId))}
+ { this.renderSettingValue(SettingsStore.getValue(i, room.roomId)) }
- ))}
+ )) }
- {_t("Back")}
+ { _t("Back") }
);
@@ -1068,36 +1068,36 @@ class SettingsExplorer extends React.PureComponent
- {_t("Setting:")} {this.state.editSetting}
+ { _t("Setting:") } { this.state.editSetting }
- {_t("Caution:")} {_t(
+ { _t("Caution:") } { _t(
"This UI does NOT check the types of the values. Use at your own risk.",
- )}
+ ) }
- {_t("Setting definition:")}
- {JSON.stringify(SETTINGS[this.state.editSetting], null, 4)}
+ { _t("Setting definition:") }
+ { JSON.stringify(SETTINGS[this.state.editSetting], null, 4) }
- {_t("Level")}
- {_t("Settable at global")}
- {_t("Settable at room")}
+ { _t("Level") }
+ { _t("Settable at global") }
+ { _t("Settable at room") }
- {LEVEL_ORDER.map(lvl => (
+ { LEVEL_ORDER.map(lvl => (
- {lvl}
- {this.renderCanEditLevel(null, lvl)}
- {this.renderCanEditLevel(room.roomId, lvl)}
+ { lvl }
+ { this.renderCanEditLevel(null, lvl) }
+ { this.renderCanEditLevel(room.roomId, lvl) }
- ))}
+ )) }
@@ -1122,8 +1122,8 @@ class SettingsExplorer extends React.PureComponent
- {_t("Save setting values")}
- {_t("Back")}
+ { _t("Save setting values") }
+ { _t("Back") }
);
@@ -1131,39 +1131,39 @@ class SettingsExplorer extends React.PureComponent
- {_t("Setting:")} {this.state.viewSetting}
+ { _t("Setting:") } { this.state.viewSetting }
- {_t("Setting definition:")}
- {JSON.stringify(SETTINGS[this.state.viewSetting], null, 4)}
+ { _t("Setting definition:") }
+ { JSON.stringify(SETTINGS[this.state.viewSetting], null, 4) }
- {_t("Value:")}
- {this.renderSettingValue(
+ { _t("Value:") }
+ { this.renderSettingValue(
SettingsStore.getValue(this.state.viewSetting),
- )}
+ ) }
- {_t("Value in this room:")}
- {this.renderSettingValue(
+ { _t("Value in this room:") }
+ { this.renderSettingValue(
SettingsStore.getValue(this.state.viewSetting, room.roomId),
- )}
+ ) }
- {_t("Values at explicit levels:")}
- {this.renderExplicitSettingValues(
+ { _t("Values at explicit levels:") }
+ { this.renderExplicitSettingValues(
this.state.viewSetting, null,
- )}
+ ) }
- {_t("Values at explicit levels in this room:")}
- {this.renderExplicitSettingValues(
+ { _t("Values at explicit levels in this room:") }
+ { this.renderExplicitSettingValues(
this.state.viewSetting, room.roomId,
- )}
+ ) }
@@ -1171,7 +1171,7 @@ class SettingsExplorer extends React.PureComponent this.onEditClick(e, this.state.viewSetting)}>{
_t("Edit Values")
}
- {_t("Back")}
+ { _t("Back") }
);
@@ -1232,12 +1232,12 @@ export default class DevtoolsDialog extends React.PureComponent
if (this.state.mode) {
body =
- {(cli) =>
+ { (cli) =>
{ this.state.mode.getLabel() }
Room ID: { this.props.roomId }
- }
+ }
;
} else {
const classes = "mx_DevTools_RoomStateExplorer_button";
diff --git a/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx b/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx
index 217e4f2d37..1eabb68081 100644
--- a/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx
+++ b/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx
@@ -151,16 +151,16 @@ export default class EditCommunityPrototypeDialog extends React.PureComponent{preview}
+ >{ preview }
- {_t("Add image (optional)")}
+ { _t("Add image (optional)") }
- {_t("An image will help people identify your community.")}
+ { _t("An image will help people identify your community.") }
- {_t("Save")}
+ { _t("Save") }
diff --git a/src/components/views/dialogs/FeedbackDialog.js b/src/components/views/dialogs/FeedbackDialog.js
index 88a57cf8cb..85171c9bf6 100644
--- a/src/components/views/dialogs/FeedbackDialog.js
+++ b/src/components/views/dialogs/FeedbackDialog.js
@@ -58,10 +58,10 @@ export default (props) => {
countlyFeedbackSection =
- {_t("Rate %(brand)s", { brand })}
+ { _t("Rate %(brand)s", { brand }) }
- {_t("Tell us below how you feel about %(brand)s so far.", { brand })}
- {_t("Please go into as much detail as you like, so we can track down the problem.")}
+ { _t("Tell us below how you feel about %(brand)s so far.", { brand }) }
+ { _t("Please go into as much detail as you like, so we can track down the problem.") }
{
let subheading;
if (hasFeedback) {
subheading = (
- {_t("There are two ways you can provide feedback and help us improve %(brand)s.", { brand })}
+ { _t("There are two ways you can provide feedback and help us improve %(brand)s.", { brand }) }
);
}
@@ -106,7 +106,7 @@ export default (props) => {
_t("PRO TIP: If you start a bug, please submit debug logs " +
"to help us track down the problem.", {}, {
debugLogsLink: sub => (
- {sub}
+ { sub }
),
})
}
@@ -121,7 +121,7 @@ export default (props) => {
{ subheading }
- {_t("Report a bug")}
+ { _t("Report a bug") }
{
_t("Please view existing bugs on Github first. " +
"No match? Start a new one .", {}, {
@@ -133,7 +133,7 @@ export default (props) => {
},
})
}
- {bugReports}
+ { bugReports }
{ countlyFeedbackSection }
}
diff --git a/src/components/views/dialogs/HostSignupDialog.tsx b/src/components/views/dialogs/HostSignupDialog.tsx
index 64c080bf01..4b8b7f32f0 100644
--- a/src/components/views/dialogs/HostSignupDialog.tsx
+++ b/src/components/views/dialogs/HostSignupDialog.tsx
@@ -177,32 +177,32 @@ export default class HostSignupDialog extends React.PureComponent
- {_t("Continuing temporarily allows the %(hostSignupBrand)s setup process to access your " +
+ { _t("Continuing temporarily allows the %(hostSignupBrand)s setup process to access your " +
"account to fetch verified email addresses. This data is not stored.", {
hostSignupBrand: this.config.brand,
- })}
+ }) }
- {_t("Learn more in our , and .",
+ { _t("Learn more in our , and .",
{},
{
cookiePolicyLink: () => (
- {_t("Cookie Policy")}
+ { _t("Cookie Policy") }
),
privacyPolicyLink: () => (
- {_t("Privacy Policy")}
+ { _t("Privacy Policy") }
),
termsOfServiceLink: () => (
- {_t("Terms of Service")}
+ { _t("Terms of Service") }
),
},
- )}
+ ) }
>
);
@@ -241,12 +241,12 @@ export default class HostSignupDialog extends React.PureComponent
- {this.state.minimized &&
+ { this.state.minimized &&
- {_t("%(hostSignupBrand)s Setup", {
+ { _t("%(hostSignupBrand)s Setup", {
hostSignupBrand: this.config.brand,
- })}
+ }) }
}
- {!this.state.minimized &&
+ { !this.state.minimized &&
}
- {this.state.error &&
+ { this.state.error &&
- {this.state.error}
+ { this.state.error }
}
- {!this.state.error &&
+ { !this.state.error &&
- {oppProfile.displayname}
+ { oppProfile.displayname }
;
} else if (this.state.opponentProfileError) {
profile =
@@ -146,42 +146,42 @@ export default class IncomingSasDialog extends React.Component {
idName={this.props.verifier.userId}
width={48} height={48}
/>
- {this.props.verifier.userId}
+ { this.props.verifier.userId }
;
} else {
profile = ;
}
const userDetailText = [
- {_t(
+
{ _t(
"Verify this user to mark them as trusted. " +
"Trusting users gives you extra peace of mind when using " +
"end-to-end encrypted messages.",
- )}
,
- {_t(
+ ) }
,
+ { _t(
// NB. Below wording adjusted to singular 'session' until we have
// cross-signing
"Verifying this user will mark their session as trusted, and " +
"also mark your session as trusted to them.",
- )}
,
+ ) },
];
const selfDetailText = [
- {_t(
+
{ _t(
"Verify this device to mark it as trusted. " +
"Trusting this device gives you and other users extra peace of mind when using " +
"end-to-end encrypted messages.",
- )}
,
- {_t(
+ ) }
,
+ { _t(
"Verifying this device will mark it as trusted, and users who have verified with " +
"you will trust this device.",
- )}
,
+ ) },
];
return (
- {profile}
- {isSelf ? selfDetailText : userDetailText}
+ { profile }
+ { isSelf ? selfDetailText : userDetailText }
- {_t("Waiting for partner to confirm...")}
+ { _t("Waiting for partner to confirm...") }
);
}
@@ -251,7 +251,7 @@ export default class IncomingSasDialog extends React.Component {
onFinished={this._onFinished}
fixedWidth={false}
>
- {body}
+ { body }
);
}
diff --git a/src/components/views/dialogs/IntegrationsDisabledDialog.js b/src/components/views/dialogs/IntegrationsDisabledDialog.js
index 1e2ff09196..6a5b2f08f9 100644
--- a/src/components/views/dialogs/IntegrationsDisabledDialog.js
+++ b/src/components/views/dialogs/IntegrationsDisabledDialog.js
@@ -49,7 +49,7 @@ export default class IntegrationsDisabledDialog extends React.Component {
title={_t("Integrations are disabled")}
>
- {_t("Enable 'Manage Integrations' in Settings to do this.")}
+ { _t("Enable 'Manage Integrations' in Settings to do this.") }
- {_t(
+ { _t(
"Your %(brand)s doesn't allow you to use an integration manager to do this. " +
"Please contact an admin.",
{ brand },
- )}
+ ) }
- {body}
+ { body }
{
return (
- {avatar}
- {this.props.member.name}
+ { avatar }
+ { this.props.member.name }
{ closeButton }
@@ -267,20 +267,20 @@ class DMRoomTile extends React.PureComponent {
// Push any text we missed (first bit/middle of text)
if (ii > i) {
// Push any text we aren't highlighting (middle of text match, or beginning of text)
- result.push({str.substring(i, ii)});
+ result.push({ str.substring(i, ii) });
}
i = ii; // copy over ii only if we have a match (to preserve i for end-of-text matching)
// Highlight the word the user entered
const substr = str.substring(i, filterStr.length + i);
- result.push({substr});
+ result.push({ substr });
i += substr.length;
}
// Push any text we missed (end of text)
if (i < str.length) {
- result.push({str.substring(i)});
+ result.push({ str.substring(i) });
}
return result;
@@ -290,7 +290,7 @@ class DMRoomTile extends React.PureComponent {
let timestamp = null;
if (this.props.lastActiveTs) {
const humanTs = humanizeTime(this.props.lastActiveTs);
- timestamp = {humanTs};
+ timestamp = { humanTs };
}
const avatarSize = 36;
@@ -317,8 +317,8 @@ class DMRoomTile extends React.PureComponent {
// the browser from reloading the image source when the avatar remounts).
const stackedAvatar = (
- {avatar}
- {checkmark}
+ { avatar }
+ { checkmark }
);
@@ -328,12 +328,12 @@ class DMRoomTile extends React.PureComponent {
return (
- {stackedAvatar}
+ { stackedAvatar }
- {this.highlightName(this.props.member.name)}
- {caption}
+ { this.highlightName(this.props.member.name) }
+ { caption }
- {timestamp}
+ { timestamp }
);
}
@@ -1152,8 +1152,8 @@ export default class InviteDialog extends React.PureComponent
- {sectionName}
- {_t("No results")}
+ { sectionName }
+ { _t("No results") }
);
}
@@ -1175,7 +1175,7 @@ export default class InviteDialog extends React.PureComponent
- {_t("Show more")}
+ { _t("Show more") }
);
}
@@ -1192,10 +1192,10 @@ export default class InviteDialog extends React.PureComponent
- {sectionName}
- {sectionSubname ? {sectionSubname}
: null}
- {tiles}
- {showMore}
+ { sectionName }
+ { sectionSubname ? { sectionSubname }
: null }
+ { tiles }
+ { showMore }
);
}
@@ -1225,8 +1225,8 @@ export default class InviteDialog extends React.PureComponent
- {targets}
- {input}
+ { targets }
+ { input }
);
}
@@ -1241,7 +1241,7 @@ export default class InviteDialog extends React.PureComponent{_t(
+ { _t(
"Use an identity server to invite by email. " +
"Use the default (%(defaultIdentityServerName)s) " +
"or manage in Settings .",
@@ -1249,20 +1249,20 @@ export default class InviteDialog extends React.PureComponent {sub},
- settings: sub => {sub},
+ default: sub => { sub },
+ settings: sub => { sub },
},
- )}
+ ) }
);
} else {
return (
- {_t(
+
+ ) }
);
}
}
@@ -1339,7 +1339,7 @@ export default class InviteDialog extends React.PureComponent {
return (
- {userId}
+ { userId }
);
} },
);
@@ -1349,7 +1349,7 @@ export default class InviteDialog extends React.PureComponent {
return (
- {userId}
+ { userId }
);
} },
);
@@ -1367,7 +1367,7 @@ export default class InviteDialog extends React.PureComponent{userId}
+ >{ userId }
);
},
a: (sub) => {
@@ -1375,13 +1375,13 @@ export default class InviteDialog extends React.PureComponent{sub}
+ >{ sub }
);
},
},
);
helpText =
- { helpText } {inviteText}
+ { helpText } { inviteText }
;
}
buttonText = _t("Go");
@@ -1438,9 +1438,9 @@ export default class InviteDialog extends React.PureComponent
- {userId},
+ { userId },
a: (sub) =>
- {sub},
+ { sub },
});
buttonText = _t("Invite");
@@ -1459,7 +1459,7 @@ export default class InviteDialog extends React.PureComponent
- {" " + _t("Invited people will be able to read old messages.")}
+ { " " + _t("Invited people will be able to read old messages.") }
;
}
}
@@ -1469,14 +1469,14 @@ export default class InviteDialog extends React.PureComponent
- {_t("Cancel")}
+ { _t("Cancel") }
- {_t("Transfer")}
+ { _t("Transfer") }
;
} else {
@@ -1497,27 +1497,27 @@ export default class InviteDialog extends React.PureComponent
- {buttonText}
+ { buttonText }
;
const usersSection =
- {helpText}
+ { helpText }
- {this.renderEditor()}
+ { this.renderEditor() }
- {goButton}
- {spinner}
+ { goButton }
+ { spinner }
- {keySharingWarning}
- {this.renderIdentityServerWarning()}
- {this.state.errorText}
+ { keySharingWarning }
+ { this.renderIdentityServerWarning() }
+ { this.state.errorText }
- {this.renderSection('recents')}
- {this.renderSection('suggestions')}
- {extraSection}
+ { this.renderSection('recents') }
+ { this.renderSection('suggestions') }
+ { extraSection }
- {footer}
+ { footer }
;
let dialogContent;
@@ -1550,7 +1550,7 @@ export default class InviteDialog extends React.PureComponent
- {dialPadField}
+ { dialPadField }
- {consultConnectSection}
+ { consultConnectSection }
;
} else {
dialogContent =
- {usersSection}
- {consultConnectSection}
+ { usersSection }
+ { consultConnectSection }
;
}
@@ -1582,7 +1582,7 @@ export default class InviteDialog extends React.PureComponent
- {dialogContent}
+ { dialogContent }
);
diff --git a/src/components/views/dialogs/KeySignatureUploadFailedDialog.js b/src/components/views/dialogs/KeySignatureUploadFailedDialog.js
index 22487af17c..9fa9fc1373 100644
--- a/src/components/views/dialogs/KeySignatureUploadFailedDialog.js
+++ b/src/components/views/dialogs/KeySignatureUploadFailedDialog.js
@@ -69,10 +69,10 @@ export default function KeySignatureUploadFailedDialog({
const brand = SdkConfig.get().brand;
body = (
- {_t("%(brand)s encountered an error during upload of:", { brand })}
- {reason}
- {retrying && }
- {JSON.stringify(failures, null, 2)}
+ { _t("%(brand)s encountered an error during upload of:", { brand }) }
+ { reason }
+ { retrying && }
+ { JSON.stringify(failures, null, 2) }
);
} else {
body = (
- {success ?
- {_t("Upload completed")} :
+ { success ?
+ { _t("Upload completed") } :
cancelled ?
- {_t("Cancelled signature upload")} :
- {_t("Unable to upload")}}
+ { _t("Cancelled signature upload") } :
+ { _t("Unable to upload") } }
{}}
>
- {body}
+ { body }
);
}
diff --git a/src/components/views/dialogs/LazyLoadingDisabledDialog.js b/src/components/views/dialogs/LazyLoadingDisabledDialog.js
index cae9510742..e43cb28a22 100644
--- a/src/components/views/dialogs/LazyLoadingDisabledDialog.js
+++ b/src/components/views/dialogs/LazyLoadingDisabledDialog.js
@@ -44,7 +44,7 @@ export default (props) => {
return ({description1}
{description2}
}
+ description={{ description1 }
{ description2 }
}
button={_t("Clear cache and resync")}
onFinished={props.onFinished}
/>);
diff --git a/src/components/views/dialogs/LazyLoadingResyncDialog.js b/src/components/views/dialogs/LazyLoadingResyncDialog.js
index 378306dc2f..a5db15ebbe 100644
--- a/src/components/views/dialogs/LazyLoadingResyncDialog.js
+++ b/src/components/views/dialogs/LazyLoadingResyncDialog.js
@@ -33,7 +33,7 @@ export default (props) => {
return ({description} }
+ description={{ description }}
button={_t("OK")}
onFinished={props.onFinished}
/>);
diff --git a/src/components/views/dialogs/LogoutDialog.js b/src/components/views/dialogs/LogoutDialog.js
index bd9411358b..469cd48093 100644
--- a/src/components/views/dialogs/LogoutDialog.js
+++ b/src/components/views/dialogs/LogoutDialog.js
@@ -123,11 +123,11 @@ export default class LogoutDialog extends React.Component {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const description =
- {_t(
+
{ _t(
"Encrypted messages are secured with end-to-end encryption. " +
"Only you and the recipient(s) have the keys to read these messages.",
- )}
- {_t("Back up your keys before signing out to avoid losing them.")}
+ ) }
+ { _t("Back up your keys before signing out to avoid losing them.") }
;
let dialogContent;
@@ -156,13 +156,13 @@ export default class LogoutDialog extends React.Component {
focus={true}
>
- {_t("I don't want my encrypted messages")}
+ { _t("I don't want my encrypted messages") }
- {_t("Advanced")}
+ { _t("Advanced") }
- {_t("Manually export keys")}
+ { _t("Manually export keys") }
;
@@ -176,7 +176,7 @@ export default class LogoutDialog extends React.Component {
hasCancel={true}
onFinished={this._onFinished}
>
- {dialogContent}
+ { dialogContent }
);
} else {
const QuestionDialog = sdk.getComponent('views.dialogs.QuestionDialog');
diff --git a/src/components/views/dialogs/MessageEditHistoryDialog.js b/src/components/views/dialogs/MessageEditHistoryDialog.js
index b9225f5932..6fce8aecd4 100644
--- a/src/components/views/dialogs/MessageEditHistoryDialog.js
+++ b/src/components/views/dialogs/MessageEditHistoryDialog.js
@@ -134,18 +134,18 @@ export default class MessageEditHistoryDialog extends React.PureComponent {
const { error } = this.state;
if (error.errcode === "M_UNRECOGNIZED") {
content = (
- {_t("Your homeserver doesn't seem to support this feature.")}
+ { _t("Your homeserver doesn't seem to support this feature.") }
);
} else if (error.errcode) {
// some kind of error from the homeserver
content = (
- {_t("Something went wrong!")}
+ { _t("Something went wrong!") }
);
} else {
content = (
- {_t("Cannot reach homeserver")}
+ { _t("Cannot reach homeserver") }
- {_t("Ensure you have a stable internet connection, or get in touch with the server admin")}
+ { _t("Ensure you have a stable internet connection, or get in touch with the server admin") }
);
}
} else if (this.state.isLoading) {
@@ -155,11 +155,11 @@ export default class MessageEditHistoryDialog extends React.PureComponent {
const ScrollPanel = sdk.getComponent("structures.ScrollPanel");
content = (
- {this._renderEdits()}
+ { this._renderEdits() }
);
}
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
@@ -170,7 +170,7 @@ export default class MessageEditHistoryDialog extends React.PureComponent {
onFinished={this.props.onFinished}
title={_t("Message edits")}
>
- {content}
+ { content }
);
}
diff --git a/src/components/views/dialogs/ModalWidgetDialog.tsx b/src/components/views/dialogs/ModalWidgetDialog.tsx
index 6bc84b66b4..1bf7eb7307 100644
--- a/src/components/views/dialogs/ModalWidgetDialog.tsx
+++ b/src/components/views/dialogs/ModalWidgetDialog.tsx
@@ -191,9 +191,9 @@ export default class ModalWidgetDialog extends React.PureComponent
- {_t("Data on this screen is shared with %(widgetDomain)s", {
+ { _t("Data on this screen is shared with %(widgetDomain)s", {
widgetDomain: parsed.hostname,
- })}
+ }) }
;
+ return { _t("Identity server") }
({ host });
case SERVICE_TYPES.IM:
- return {_t("Integration manager")}
({host});
+ return { _t("Integration manager") }
({ host });
}
}
@@ -100,13 +100,13 @@ export default class TermsDialog extends React.PureComponent
- {_t("Find others by phone or email")}
+ { _t("Find others by phone or email") }
- {_t("Be found by phone or email")}
+ { _t("Be found by phone or email") }
;
case SERVICE_TYPES.IM:
return
- {_t("Use bots, bridges, widgets and sticker packs")}
+ { _t("Use bots, bridges, widgets and sticker packs") }
;
}
}
@@ -136,10 +136,10 @@ export default class TermsDialog extends React.PureComponent
- {serviceName}
- {summary}
+ { serviceName }
+ { summary }
- {termDoc[termsLang].name}
+ { termDoc[termsLang].name }
@@ -186,16 +186,16 @@ export default class TermsDialog extends React.PureComponent
- {_t("To continue you need to accept the terms of this service.")}
+ { _t("To continue you need to accept the terms of this service.") }
- {_t("Service")}
- {_t("Summary")}
- {_t("Document")}
- {_t("Accept")}
+ { _t("Service") }
+ { _t("Summary") }
+ { _t("Document") }
+ { _t("Accept") }
- {rows}
+ { rows }
diff --git a/src/components/views/dialogs/UntrustedDeviceDialog.tsx b/src/components/views/dialogs/UntrustedDeviceDialog.tsx
index b89293b386..8389757347 100644
--- a/src/components/views/dialogs/UntrustedDeviceDialog.tsx
+++ b/src/components/views/dialogs/UntrustedDeviceDialog.tsx
@@ -48,13 +48,13 @@ const UntrustedDeviceDialog: React.FC = ({ device, user, onFinished }) =
className="mx_UntrustedDeviceDialog"
title={<>
- { _t("Not Trusted")}
+ { _t("Not Trusted") }
>}
>
- {newSessionText}
- {device.getDisplayName()} ({device.deviceId})
- {askToVerifyText}
+ { newSessionText }
+ { device.getDisplayName() } ({ device.deviceId })
+ { askToVerifyText }
onFinished("legacy")}>
diff --git a/src/components/views/dialogs/UploadConfirmDialog.tsx b/src/components/views/dialogs/UploadConfirmDialog.tsx
index e68067cd2b..508bb95e43 100644
--- a/src/components/views/dialogs/UploadConfirmDialog.tsx
+++ b/src/components/views/dialogs/UploadConfirmDialog.tsx
@@ -86,7 +86,7 @@ export default class UploadConfirmDialog extends React.Component {
preview =
- {this.props.file.name} ({filesize(this.props.file.size)})
+ { this.props.file.name } ({ filesize(this.props.file.size) })
;
} else {
@@ -95,7 +95,7 @@ export default class UploadConfirmDialog extends React.Component {
- {this.props.file.name} ({filesize(this.props.file.size)})
+ { this.props.file.name } ({ filesize(this.props.file.size) })
;
}
@@ -103,7 +103,7 @@ export default class UploadConfirmDialog extends React.Component {
let uploadAllButton;
if (this.props.currentIndex + 1 < this.props.totalFiles) {
uploadAllButton =
- {_t("Upload all")}
+ { _t("Upload all") }
;
}
@@ -115,7 +115,7 @@ export default class UploadConfirmDialog extends React.Component {
contentId='mx_Dialog_content'
>
- {preview}
+ { preview }
{
onPrimaryButtonClick={this.onUploadClick}
focus={true}
>
- {uploadAllButton}
+ { uploadAllButton }
);
diff --git a/src/components/views/dialogs/UploadFailureDialog.js b/src/components/views/dialogs/UploadFailureDialog.js
index d26b83d0d6..224098f935 100644
--- a/src/components/views/dialogs/UploadFailureDialog.js
+++ b/src/components/views/dialogs/UploadFailureDialog.js
@@ -60,7 +60,7 @@ export default class UploadFailureDialog extends React.Component {
limit: filesize(this.props.contentMessages.getUploadLimit()),
sizeOfThisFile: filesize(this.props.badFiles[0].size),
}, {
- b: sub => {sub},
+ b: sub => { sub },
},
);
buttons = {sub},
+ b: sub => { sub },
},
);
buttons = {sub},
+ b: sub => { sub },
},
);
const howManyOthers = this.props.totalFiles - this.props.badFiles.length;
@@ -111,11 +111,11 @@ export default class UploadFailureDialog extends React.Component {
contentId='mx_Dialog_content'
>
- {message}
- {preview}
+ { message }
+ { preview }
- {buttons}
+ { buttons }
);
}
diff --git a/src/components/views/dialogs/UserSettingsDialog.tsx b/src/components/views/dialogs/UserSettingsDialog.tsx
index e85938afe0..7608d7cb55 100644
--- a/src/components/views/dialogs/UserSettingsDialog.tsx
+++ b/src/components/views/dialogs/UserSettingsDialog.tsx
@@ -81,7 +81,7 @@ export default class UserSettingsDialog extends React.Component
this.setState({ mjolnirEnabled: newValue });
};
- _getTabs() {
+ private getTabs() {
const tabs = [];
tabs.push(new Tab(
@@ -170,7 +170,7 @@ export default class UserSettingsDialog extends React.Component
title={_t("Settings")}
>
-
+
);
diff --git a/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx b/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx
index 638d5cde93..ebeab191b1 100644
--- a/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx
+++ b/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx
@@ -105,7 +105,7 @@ export default class WidgetCapabilitiesPromptDialog extends React.PureComponent<
const checkboxRows = Object.entries(this.state.booleanStates).map(([cap, isChecked], i) => {
const text = CapabilityText.for(cap, this.props.widgetKind);
const byline = text.byline
- ? {text.byline}
+ ? { text.byline }
: null;
return (
@@ -113,8 +113,8 @@ export default class WidgetCapabilitiesPromptDialog extends React.PureComponent<
this.onToggle(cap)}
- >{text.primary}
- {byline}
+ >{ text.primary }
+ { byline }
);
});
@@ -127,8 +127,8 @@ export default class WidgetCapabilitiesPromptDialog extends React.PureComponent<
>
- {_t("This widget would like to:")}
- {checkboxRows}
+ { _t("This widget would like to:") }
+ { checkboxRows }
- {_t("The widget will verify your user ID, but won't be able to perform actions for you:")}
+ { _t("The widget will verify your user ID, but won't be able to perform actions for you:") }
- {/* cheap trim to just get the path */}
- {this.props.widget.templateUrl.split("?")[0].split("#")[0]}
+ { /* cheap trim to just get the path */ }
+ { this.props.widget.templateUrl.split("?")[0].split("#")[0] }
- {_t("Forgotten or lost all recovery methods? Reset all", null, {
+ { _t("Forgotten or lost all recovery methods? Reset all", null, {
a: (sub) => {sub},
- })}
+ className="mx_AccessSecretStorageDialog_reset_link">{ sub },
+ }) }
);
@@ -300,9 +300,9 @@ export default class AccessSecretStorageDialog extends React.PureComponent
- {_t("Only do this if you have no other device to complete verification with.")}
- {_t("If you reset everything, you will restart with no trusted sessions, no trusted users, and "
- + "might not be able to see past messages.")}
+ { _t("Only do this if you have no other device to complete verification with.") }
+ { _t("If you reset everything, you will restart with no trusted sessions, no trusted users, and "
+ + "might not be able to see past messages.") }
- {"\uD83D\uDC4E "}{_t(
+ { "\uD83D\uDC4E " }{ _t(
"Unable to access secret storage. " +
"Please verify that you entered the correct Security Phrase.",
- )}
+ ) }
;
} else {
keyStatus = ;
}
content =
- {_t(
+
{ _t(
"Enter your Security Phrase or Use your Security Key to continue.", {},
{
button: s =>
- {s}
+ { s }
,
},
- )}
+ ) }
- {keyStatus}
+ { keyStatus }
- {this.getKeyValidationText()}
+ { this.getKeyValidationText() }
;
content =
- {_t("Use your Security Key to continue.")}
+ { _t("Use your Security Key to continue.") }
- {_t("or")}
+ { _t("or") }
- {_t("Upload")}
+ { _t("Upload") }
- {recoveryKeyFeedback}
+ { recoveryKeyFeedback }
- {content}
+ { content }
);
diff --git a/src/components/views/dialogs/security/ConfirmDestroyCrossSigningDialog.tsx b/src/components/views/dialogs/security/ConfirmDestroyCrossSigningDialog.tsx
index c0530a35ea..392598ca36 100644
--- a/src/components/views/dialogs/security/ConfirmDestroyCrossSigningDialog.tsx
+++ b/src/components/views/dialogs/security/ConfirmDestroyCrossSigningDialog.tsx
@@ -44,12 +44,12 @@ export default class ConfirmDestroyCrossSigningDialog extends React.Component
- {_t(
+ { _t(
"Deleting cross-signing keys is permanent. " +
"Anyone you have verified with will see security alerts. " +
"You almost certainly don't want to do this, unless " +
"you've lost every device you can cross-sign from.",
- )}
+ ) }
- {_t("Unable to set up keys")}
+ { _t("Unable to set up keys") }
- {content}
+ { content }
);
diff --git a/src/components/views/dialogs/security/RestoreKeyBackupDialog.js b/src/components/views/dialogs/security/RestoreKeyBackupDialog.js
index 5f21033d29..e8bd8af01c 100644
--- a/src/components/views/dialogs/security/RestoreKeyBackupDialog.js
+++ b/src/components/views/dialogs/security/RestoreKeyBackupDialog.js
@@ -288,7 +288,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
details = _t("Fetching keys from server...");
}
content =
- {details}
+ { details }
;
} else if (this.state.loadError) {
@@ -299,18 +299,18 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
if (this.state.restoreType === RESTORE_TYPE_RECOVERYKEY) {
title = _t("Security Key mismatch");
content =
- {_t(
+
{ _t(
"Backup could not be decrypted with this Security Key: " +
"please verify that you entered the correct Security Key.",
- )}
+ ) }
;
} else {
title = _t("Incorrect Security Phrase");
content =
- {_t(
+
{ _t(
"Backup could not be decrypted with this Security Phrase: " +
"please verify that you entered the correct Security Phrase.",
- )}
+ ) }
;
}
} else {
@@ -325,14 +325,14 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
title = _t("Keys restored");
let failedToDecrypt;
if (this.state.recoverInfo.total > this.state.recoverInfo.imported) {
- failedToDecrypt = {_t(
+ failedToDecrypt =
{ _t(
"Failed to decrypt %(failedCount)s sessions!",
{ failedCount: this.state.recoverInfo.total - this.state.recoverInfo.imported },
- )}
;
+ ) };
}
content =
- {_t("Successfully restored %(sessionCount)s keys", { sessionCount: this.state.recoverInfo.imported })}
- {failedToDecrypt}
+ { _t("Successfully restored %(sessionCount)s keys", { sessionCount: this.state.recoverInfo.imported }) }
+ { failedToDecrypt }
- {_t(
+
{ _t(
"Warning: you should only set up key backup " +
"from a trusted computer.", {},
- { b: sub => {sub} },
- )}
- {_t(
+ { b: sub => { sub } },
+ ) }
+ { _t(
"Access your secure message history and set up secure " +
"messaging by entering your Security Phrase.",
- )}
+ ) }
- {_t(
+ { _t(
"If you've forgotten your Security Phrase you can "+
"use your Security Key or " +
"set up new recovery options ",
@@ -381,16 +381,16 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
element="span"
onClick={this._onUseRecoveryKeyClick}
>
- {s}
+ { s }
,
button2: s =>
- {s}
+ { s }
,
- })}
+ }) }
;
} else {
title = _t("Enter Security Key");
@@ -402,24 +402,24 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
keyStatus = ;
} else if (this.state.recoveryKeyValid) {
keyStatus =
- {"\uD83D\uDC4D "}{_t("This looks like a valid Security Key!")}
+ { "\uD83D\uDC4D " }{ _t("This looks like a valid Security Key!") }
;
} else {
keyStatus =
- {"\uD83D\uDC4E "}{_t("Not a valid Security Key")}
+ { "\uD83D\uDC4E " }{ _t("Not a valid Security Key") }
;
}
content =
- {_t(
+
{ _t(
"Warning: You should only set up key backup " +
"from a trusted computer.", {},
- { b: sub => {sub} },
- )}
- {_t(
+ { b: sub => { sub } },
+ ) }
+ { _t(
"Access your secure message history and set up secure " +
"messaging by entering your Security Key.",
- )}
+ ) }
- {keyStatus}
+ { keyStatus }
- {_t(
+ { _t(
"If you've forgotten your Security Key you can "+
"set up new recovery options ",
{},
@@ -445,10 +445,10 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
element="span"
onClick={this._onResetRecoveryClick}
>
- {s}
+ { s }
,
},
- )}
+ ) }
;
}
@@ -458,7 +458,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
title={title}
>
- {content}
+ { content }
);
diff --git a/src/components/views/directory/NetworkDropdown.tsx b/src/components/views/directory/NetworkDropdown.tsx
index e4a967fbdc..dbad2ca024 100644
--- a/src/components/views/directory/NetworkDropdown.tsx
+++ b/src/components/views/directory/NetworkDropdown.tsx
@@ -184,7 +184,7 @@ const NetworkDropdown = ({ onOptionChange, protocols = {}, selectedServerName, s
if (server === hsName) {
subtitle = (
- {_t("Your server")}
+ { _t("Your server") }
);
}
@@ -238,7 +238,7 @@ const NetworkDropdown = ({ onOptionChange, protocols = {}, selectedServerName, s
label={_t("Matrix")}
className="mx_NetworkDropdown_server_network"
>
- {_t("Matrix")}
+ { _t("Matrix") }
{ entries }
@@ -270,9 +270,9 @@ const NetworkDropdown = ({ onOptionChange, protocols = {}, selectedServerName, s
const buttonRect = handle.current.getBoundingClientRect();
content =
- {options}
+ { options }
;
@@ -295,15 +295,15 @@ const NetworkDropdown = ({ onOptionChange, protocols = {}, selectedServerName, s
isExpanded={menuDisplayed}
>
- {currentValue}
+ { currentValue }
- ({selectedServerName})
+ ({ selectedServerName })
;
}
return
- {content}
+ { content }
;
};
diff --git a/src/components/views/elements/AppPermission.js b/src/components/views/elements/AppPermission.js
index c1f370b626..a7d249164b 100644
--- a/src/components/views/elements/AppPermission.js
+++ b/src/components/views/elements/AppPermission.js
@@ -94,15 +94,15 @@ export default class AppPermission extends React.Component {
const warningTooltipText = (
- {_t("Any of the following data may be shared:")}
+ { _t("Any of the following data may be shared:") }
- - {_t("Your display name")}
- - {_t("Your avatar URL")}
- - {_t("Your user ID")}
- - {_t("Your theme")}
- - {_t("%(brand)s URL", { brand })}
- - {_t("Room ID")}
- - {_t("Widget ID")}
+ - { _t("Your display name") }
+ - { _t("Your avatar URL") }
+ - { _t("Your user ID") }
+ - { _t("Your theme") }
+ - { _t("%(brand)s URL", { brand }) }
+ - { _t("Room ID") }
+ - { _t("Widget ID") }
);
@@ -124,22 +124,22 @@ export default class AppPermission extends React.Component {
return (
- {_t("Widget added by")}
+ { _t("Widget added by") }
- {avatar}
- {displayName}
- {userId}
+ { avatar }
+ { displayName }
+ { userId }
- {warning}
+ { warning }
- {_t("This widget may use cookies.")} {encryptionWarning}
+ { _t("This widget may use cookies.") } { encryptionWarning }
- {_t("Continue")}
+ { _t("Continue") }
diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js
index 7e98537180..74ef178066 100644
--- a/src/components/views/elements/AppTile.js
+++ b/src/components/views/elements/AppTile.js
@@ -408,7 +408,7 @@ export default class AppTile extends React.Component {
// AppTile's border is in the wrong place
appTileBody =
- {appTileBody}
+ { appTileBody }
;
}
@@ -453,13 +453,13 @@ export default class AppTile extends React.Component {
title={_t('Popout widget')}
onClick={this._onPopoutWidgetClick}
/> }
- { }
+ />
}
{ appTileBody }
diff --git a/src/components/views/elements/DNDTagTile.js b/src/components/views/elements/DNDTagTile.js
index 2e88d37882..97bae82e61 100644
--- a/src/components/views/elements/DNDTagTile.js
+++ b/src/components/views/elements/DNDTagTile.js
@@ -41,6 +41,6 @@ export default function DNDTagTile(props) {
menuDisplayed={menuDisplayed}
openMenu={openMenu}
/>
- {contextMenu}
+ { contextMenu }
>;
}
diff --git a/src/components/views/elements/DesktopBuildsNotice.tsx b/src/components/views/elements/DesktopBuildsNotice.tsx
index c97a9b6cef..f2441b83a4 100644
--- a/src/components/views/elements/DesktopBuildsNotice.tsx
+++ b/src/components/views/elements/DesktopBuildsNotice.tsx
@@ -38,7 +38,7 @@ export default function DesktopBuildsNotice({ isRoomEncrypted, kind }: IProps) {
if (EventIndexPeg.error) {
return <>
- {_t("Message search initialisation failed, check your settings for more information", {}, {
+ { _t("Message search initialisation failed, check your settings for more information", {}, {
a: sub => ( {
evt.preventDefault();
dis.dispatch({
@@ -46,9 +46,9 @@ export default function DesktopBuildsNotice({ isRoomEncrypted, kind }: IProps) {
initialTabId: UserTab.Security,
});
}}>
- {sub}
+ { sub }
),
- })}
+ }) }
>;
}
@@ -61,12 +61,12 @@ export default function DesktopBuildsNotice({ isRoomEncrypted, kind }: IProps) {
switch (kind) {
case WarningKind.Files:
text = _t("Use the Desktop app to see all encrypted files", {}, {
- a: sub => ({sub}),
+ a: sub => ({ sub }),
});
break;
case WarningKind.Search:
text = _t("Use the Desktop app to search encrypted messages", {}, {
- a: sub => ({sub}),
+ a: sub => ({ sub }),
});
break;
}
@@ -89,8 +89,8 @@ export default function DesktopBuildsNotice({ isRoomEncrypted, kind }: IProps) {
return (
- {logo}
- {text}
+ { logo }
+ { text }
);
}
diff --git a/src/components/views/elements/DesktopCapturerSourcePicker.tsx b/src/components/views/elements/DesktopCapturerSourcePicker.tsx
index 8f9b847f4f..82d0aa4976 100644
--- a/src/components/views/elements/DesktopCapturerSourcePicker.tsx
+++ b/src/components/views/elements/DesktopCapturerSourcePicker.tsx
@@ -56,7 +56,7 @@ export class ExistingSource extends React.Component
className="mx_desktopCapturerSourcePicker_stream_thumbnail"
src={this.props.source.thumbnailURL}
/>
- {this.props.source.name}
+ { this.props.source.name }
);
}
@@ -157,13 +157,13 @@ export default class DesktopCapturerSourcePicker extends React.Component<
className={screensButtonStyle}
onClick={this.onScreensClick}
>
- {_t("Screens")}
+ { _t("Screens") }
- {_t("Windows")}
+ { _t("Windows") }
diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js
index af68260563..9dd4a84b9a 100644
--- a/src/components/views/elements/DialogButtons.js
+++ b/src/components/views/elements/DialogButtons.js
@@ -92,7 +92,7 @@ export default class DialogButtons extends React.Component {
let additive = null;
if (this.props.additive) {
- additive = {this.props.additive};
+ additive = { this.props.additive };
}
return (
diff --git a/src/components/views/elements/DirectorySearchBox.js b/src/components/views/elements/DirectorySearchBox.js
index 45270ada64..11b1ed2cd2 100644
--- a/src/components/views/elements/DirectorySearchBox.js
+++ b/src/components/views/elements/DirectorySearchBox.js
@@ -88,7 +88,7 @@ export default class DirectorySearchBox extends React.Component {
if (this.props.showJoinButton) {
joinButton = {_t("Join")} ;
+ >{ _t("Join") };
}
return
diff --git a/src/components/views/elements/EditableItemList.tsx b/src/components/views/elements/EditableItemList.tsx
index 89e2e1b8a0..5d6e24ab27 100644
--- a/src/components/views/elements/EditableItemList.tsx
+++ b/src/components/views/elements/EditableItemList.tsx
@@ -63,21 +63,21 @@ export class EditableItem extends React.Component {
return (
- {_t("Are you sure?")}
+ { _t("Are you sure?") }
- {_t("Yes")}
+ { _t("Yes") }
- {_t("No")}
+ { _t("No") }
);
@@ -86,7 +86,7 @@ export class EditableItem extends React.Component {
return (
- {this.props.value}
+ { this.props.value }
);
}
@@ -155,7 +155,7 @@ export default class EditableItemList extends React.PureComponent {
if (!this.props.canRemove) {
- return {item} ;
+ return { item } ;
}
return extends React.PureComponent ;
});
- const editableItemsSection = this.props.canRemove ? editableItems : {editableItems}
;
+ const editableItemsSection = this.props.canRemove ? editableItems : { editableItems }
;
const label = this.props.items.length > 0 ? this.props.itemsLabel : this.props.noItemsLabel;
return (
diff --git a/src/components/views/elements/ErrorBoundary.tsx b/src/components/views/elements/ErrorBoundary.tsx
index f967b8c594..334e569163 100644
--- a/src/components/views/elements/ErrorBoundary.tsx
+++ b/src/components/views/elements/ErrorBoundary.tsx
@@ -81,33 +81,33 @@ export default class ErrorBoundary extends React.PureComponent<{}, IState> {
let bugReportSection;
if (SdkConfig.get().bug_report_endpoint_url) {
bugReportSection =
- {_t(
+
{ _t(
"Please create a new issue " +
"on GitHub so that we can investigate this bug.", {}, {
newIssueLink: (sub) => {
return { sub };
},
},
- )}
- {_t(
+ ) }
+ { _t(
"If you've submitted a bug via GitHub, debug logs can help " +
"us track down the problem. Debug logs contain application " +
"usage data including your username, the IDs or aliases of " +
"the rooms or groups you have visited and the usernames of " +
"other users. They do not contain messages.",
- )}
+ ) }
- {_t("Submit debug logs")}
+ { _t("Submit debug logs") }
;
}
return
- {_t("Something went wrong!")}
+ { _t("Something went wrong!") }
{ bugReportSection }
- {_t("Clear cache and reload")}
+ { _t("Clear cache and reload") }
;
diff --git a/src/components/views/elements/EventListSummary.tsx b/src/components/views/elements/EventListSummary.tsx
index 681817ca86..b1cc9c773d 100644
--- a/src/components/views/elements/EventListSummary.tsx
+++ b/src/components/views/elements/EventListSummary.tsx
@@ -63,7 +63,7 @@ const EventListSummary: React.FC = ({
// If we are only given few events then just pass them through
if (events.length < threshold) {
return (
-
+
{ children }
);
@@ -92,7 +92,7 @@ const EventListSummary: React.FC = ({
}
return (
-
+
{ expanded ? _t('collapse') : _t('expand') }
@@ -101,4 +101,8 @@ const EventListSummary: React.FC = ({
);
};
+EventListSummary.defaultProps = {
+ startExpanded: false,
+};
+
export default EventListSummary;
diff --git a/src/components/views/elements/FacePile.tsx b/src/components/views/elements/FacePile.tsx
index aeca2e844b..0c19a7a63a 100644
--- a/src/components/views/elements/FacePile.tsx
+++ b/src/components/views/elements/FacePile.tsx
@@ -78,7 +78,7 @@ const FacePile = ({ room, onlyKnownUsers = true, numShown = DEFAULT_NUM_FACES, .
{ members.length > numShown ? : null }
{ shownMembers.map(m =>
- )}
+ ) }
{ onlyKnownUsers &&
{ _t("%(count)s people you know have already joined", { count: members.length }) }
diff --git a/src/components/views/elements/Field.tsx b/src/components/views/elements/Field.tsx
index 60f029c32e..5713518eb8 100644
--- a/src/components/views/elements/Field.tsx
+++ b/src/components/views/elements/Field.tsx
@@ -240,11 +240,11 @@ export default class Field extends React.PureComponent {
let prefixContainer = null;
if (prefixComponent) {
- prefixContainer = {prefixComponent};
+ prefixContainer = { prefixComponent };
}
let postfixContainer = null;
if (postfixComponent) {
- postfixContainer = {postfixComponent};
+ postfixContainer = { postfixComponent };
}
const hasValidationFlag = forceValidity !== null && forceValidity !== undefined;
@@ -273,11 +273,11 @@ export default class Field extends React.PureComponent {
}
return
- {prefixContainer}
- {fieldInput}
-
- {postfixContainer}
- {fieldTooltip}
+ { prefixContainer }
+ { fieldInput }
+
+ { postfixContainer }
+ { fieldTooltip }
;
}
}
diff --git a/src/components/views/elements/ImageView.tsx b/src/components/views/elements/ImageView.tsx
index 16263e5204..954c1ab783 100644
--- a/src/components/views/elements/ImageView.tsx
+++ b/src/components/views/elements/ImageView.tsx
@@ -457,7 +457,7 @@ export default class ImageView extends React.Component {
+ onClick={this.onRotateCounterClockwiseClick}>
{
+ onClick={this.onDownloadClick}>
{ contextMenuButton }
+ onClick={this.props.onFinished}>
{ this.renderContextMenu() }
@@ -488,8 +488,8 @@ export default class ImageView extends React.Component {
>
- {children}
- {tip}
+ { children }
+ { tip }
);
}
diff --git a/src/components/views/elements/InlineSpinner.tsx b/src/components/views/elements/InlineSpinner.tsx
index a98e03502b..e2cda2f28d 100644
--- a/src/components/views/elements/InlineSpinner.tsx
+++ b/src/components/views/elements/InlineSpinner.tsx
@@ -39,7 +39,7 @@ export default class InlineSpinner extends React.PureComponent {
style={{ width: this.props.w, height: this.props.h }}
aria-label={_t("Loading...")}
>
- {this.props.children}
+ { this.props.children }
);
diff --git a/src/components/views/elements/InviteReason.tsx b/src/components/views/elements/InviteReason.tsx
index d684f61859..dff5c7d6bd 100644
--- a/src/components/views/elements/InviteReason.tsx
+++ b/src/components/views/elements/InviteReason.tsx
@@ -51,11 +51,11 @@ export default class InviteReason extends React.PureComponent {
});
return
- {this.props.reason}
+ { this.props.reason }
- {_t("View message")}
+ { _t("View message") }
;
}
diff --git a/src/components/views/elements/LabelledToggleSwitch.tsx b/src/components/views/elements/LabelledToggleSwitch.tsx
index 14853ea117..24647df502 100644
--- a/src/components/views/elements/LabelledToggleSwitch.tsx
+++ b/src/components/views/elements/LabelledToggleSwitch.tsx
@@ -57,8 +57,8 @@ export default class LabelledToggleSwitch extends React.PureComponent {
const classes = `mx_SettingsFlag ${this.props.className || ""}`;
return (
- {firstPart}
- {secondPart}
+ { firstPart }
+ { secondPart }
);
}
diff --git a/src/components/views/elements/PersistedElement.js b/src/components/views/elements/PersistedElement.js
index 22d4bfdd68..deb1cd92e2 100644
--- a/src/components/views/elements/PersistedElement.js
+++ b/src/components/views/elements/PersistedElement.js
@@ -83,7 +83,7 @@ export default class PersistedElement extends React.Component {
// for this, so we bodge it by listening for document resize and
// the timeline_resize action.
window.addEventListener('resize', this._repositionChild);
- this._dispatcherRef = dis.register(this._onAction);
+ this.dispatcherRef = dis.register(this._onAction);
}
/**
@@ -156,7 +156,7 @@ export default class PersistedElement extends React.Component {
renderApp() {
const content =
- {this.props.children}
+ { this.props.children }
;
diff --git a/src/components/views/elements/PowerSelector.js b/src/components/views/elements/PowerSelector.js
index ef449df295..016e7ddea5 100644
--- a/src/components/views/elements/PowerSelector.js
+++ b/src/components/views/elements/PowerSelector.js
@@ -161,7 +161,7 @@ export default class PowerSelector extends React.Component {
label={label} onChange={this.onSelectChange}
value={String(this.state.selectValue)} disabled={this.props.disabled}
>
- {options}
+ { options }
);
}
diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.tsx
similarity index 85%
rename from src/components/views/elements/ReplyThread.js
rename to src/components/views/elements/ReplyThread.tsx
index 89427515e2..0eb795e257 100644
--- a/src/components/views/elements/ReplyThread.js
+++ b/src/components/views/elements/ReplyThread.tsx
@@ -14,14 +14,14 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
+
import React from 'react';
import { _t } from '../../../languageHandler';
-import PropTypes from 'prop-types';
import dis from '../../../dispatcher/dispatcher';
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
import { makeUserPermalink, RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks";
import SettingsStore from "../../../settings/SettingsStore";
-import { LayoutPropType } from "../../../settings/Layout";
+import { Layout } from "../../../settings/Layout";
import escapeHtml from "escape-html";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { getUserNameColorClass } from "../../../utils/FormattingUtils";
@@ -32,51 +32,54 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
import Spinner from './Spinner';
import ReplyTile from "../rooms/ReplyTile";
import Pill from './Pill';
+import { Room } from 'matrix-js-sdk/src/models/room';
+
+interface IProps {
+ // the latest event in this chain of replies
+ parentEv?: MatrixEvent;
+ // called when the ReplyThread contents has changed, including EventTiles thereof
+ onHeightChanged: () => void;
+ permalinkCreator: RoomPermalinkCreator;
+ // Specifies which layout to use.
+ layout?: Layout;
+ // Whether to always show a timestamp
+ alwaysShowTimestamps?: boolean;
+}
+
+interface IState {
+ // The loaded events to be rendered as linear-replies
+ events: MatrixEvent[];
+ // The latest loaded event which has not yet been shown
+ loadedEv: MatrixEvent;
+ // Whether the component is still loading more events
+ loading: boolean;
+ // Whether as error was encountered fetching a replied to event.
+ err: boolean;
+}
// This component does no cycle detection, simply because the only way to make such a cycle would be to
// craft event_id's, using a homeserver that generates predictable event IDs; even then the impact would
// be low as each event being loaded (after the first) is triggered by an explicit user action.
@replaceableComponent("views.elements.ReplyThread")
-export default class ReplyThread extends React.Component {
- static propTypes = {
- // the latest event in this chain of replies
- parentEv: PropTypes.instanceOf(MatrixEvent),
- // called when the ReplyThread contents has changed, including EventTiles thereof
- onHeightChanged: PropTypes.func.isRequired,
- permalinkCreator: PropTypes.instanceOf(RoomPermalinkCreator).isRequired,
- // Specifies which layout to use.
- layout: LayoutPropType,
- // Whether to always show a timestamp
- alwaysShowTimestamps: PropTypes.bool,
- };
-
+export default class ReplyThread extends React.Component {
static contextType = MatrixClientContext;
+ private unmounted = false;
+ private room: Room;
constructor(props, context) {
super(props, context);
this.state = {
- // The loaded events to be rendered as linear-replies
events: [],
-
- // The latest loaded event which has not yet been shown
loadedEv: null,
- // Whether the component is still loading more events
loading: true,
-
- // Whether as error was encountered fetching a replied to event.
err: false,
};
- this.unmounted = false;
this.room = this.context.getRoom(this.props.parentEv.getRoomId());
-
- this.onQuoteClick = this.onQuoteClick.bind(this);
- this.canCollapse = this.canCollapse.bind(this);
- this.collapse = this.collapse.bind(this);
}
- static getParentEventId(ev) {
+ public static getParentEventId(ev: MatrixEvent): string {
if (!ev || ev.isRedacted()) return;
// XXX: For newer relations (annotations, replacements, etc.), we now
@@ -92,7 +95,7 @@ export default class ReplyThread extends React.Component {
}
// Part of Replies fallback support
- static stripPlainReply(body) {
+ public static stripPlainReply(body: string): string {
// Removes lines beginning with `> ` until you reach one that doesn't.
const lines = body.split('\n');
while (lines.length && lines[0].startsWith('> ')) lines.shift();
@@ -102,7 +105,7 @@ export default class ReplyThread extends React.Component {
}
// Part of Replies fallback support
- static stripHTMLReply(html) {
+ public static stripHTMLReply(html: string): string {
// Sanitize the original HTML for inclusion in . We allow
// any HTML, since the original sender could use special tags that we
// don't recognize, but want to pass along to any recipients who do
@@ -124,7 +127,10 @@ export default class ReplyThread extends React.Component {
}
// Part of Replies fallback support
- static getNestedReplyText(ev, permalinkCreator) {
+ public static getNestedReplyText(
+ ev: MatrixEvent,
+ permalinkCreator: RoomPermalinkCreator,
+ ): { body: string, html: string } {
if (!ev) return null;
let { body, formatted_body: html } = ev.getContent();
@@ -200,7 +206,7 @@ export default class ReplyThread extends React.Component {
return { body, html };
}
- static makeReplyMixIn(ev) {
+ public static makeReplyMixIn(ev: MatrixEvent) {
if (!ev) return {};
return {
'm.relates_to': {
@@ -211,10 +217,15 @@ export default class ReplyThread extends React.Component {
};
}
- static makeThread(parentEv, onHeightChanged, permalinkCreator, ref, layout, alwaysShowTimestamps) {
- if (!ReplyThread.getParentEventId(parentEv)) {
- return null;
- }
+ public static makeThread(
+ parentEv: MatrixEvent,
+ onHeightChanged: () => void,
+ permalinkCreator: RoomPermalinkCreator,
+ ref: React.RefObject,
+ layout: Layout,
+ alwaysShowTimestamps: boolean,
+ ): JSX.Element {
+ if (!ReplyThread.getParentEventId(parentEv)) return null;
return {
const { parentEv } = this.props;
// at time of making this component we checked that props.parentEv has a parentEventId
const ev = await this.getEvent(ReplyThread.getParentEventId(parentEv));
@@ -256,7 +267,7 @@ export default class ReplyThread extends React.Component {
}
}
- async getNextEvent(ev) {
+ private async getNextEvent(ev: MatrixEvent): Promise {
try {
const inReplyToEventId = ReplyThread.getParentEventId(ev);
return await this.getEvent(inReplyToEventId);
@@ -265,7 +276,7 @@ export default class ReplyThread extends React.Component {
}
}
- async getEvent(eventId) {
+ private async getEvent(eventId: string): Promise {
if (!eventId) return null;
const event = this.room.findEventById(eventId);
if (event) return event;
@@ -282,15 +293,15 @@ export default class ReplyThread extends React.Component {
return this.room.findEventById(eventId);
}
- canCollapse() {
+ public canCollapse = (): boolean => {
return this.state.events.length > 1;
- }
+ };
- collapse() {
+ public collapse = (): void => {
this.initialize();
- }
+ };
- async onQuoteClick() {
+ private onQuoteClick = async (): Promise => {
const events = [this.state.loadedEv, ...this.state.events];
let loadedEv = null;
@@ -304,9 +315,9 @@ export default class ReplyThread extends React.Component {
});
dis.fire(Action.FocusSendMessageComposer);
- }
+ };
- getReplyThreadColorClass(ev) {
+ private getReplyThreadColorClass(ev: MatrixEvent): string {
return getUserNameColorClass(ev.getSender()).replace("Username", "ReplyThread");
}
diff --git a/src/components/views/elements/RoomAliasField.tsx b/src/components/views/elements/RoomAliasField.tsx
index 62de4dd2bb..a7676e4214 100644
--- a/src/components/views/elements/RoomAliasField.tsx
+++ b/src/components/views/elements/RoomAliasField.tsx
@@ -55,7 +55,7 @@ export default class RoomAliasField extends React.PureComponent
render() {
const poundSign = (#);
const aliasPostfix = ":" + this.props.domain;
- const domain = ({aliasPostfix});
+ const domain = ({ aliasPostfix });
const maxlength = 255 - this.props.domain.length - 2; // 2 for # and :
return (
- {_t("Edit")}
+ { _t("Edit") }
;
}
let serverName: React.ReactNode = serverConfig.isNameResolvable ? serverConfig.hsName : serverConfig.hsUrl;
if (serverConfig.hsNameIsDifferent) {
serverName =
- {serverConfig.hsName}
+ { serverConfig.hsName }
;
}
let desc;
if (serverConfig.hsName === "matrix.org") {
desc =
- {_t("Join millions for free on the largest public server")}
+ { _t("Join millions for free on the largest public server") }
;
}
return
- {title || _t("Homeserver")}
+ { title || _t("Homeserver") }
- {serverName}
+ { serverName }
{ editBtn }
{ desc }
;
diff --git a/src/components/views/elements/SettingsFlag.tsx b/src/components/views/elements/SettingsFlag.tsx
index ccde80ff00..0847db801e 100644
--- a/src/components/views/elements/SettingsFlag.tsx
+++ b/src/components/views/elements/SettingsFlag.tsx
@@ -88,12 +88,12 @@ export default class SettingsFlag extends React.Component {
onChange={this.checkBoxOnChange}
disabled={this.props.disabled || !canChange}
>
- {label}
+ { label }
;
} else {
return (
- {label}
+ { label }
{
{ selection }
- {dots}
+ { dots }
;
@@ -139,7 +139,7 @@ class Dot extends React.PureComponent {
- {this.props.label}
+ { this.props.label }
;
diff --git a/src/components/views/elements/SpellCheckLanguagesDropdown.tsx b/src/components/views/elements/SpellCheckLanguagesDropdown.tsx
index 5230042c38..972dac909a 100644
--- a/src/components/views/elements/SpellCheckLanguagesDropdown.tsx
+++ b/src/components/views/elements/SpellCheckLanguagesDropdown.tsx
@@ -45,7 +45,7 @@ export default class SpellCheckLanguagesDropdown extends React.Component {
constructor(props) {
super(props);
- this._onSearchChange = this._onSearchChange.bind(this);
+ this.onSearchChange = this.onSearchChange.bind(this);
this.state = {
searchQuery: '',
@@ -76,10 +76,8 @@ export default class SpellCheckLanguagesDropdown extends React.Component
diff --git a/src/components/views/elements/Spoiler.js b/src/components/views/elements/Spoiler.js
index 56c18c6e33..802c6cf841 100644
--- a/src/components/views/elements/Spoiler.js
+++ b/src/components/views/elements/Spoiler.js
@@ -37,7 +37,7 @@ export default class Spoiler extends React.Component {
render() {
const reason = this.props.reason ? (
- {"(" + this.props.reason + ")"}
+ { "(" + this.props.reason + ")" }
) : null;
// react doesn't allow appending a DOM node as child.
// as such, we pass the this.props.contentHtml instead and then set the raw
diff --git a/src/components/views/elements/StyledCheckbox.tsx b/src/components/views/elements/StyledCheckbox.tsx
index 366cc2f1f7..b609f7159e 100644
--- a/src/components/views/elements/StyledCheckbox.tsx
+++ b/src/components/views/elements/StyledCheckbox.tsx
@@ -44,7 +44,7 @@ export default class StyledCheckbox extends React.PureComponent
return
diff --git a/src/components/views/settings/SecureBackupPanel.js b/src/components/views/settings/SecureBackupPanel.js
index b0292debe6..d473708ce1 100644
--- a/src/components/views/settings/SecureBackupPanel.js
+++ b/src/components/views/settings/SecureBackupPanel.js
@@ -221,7 +221,7 @@ export default class SecureBackupPanel extends React.PureComponent {
if (error) {
statusDescription = (
- {_t("Unable to load key backup status")}
+ { _t("Unable to load key backup status") }
);
} else if (loading) {
@@ -230,19 +230,19 @@ export default class SecureBackupPanel extends React.PureComponent {
let restoreButtonCaption = _t("Restore from Backup");
if (MatrixClientPeg.get().getKeyBackupEnabled()) {
- statusDescription = ✅ {_t("This session is backing up your keys. ")}
;
+ statusDescription = ✅ { _t("This session is backing up your keys. ") }
;
} else {
statusDescription = <>
- {_t(
+
{ _t(
"This session is not backing up your keys, " +
"but you do have an existing backup you can restore from " +
"and add to going forward.", {},
- { b: sub => {sub} },
- )}
- {_t(
+ { b: sub => { sub } },
+ ) }
+ { _t(
"Connect this session to key backup before signing out to avoid " +
"losing any keys that may only be on this session.",
- )}
+ ) }
>;
restoreButtonCaption = _t("Connect this session to Key Backup");
}
@@ -253,11 +253,11 @@ export default class SecureBackupPanel extends React.PureComponent {
uploadStatus = "";
} else if (sessionsRemaining > 0) {
uploadStatus =
- {_t("Backing up %(sessionsRemaining)s keys...", { sessionsRemaining })}
+ { _t("Backing up %(sessionsRemaining)s keys...", { sessionsRemaining }) }
;
} else {
uploadStatus =
- {_t("All keys backed up")}
+ { _t("All keys backed up") }
;
}
@@ -265,13 +265,13 @@ export default class SecureBackupPanel extends React.PureComponent {
const deviceName = sig.device ? (sig.device.getDisplayName() || sig.device.deviceId) : null;
const validity = sub =>
- {sub}
+ { sub }
;
const verify = sub =>
- {sub}
+ { sub }
;
- const device = sub => {deviceName};
+ const device = sub => { deviceName };
const fromThisDevice = (
sig.device &&
sig.device.getFingerprint() === MatrixClientPeg.get().getDeviceEd25519Key()
@@ -339,7 +339,7 @@ export default class SecureBackupPanel extends React.PureComponent {
}
return
- {sigStatus}
+ { sigStatus }
;
});
if (backupSigStatus.sigs.length === 0) {
@@ -353,45 +353,45 @@ export default class SecureBackupPanel extends React.PureComponent {
extraDetailsTableRows = <>
- {_t("Backup version:")}
- {backupInfo.version}
+ { _t("Backup version:") }
+ { backupInfo.version }
- {_t("Algorithm:")}
- {backupInfo.algorithm}
+ { _t("Algorithm:") }
+ { backupInfo.algorithm }
>;
extraDetails = <>
- {uploadStatus}
- {backupSigStatuses}
- {trustedLocally}
+ { uploadStatus }
+ { backupSigStatuses }
+ { trustedLocally }
>;
actions.push(
- {restoreButtonCaption}
+ { restoreButtonCaption }
,
);
if (!isSecureBackupRequired()) {
actions.push(
- {_t("Delete Backup")}
+ { _t("Delete Backup") }
,
);
}
} else {
statusDescription = <>
- {_t(
+
{ _t(
"Your keys are not being backed up from this session.", {},
- { b: sub => {sub} },
- )}
- {_t("Back up your keys before signing out to avoid losing them.")}
+ { b: sub => { sub } },
+ ) }
+ { _t("Back up your keys before signing out to avoid losing them.") }
>;
actions.push(
- {_t("Set up")}
+ { _t("Set up") }
,
);
}
@@ -399,7 +399,7 @@ export default class SecureBackupPanel extends React.PureComponent {
if (secretStorageKeyInAccount) {
actions.push(
- {_t("Reset")}
+ { _t("Reset") }
,
);
}
@@ -417,47 +417,47 @@ export default class SecureBackupPanel extends React.PureComponent {
let actionRow;
if (actions.length) {
actionRow =
- {actions}
+ { actions }
;
}
return (
- {_t(
+
{ _t(
"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.",
- )}
- {statusDescription}
+ ) }
+ { statusDescription }
- {_t("Advanced")}
+ { _t("Advanced") }
- {_t("Backup key stored:")}
+ { _t("Backup key stored:") }
{
backupKeyStored === true ? _t("in secret storage") : _t("not stored")
}
- {_t("Backup key cached:")}
+ { _t("Backup key cached:") }
- {backupKeyCached ? _t("cached locally") : _t("not found locally")}
- {backupKeyWellFormedText}
+ { backupKeyCached ? _t("cached locally") : _t("not found locally") }
+ { backupKeyWellFormedText }
- {_t("Secret storage public key:")}
- {secretStorageKeyInAccount ? _t("in account data") : _t("not found")}
+ { _t("Secret storage public key:") }
+ { secretStorageKeyInAccount ? _t("in account data") : _t("not found") }
- {_t("Secret storage:")}
- {secretStorageReady ? _t("ready") : _t("not ready")}
+ { _t("Secret storage:") }
+ { secretStorageReady ? _t("ready") : _t("not ready") }
- {extraDetailsTableRows}
+ { extraDetailsTableRows }
- {extraDetails}
+ { extraDetails }
- {actionRow}
+ { actionRow }
);
}
diff --git a/src/components/views/settings/SetIdServer.tsx b/src/components/views/settings/SetIdServer.tsx
index dc38055c10..fd8abc0dbe 100644
--- a/src/components/views/settings/SetIdServer.tsx
+++ b/src/components/views/settings/SetIdServer.tsx
@@ -134,7 +134,7 @@ export default class SetIdServer extends React.Component {
{ _t("Checking server") }
;
} else if (this.state.error) {
- return {this.state.error};
+ return { this.state.error };
} else {
return null;
}
@@ -193,8 +193,8 @@ export default class SetIdServer extends React.Component {
"Disconnect from the identity server and " +
"connect to instead?", {},
{
- current: sub => {abbreviateUrl(currentClientIdServer)},
- new: sub => {abbreviateUrl(idServer)},
+ current: sub => { abbreviateUrl(currentClientIdServer) },
+ new: sub => { abbreviateUrl(idServer) },
},
),
button: _t("Continue"),
@@ -224,10 +224,10 @@ export default class SetIdServer extends React.Component {
description: (
- {_t("The identity server you have chosen does not have any terms of service.")}
+ { _t("The identity server you have chosen does not have any terms of service.") }
- {_t("Only continue if you trust the owner of the server.")}
+ { _t("Only continue if you trust the owner of the server.") }
),
@@ -243,7 +243,7 @@ export default class SetIdServer extends React.Component {
title: _t("Disconnect identity server"),
unboundMessage: _t(
"Disconnect from the identity server ?", {},
- { idserver: sub => {abbreviateUrl(this.state.currentClientIdServer)} },
+ { idserver: sub => { abbreviateUrl(this.state.currentClientIdServer) } },
),
button: _t("Disconnect"),
});
@@ -278,41 +278,41 @@ export default class SetIdServer extends React.Component {
let message;
let danger = false;
const messageElements = {
- idserver: sub => {abbreviateUrl(currentClientIdServer)},
- b: sub => {sub},
+ idserver: sub => { abbreviateUrl(currentClientIdServer) },
+ b: sub => { sub },
};
if (!currentServerReachable) {
message =
- {_t(
+
{ _t(
"You should remove your personal data from identity server " +
" before disconnecting. Unfortunately, identity server " +
" is currently offline or cannot be reached.",
{}, messageElements,
- )}
- {_t("You should:")}
+ ) }
+ { _t("You should:") }
- - {_t(
+
- { _t(
"check your browser plugins for anything that might block " +
"the identity server (such as Privacy Badger)",
- )}
- - {_t("contact the administrators of identity server
", {}, {
+ ) }
+ - { _t("contact the administrators of identity server
", {}, {
idserver: messageElements.idserver,
- })}
- - {_t("wait and try again later")}
+ }) }
+ - { _t("wait and try again later") }
;
danger = true;
button = _t("Disconnect anyway");
} else if (boundThreepids.length) {
message =
- {_t(
+
{ _t(
"You are still sharing your personal data on the identity " +
"server .", {}, messageElements,
- )}
- {_t(
+ ) }
+ { _t(
"We recommend that you remove your email addresses and phone numbers " +
"from the identity server before disconnecting.",
- )}
+ ) }
;
danger = true;
button = _t("Disconnect anyway");
@@ -361,13 +361,13 @@ export default class SetIdServer extends React.Component {
"You are currently using to discover and be discoverable by " +
"existing contacts you know. You can change your identity server below.",
{},
- { server: sub => {abbreviateUrl(idServerUrl)} },
+ { server: sub => { abbreviateUrl(idServerUrl) } },
);
if (this.props.missingTerms) {
bodyText = _t(
"If you don't want to use to discover and be discoverable by existing " +
"contacts you know, enter another identity server below.",
- {}, { server: sub => {abbreviateUrl(idServerUrl)} },
+ {}, { server: sub => { abbreviateUrl(idServerUrl) } },
);
}
} else {
@@ -399,9 +399,9 @@ export default class SetIdServer extends React.Component {
discoButtonContent = ;
}
discoSection =
- {discoBodyText}
+ { discoBodyText }
- {discoButtonContent}
+ { discoButtonContent }
;
}
@@ -409,10 +409,10 @@ export default class SetIdServer extends React.Component {
return (
- {sectionTitle}
+ { sectionTitle }
- {bodyText}
+ { bodyText }
{
{_t("Change")}
- {discoSection}
+ >{ _t("Change") }
+ { discoSection }
);
}
diff --git a/src/components/views/settings/SetIntegrationManager.tsx b/src/components/views/settings/SetIntegrationManager.tsx
index f1922f93ee..e083efae0e 100644
--- a/src/components/views/settings/SetIntegrationManager.tsx
+++ b/src/components/views/settings/SetIntegrationManager.tsx
@@ -68,7 +68,7 @@ export default class SetIntegrationManager extends React.Component(%(serverName)s) to manage bots, widgets, " +
"and sticker packs.",
{ serverName: currentManager.name },
- { b: sub => {sub} },
+ { b: sub => { sub } },
);
} else {
bodyText = _t("Use an integration manager to manage bots, widgets, and sticker packs.");
@@ -77,18 +77,18 @@ export default class SetIntegrationManager extends React.Component
- {_t("Manage integrations")}
- {managerName}
+ { _t("Manage integrations") }
+ { managerName }
- {bodyText}
+ { bodyText }
- {_t(
+ { _t(
"Integration managers receive configuration data, and can modify widgets, " +
"send room invites, and set power levels on your behalf.",
- )}
+ ) }
);
diff --git a/src/components/views/settings/SpellCheckSettings.tsx b/src/components/views/settings/SpellCheckSettings.tsx
index 1858412dac..c653b272c8 100644
--- a/src/components/views/settings/SpellCheckSettings.tsx
+++ b/src/components/views/settings/SpellCheckSettings.tsx
@@ -35,7 +35,7 @@ interface SpellCheckLanguagesIState {
}
export class ExistingSpellCheckLanguage extends React.Component {
- _onRemove = (e) => {
+ private onRemove = (e) => {
e.stopPropagation();
e.preventDefault();
@@ -45,9 +45,9 @@ export class ExistingSpellCheckLanguage extends React.Component
- {this.props.language}
-
- {_t("Remove")}
+ { this.props.language }
+
+ { _t("Remove") }
);
@@ -63,12 +63,12 @@ export default class SpellCheckLanguages extends React.Component {
+ private onRemoved = (language: string) => {
const languages = this.props.languages.filter((e) => e !== language);
this.props.onLanguagesChange(languages);
};
- _onAddClick = (e) => {
+ private onAddClick = (e) => {
e.stopPropagation();
e.preventDefault();
@@ -81,31 +81,31 @@ export default class SpellCheckLanguages extends React.Component {
+ private onNewLanguageChange = (language: string) => {
if (this.state.newLanguage === language) return;
this.setState({ newLanguage: language });
};
render() {
const existingSpellCheckLanguages = this.props.languages.map((e) => {
- return ;
+ return ;
});
const addButton = (
-
- {_t("Add")}
+
+ { _t("Add") }
);
return (
- {existingSpellCheckLanguages}
-
+ { existingSpellCheckLanguages }
+
- {addButton}
+ onOptionChange={this.onNewLanguageChange} />
+ { addButton }
);
diff --git a/src/components/views/settings/UpdateCheckButton.tsx b/src/components/views/settings/UpdateCheckButton.tsx
index 2781aa971d..9d88e079a7 100644
--- a/src/components/views/settings/UpdateCheckButton.tsx
+++ b/src/components/views/settings/UpdateCheckButton.tsx
@@ -42,7 +42,7 @@ function getStatusText(status: UpdateCheckStatus, errorDetail?: string) {
return _t('Downloading update...');
case UpdateCheckStatus.Ready:
return _t("New version available. Update now.", {}, {
- a: sub => {sub} ,
+ a: sub => { sub } ,
});
}
}
@@ -72,14 +72,14 @@ const UpdateCheckButton = () => {
let suffix;
if (state) {
suffix =
- {getStatusText(state.status, state.detail)}
- {busy && }
+ { getStatusText(state.status, state.detail) }
+ { busy && }
;
}
return
- {_t("Check for update")}
+ { _t("Check for update") }
{ suffix }
;
diff --git a/src/components/views/settings/account/EmailAddresses.js b/src/components/views/settings/account/EmailAddresses.js
index 3c5ba21ae5..88e2217ec1 100644
--- a/src/components/views/settings/account/EmailAddresses.js
+++ b/src/components/views/settings/account/EmailAddresses.js
@@ -88,21 +88,21 @@ export class ExistingEmailAddress extends React.Component {
return (
- {_t("Remove %(email)s?", { email: this.props.email.address } )}
+ { _t("Remove %(email)s?", { email: this.props.email.address } ) }
- {_t("Remove")}
+ { _t("Remove") }
- {_t("Cancel")}
+ { _t("Cancel") }
);
@@ -110,9 +110,9 @@ export class ExistingEmailAddress extends React.Component {
return (
- {this.props.email.address}
+ { this.props.email.address }
- {_t("Remove")}
+ { _t("Remove") }
);
@@ -229,19 +229,19 @@ export default class EmailAddresses extends React.Component {
let addButton = (
- {_t("Add")}
+ { _t("Add") }
);
if (this.state.verifying) {
addButton = (
- {_t("We've sent you an email to verify your address. Please follow the instructions there and then click the button below.")}
+ { _t("We've sent you an email to verify your address. Please follow the instructions there and then click the button below.") }
- {_t("Continue")}
+ { _t("Continue") }
);
@@ -249,7 +249,7 @@ export default class EmailAddresses extends React.Component {
return (
- {existingEmailElements}
+ { existingEmailElements }
- {addButton}
+ { addButton }
);
diff --git a/src/components/views/settings/account/PhoneNumbers.js b/src/components/views/settings/account/PhoneNumbers.js
index c158d323ac..604abd1bd6 100644
--- a/src/components/views/settings/account/PhoneNumbers.js
+++ b/src/components/views/settings/account/PhoneNumbers.js
@@ -83,21 +83,21 @@ export class ExistingPhoneNumber extends React.Component {
return (
- {_t("Remove %(phone)s?", { phone: this.props.msisdn.address })}
+ { _t("Remove %(phone)s?", { phone: this.props.msisdn.address }) }
- {_t("Remove")}
+ { _t("Remove") }
- {_t("Cancel")}
+ { _t("Cancel") }
);
@@ -105,9 +105,9 @@ export class ExistingPhoneNumber extends React.Component {
return (
- +{this.props.msisdn.address}
+ +{ this.props.msisdn.address }
- {_t("Remove")}
+ { _t("Remove") }
);
@@ -230,7 +230,7 @@ export default class PhoneNumbers extends React.Component {
let addVerifySection = (
- {_t("Add")}
+ { _t("Add") }
);
if (this.state.verifying) {
@@ -238,10 +238,10 @@ export default class PhoneNumbers extends React.Component {
addVerifySection = (
- {_t("A text message has been sent to +%(msisdn)s. " +
- "Please enter the verification code it contains.", { msisdn: msisdn })}
+ { _t("A text message has been sent to +%(msisdn)s. " +
+ "Please enter the verification code it contains.", { msisdn: msisdn }) }
- {this.state.verifyError}
+ { this.state.verifyError }
- {_t("Continue")}
+ { _t("Continue") }
@@ -274,7 +274,7 @@ export default class PhoneNumbers extends React.Component {
return (
- {existingPhoneElements}
+ { existingPhoneElements }
- {addVerifySection}
+ { addVerifySection }
);
}
diff --git a/src/components/views/settings/discovery/EmailAddresses.js b/src/components/views/settings/discovery/EmailAddresses.js
index 352ff1b0ba..970407774b 100644
--- a/src/components/views/settings/discovery/EmailAddresses.js
+++ b/src/components/views/settings/discovery/EmailAddresses.js
@@ -198,14 +198,14 @@ export class EmailAddress extends React.Component {
let status;
if (verifying) {
status =
- {_t("Verify the link in your inbox")}
+ { _t("Verify the link in your inbox") }
- {_t("Complete")}
+ { _t("Complete") }
;
} else if (bound) {
@@ -214,7 +214,7 @@ export class EmailAddress extends React.Component {
kind="danger_sm"
onClick={this.onRevokeClick}
>
- {_t("Revoke")}
+ { _t("Revoke") }
;
} else {
status =
- {_t("Share")}
+ { _t("Share") }
;
}
return (
- {address}
- {status}
+ { address }
+ { status }
);
}
@@ -249,13 +249,13 @@ export default class EmailAddresses extends React.Component {
});
} else {
content =
- {_t("Discovery options will appear once you have added an email above.")}
+ { _t("Discovery options will appear once you have added an email above.") }
;
}
return (
- {content}
+ { content }
);
}
diff --git a/src/components/views/settings/discovery/PhoneNumbers.js b/src/components/views/settings/discovery/PhoneNumbers.js
index 9df4a38f70..b6c944c733 100644
--- a/src/components/views/settings/discovery/PhoneNumbers.js
+++ b/src/components/views/settings/discovery/PhoneNumbers.js
@@ -205,9 +205,9 @@ export class PhoneNumber extends React.Component {
if (verifying) {
status =
- {_t("Please enter verification code sent via text.")}
+ { _t("Please enter verification code sent via text.") }
- {this.state.verifyError}
+ { this.state.verifyError }
- {_t("Revoke")}
+ { _t("Revoke") }
;
} else {
status =
- {_t("Share")}
+ { _t("Share") }
;
}
return (
- +{address}
- {status}
+ +{ address }
+ { status }
);
}
@@ -261,13 +261,13 @@ export default class PhoneNumbers extends React.Component {
});
} else {
content =
- {_t("Discovery options will appear once you have added a phone number above.")}
+ { _t("Discovery options will appear once you have added a phone number above.") }
;
}
return (
- {content}
+ { content }
);
}
diff --git a/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.tsx
index eda3419d14..9322eab711 100644
--- a/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.tsx
+++ b/src/components/views/settings/tabs/room/AdvancedRoomSettingsTab.tsx
@@ -116,8 +116,8 @@ export default class AdvancedRoomSettingsTab extends React.Component We'll post a link to the new room in the old " +
"version of the room - room members will have to click this link to join the new room.",
{}, {
- "b": (sub) => {sub},
- "i": (sub) => {sub},
+ "b": (sub) => { sub },
+ "i": (sub) => { sub },
},
) }
diff --git a/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx b/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx
index fb144da399..c8188250b1 100644
--- a/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx
+++ b/src/components/views/settings/tabs/room/BridgeSettingsTab.tsx
@@ -61,36 +61,36 @@ export default class BridgeSettingsTab extends React.Component {
let content: JSX.Element;
if (bridgeEvents.length > 0) {
content =
- {_t(
+
{ _t(
"This room is bridging messages to the following platforms. " +
"Learn more.", {},
{
// TODO: We don't have this link yet: this will prevent the translators
// having to re-translate the string when we do.
- a: sub => {sub},
+ a: sub => { sub },
},
- )}
+ ) }
{ bridgeEvents.map((event) => this.renderBridgeCard(event, room)) }
;
} else {
- content = {_t(
+ content =
{ _t(
"This room isn’t bridging messages to any platforms. " +
"Learn more.", {},
{
// TODO: We don't have this link yet: this will prevent the translators
// having to re-translate the string when we do.
- a: sub => {sub},
+ a: sub => { sub },
},
- )}
;
+ ) };
}
return (
- {_t("Bridges")}
+ { _t("Bridges") }
- {content}
+ { content }
);
diff --git a/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.js b/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.js
index 125558732d..e2f30192b9 100644
--- a/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.js
+++ b/src/components/views/settings/tabs/room/GeneralRoomSettingsTab.js
@@ -65,7 +65,7 @@ export default class GeneralRoomSettingsTab extends React.Component {
const groupsEvent = room.currentState.getStateEvents("m.room.related_groups", "");
let urlPreviewSettings = <>
- {_t("URL Previews")}
+ { _t("URL Previews") }
@@ -77,7 +77,7 @@ export default class GeneralRoomSettingsTab extends React.Component {
let flairSection;
if (SettingsStore.getValue(UIFeature.Flair)) {
flairSection = <>
- {_t("Flair")}
+ { _t("Flair") }
- {_t("General")}
+ { _t("General") }
- {_t("Room Addresses")}
+ { _t("Room Addresses") }
- {_t("Other")}
+ { _t("Other") }
{ flairSection }
{ urlPreviewSettings }
- {_t("Leave room")}
+ { _t("Leave room") }
{ _t('Leave room') }
diff --git a/src/components/views/settings/tabs/room/NotificationSettingsTab.js b/src/components/views/settings/tabs/room/NotificationSettingsTab.js
index cb65e13825..9200fb65d1 100644
--- a/src/components/views/settings/tabs/room/NotificationSettingsTab.js
+++ b/src/components/views/settings/tabs/room/NotificationSettingsTab.js
@@ -142,36 +142,36 @@ export default class NotificationsSettingsTab extends React.Component {
if (this.state.uploadedFile) {
currentUploadedFile = (
- {_t("Uploaded sound")}: {this.state.uploadedFile.name}
+ { _t("Uploaded sound") }: { this.state.uploadedFile.name }
);
}
return (
- {_t("Notifications")}
+ { _t("Notifications") }
- {_t("Sounds")}
+ { _t("Sounds") }
- {_t("Notification sound")}: {this.state.currentSound}
+ { _t("Notification sound") }: { this.state.currentSound }
- {_t("Reset")}
+ { _t("Reset") }
- {_t("Set a new custom sound")}
+ { _t("Set a new custom sound") }
- {currentUploadedFile}
+ { currentUploadedFile }
- {_t("Browse")}
+ { _t("Browse") }
- {_t("Save")}
+ { _t("Save") }
diff --git a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx
index 2679dcaa57..edc0220921 100644
--- a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx
+++ b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.tsx
@@ -102,10 +102,10 @@ export class BannedUser extends React.Component {
const userId = this.props.member.name === this.props.member.userId ? null : this.props.member.userId;
return (
- {unbanButton}
+ { unbanButton }
- { this.props.member.name } {userId}
- {this.props.reason ? " " + _t('Reason') + ": " + this.props.reason : ""}
+ { this.props.member.name } { userId }
+ { this.props.reason ? " " + _t('Reason') + ": " + this.props.reason : "" }
);
@@ -273,7 +273,7 @@ export default class RolesRoomSettingsTab extends React.Component {
parseIntWithDefault(plContent.events_default, powerLevelDescriptors.events_default.defaultValue),
);
- let privilegedUsersSection = {_t('No users have specific privileges in this room')};
+ let privilegedUsersSection = { _t('No users have specific privileges in this room') };
let mutedUsersSection;
if (Object.keys(userLevels).length) {
const privilegedUsers = [];
@@ -320,14 +320,14 @@ export default class RolesRoomSettingsTab extends React.Component {
privilegedUsersSection =
{ _t('Privileged Users') }
- {privilegedUsers}
+ { privilegedUsers }
;
}
if (mutedUsers.length) {
mutedUsersSection =
{ _t('Muted Users') }
- {mutedUsers}
+ { mutedUsers }
;
}
}
@@ -340,7 +340,7 @@ export default class RolesRoomSettingsTab extends React.Component {
{ _t('Banned users') }
- {banned.map((member) => {
+ { banned.map((member) => {
const banEvent = member.events.member.getContent();
const sender = room.getMember(member.events.member.getSender());
let bannedBy = member.events.member.getSender(); // start by falling back to mxid
@@ -351,7 +351,7 @@ export default class RolesRoomSettingsTab extends React.Component {
by={bannedBy}
/>
);
- })}
+ }) }
;
}
@@ -409,15 +409,15 @@ export default class RolesRoomSettingsTab extends React.Component {
return (
- {_t("Roles & Permissions")}
- {privilegedUsersSection}
- {mutedUsersSection}
- {bannedUsersSection}
+ { _t("Roles & Permissions") }
+ { privilegedUsersSection }
+ { mutedUsersSection }
+ { bannedUsersSection }
- {_t("Permissions")}
- {_t('Select the roles required to change various parts of the room')}
- {powerSelectors}
- {eventPowerSelectors}
+ { _t("Permissions") }
+ { _t('Select the roles required to change various parts of the room') }
+ { powerSelectors }
+ { eventPowerSelectors }
);
diff --git a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx
index 78d8fecf3b..88bc2046ce 100644
--- a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx
+++ b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx
@@ -78,7 +78,7 @@ export default class SecurityRoomSettingsTab extends React.Component {sub},
+ >{ sub },
},
),
onFinished: (confirm) => {
@@ -289,8 +289,8 @@ export default class SecurityRoomSettingsTab extends React.Component
- {_t("Guests cannot join this room even if explicitly invited.")}
- {_t("Click here to fix")}
+ { _t("Guests cannot join this room even if explicitly invited.") }
+ { _t("Click here to fix") }
);
@@ -302,7 +302,7 @@ export default class SecurityRoomSettingsTab extends React.Component
- {_t("To link to this room, please add an address.")}
+ { _t("To link to this room, please add an address.") }
);
@@ -310,8 +310,8 @@ export default class SecurityRoomSettingsTab extends React.Component
- {guestWarning}
- {aliasWarning}
+ { guestWarning }
+ { aliasWarning }
- {_t('Changes to who can read history will only apply to future messages in this room. ' +
- 'The visibility of existing history will be unchanged.')}
+ { _t('Changes to who can read history will only apply to future messages in this room. ' +
+ 'The visibility of existing history will be unchanged.') }
- {_t("Who can read history?")}
+ { _t("Who can read history?") }
- {this.renderHistory()}
+ { this.renderHistory() }
>);
if (!SettingsStore.getValue(UIFeature.RoomHistorySettings)) {
@@ -416,27 +416,27 @@ export default class SecurityRoomSettingsTab extends React.Component
- {_t("Security & Privacy")}
+ { _t("Security & Privacy") }
- {_t("Encryption")}
+ { _t("Encryption") }
- {_t("Once enabled, encryption cannot be disabled.")}
+ { _t("Once enabled, encryption cannot be disabled.") }
- {encryptionSettings}
+ { encryptionSettings }
- {_t("Who can access this room?")}
+ { _t("Who can access this room?") }
- {this.renderRoomAccess()}
+ { this.renderRoomAccess() }
- {historySection}
+ { historySection }
);
}
diff --git a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx
index a94821e94a..bd488f42b6 100644
--- a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx
+++ b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx
@@ -37,6 +37,8 @@ import StyledRadioGroup from "../../../elements/StyledRadioGroup";
import { SettingLevel } from "../../../../../settings/SettingLevel";
import { UIFeature } from "../../../../../settings/UIFeature";
import { Layout } from "../../../../../settings/Layout";
+import classNames from 'classnames';
+import StyledRadioButton from '../../../elements/StyledRadioButton';
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
import { compare } from "../../../../../utils/strings";
@@ -241,6 +243,19 @@ export default class AppearanceUserSettingsTab extends React.Component): void => {
+ let layout;
+ switch (e.target.value) {
+ case "irc": layout = Layout.IRC; break;
+ case "group": layout = Layout.Group; break;
+ case "bubble": layout = Layout.Bubble; break;
+ }
+
+ this.setState({ layout: layout });
+
+ SettingsStore.setValue("layout", null, SettingLevel.DEVICE, layout);
+ };
+
private onIRCLayoutChange = (enabled: boolean) => {
if (enabled) {
this.setState({ layout: Layout.IRC });
@@ -260,7 +275,7 @@ export default class AppearanceUserSettingsTab extends React.Component this.onUseSystemThemeChanged(e.target.checked)}
>
- {SettingsStore.getDisplayName("use_system_theme")}
+ { SettingsStore.getDisplayName("use_system_theme") }
;
}
@@ -270,9 +285,9 @@ export default class AppearanceUserSettingsTab extends React.Component{this.state.customThemeMessage.text};
+ messageElement = { this.state.customThemeMessage.text };
} else {
- messageElement = {this.state.customThemeMessage.text};
+ messageElement = { this.state.customThemeMessage.text };
}
}
customThemeForm = (
@@ -290,8 +305,8 @@ export default class AppearanceUserSettingsTab extends React.Component{_t("Add theme")}
- {messageElement}
+ >{ _t("Add theme") }
+ { messageElement }
);
@@ -306,8 +321,8 @@ export default class AppearanceUserSettingsTab extends React.Component
- {_t("Theme")}
- {systemThemeSection}
+ { _t("Theme") }
+ { systemThemeSection }
- {customThemeForm}
+ { customThemeForm }
);
}
@@ -330,7 +345,7 @@ export default class AppearanceUserSettingsTab extends React.Component
- {_t("Font size")}
+ { _t("Font size") }
;
}
+ private renderLayoutSection = () => {
+ return
+ { _t("Message layout") }
+
+
+
+
+
+ { _t("IRC") }
+
+
+
+
+
+
+ { _t("Modern") }
+
+
+
+
+
+
+ { _t("Message bubbles") }
+
+
+
+ ;
+ };
+
private renderAdvancedSection() {
if (!SettingsStore.getValue(UIFeature.AdvancedSettings)) return null;
@@ -381,7 +467,7 @@ export default class AppearanceUserSettingsTab extends React.Component this.setState({ showAdvanced: !this.state.showAdvanced })}
>
- {this.state.showAdvanced ? _t("Hide advanced") : _t("Show advanced")}
+ { this.state.showAdvanced ? _t("Hide advanced") : _t("Show advanced") }
;
let advanced: React.ReactNode;
@@ -396,14 +482,17 @@ export default class AppearanceUserSettingsTab extends React.Component
- this.onIRCLayoutChange(ev.target.checked)}
- >
- {_t("Enable experimental, compact IRC style layout")}
-
+
+ { !SettingsStore.getValue("feature_new_layout_switcher") ?
+ this.onIRCLayoutChange(ev.target.checked)}
+ >
+ { _t("Enable experimental, compact IRC style layout") }
+ : null
+ }
;
}
return
- {toggle}
- {advanced}
+ { toggle }
+ { advanced }
;
}
@@ -439,13 +528,14 @@ export default class AppearanceUserSettingsTab extends React.Component
- {_t("Customise your appearance")}
+ { _t("Customise your appearance") }
- {_t("Appearance Settings only affect this %(brand)s session.", { brand })}
+ { _t("Appearance Settings only affect this %(brand)s session.", { brand }) }
- {this.renderThemeSection()}
- {this.renderFontSection()}
- {this.renderAdvancedSection()}
+ { this.renderThemeSection() }
+ { SettingsStore.getValue("feature_new_layout_switcher") ? this.renderLayoutSection() : null }
+ { this.renderFontSection() }
+ { this.renderAdvancedSection() }
);
}
diff --git a/src/components/views/settings/tabs/user/FlairUserSettingsTab.js b/src/components/views/settings/tabs/user/FlairUserSettingsTab.js
index 272f5ec071..180cb5df2c 100644
--- a/src/components/views/settings/tabs/user/FlairUserSettingsTab.js
+++ b/src/components/views/settings/tabs/user/FlairUserSettingsTab.js
@@ -24,7 +24,7 @@ export default class FlairUserSettingsTab extends React.Component {
render() {
return (
- {_t("Flair")}
+ { _t("Flair") }
diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js
index f1b7df3eb5..2a6e8937a3 100644
--- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js
+++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js
@@ -289,11 +289,11 @@ export default class GeneralUserSettingsTab extends React.Component {
onMsisdnsChange={this._onMsisdnsChange}
/>;
threepidSection =
- {_t("Email addresses")}
- {emails}
+ { _t("Email addresses") }
+ { emails }
- {_t("Phone numbers")}
- {msisdns}
+ { _t("Phone numbers") }
+ { msisdns }
;
} else if (this.state.serverSupportsSeparateAddAndBind === null) {
threepidSection = ;
@@ -308,12 +308,12 @@ export default class GeneralUserSettingsTab extends React.Component {
return (
- {_t("Account")}
+ { _t("Account") }
- {passwordChangeText}
+ { passwordChangeText }
- {passwordChangeForm}
- {threepidSection}
+ { passwordChangeForm }
+ { threepidSection }
);
}
@@ -322,7 +322,7 @@ export default class GeneralUserSettingsTab extends React.Component {
// TODO: Convert to new-styled Field
return (
- {_t("Language and region")}
+ { _t("Language and region") }
- {_t("Spell check dictionaries")}
+ { _t("Spell check dictionaries") }
- {_t(
+ { _t(
"Agree to the identity server (%(serverName)s) Terms of Service to " +
"allow yourself to be discoverable by email address or phone number.",
{ serverName: this.state.idServerName },
- )}
+ ) }
;
return (
@@ -377,16 +377,16 @@ export default class GeneralUserSettingsTab extends React.Component {
const msisdns = this.state.loading3pids ? : ;
const threepidSection = this.state.haveIdServer ?
- {_t("Email addresses")}
- {emails}
+ { _t("Email addresses") }
+ { emails }
- {_t("Phone numbers")}
- {msisdns}
+ { _t("Phone numbers") }
+ { msisdns }
: null;
return (
- {threepidSection}
+ { threepidSection }
{ /* has its own heading as it includes the current identity server */ }
@@ -397,12 +397,12 @@ export default class GeneralUserSettingsTab extends React.Component {
// TODO: Improve warning text for account deactivation
return (
- {_t("Account management")}
+ { _t("Account management") }
- {_t("Deactivating your account is a permanent action - be careful!")}
+ { _t("Deactivating your account is a permanent action - be careful!") }
- {_t("Deactivate Account")}
+ { _t("Deactivate Account") }
);
@@ -434,28 +434,28 @@ export default class GeneralUserSettingsTab extends React.Component {
let accountManagementSection;
if (SettingsStore.getValue(UIFeature.Deactivate)) {
accountManagementSection = <>
- {_t("Deactivate account")}
- {this._renderManagementSection()}
+ { _t("Deactivate account") }
+ { this._renderManagementSection() }
>;
}
let discoverySection;
if (SettingsStore.getValue(UIFeature.IdentityServer)) {
discoverySection = <>
- {discoWarning} {_t("Discovery")}
- {this._renderDiscoverySection()}
+ { discoWarning } { _t("Discovery") }
+ { this._renderDiscoverySection() }
>;
}
return (
- {_t("General")}
- {this._renderProfileSection()}
- {this._renderAccountSection()}
- {this._renderLanguageSection()}
- {supportsMultiLanguageSpellCheck ? this._renderSpellCheckSection() : null}
+ { _t("General") }
+ { this._renderProfileSection() }
+ { this._renderAccountSection() }
+ { this._renderLanguageSection() }
+ { supportsMultiLanguageSpellCheck ? this._renderSpellCheckSection() : null }
{ discoverySection }
- {this._renderIntegrationManagerSection() /* Has its own title */}
+ { this._renderIntegrationManagerSection() /* Has its own title */ }
{ accountManagementSection }
);
diff --git a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx
index f2857720a5..33de634611 100644
--- a/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx
+++ b/src/components/views/settings/tabs/user/HelpUserSettingsTab.tsx
@@ -112,15 +112,15 @@ export default class HelpUserSettingsTab extends React.Component
const legalLinks = [];
for (const tocEntry of SdkConfig.get().terms_and_conditions_links) {
legalLinks.push();
}
return (
- {_t("Legal")}
+ { _t("Legal") }
- {legalLinks}
+ { legalLinks }
);
@@ -131,7 +131,7 @@ export default class HelpUserSettingsTab extends React.Component
// Also, is ugly but necessary.
return (
- {_t("Credits")}
+ { _t("Credits") }
-
The
rel="noreferrer noopener"
target="_blank"
>
- {sub}
+ { sub }
,
},
);
if (SdkConfig.get().welcomeUserId && getCurrentLanguage().startsWith('en')) {
faqText = (
- {_t(
+ { _t(
'For help with using %(brand)s, click here or start a chat with our ' +
'bot using the button below.',
{
@@ -208,13 +208,13 @@ export default class HelpUserSettingsTab extends React.Component
rel='noreferrer noopener'
target='_blank'
>
- {sub}
+ { sub }
,
},
- )}
+ ) }
- {_t("Chat with %(brand)s Bot", { brand })}
+ { _t("Chat with %(brand)s Bot", { brand }) }
@@ -235,29 +235,29 @@ export default class HelpUserSettingsTab extends React.Component
if (SdkConfig.get().bug_report_endpoint_url) {
bugReportingSection = (
- {_t('Bug reporting')}
+ { _t('Bug reporting') }
- {_t(
+ { _t(
"If you've submitted a bug via GitHub, debug logs can help " +
"us track down the problem. Debug logs contain application " +
"usage data including your username, the IDs or aliases of " +
"the rooms or groups you have visited and the usernames of " +
"other users. They do not contain messages.",
- )}
+ ) }
- {_t("Submit debug logs")}
+ { _t("Submit debug logs") }
- {_t(
+ { _t(
"To report a Matrix-related security issue, please read the Matrix.org " +
"Security Disclosure Policy.", {},
{
a: sub => {sub},
+ >{ sub },
},
- )}
+ ) }
);
@@ -265,39 +265,39 @@ export default class HelpUserSettingsTab extends React.Component
return (
- {_t("Help & About")}
+ { _t("Help & About") }
{ bugReportingSection }
- {_t("FAQ")}
+ { _t("FAQ") }
- {faqText}
+ { faqText }
{ _t("Keyboard Shortcuts") }
- {_t("Versions")}
+ { _t("Versions") }
- {_t("%(brand)s version:", { brand })} {appVersion}
- {_t("olm version:")} {olmVersion}
- {updateButton}
+ { _t("%(brand)s version:", { brand }) } { appVersion }
+ { _t("olm version:") } { olmVersion }
+ { updateButton }
- {this.renderLegal()}
- {this.renderCredits()}
+ { this.renderLegal() }
+ { this.renderCredits() }
- {_t("Advanced")}
+ { _t("Advanced") }
- {_t("Homeserver is")} {MatrixClientPeg.get().getHomeserverUrl()}
- {_t("Identity server is")} {MatrixClientPeg.get().getIdentityServerUrl()}
+ { _t("Homeserver is") } { MatrixClientPeg.get().getHomeserverUrl() }
+ { _t("Identity server is") } { MatrixClientPeg.get().getIdentityServerUrl() }
- {_t("Access Token")}
- {_t("Your access token gives full access to your account."
- + " Do not share it with anyone." )}
+ { _t("Access Token") }
+ { _t("Your access token gives full access to your account."
+ + " Do not share it with anyone." ) }
- {MatrixClientPeg.get().getAccessToken()}
+ { MatrixClientPeg.get().getAccessToken() }
- {_t("Clear cache and reload")}
+ { _t("Clear cache and reload") }
diff --git a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js
index abf9709f50..aace4ca557 100644
--- a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js
+++ b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js
@@ -69,7 +69,7 @@ export default class LabsUserSettingsTab extends React.Component {
const flags = labs.map(f => );
labsSection =
- {flags}
+ { flags }
@@ -79,7 +79,7 @@ export default class LabsUserSettingsTab extends React.Component {
return (
- {_t("Labs")}
+ { _t("Labs") }
{
_t('Feeling experimental? Labs are the best way to get things early, ' +
@@ -87,7 +87,7 @@ export default class LabsUserSettingsTab extends React.Component {
'Learn more.', {}, {
'a': (sub) => {
return {sub};
+ rel='noreferrer noopener' target='_blank'>{ sub };
},
})
}
diff --git a/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.tsx b/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.tsx
index 41c44e65a0..0653198aa0 100644
--- a/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.tsx
+++ b/src/components/views/settings/tabs/user/MjolnirUserSettingsTab.tsx
@@ -140,23 +140,23 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
const name = room ? room.name : list.roomId;
const renderRules = (rules: ListRule[]) => {
- if (rules.length === 0) return {_t("None")};
+ if (rules.length === 0) return { _t("None") };
const tiles = [];
for (const rule of rules) {
- tiles.push({rule.entity} );
+ tiles.push({ rule.entity } );
}
- return {tiles}
;
+ return { tiles }
;
};
Modal.createTrackedDialog('View Mjolnir list rules', '', QuestionDialog, {
title: _t("Ban list rules - %(roomName)s", { roomName: name }),
description: (
- {_t("Server rules")}
- {renderRules(list.serverRules)}
- {_t("User rules")}
- {renderRules(list.userRules)}
+ { _t("Server rules") }
+ { renderRules(list.serverRules) }
+ { _t("User rules") }
+ { renderRules(list.userRules) }
),
button: _t("Close"),
@@ -167,7 +167,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
private renderPersonalBanListRules() {
const list = Mjolnir.sharedInstance().getPersonalList();
const rules = list ? [...list.userRules, ...list.serverRules] : [];
- if (!list || rules.length <= 0) return {_t("You have not ignored anyone.")};
+ if (!list || rules.length <= 0) return { _t("You have not ignored anyone.") };
const tiles = [];
for (const rule of rules) {
@@ -178,17 +178,17 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
onClick={() => this.removePersonalRule(rule)}
disabled={this.state.busy}
>
- {_t("Remove")}
+ { _t("Remove") }
- {rule.entity}
+ { rule.entity }
,
);
}
return (
- {_t("You are currently ignoring:")}
- {tiles}
+ { _t("You are currently ignoring:") }
+ { tiles }
);
}
@@ -198,12 +198,12 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
const lists = Mjolnir.sharedInstance().lists.filter(b => {
return personalList? personalList.roomId !== b.roomId : true;
});
- if (!lists || lists.length <= 0) return {_t("You are not subscribed to any lists")};
+ if (!lists || lists.length <= 0) return { _t("You are not subscribed to any lists") };
const tiles = [];
for (const list of lists) {
const room = MatrixClientPeg.get().getRoom(list.roomId);
- const name = room ? {room.name} ({list.roomId}) : list.roomId;
+ const name = room ? { room.name } ({ list.roomId }) : list.roomId;
tiles.push(
-
onClick={() => this.unsubscribeFromList(list)}
disabled={this.state.busy}
>
- {_t("Unsubscribe")}
+ { _t("Unsubscribe") }
this.viewListRules(list)}
disabled={this.state.busy}
>
- {_t("View rules")}
+ { _t("View rules") }
- {name}
+ { name }
,
);
}
return (
- {_t("You are currently subscribed to:")}
- {tiles}
+ { _t("You are currently subscribed to:") }
+ { tiles }
);
}
@@ -238,37 +238,37 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
return (
- {_t("Ignored users")}
+ { _t("Ignored users") }
- {_t("âš These settings are meant for advanced users.")}
+ { _t("âš These settings are meant for advanced users.") }
- {_t(
+ { _t(
"Add users and servers you want to ignore here. Use asterisks " +
"to have %(brand)s match any characters. For example, @bot:* " +
"would ignore all users that have the name 'bot' on any server.",
- { brand }, { code: (s) => {s} },
- )}
+ { brand }, { code: (s) => { s } },
+ ) }
- {_t(
+ { _t(
"Ignoring people is done through ban lists which contain rules for " +
"who to ban. Subscribing to a ban list means the users/servers blocked by " +
"that list will be hidden from you.",
- )}
+ ) }
- {_t("Personal ban list")}
+ { _t("Personal ban list") }
- {_t(
+ { _t(
"Your personal ban list holds all the users/servers you personally don't " +
"want to see messages from. After ignoring your first user/server, a new room " +
"will show up in your room list named 'My Ban List' - stay in this room to keep " +
"the ban list in effect.",
- )}
+ ) }
- {this.renderPersonalBanListRules()}
+ { this.renderPersonalBanListRules() }
@@ -285,22 +285,22 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
onClick={this.onAddPersonalRule}
disabled={this.state.busy}
>
- {_t("Ignore")}
+ { _t("Ignore") }
- {_t("Subscribed lists")}
+ { _t("Subscribed lists") }
- {_t("Subscribing to a ban list will cause you to join it!")}
+ { _t("Subscribing to a ban list will cause you to join it!") }
- {_t(
+ { _t(
"If this isn't what you want, please use a different tool to ignore users.",
- )}
+ ) }
- {this.renderSubscribedBanLists()}
+ { this.renderSubscribedBanLists() }
@@ -316,7 +316,7 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
onClick={this.onSubscribeList}
disabled={this.state.busy}
>
- {_t("Subscribe")}
+ { _t("Subscribe") }
diff --git a/src/components/views/settings/tabs/user/NotificationUserSettingsTab.tsx b/src/components/views/settings/tabs/user/NotificationUserSettingsTab.tsx
index a0f4e330bb..5717813ae1 100644
--- a/src/components/views/settings/tabs/user/NotificationUserSettingsTab.tsx
+++ b/src/components/views/settings/tabs/user/NotificationUserSettingsTab.tsx
@@ -24,7 +24,7 @@ export default class NotificationUserSettingsTab extends React.Component {
render() {
return (
- {_t("Notifications")}
+ { _t("Notifications") }
diff --git a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx
index c4140153a5..2e5db59d9b 100644
--- a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx
+++ b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx
@@ -224,53 +224,53 @@ export default class PreferencesUserSettingsTab extends React.Component<{}, ISta
return (
- {_t("Preferences")}
+ { _t("Preferences") }
- {_t("Room list")}
- {this.renderGroup(PreferencesUserSettingsTab.ROOM_LIST_SETTINGS)}
+ { _t("Room list") }
+ { this.renderGroup(PreferencesUserSettingsTab.ROOM_LIST_SETTINGS) }
- {_t("Keyboard shortcuts")}
+ { _t("Keyboard shortcuts") }
{ _t("To view all keyboard shortcuts, click here.") }
- {this.renderGroup(PreferencesUserSettingsTab.KEYBINDINGS_SETTINGS)}
+ { this.renderGroup(PreferencesUserSettingsTab.KEYBINDINGS_SETTINGS) }
- {_t("Displaying time")}
- {this.renderGroup(PreferencesUserSettingsTab.TIME_SETTINGS)}
+ { _t("Displaying time") }
+ { this.renderGroup(PreferencesUserSettingsTab.TIME_SETTINGS) }
- {_t("Composer")}
- {this.renderGroup(PreferencesUserSettingsTab.COMPOSER_SETTINGS)}
+ { _t("Composer") }
+ { this.renderGroup(PreferencesUserSettingsTab.COMPOSER_SETTINGS) }
- {_t("Code blocks")}
- {this.renderGroup(PreferencesUserSettingsTab.CODE_BLOCKS_SETTINGS)}
+ { _t("Code blocks") }
+ { this.renderGroup(PreferencesUserSettingsTab.CODE_BLOCKS_SETTINGS) }
- {_t("Images, GIFs and videos")}
- {this.renderGroup(PreferencesUserSettingsTab.IMAGES_AND_VIDEOS_SETTINGS)}
+ { _t("Images, GIFs and videos") }
+ { this.renderGroup(PreferencesUserSettingsTab.IMAGES_AND_VIDEOS_SETTINGS) }
- {_t("Timeline")}
- {this.renderGroup(PreferencesUserSettingsTab.TIMELINE_SETTINGS)}
+ { _t("Timeline") }
+ { this.renderGroup(PreferencesUserSettingsTab.TIMELINE_SETTINGS) }
- {_t("General")}
- {this.renderGroup(PreferencesUserSettingsTab.GENERAL_SETTINGS)}
- {minimizeToTrayOption}
- {autoHideMenuOption}
- {autoLaunchOption}
- {warnBeforeExitOption}
+ { _t("General") }
+ { this.renderGroup(PreferencesUserSettingsTab.GENERAL_SETTINGS) }
+ { minimizeToTrayOption }
+ { autoHideMenuOption }
+ { autoLaunchOption }
+ { warnBeforeExitOption }
- {_t("Export E2E room keys")}
+ { _t("Export E2E room keys") }
- {_t("Import E2E room keys")}
+ { _t("Import E2E room keys") }
);
@@ -235,19 +235,19 @@ export default class SecurityUserSettingsTab extends React.Component {
return (
- {_t("Cryptography")}
+ { _t("Cryptography") }
-
-
{_t("Session ID:")}
- {deviceId}
+ { _t("Session ID:") }
+ { deviceId }
-
-
{_t("Session key:")}
- {identityKey}
+ { _t("Session key:") }
+ { identityKey }
- {importExportButtons}
- {noSendUnverifiedSetting}
+ { importExportButtons }
+ { noSendUnverifiedSetting }
);
}
@@ -270,9 +270,9 @@ export default class SecurityUserSettingsTab extends React.Component {
return (
- {_t('Ignored users')}
+ { _t('Ignored users') }
- {userIds}
+ { userIds }
);
@@ -289,14 +289,14 @@ export default class SecurityUserSettingsTab extends React.Component {
const onClickReject = this._onRejectAllInvitesClicked.bind(this, invitedRooms);
return (
- {_t('Bulk options')}
+ { _t('Bulk options') }
- {_t("Accept all %(invitedRooms)s invites", { invitedRooms: this.state.invitedRoomAmt })}
+ { _t("Accept all %(invitedRooms)s invites", { invitedRooms: this.state.invitedRoomAmt }) }
- {_t("Reject all %(invitedRooms)s invites", { invitedRooms: this.state.invitedRoomAmt })}
+ { _t("Reject all %(invitedRooms)s invites", { invitedRooms: this.state.invitedRoomAmt }) }
- {this.state.managingInvites ? : }
+ { this.state.managingInvites ? : }
);
}
@@ -309,7 +309,7 @@ export default class SecurityUserSettingsTab extends React.Component {
const secureBackup = (
- {_t("Secure Backup")}
+ { _t("Secure Backup") }
@@ -318,7 +318,7 @@ export default class SecurityUserSettingsTab extends React.Component {
const eventIndex = (
- {_t("Message search")}
+ { _t("Message search") }
);
@@ -330,7 +330,7 @@ export default class SecurityUserSettingsTab extends React.Component {
const CrossSigningPanel = sdk.getComponent('views.settings.CrossSigningPanel');
const crossSigning = (
- {_t("Cross-signing")}
+ { _t("Cross-signing") }
@@ -348,19 +348,19 @@ export default class SecurityUserSettingsTab extends React.Component {
let privacySection;
if (Analytics.canEnable() || CountlyAnalytics.instance.canEnable()) {
privacySection =
- {_t("Privacy")}
+ { _t("Privacy") }
- {_t("Analytics")}
+ { _t("Analytics") }
- {_t(
+ { _t(
"%(brand)s collects anonymous analytics to allow us to improve the application.",
{ brand },
- )}
+ ) }
- {_t("Privacy is important to us, so we don't collect any personal or " +
- "identifiable data for our analytics.")}
+ { _t("Privacy is important to us, so we don't collect any personal or " +
+ "identifiable data for our analytics.") }
- {_t("Learn more about how we use analytics.")}
+ { _t("Learn more about how we use analytics.") }
@@ -377,11 +377,11 @@ export default class SecurityUserSettingsTab extends React.Component {
// only show the section if there's something to show
if (ignoreUsersPanel || invitesPanel || e2ePanel) {
advancedSection = <>
- {_t("Advanced")}
+ { _t("Advanced") }
- {ignoreUsersPanel}
- {invitesPanel}
- {e2ePanel}
+ { ignoreUsersPanel }
+ { invitesPanel }
+ { e2ePanel }
>;
}
@@ -389,31 +389,31 @@ export default class SecurityUserSettingsTab extends React.Component {
return (
- {warning}
- {_t("Where you’re logged in")}
+ { warning }
+ { _t("Where you’re logged in") }
- {_t(
+ { _t(
"Manage the names of and sign out of your sessions below or " +
"verify them in your User Profile.", {},
{
a: sub =>
- {sub}
+ { sub }
,
},
- )}
+ ) }
- {_t("A session's public name is visible to people you communicate with")}
+ { _t("A session's public name is visible to people you communicate with") }
- {_t("Encryption")}
+ { _t("Encryption") }
- {secureBackup}
- {eventIndex}
- {crossSigning}
- {this._renderCurrentDeviceInfo()}
+ { secureBackup }
+ { eventIndex }
+ { crossSigning }
+ { this._renderCurrentDeviceInfo() }
{ privacySection }
{ advancedSection }
diff --git a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx
index 86c32cc6cd..b28ec592dd 100644
--- a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx
+++ b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx
@@ -130,7 +130,7 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
private renderDeviceOptions(devices: Array, category: MediaDeviceKindEnum): Array {
return devices.map((d) => {
- return ();
+ return ();
});
}
@@ -159,9 +159,9 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
if (!this.state.mediaDevices) {
requestButton = (
- {_t("Missing media permissions, click the button below to request.")}
+ { _t("Missing media permissions, click the button below to request.") }
- {_t("Request media permissions")}
+ { _t("Request media permissions") }
);
@@ -182,7 +182,7 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
return (
- {_t("Voice & Video")}
+ { _t("Voice & Video") }
{ requestButton }
{ speakerDropdown }
diff --git a/src/components/views/spaces/SpacePanel.tsx b/src/components/views/spaces/SpacePanel.tsx
index 9cefbbd94c..60ebec0752 100644
--- a/src/components/views/spaces/SpacePanel.tsx
+++ b/src/components/views/spaces/SpacePanel.tsx
@@ -156,7 +156,7 @@ const InnerSpacePanel = React.memo(({ children, isPanelCo
)) }
{ spaces.map((s, i) => (
- {(provided, snapshot) => (
+ { (provided, snapshot) => (
(({ children, isPanelCo
isPanelCollapsed={isPanelCollapsed}
onExpand={() => setPanelCollapsed(false)}
/>
- )}
+ ) }
)) }
{ children }
@@ -266,13 +266,13 @@ const SpacePanel = () => {
SpaceStore.instance.moveRootSpace(result.source.index, result.destination.index);
}}>
- {({ onKeyDownHandler }) => (
+ { ({ onKeyDownHandler }) => (
- {(provided, snapshot) => (
+ { (provided, snapshot) => (
{
isNarrow={isPanelCollapsed}
/>
- )}
+ ) }
{
/>
{ contextMenu }
- )}
+ ) }
);
diff --git a/src/components/views/spaces/SpaceSettingsGeneralTab.tsx b/src/components/views/spaces/SpaceSettingsGeneralTab.tsx
index 9f4e0ecea7..a43b180752 100644
--- a/src/components/views/spaces/SpaceSettingsGeneralTab.tsx
+++ b/src/components/views/spaces/SpaceSettingsGeneralTab.tsx
@@ -123,7 +123,7 @@ const SpaceSettingsGeneralTab = ({ matrixClient: cli, space, onFinished }: IProp
- {_t("Leave Space")}
+ { _t("Leave Space") }
{
let addressesSection;
if (visibility !== SpaceVisibility.Private) {
addressesSection = <>
- {_t("Address")}
+ { _t("Address") }
= ({
parents,
}) => {
return
- {spaces.map(s => {
+ { spaces.map(s => {
return ( = ({
isNested={isNested}
parents={parents}
/>);
- })}
+ }) }
;
};
diff --git a/src/components/views/terms/InlineTermsAgreement.tsx b/src/components/views/terms/InlineTermsAgreement.tsx
index 306dfea6b9..54c0258d37 100644
--- a/src/components/views/terms/InlineTermsAgreement.tsx
+++ b/src/components/views/terms/InlineTermsAgreement.tsx
@@ -91,7 +91,7 @@ export default class InlineTermsAgreement extends React.Component {
return (
- {policy.name}
+ { policy.name }
);
@@ -100,10 +100,10 @@ export default class InlineTermsAgreement extends React.Component
- {introText}
+ { introText }
this.togglePolicy(i)} checked={policy.checked}>
- {_t("Accept")}
+ { _t("Accept") }
,
@@ -118,14 +118,14 @@ export default class InlineTermsAgreement extends React.Component
- {this.props.introElement}
- {this.renderCheckboxes()}
+ { this.props.introElement }
+ { this.renderCheckboxes() }
- {_t("Continue")}
+ { _t("Continue") }
);
diff --git a/src/components/views/toasts/GenericToast.tsx b/src/components/views/toasts/GenericToast.tsx
index 78f45be899..4738e38c0d 100644
--- a/src/components/views/toasts/GenericToast.tsx
+++ b/src/components/views/toasts/GenericToast.tsx
@@ -41,16 +41,16 @@ const GenericToast: React.FC> = ({
onReject,
}) => {
const detailContent = detail ?
- {detail}
+ { detail }
: null;
return
- {description}
- {detailContent}
+ { description }
+ { detailContent }
- {onReject && rejectLabel &&
+ { onReject && rejectLabel &&
{ rejectLabel }
}
diff --git a/src/components/views/toasts/NonUrgentEchoFailureToast.tsx b/src/components/views/toasts/NonUrgentEchoFailureToast.tsx
index 906a56ef09..9d69922678 100644
--- a/src/components/views/toasts/NonUrgentEchoFailureToast.tsx
+++ b/src/components/views/toasts/NonUrgentEchoFailureToast.tsx
@@ -31,11 +31,11 @@ export default class NonUrgentEchoFailureToast extends React.PureComponent {
return (
- {_t("Your server isn't responding to some requests.", {}, {
+ { _t("Your server isn't responding to some requests.", {}, {
'a': (sub) => (
- {sub}
+ { sub }
),
- })}
+ }) }
);
}
diff --git a/src/components/views/toasts/VerificationRequestToast.tsx b/src/components/views/toasts/VerificationRequestToast.tsx
index 45f1464b0e..63e23bfdef 100644
--- a/src/components/views/toasts/VerificationRequestToast.tsx
+++ b/src/components/views/toasts/VerificationRequestToast.tsx
@@ -60,14 +60,14 @@ export default class VerificationRequestToast extends React.PureComponent {
+ private checkRequestIsPending = () => {
const { request } = this.props;
if (!request.canAccept) {
ToastStore.sharedInstance().dismissToast(this.props.toastKey);
diff --git a/src/components/views/verification/VerificationCancelled.tsx b/src/components/views/verification/VerificationCancelled.tsx
index aa34b22382..c8c068f5eb 100644
--- a/src/components/views/verification/VerificationCancelled.tsx
+++ b/src/components/views/verification/VerificationCancelled.tsx
@@ -28,9 +28,9 @@ export default class VerificationCancelled extends React.Component {
public render(): React.ReactNode {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return
- {_t(
+
{ _t(
"The other party cancelled the verification.",
- )}
+ ) }
{
public render(): React.ReactNode {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return
- {_t("Verified!")}
- {_t("You've successfully verified this user.")}
- {_t(
+
{ _t("Verified!") }
+ { _t("You've successfully verified this user.") }
+ { _t(
"Secure messages with this user are end-to-end encrypted and not able to be " +
"read by third parties.",
- )}
+ ) }
{ emoji[0] }
- {_t(capFirst(emoji[1]))}
+ { _t(capFirst(emoji[1])) }
,
);
sasDisplay =
- {emojiBlocks.slice(0, 4)}
+ { emojiBlocks.slice(0, 4) }
- {emojiBlocks.slice(4)}
+ { emojiBlocks.slice(4) }
;
sasCaption = this.props.isSelf ?
_t(
@@ -99,10 +99,10 @@ export default class VerificationShowSas extends React.Component
);
} else if (this.props.sas.decimal) {
const numberBlocks = this.props.sas.decimal.map((num, i) =>
- {num}
+ { num }
);
sasDisplay =
- {numberBlocks}
+ { numberBlocks }
;
sasCaption = this.props.isSelf ?
_t(
@@ -113,9 +113,9 @@ export default class VerificationShowSas extends React.Component
);
} else {
return
- {_t("Unable to find a supported verification method.")}
+ { _t("Unable to find a supported verification method.") }
- {_t('Cancel')}
+ { _t('Cancel') }
;
}
@@ -165,12 +165,12 @@ export default class VerificationShowSas extends React.Component
}
return
- {sasCaption}
- {sasDisplay}
- {this.props.isSelf ?
+
{ sasCaption }
+ { sasDisplay }
+ { this.props.isSelf ?
"":
- _t("To be secure, do this in person or use a trusted way to communicate.")}
- {confirm}
+ _t("To be secure, do this in person or use a trusted way to communicate.") }
+ { confirm }
;
}
}
diff --git a/src/components/views/voip/CallPreview.tsx b/src/components/views/voip/CallPreview.tsx
index ddcb9057ec..895d9773e4 100644
--- a/src/components/views/voip/CallPreview.tsx
+++ b/src/components/views/voip/CallPreview.tsx
@@ -30,6 +30,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
import UIStore from '../../../stores/UIStore';
import { lerp } from '../../../utils/AnimationUtils';
import { MarkedExecution } from '../../../utils/MarkedExecution';
+import { EventSubscription } from 'fbemitter';
const PIP_VIEW_WIDTH = 336;
const PIP_VIEW_HEIGHT = 232;
@@ -108,7 +109,7 @@ function getPrimarySecondaryCalls(calls: MatrixCall[]): [MatrixCall, MatrixCall[
*/
@replaceableComponent("views.voip.CallPreview")
export default class CallPreview extends React.Component {
- private roomStoreToken: any;
+ private roomStoreToken: EventSubscription;
private dispatcherRef: string;
private settingsWatcherRef: string;
private callViewWrapper = createRef();
@@ -240,7 +241,7 @@ export default class CallPreview extends React.Component {
this.scheduledUpdate.mark();
};
- private onRoomViewStoreUpdate = (payload) => {
+ private onRoomViewStoreUpdate = () => {
if (RoomViewStore.getRoomId() === this.state.roomId) return;
const roomId = RoomViewStore.getRoomId();
diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx
index 64c101a284..8bdd6e0f55 100644
--- a/src/components/views/voip/CallView.tsx
+++ b/src/components/views/voip/CallView.tsx
@@ -465,7 +465,7 @@ export default class CallView extends React.Component {
// in the near future, the dial pad button will go on the left. For now, it's the nothing button
// because something needs to have margin-right: auto to make the alignment correct.
const callControls =
- {dialpadButton}
+ { dialpadButton }
{
});
}}
/>
- {vidMuteButton}
+ { vidMuteButton }
- {contextMenuButton}
+ { contextMenuButton }
;
const avatarSize = this.props.pipMode ? 76 : 160;
@@ -506,16 +506,18 @@ export default class CallView extends React.Component {
const transfereeName = transfereeRoom ? transfereeRoom.name : _t("unknown person");
holdTransferContent =
- {_t(
+ { _t(
"Consulting with %(transferTarget)s. Transfer to %(transferee)s",
{
transferTarget: transferTargetName,
transferee: transfereeName,
},
{
- a: sub => {sub} ,
+ a: sub =>
+ { sub }
+ ,
},
- )}
+ ) }
;
} else if (isOnHold) {
let onHoldText = null;
@@ -524,7 +526,7 @@ export default class CallView extends React.Component {
_td("You held the call Switch") : _td("You held the call Resume");
onHoldText = _t(holdString, {}, {
a: sub =>
- {sub}
+ { sub }
,
});
} else if (this.state.isLocalOnHold) {
@@ -533,7 +535,7 @@ export default class CallView extends React.Component {
});
}
holdTransferContent =
- {onHoldText}
+ { onHoldText }
;
}
@@ -556,9 +558,9 @@ export default class CallView extends React.Component {
contentView = (
- {onHoldBackground}
- {holdTransferContent}
- {callControls}
+ { onHoldBackground }
+ { holdTransferContent }
+ { callControls }
);
} else {
@@ -582,8 +584,8 @@ export default class CallView extends React.Component {
/>
- {holdTransferContent}
- {callControls}
+ { holdTransferContent }
+ { callControls }
);
}
@@ -615,7 +617,7 @@ export default class CallView extends React.Component {
// Saying "Connecting" here isn't really true, but the best thing
// I can come up with, but this might be subject to change as well
contentView =
- {feeds}
+ { feeds }
{
/>
- {_t("Connecting")}
- {callControls}
+ { _t("Connecting") }
+ { callControls }
;
} else {
const containerClasses = classNames({
@@ -653,8 +655,8 @@ export default class CallView extends React.Component {
});
contentView =
- {feeds}
- {callControls}
+ { feeds }
+ { callControls }
;
}
@@ -676,16 +678,16 @@ export default class CallView extends React.Component {
}
const headerControls =
- {fullScreenButton}
- {expandButton}
+ { fullScreenButton }
+ { expandButton }
;
let header: React.ReactNode;
if (!this.props.pipMode) {
header =
- {callTypeText}
- {headerControls}
+ { callTypeText }
+ { headerControls }
;
myClassName = 'mx_CallView_large';
} else {
@@ -695,7 +697,7 @@ export default class CallView extends React.Component {
- {_t("%(name)s on hold", { name: secCallRoom.name })}
+ { _t("%(name)s on hold", { name: secCallRoom.name }) }
;
@@ -710,23 +712,23 @@ export default class CallView extends React.Component {
- {callRoom.name}
+ { callRoom.name }
- {callTypeText}
- {secondaryCallInfo}
+ { callTypeText }
+ { secondaryCallInfo }
- {headerControls}
+ { headerControls }
);
myClassName = 'mx_CallView_pip';
}
return
- {header}
- {contentView}
- {dialPad}
- {contextMenu}
+ { header }
+ { contentView }
+ { dialPad }
+ { contextMenu }
;
}
}
diff --git a/src/components/views/voip/DialPad.tsx b/src/components/views/voip/DialPad.tsx
index 6687c89b52..2af8bd6989 100644
--- a/src/components/views/voip/DialPad.tsx
+++ b/src/components/views/voip/DialPad.tsx
@@ -42,9 +42,9 @@ class DialPadButton extends React.PureComponent {
switch (this.props.kind) {
case DialPadButtonKind.Digit:
return
- {this.props.digit}
+ { this.props.digit }
- {this.props.digitSubtext}
+ { this.props.digitSubtext }
;
case DialPadButtonKind.Dial:
@@ -80,7 +80,7 @@ export default class Dialpad extends React.PureComponent {
}
return
- {buttonNodes}
+ { buttonNodes }
;
}
}
diff --git a/src/components/views/voip/DialPadModal.tsx b/src/components/views/voip/DialPadModal.tsx
index 033aa2e700..0bba65e44f 100644
--- a/src/components/views/voip/DialPadModal.tsx
+++ b/src/components/views/voip/DialPadModal.tsx
@@ -101,7 +101,7 @@ export default class DialpadModal extends React.PureComponent {
- {dialPadField}
+ { dialPadField }
diff --git a/src/components/views/voip/IncomingCallBox.tsx b/src/components/views/voip/IncomingCallBox.tsx
index 76e96c62c2..95e97f1080 100644
--- a/src/components/views/voip/IncomingCallBox.tsx
+++ b/src/components/views/voip/IncomingCallBox.tsx
@@ -145,8 +145,8 @@ export default class IncomingCallBox extends React.Component {
width={32}
/>
- {caller}
- {incomingCallText}
+ { caller }
+ { incomingCallText }
{
@@ -164,7 +164,7 @@ export default class IncomingCallBox extends React.Component {
diff --git a/src/createRoom.ts b/src/createRoom.ts
index afbeb7fdb9..effc6ec1ac 100644
--- a/src/createRoom.ts
+++ b/src/createRoom.ts
@@ -17,6 +17,7 @@ limitations under the License.
import { MatrixClient } from "matrix-js-sdk/src/client";
import { Room } from "matrix-js-sdk/src/models/room";
+import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { MatrixClientPeg } from './MatrixClientPeg';
@@ -247,11 +248,11 @@ export function findDMForUser(client: MatrixClient, userId: string): Room {
* NOTE: this assumes you've just created the room and there's not been an opportunity
* for other code to run, so we shouldn't miss RoomState.newMember when it comes by.
*/
-export async function _waitForMember(client: MatrixClient, roomId: string, userId: string, opts = { timeout: 1500 }) {
+export async function waitForMember(client: MatrixClient, roomId: string, userId: string, opts = { timeout: 1500 }) {
const { timeout } = opts;
let handler;
return new Promise((resolve) => {
- handler = function(_event, _roomstate, member) {
+ handler = function(_, __, member: RoomMember) { // eslint-disable-line @typescript-eslint/naming-convention
if (member.userId !== userId) return;
if (member.roomId !== roomId) return;
resolve(true);
@@ -324,7 +325,7 @@ export async function ensureDMExists(client: MatrixClient, userId: string): Prom
}
roomId = await createRoom({ encryption, dmUserId: userId, spinner: false, andView: false });
- await _waitForMember(client, roomId, userId);
+ await waitForMember(client, roomId, userId);
}
return roomId;
}
diff --git a/src/editor/parts.ts b/src/editor/parts.ts
index 351df5062f..7bda8e1901 100644
--- a/src/editor/parts.ts
+++ b/src/editor/parts.ts
@@ -274,7 +274,7 @@ abstract class PillPart extends BasePart implements IPillPart {
}
// helper method for subclasses
- _setAvatarVars(node: HTMLElement, avatarUrl: string, initialLetter: string) {
+ protected setAvatarVars(node: HTMLElement, avatarUrl: string, initialLetter: string) {
const avatarBackground = `url('${avatarUrl}')`;
const avatarLetter = `'${initialLetter}'`;
// check if the value is changing,
@@ -354,7 +354,7 @@ class RoomPillPart extends PillPart {
initialLetter = Avatar.getInitialLetter(this.room ? this.room.name : this.resourceId);
avatarUrl = Avatar.defaultAvatarUrlForString(this.room ? this.room.roomId : this.resourceId);
}
- this._setAvatarVars(node, avatarUrl, initialLetter);
+ this.setAvatarVars(node, avatarUrl, initialLetter);
}
get type(): IPillPart["type"] {
@@ -399,7 +399,7 @@ class UserPillPart extends PillPart {
if (avatarUrl === defaultAvatarUrl) {
initialLetter = Avatar.getInitialLetter(name);
}
- this._setAvatarVars(node, avatarUrl, initialLetter);
+ this.setAvatarVars(node, avatarUrl, initialLetter);
}
get type(): IPillPart["type"] {
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index c7955fa767..5147e5a1f0 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -809,6 +809,7 @@
"Offline encrypted messaging using dehydrated devices": "Offline encrypted messaging using dehydrated devices",
"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",
+ "New layout switcher (with message bubbles)": "New layout switcher (with message bubbles)",
"Font size": "Font size",
"Use custom size": "Use custom size",
"Enable Emoji suggestions while typing": "Enable Emoji suggestions while typing",
@@ -1132,8 +1133,8 @@
"New keyword": "New keyword",
"Global": "Global",
"Mentions & keywords": "Mentions & keywords",
- "On": "On",
"Off": "Off",
+ "On": "On",
"Noisy": "Noisy",
"Notification targets": "Notification targets",
"There was an error loading your notification settings.": "There was an error loading your notification settings.",
@@ -1231,6 +1232,10 @@
"Custom theme URL": "Custom theme URL",
"Add theme": "Add theme",
"Theme": "Theme",
+ "Message layout": "Message layout",
+ "IRC": "IRC",
+ "Modern": "Modern",
+ "Message bubbles": "Message bubbles",
"Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Set the name of a font installed on your system & %(brand)s will attempt to use it.",
"Enable experimental, compact IRC style layout": "Enable experimental, compact IRC style layout",
"Customise your appearance": "Customise your appearance",
@@ -1643,7 +1648,7 @@
"Favourite": "Favourite",
"Low Priority": "Low Priority",
"Invite People": "Invite People",
- "Copy Link": "Copy Link",
+ "Copy Room Link": "Copy Room Link",
"Leave Room": "Leave Room",
"Room options": "Room options",
"%(count)s unread messages including mentions.|other": "%(count)s unread messages including mentions.",
diff --git a/src/languageHandler.tsx b/src/languageHandler.tsx
index a15eb4a4b7..e7329e4f2e 100644
--- a/src/languageHandler.tsx
+++ b/src/languageHandler.tsx
@@ -67,7 +67,7 @@ export function getUserLanguage(): string {
// Function which only purpose is to mark that a string is translatable
// Does not actually do anything. It's helpful for automatic extraction of translatable strings
-export function _td(s: string): string {
+export function _td(s: string): string { // eslint-disable-line @typescript-eslint/naming-convention
return s;
}
@@ -132,6 +132,8 @@ export type TranslatedString = string | React.ReactNode;
*
* @return a React component if any non-strings were used in substitutions, otherwise a string
*/
+// eslint-next-line @typescript-eslint/naming-convention
+// eslint-nexline @typescript-eslint/naming-convention
export function _t(text: string, variables?: IVariables): string;
export function _t(text: string, variables: IVariables, tags: Tags): React.ReactNode;
export function _t(text: string, variables?: IVariables, tags?: Tags): TranslatedString {
@@ -151,7 +153,7 @@ export function _t(text: string, variables?: IVariables, tags?: Tags): Translate
if (typeof substituted === 'string') {
return `@@${text}##${substituted}@@`;
} else {
- return {substituted};
+ return { substituted };
}
} else {
return substituted;
diff --git a/src/mjolnir/Mjolnir.ts b/src/mjolnir/Mjolnir.ts
index 21616eece3..fd30909798 100644
--- a/src/mjolnir/Mjolnir.ts
+++ b/src/mjolnir/Mjolnir.ts
@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
+import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { ALL_RULE_TYPES, BanList } from "./BanList";
import SettingsStore from "../settings/SettingsStore";
@@ -21,19 +22,17 @@ import { _t } from "../languageHandler";
import dis from "../dispatcher/dispatcher";
import { SettingLevel } from "../settings/SettingLevel";
import { Preset } from "matrix-js-sdk/src/@types/partials";
+import { ActionPayload } from "../dispatcher/payloads";
// TODO: Move this and related files to the js-sdk or something once finalized.
export class Mjolnir {
- static _instance: Mjolnir = null;
+ private static instance: Mjolnir = null;
- _lists: BanList[] = [];
- _roomIds: string[] = [];
- _mjolnirWatchRef = null;
- _dispatcherRef = null;
-
- constructor() {
- }
+ private _lists: BanList[] = []; // eslint-disable-line @typescript-eslint/naming-convention
+ private _roomIds: string[] = []; // eslint-disable-line @typescript-eslint/naming-convention
+ private mjolnirWatchRef: string = null;
+ private dispatcherRef: string = null;
get roomIds(): string[] {
return this._roomIds;
@@ -44,16 +43,16 @@ export class Mjolnir {
}
start() {
- this._mjolnirWatchRef = SettingsStore.watchSetting("mjolnirRooms", null, this._onListsChanged.bind(this));
+ this.mjolnirWatchRef = SettingsStore.watchSetting("mjolnirRooms", null, this.onListsChanged.bind(this));
- this._dispatcherRef = dis.register(this._onAction);
+ this.dispatcherRef = dis.register(this.onAction);
dis.dispatch({
action: 'do_after_sync_prepared',
deferred_action: { action: 'setup_mjolnir' },
});
}
- _onAction = (payload) => {
+ private onAction = (payload: ActionPayload) => {
if (payload['action'] === 'setup_mjolnir') {
console.log("Setting up Mjolnir: after sync");
this.setup();
@@ -62,23 +61,23 @@ export class Mjolnir {
setup() {
if (!MatrixClientPeg.get()) return;
- this._updateLists(SettingsStore.getValue("mjolnirRooms"));
- MatrixClientPeg.get().on("RoomState.events", this._onEvent);
+ this.updateLists(SettingsStore.getValue("mjolnirRooms"));
+ MatrixClientPeg.get().on("RoomState.events", this.onEvent);
}
stop() {
- if (this._mjolnirWatchRef) {
- SettingsStore.unwatchSetting(this._mjolnirWatchRef);
- this._mjolnirWatchRef = null;
+ if (this.mjolnirWatchRef) {
+ SettingsStore.unwatchSetting(this.mjolnirWatchRef);
+ this.mjolnirWatchRef = null;
}
- if (this._dispatcherRef) {
- dis.unregister(this._dispatcherRef);
- this._dispatcherRef = null;
+ if (this.dispatcherRef) {
+ dis.unregister(this.dispatcherRef);
+ this.dispatcherRef = null;
}
if (!MatrixClientPeg.get()) return;
- MatrixClientPeg.get().removeListener("RoomState.events", this._onEvent);
+ MatrixClientPeg.get().removeListener("RoomState.events", this.onEvent);
}
async getOrCreatePersonalList(): Promise {
@@ -132,20 +131,20 @@ export class Mjolnir {
this._lists = this._lists.filter(b => b.roomId !== roomId);
}
- _onEvent = (event) => {
+ private onEvent = (event: MatrixEvent) => {
if (!MatrixClientPeg.get()) return;
if (!this._roomIds.includes(event.getRoomId())) return;
if (!ALL_RULE_TYPES.includes(event.getType())) return;
- this._updateLists(this._roomIds);
+ this.updateLists(this._roomIds);
};
- _onListsChanged(settingName, roomId, atLevel, newValue) {
+ private onListsChanged(settingName: string, roomId: string, atLevel: SettingLevel, newValue: string[]) {
// We know that ban lists are only recorded at one level so we don't need to re-eval them
- this._updateLists(newValue);
+ this.updateLists(newValue);
}
- _updateLists(listRoomIds: string[]) {
+ private updateLists(listRoomIds: string[]) {
if (!MatrixClientPeg.get()) return;
console.log("Updating Mjolnir ban lists to: " + listRoomIds);
@@ -182,10 +181,10 @@ export class Mjolnir {
}
static sharedInstance(): Mjolnir {
- if (!Mjolnir._instance) {
- Mjolnir._instance = new Mjolnir();
+ if (!Mjolnir.instance) {
+ Mjolnir.instance = new Mjolnir();
}
- return Mjolnir._instance;
+ return Mjolnir.instance;
}
}
diff --git a/src/rageshake/submit-rageshake.ts b/src/rageshake/submit-rageshake.ts
index b629ddafd8..fd84f479ad 100644
--- a/src/rageshake/submit-rageshake.ts
+++ b/src/rageshake/submit-rageshake.ts
@@ -203,7 +203,7 @@ export default async function sendBugReport(bugReportEndpoint: string, opts: IOp
const body = await collectBugReport(opts);
progressCallback(_t("Uploading logs"));
- await _submitReport(bugReportEndpoint, body, progressCallback);
+ await submitReport(bugReportEndpoint, body, progressCallback);
}
/**
@@ -289,10 +289,10 @@ export async function submitFeedback(
body.append(k, extraData[k]);
}
- await _submitReport(SdkConfig.get().bug_report_endpoint_url, body, () => {});
+ await submitReport(SdkConfig.get().bug_report_endpoint_url, body, () => {});
}
-function _submitReport(endpoint: string, body: FormData, progressCallback: (string) => void) {
+function submitReport(endpoint: string, body: FormData, progressCallback: (str: string) => void) {
return new Promise((resolve, reject) => {
const req = new XMLHttpRequest();
req.open("POST", endpoint);
diff --git a/src/settings/Layout.ts b/src/settings/Layout.ts
index 3a42b2b510..d4e1f06c0a 100644
--- a/src/settings/Layout.ts
+++ b/src/settings/Layout.ts
@@ -1,5 +1,6 @@
/*
Copyright 2021 Å imon Brandner
+Copyright 2021 Quirin Götz
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -19,7 +20,8 @@ import PropTypes from 'prop-types';
/* TODO: This should be later reworked into something more generic */
export enum Layout {
IRC = "irc",
- Group = "group"
+ Group = "group",
+ Bubble = "bubble",
}
/* We need this because multiple components are still using JavaScript */
diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx
index 830ea9e32e..f0bdb2e0e5 100644
--- a/src/settings/Settings.tsx
+++ b/src/settings/Settings.tsx
@@ -41,6 +41,7 @@ import { Layout } from "./Layout";
import ReducedMotionController from './controllers/ReducedMotionController';
import IncompatibleController from "./controllers/IncompatibleController";
import SdkConfig from "../SdkConfig";
+import NewLayoutSwitcherController from './controllers/NewLayoutSwitcherController';
// These are just a bunch of helper arrays to avoid copy/pasting a bunch of times
const LEVELS_ROOM_SETTINGS = [
@@ -321,6 +322,13 @@ export const SETTINGS: {[setting: string]: ISetting} = {
displayName: _td("Show info about bridges in room settings"),
default: false,
},
+ "feature_new_layout_switcher": {
+ isFeature: true,
+ supportedLevels: LEVELS_FEATURE,
+ displayName: _td("New layout switcher (with message bubbles)"),
+ default: false,
+ controller: new NewLayoutSwitcherController(),
+ },
"RoomList.backgroundImage": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
default: null,
diff --git a/src/settings/controllers/NewLayoutSwitcherController.ts b/src/settings/controllers/NewLayoutSwitcherController.ts
new file mode 100644
index 0000000000..b1d6cac55e
--- /dev/null
+++ b/src/settings/controllers/NewLayoutSwitcherController.ts
@@ -0,0 +1,26 @@
+/*
+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 SettingController from "./SettingController";
+import { SettingLevel } from "../SettingLevel";
+import SettingsStore from "../SettingsStore";
+import { Layout } from "../Layout";
+
+export default class NewLayoutSwitcherController extends SettingController {
+ public onChange(level: SettingLevel, roomId: string, newValue: any) {
+ // On disabling switch back to Layout.Group if Layout.Bubble
+ if (!newValue && SettingsStore.getValue("layout") == Layout.Bubble) {
+ SettingsStore.setValue("layout", null, SettingLevel.DEVICE, Layout.Group);
+ }
+ }
+}
diff --git a/src/stores/GroupFilterOrderStore.js b/src/stores/GroupFilterOrderStore.js
index e6401f21f8..e81d1b81f7 100644
--- a/src/stores/GroupFilterOrderStore.js
+++ b/src/stores/GroupFilterOrderStore.js
@@ -49,7 +49,7 @@ class GroupFilterOrderStore extends Store {
this.__emitChange();
}
- __onDispatch(payload) {
+ __onDispatch(payload) { // eslint-disable-line @typescript-eslint/naming-convention
switch (payload.action) {
// Initialise state after initial sync
case 'view_room': {
diff --git a/src/stores/LifecycleStore.ts b/src/stores/LifecycleStore.ts
index 5381fc58ed..7db50af7a1 100644
--- a/src/stores/LifecycleStore.ts
+++ b/src/stores/LifecycleStore.ts
@@ -44,7 +44,7 @@ class LifecycleStore extends Store {
this.__emitChange();
}
- protected __onDispatch(payload: ActionPayload) {
+ protected __onDispatch(payload: ActionPayload) { // eslint-disable-line @typescript-eslint/naming-convention
switch (payload.action) {
case 'do_after_sync_prepared':
this.setState({
diff --git a/src/stores/RightPanelStore.ts b/src/stores/RightPanelStore.ts
index 521d124bad..b6f91bf835 100644
--- a/src/stores/RightPanelStore.ts
+++ b/src/stores/RightPanelStore.ts
@@ -144,7 +144,7 @@ export default class RightPanelStore extends Store {
this.__emitChange();
}
- __onDispatch(payload: ActionPayload) {
+ __onDispatch(payload: ActionPayload) { // eslint-disable-line @typescript-eslint/naming-convention
switch (payload.action) {
case 'view_room':
if (payload.room_id === this.lastRoomId) break; // skip this transition, probably a permalink
diff --git a/src/stores/RoomViewStore.tsx b/src/stores/RoomViewStore.tsx
index 10f42f3166..f2a7c135a3 100644
--- a/src/stores/RoomViewStore.tsx
+++ b/src/stores/RoomViewStore.tsx
@@ -96,7 +96,7 @@ class RoomViewStore extends Store {
this.__emitChange();
}
- __onDispatch(payload) {
+ __onDispatch(payload) { // eslint-disable-line @typescript-eslint/naming-convention
switch (payload.action) {
// view_room:
// - room_alias: '#somealias:matrix.org'
@@ -325,8 +325,8 @@ class RoomViewStore extends Store {
msg = _t("There was an error joining the room");
} else if (err.errcode === 'M_INCOMPATIBLE_ROOM_VERSION') {
msg =
- {_t("Sorry, your homeserver is too old to participate in this room.")}
- {_t("Please contact your homeserver administrator.")}
+ { _t("Sorry, your homeserver is too old to participate in this room.") }
+ { _t("Please contact your homeserver administrator.") }
;
} else if (err.httpStatus === 404) {
const invitingUserId = this.getInvitingUserId(this.state.roomId);
@@ -429,7 +429,7 @@ class RoomViewStore extends Store {
}
}
-let singletonRoomViewStore = null;
+let singletonRoomViewStore: RoomViewStore = null;
if (!singletonRoomViewStore) {
singletonRoomViewStore = new RoomViewStore();
}
diff --git a/src/stores/room-list/MessagePreviewStore.ts b/src/stores/room-list/MessagePreviewStore.ts
index 99f24cfbe7..44ec173e08 100644
--- a/src/stores/room-list/MessagePreviewStore.ts
+++ b/src/stores/room-list/MessagePreviewStore.ts
@@ -63,7 +63,7 @@ const PREVIEWS = {
const MAX_EVENTS_BACKWARDS = 50;
// type merging ftw
-type TAG_ANY = "im.vector.any";
+type TAG_ANY = "im.vector.any"; // eslint-disable-line @typescript-eslint/naming-convention
const TAG_ANY: TAG_ANY = "im.vector.any";
interface IState {
diff --git a/src/stores/room-list/algorithms/Algorithm.ts b/src/stores/room-list/algorithms/Algorithm.ts
index 8574f095d6..eb6ffe6dcf 100644
--- a/src/stores/room-list/algorithms/Algorithm.ts
+++ b/src/stores/room-list/algorithms/Algorithm.ts
@@ -124,7 +124,11 @@ export class Algorithm extends EventEmitter {
* @param val The new room to sticky.
*/
public setStickyRoom(val: Room) {
- this.updateStickyRoom(val);
+ try {
+ this.updateStickyRoom(val);
+ } catch (e) {
+ console.warn("Failed to update sticky room", e);
+ }
}
public getTagSorting(tagId: TagID): SortAlgorithm {
diff --git a/src/toasts/ServerLimitToast.tsx b/src/toasts/ServerLimitToast.tsx
index f915077bf4..9a104f552e 100644
--- a/src/toasts/ServerLimitToast.tsx
+++ b/src/toasts/ServerLimitToast.tsx
@@ -37,7 +37,7 @@ export const showToast = (limitType: string, onHideToast: () => void, adminConta
key: TOAST_KEY,
title: _t("Warning"),
props: {
- description: {errorText} {contactText} ,
+ description: { errorText } { contactText } ,
acceptLabel: _t("Ok"),
onAccept: () => {
hideToast();
diff --git a/src/toasts/UpdateToast.tsx b/src/toasts/UpdateToast.tsx
index eb35c41512..cb072705ce 100644
--- a/src/toasts/UpdateToast.tsx
+++ b/src/toasts/UpdateToast.tsx
@@ -51,7 +51,7 @@ export const showToast = (version: string, newVersion: string, releaseNotes?: st
onAccept = () => {
Modal.createTrackedDialog('Display release notes', '', QuestionDialog, {
title: _t("What's New"),
- description: {releaseNotes},
+ description: { releaseNotes },
button: _t("Update"),
onFinished: (update) => {
if (update && PlatformPeg.get()) {
diff --git a/src/utils/AutoDiscoveryUtils.tsx b/src/utils/AutoDiscoveryUtils.tsx
index 6c0c8b2e13..bad87db2b9 100644
--- a/src/utils/AutoDiscoveryUtils.tsx
+++ b/src/utils/AutoDiscoveryUtils.tsx
@@ -90,7 +90,7 @@ export default class AutoDiscoveryUtils {
href="https://github.com/vector-im/element-web/blob/master/docs/config.md"
target="_blank"
rel="noreferrer noopener"
- >{sub};
+ >{ sub };
},
},
);
@@ -130,8 +130,8 @@ export default class AutoDiscoveryUtils {
serverErrorIsFatal: isFatalError,
serverDeadError: (
- {title}
- {body}
+ { title }
+ { body }
),
};
diff --git a/src/utils/ErrorUtils.tsx b/src/utils/ErrorUtils.tsx
index c39ee21f09..4253564ffd 100644
--- a/src/utils/ErrorUtils.tsx
+++ b/src/utils/ErrorUtils.tsx
@@ -44,7 +44,7 @@ export function messageForResourceLimitError(
const linkSub = sub => {
if (adminContact) {
- return {sub};
+ return { sub };
} else {
return sub;
}
@@ -76,12 +76,12 @@ export function messageForSyncError(err: MatrixError | Error): ReactNode {
},
);
return
- {limitError}
- {adminContact}
+ { limitError }
+ { adminContact }
;
} else {
return
- {_t("Unable to connect to Homeserver. Retrying...")}
+ { _t("Unable to connect to Homeserver. Retrying...") }
;
}
}
diff --git a/src/widgets/CapabilityText.tsx b/src/widgets/CapabilityText.tsx
index 304a340247..63e34eea7a 100644
--- a/src/widgets/CapabilityText.tsx
+++ b/src/widgets/CapabilityText.tsx
@@ -20,7 +20,7 @@ import { EventType, MsgType } from "matrix-js-sdk/src/@types/event";
import { ElementWidgetCapabilities } from "../stores/widgets/ElementWidgetCapabilities";
import React from "react";
-type GENERIC_WIDGET_KIND = "generic";
+type GENERIC_WIDGET_KIND = "generic"; // eslint-disable-line @typescript-eslint/naming-convention
const GENERIC_WIDGET_KIND: GENERIC_WIDGET_KIND = "generic";
interface ISendRecvStaticCapText {
@@ -176,7 +176,7 @@ export class CapabilityText {
primary: _t("Send %(eventType)s events as you in this room", {
eventType: eventCap.eventType,
}, {
- b: sub => {sub},
+ b: sub => { sub },
}),
byline: CapabilityText.bylineFor(eventCap),
};
@@ -185,7 +185,7 @@ export class CapabilityText {
primary: _t("See %(eventType)s events posted to this room", {
eventType: eventCap.eventType,
}, {
- b: sub => {sub},
+ b: sub => { sub },
}),
byline: CapabilityText.bylineFor(eventCap),
};
@@ -196,7 +196,7 @@ export class CapabilityText {
primary: _t("Send %(eventType)s events as you in your active room", {
eventType: eventCap.eventType,
}, {
- b: sub => {sub},
+ b: sub => { sub },
}),
byline: CapabilityText.bylineFor(eventCap),
};
@@ -205,7 +205,7 @@ export class CapabilityText {
primary: _t("See %(eventType)s events posted to your active room", {
eventType: eventCap.eventType,
}, {
- b: sub => {sub},
+ b: sub => { sub },
}),
byline: CapabilityText.bylineFor(eventCap),
};
@@ -216,7 +216,7 @@ export class CapabilityText {
// We don't have enough context to render this capability specially, so we'll present it as-is
return {
primary: _t("The %(capability)s capability", { capability }, {
- b: sub => {sub},
+ b: sub => { sub },
}),
};
}
@@ -324,13 +324,13 @@ export class CapabilityText {
primary = _t("Send %(msgtype)s messages as you in this room", {
msgtype: eventCap.keyStr,
}, {
- b: sub => {sub},
+ b: sub => { sub },
});
} else {
primary = _t("Send %(msgtype)s messages as you in your active room", {
msgtype: eventCap.keyStr,
}, {
- b: sub => {sub},
+ b: sub => { sub },
});
}
} else {
@@ -338,13 +338,13 @@ export class CapabilityText {
primary = _t("See %(msgtype)s messages posted to this room", {
msgtype: eventCap.keyStr,
}, {
- b: sub => {sub},
+ b: sub => { sub },
});
} else {
primary = _t("See %(msgtype)s messages posted to your active room", {
msgtype: eventCap.keyStr,
}, {
- b: sub => {sub},
+ b: sub => { sub },
});
}
}
diff --git a/test/accessibility/RovingTabIndex-test.js b/test/accessibility/RovingTabIndex-test.js
index bead5c3158..72d4253710 100644
--- a/test/accessibility/RovingTabIndex-test.js
+++ b/test/accessibility/RovingTabIndex-test.js
@@ -48,7 +48,7 @@ const button4 = d ;
describe("RovingTabIndex", () => {
it("RovingTabIndexProvider renders children as expected", () => {
const wrapper = mount(
- {() => Test}
+ { () => Test }
);
expect(wrapper.text()).toBe("Test");
expect(wrapper.html()).toBe('Test');
@@ -56,11 +56,11 @@ describe("RovingTabIndex", () => {
it("RovingTabIndexProvider works as expected with useRovingTabIndex", () => {
const wrapper = mount(
- {() =>
+ { () =>
{ button1 }
{ button2 }
{ button3 }
- }
+ }
);
// should begin with 0th being active
@@ -98,15 +98,15 @@ describe("RovingTabIndex", () => {
it("RovingTabIndexProvider works as expected with RovingTabIndexWrapper", () => {
const wrapper = mount(
- {() =>
+ { () =>
{ button1 }
{ button2 }
- {({ onFocus, isActive, ref }) =>
+ { ({ onFocus, isActive, ref }) =>
.
}
- }
+ }
);
// should begin with 0th being active
diff --git a/test/components/views/messages/TextualBody-test.js b/test/components/views/messages/TextualBody-test.js
index fd11a9d46b..85a02aad7b 100644
--- a/test/components/views/messages/TextualBody-test.js
+++ b/test/components/views/messages/TextualBody-test.js
@@ -23,6 +23,7 @@ import { mkEvent, mkStubRoom } from "../../../test-utils";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import * as languageHandler from "../../../../src/languageHandler";
import * as TestUtils from "../../../test-utils";
+import DMRoomMap from "../../../../src/utils/DMRoomMap";
const _TextualBody = sdk.getComponent("views.messages.TextualBody");
const TextualBody = TestUtils.wrapInMatrixClientContext(_TextualBody);
@@ -41,6 +42,7 @@ describe(" ", () => {
isGuest: () => false,
mxcUrlToHttp: (s) => s,
};
+ DMRoomMap.makeShared();
const ev = mkEvent({
type: "m.room.message",
@@ -66,6 +68,7 @@ describe(" ", () => {
isGuest: () => false,
mxcUrlToHttp: (s) => s,
};
+ DMRoomMap.makeShared();
const ev = mkEvent({
type: "m.room.message",
@@ -92,6 +95,7 @@ describe(" ", () => {
isGuest: () => false,
mxcUrlToHttp: (s) => s,
};
+ DMRoomMap.makeShared();
});
it("simple message renders as expected", () => {
@@ -146,6 +150,7 @@ describe(" ", () => {
isGuest: () => false,
mxcUrlToHttp: (s) => s,
};
+ DMRoomMap.makeShared();
});
it("italics, bold, underline and strikethrough render as expected", () => {
@@ -292,6 +297,7 @@ describe(" ", () => {
isGuest: () => false,
mxcUrlToHttp: (s) => s,
};
+ DMRoomMap.makeShared();
const ev = mkEvent({
type: "m.room.message",
diff --git a/test/createRoom-test.js b/test/createRoom-test.js
index b9b7e7df01..11cb7edf5d 100644
--- a/test/createRoom-test.js
+++ b/test/createRoom-test.js
@@ -1,5 +1,5 @@
import './skinned-sdk'; // Must be first for skinning to work
-import { _waitForMember, canEncryptToAllUsers } from '../src/createRoom';
+import { waitForMember, canEncryptToAllUsers } from '../src/createRoom';
import { EventEmitter } from 'events';
/* Shorter timeout, we've got tests to run */
@@ -13,7 +13,7 @@ describe("waitForMember", () => {
});
it("resolves with false if the timeout is reached", (done) => {
- _waitForMember(client, "", "", { timeout: 0 }).then((r) => {
+ waitForMember(client, "", "", { timeout: 0 }).then((r) => {
expect(r).toBe(false);
done();
});
@@ -22,7 +22,7 @@ describe("waitForMember", () => {
it("resolves with false if the timeout is reached, even if other RoomState.newMember events fire", (done) => {
const roomId = "!roomId:domain";
const userId = "@clientId:domain";
- _waitForMember(client, roomId, userId, { timeout }).then((r) => {
+ waitForMember(client, roomId, userId, { timeout }).then((r) => {
expect(r).toBe(false);
done();
});
@@ -32,7 +32,7 @@ describe("waitForMember", () => {
it("resolves with true if RoomState.newMember fires", (done) => {
const roomId = "!roomId:domain";
const userId = "@clientId:domain";
- _waitForMember(client, roomId, userId, { timeout }).then((r) => {
+ waitForMember(client, roomId, userId, { timeout }).then((r) => {
expect(r).toBe(true);
expect(client.listeners("RoomState.newMember").length).toBe(0);
done();
diff --git a/yarn.lock b/yarn.lock
index 96c02681fd..228550a57a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3242,7 +3242,7 @@ eslint-config-google@^0.14.0:
"eslint-plugin-matrix-org@github:matrix-org/eslint-plugin-matrix-org#main":
version "0.3.2"
- resolved "https://codeload.github.com/matrix-org/eslint-plugin-matrix-org/tar.gz/e8197938dca66849ffdac4baca7c05275df12835"
+ resolved "https://codeload.github.com/matrix-org/eslint-plugin-matrix-org/tar.gz/8529f1d77863db6327cf1a1a4fa65d06cc26f91b"
eslint-plugin-react-hooks@^4.2.0:
version "4.2.0"
@@ -5455,10 +5455,10 @@ mathml-tag-names@^2.1.3:
resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3"
integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==
-matrix-js-sdk@12.0.1:
- version "12.0.1"
- resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-12.0.1.tgz#3a63881f743420a4d39474daa39bd0fb90930d43"
- integrity sha512-HkOWv8QHojceo3kPbC+vAIFUjsRAig6MBvEY35UygS3g2dL0UcJ5Qx09/2wcXtu6dowlDnWsz2HHk62tS2cklA==
+matrix-js-sdk@12.1.0:
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-12.1.0.tgz#7d159dd9bc03701e45a6b2777f1fa582a7e8b970"
+ integrity sha512-/fSqOjD+mTlMD+/B3s3Ja6BfI46FnTDl43ojzGDUOsHRRmSYUmoONb83qkH5Fjm8cI2q5ZBJMsBfjuZwLVeiZw==
dependencies:
"@babel/runtime" "^7.12.5"
another-json "^0.2.0"