Merge remote-tracking branch 'upstream/develop' into feature/call-event-tile

This commit is contained in:
Šimon Brandner 2021-07-08 13:30:57 +02:00
commit 9c67679b35
No known key found for this signature in database
GPG key ID: 9760693FDD98A790
132 changed files with 882 additions and 876 deletions

View file

@ -1,3 +1,174 @@
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)
* Remove reminescent references to the tinter
[\#6316](https://github.com/matrix-org/matrix-react-sdk/pull/6316)
* Update to released version of js-sdk
Changes in [3.25.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.25.0-rc.1) (2021-06-29)
===============================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.24.0...v3.25.0-rc.1)
* Update to js-sdk v12.0.1-rc.1
* Translations update from Weblate
[\#6286](https://github.com/matrix-org/matrix-react-sdk/pull/6286)
* Fix back button on user info card after clicking a permalink
[\#6277](https://github.com/matrix-org/matrix-react-sdk/pull/6277)
* Group ACLs with MELS
[\#6280](https://github.com/matrix-org/matrix-react-sdk/pull/6280)
* Fix editState not getting passed through
[\#6282](https://github.com/matrix-org/matrix-react-sdk/pull/6282)
* Migrate message context menu to IconizedContextMenu
[\#5671](https://github.com/matrix-org/matrix-react-sdk/pull/5671)
* Improve audio recording performance
[\#6240](https://github.com/matrix-org/matrix-react-sdk/pull/6240)
* Fix multiple timeline panels handling composer and edit events
[\#6278](https://github.com/matrix-org/matrix-react-sdk/pull/6278)
* Let m.notice messages mark a room as unread
[\#6281](https://github.com/matrix-org/matrix-react-sdk/pull/6281)
* Removes the override on the Bubble Container
[\#5953](https://github.com/matrix-org/matrix-react-sdk/pull/5953)
* Fix IRC layout regressions
[\#6193](https://github.com/matrix-org/matrix-react-sdk/pull/6193)
* Fix trashcan.svg by exporting it with its viewbox
[\#6248](https://github.com/matrix-org/matrix-react-sdk/pull/6248)
* Fix tiny scrollbar dot on chrome/electron in Forward Dialog
[\#6276](https://github.com/matrix-org/matrix-react-sdk/pull/6276)
* Upgrade puppeteer to use newer version of Chrome
[\#6268](https://github.com/matrix-org/matrix-react-sdk/pull/6268)
* Make toast dismiss button less prominent
[\#6275](https://github.com/matrix-org/matrix-react-sdk/pull/6275)
* Encrypt the voice message file if needed
[\#6269](https://github.com/matrix-org/matrix-react-sdk/pull/6269)
* Fix hyper-precise presence
[\#6270](https://github.com/matrix-org/matrix-react-sdk/pull/6270)
* Fix issues around private spaces, including previewable
[\#6265](https://github.com/matrix-org/matrix-react-sdk/pull/6265)
* Make _pinned messages_ in `m.room.pinned_events` event clickable
[\#6257](https://github.com/matrix-org/matrix-react-sdk/pull/6257)
* Fix space avatar management layout being broken
[\#6266](https://github.com/matrix-org/matrix-react-sdk/pull/6266)
* Convert EntityTile, MemberTile and PresenceLabel to TS
[\#6251](https://github.com/matrix-org/matrix-react-sdk/pull/6251)
* Fix UserInfo not working when rendered without a room
[\#6260](https://github.com/matrix-org/matrix-react-sdk/pull/6260)
* Update membership reason handling, including leave reason displaying
[\#6253](https://github.com/matrix-org/matrix-react-sdk/pull/6253)
* Consolidate types with js-sdk changes
[\#6220](https://github.com/matrix-org/matrix-react-sdk/pull/6220)
* Fix edit history modal
[\#6258](https://github.com/matrix-org/matrix-react-sdk/pull/6258)
* Convert MemberList to TS
[\#6249](https://github.com/matrix-org/matrix-react-sdk/pull/6249)
* Fix two PRs duplicating the css attribute
[\#6259](https://github.com/matrix-org/matrix-react-sdk/pull/6259)
* Improve invite error messages in InviteDialog for room invites
[\#6201](https://github.com/matrix-org/matrix-react-sdk/pull/6201)
* Fix invite dialog being cut off when it has limited results
[\#6256](https://github.com/matrix-org/matrix-react-sdk/pull/6256)
* Fix pinning event in a room which hasn't had events pinned in before
[\#6255](https://github.com/matrix-org/matrix-react-sdk/pull/6255)
* Allow modal widget buttons to be disabled when the modal opens
[\#6178](https://github.com/matrix-org/matrix-react-sdk/pull/6178)
* Decrease e2e shield fill mask size so that it doesn't overlap
[\#6250](https://github.com/matrix-org/matrix-react-sdk/pull/6250)
* Dial Pad UI bug fixes
[\#5786](https://github.com/matrix-org/matrix-react-sdk/pull/5786)
* Simple handling of mid-call output changes
[\#6247](https://github.com/matrix-org/matrix-react-sdk/pull/6247)
* Improve ForwardDialog performance by using TruncatedList
[\#6228](https://github.com/matrix-org/matrix-react-sdk/pull/6228)
* Fix dependency and lockfile mismatch
[\#6246](https://github.com/matrix-org/matrix-react-sdk/pull/6246)
* Improve room directory click behaviour
[\#6234](https://github.com/matrix-org/matrix-react-sdk/pull/6234)
* Fix keyboard accessibility of the space panel
[\#6239](https://github.com/matrix-org/matrix-react-sdk/pull/6239)
* Add ways to manage addresses for Spaces
[\#6151](https://github.com/matrix-org/matrix-react-sdk/pull/6151)
* Hide communities invites and the community autocompleter when Spaces on
[\#6244](https://github.com/matrix-org/matrix-react-sdk/pull/6244)
* Convert bunch of files to TS
[\#6241](https://github.com/matrix-org/matrix-react-sdk/pull/6241)
* Open local addresses section by default when there are no existing local
addresses
[\#6179](https://github.com/matrix-org/matrix-react-sdk/pull/6179)
* Allow reordering of the space panel via Drag and Drop
[\#6137](https://github.com/matrix-org/matrix-react-sdk/pull/6137)
* Replace drag and drop mechanism in communities with something simpler
[\#6134](https://github.com/matrix-org/matrix-react-sdk/pull/6134)
* EventTilePreview fixes
[\#6000](https://github.com/matrix-org/matrix-react-sdk/pull/6000)
* Upgrade @types/react and @types/react-dom
[\#6233](https://github.com/matrix-org/matrix-react-sdk/pull/6233)
* Fix type error in the SpaceStore
[\#6242](https://github.com/matrix-org/matrix-react-sdk/pull/6242)
* Add experimental options to the Spaces beta
[\#6199](https://github.com/matrix-org/matrix-react-sdk/pull/6199)
* Consolidate types with js-sdk changes
[\#6215](https://github.com/matrix-org/matrix-react-sdk/pull/6215)
* Fix branch matching for Buildkite
[\#6236](https://github.com/matrix-org/matrix-react-sdk/pull/6236)
* Migrate SearchBar to TypeScript
[\#6230](https://github.com/matrix-org/matrix-react-sdk/pull/6230)
* Add support to keyboard shortcuts dialog for [digits]
[\#6088](https://github.com/matrix-org/matrix-react-sdk/pull/6088)
* Fix modal opening race condition
[\#6238](https://github.com/matrix-org/matrix-react-sdk/pull/6238)
* Deprecate FormButton in favour of AccessibleButton
[\#6229](https://github.com/matrix-org/matrix-react-sdk/pull/6229)
* Add PR template
[\#6216](https://github.com/matrix-org/matrix-react-sdk/pull/6216)
* Prefer canonical aliases while autocompleting rooms
[\#6222](https://github.com/matrix-org/matrix-react-sdk/pull/6222)
* Fix quote button
[\#6232](https://github.com/matrix-org/matrix-react-sdk/pull/6232)
* Restore branch matching support for GitHub Actions e2e tests
[\#6224](https://github.com/matrix-org/matrix-react-sdk/pull/6224)
* Fix View Source accessing renamed private field on MatrixEvent
[\#6225](https://github.com/matrix-org/matrix-react-sdk/pull/6225)
* Fix ConfirmUserActionDialog returning an input field rather than text
[\#6219](https://github.com/matrix-org/matrix-react-sdk/pull/6219)
* Revert "Partially restore immutable event objects at the rendering layer"
[\#6221](https://github.com/matrix-org/matrix-react-sdk/pull/6221)
* Add jq to e2e tests Dockerfile
[\#6218](https://github.com/matrix-org/matrix-react-sdk/pull/6218)
* Partially restore immutable event objects at the rendering layer
[\#6196](https://github.com/matrix-org/matrix-react-sdk/pull/6196)
* Update MSC number references for voice messages
[\#6197](https://github.com/matrix-org/matrix-react-sdk/pull/6197)
* Fix phase enum usage in JS modules as well
[\#6214](https://github.com/matrix-org/matrix-react-sdk/pull/6214)
* Migrate some dialogs to TypeScript
[\#6185](https://github.com/matrix-org/matrix-react-sdk/pull/6185)
* Typescript fixes due to MatrixEvent being TSified
[\#6208](https://github.com/matrix-org/matrix-react-sdk/pull/6208)
* Allow click-to-ping, quote & emoji picker for edit composer too
[\#5858](https://github.com/matrix-org/matrix-react-sdk/pull/5858)
* Add call silencing
[\#6082](https://github.com/matrix-org/matrix-react-sdk/pull/6082)
* Fix types in SlashCommands
[\#6207](https://github.com/matrix-org/matrix-react-sdk/pull/6207)
* Benchmark multiple common user scenario
[\#6190](https://github.com/matrix-org/matrix-react-sdk/pull/6190)
* Fix forward dialog message preview display names
[\#6204](https://github.com/matrix-org/matrix-react-sdk/pull/6204)
* Remove stray bullet point in reply preview
[\#6206](https://github.com/matrix-org/matrix-react-sdk/pull/6206)
* Stop requesting null next replies from the server
[\#6203](https://github.com/matrix-org/matrix-react-sdk/pull/6203)
* Fix soft crash caused by a broken shouldComponentUpdate
[\#6202](https://github.com/matrix-org/matrix-react-sdk/pull/6202)
* Keep composer reply when scrolling away from a highlighted event
[\#6200](https://github.com/matrix-org/matrix-react-sdk/pull/6200)
* Cache virtual/native room mappings when they're created
[\#6194](https://github.com/matrix-org/matrix-react-sdk/pull/6194)
* Disable comment-on-alert
[\#6191](https://github.com/matrix-org/matrix-react-sdk/pull/6191)
* Bump postcss from 7.0.35 to 7.0.36
[\#6195](https://github.com/matrix-org/matrix-react-sdk/pull/6195)
Changes in [3.24.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.24.0) (2021-06-21) Changes in [3.24.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.24.0) (2021-06-21)
===================================================================================================== =====================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.24.0-rc.1...v3.24.0) [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.24.0-rc.1...v3.24.0)

View file

@ -1,6 +1,6 @@
{ {
"name": "matrix-react-sdk", "name": "matrix-react-sdk",
"version": "3.24.0", "version": "3.25.0",
"description": "SDK for matrix.org using React", "description": "SDK for matrix.org using React",
"author": "matrix.org", "author": "matrix.org",
"repository": { "repository": {
@ -54,7 +54,6 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.12.5", "@babel/runtime": "^7.12.5",
"@types/commonmark": "^0.27.4",
"await-lock": "^2.1.0", "await-lock": "^2.1.0",
"blurhash": "^1.1.3", "blurhash": "^1.1.3",
"browser-encrypt-attachment": "^0.3.0", "browser-encrypt-attachment": "^0.3.0",
@ -80,7 +79,7 @@
"katex": "^0.12.0", "katex": "^0.12.0",
"linkifyjs": "^2.1.9", "linkifyjs": "^2.1.9",
"lodash": "^4.17.20", "lodash": "^4.17.20",
"matrix-js-sdk": "12.0.0", "matrix-js-sdk": "12.0.1",
"matrix-widget-api": "^0.1.0-beta.15", "matrix-widget-api": "^0.1.0-beta.15",
"minimist": "^1.2.5", "minimist": "^1.2.5",
"opus-recorder": "^8.0.3", "opus-recorder": "^8.0.3",
@ -92,6 +91,7 @@
"re-resizable": "^6.9.0", "re-resizable": "^6.9.0",
"react": "^17.0.2", "react": "^17.0.2",
"react-beautiful-dnd": "^13.1.0", "react-beautiful-dnd": "^13.1.0",
"react-blurhash": "^0.1.3",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-focus-lock": "^2.5.0", "react-focus-lock": "^2.5.0",
"react-transition-group": "^4.4.1", "react-transition-group": "^4.4.1",
@ -124,6 +124,7 @@
"@peculiar/webcrypto": "^1.1.4", "@peculiar/webcrypto": "^1.1.4",
"@sinonjs/fake-timers": "^7.0.2", "@sinonjs/fake-timers": "^7.0.2",
"@types/classnames": "^2.2.11", "@types/classnames": "^2.2.11",
"@types/commonmark": "^0.27.4",
"@types/counterpart": "^0.18.1", "@types/counterpart": "^0.18.1",
"@types/diff-match-patch": "^1.0.32", "@types/diff-match-patch": "^1.0.32",
"@types/flux": "^3.1.9", "@types/flux": "^3.1.9",

View file

@ -57,7 +57,6 @@
@import "./views/avatars/_BaseAvatar.scss"; @import "./views/avatars/_BaseAvatar.scss";
@import "./views/avatars/_DecoratedRoomAvatar.scss"; @import "./views/avatars/_DecoratedRoomAvatar.scss";
@import "./views/avatars/_MemberStatusMessageAvatar.scss"; @import "./views/avatars/_MemberStatusMessageAvatar.scss";
@import "./views/avatars/_PulsedAvatar.scss";
@import "./views/avatars/_WidgetAvatar.scss"; @import "./views/avatars/_WidgetAvatar.scss";
@import "./views/beta/_BetaCard.scss"; @import "./views/beta/_BetaCard.scss";
@import "./views/context_menus/_CallContextMenu.scss"; @import "./views/context_menus/_CallContextMenu.scss";

View file

@ -121,23 +121,51 @@ $pulse-color: $pinned-unread-color;
box-shadow: 0 0 0 0 rgba($pulse-color, 1); box-shadow: 0 0 0 0 rgba($pulse-color, 1);
animation: mx_RightPanel_indicator_pulse 2s infinite; animation: mx_RightPanel_indicator_pulse 2s infinite;
animation-iteration-count: 1; animation-iteration-count: 1;
&::after {
content: "";
position: absolute;
width: inherit;
height: inherit;
top: 0;
left: 0;
transform: scale(1);
transform-origin: center center;
animation-name: mx_RightPanel_indicator_pulse_shadow;
animation-duration: inherit;
animation-iteration-count: inherit;
border-radius: 50%;
background: rgba($pulse-color, 1);
}
} }
} }
@keyframes mx_RightPanel_indicator_pulse { @keyframes mx_RightPanel_indicator_pulse {
0% { 0% {
transform: scale(0.95); transform: scale(0.95);
box-shadow: 0 0 0 0 rgba($pulse-color, 0.7);
} }
70% { 70% {
transform: scale(1); transform: scale(1);
box-shadow: 0 0 0 10px rgba($pulse-color, 0);
} }
100% { 100% {
transform: scale(0.95); transform: scale(0.95);
box-shadow: 0 0 0 0 rgba($pulse-color, 0); }
}
@keyframes mx_RightPanel_indicator_pulse_shadow {
0% {
opacity: 0.7;
}
70% {
transform: scale(2.2);
opacity: 0;
}
100% {
opacity: 0;
} }
} }

View file

@ -57,14 +57,15 @@ limitations under the License.
@keyframes mx_RoomView_fileDropTarget_image_animation { @keyframes mx_RoomView_fileDropTarget_image_animation {
from { from {
width: 0px; transform: scaleX(0);
} }
to { to {
width: 32px; transform: scaleX(1);
} }
} }
.mx_RoomView_fileDropTarget_image { .mx_RoomView_fileDropTarget_image {
width: 32px;
animation: mx_RoomView_fileDropTarget_image_animation; animation: mx_RoomView_fileDropTarget_image_animation;
animation-duration: 0.5s; animation-duration: 0.5s;
margin-bottom: 16px; margin-bottom: 16px;

View file

@ -1,30 +0,0 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_PulsedAvatar {
@keyframes shadow-pulse {
0% {
box-shadow: 0 0 0 0px rgba($accent-color, 0.2);
}
100% {
box-shadow: 0 0 0 6px rgba($accent-color, 0);
}
}
img {
animation: shadow-pulse 1s infinite;
}
}

View file

@ -110,24 +110,52 @@ $dot-size: 12px;
width: $dot-size; width: $dot-size;
transform: scale(1); transform: scale(1);
background: rgba($pulse-color, 1); background: rgba($pulse-color, 1);
box-shadow: 0 0 0 0 rgba($pulse-color, 1);
animation: mx_Beta_bluePulse 2s infinite; animation: mx_Beta_bluePulse 2s infinite;
animation-iteration-count: 20; animation-iteration-count: 20;
position: relative;
&::after {
content: "";
position: absolute;
width: inherit;
height: inherit;
top: 0;
left: 0;
transform: scale(1);
transform-origin: center center;
animation-name: mx_Beta_bluePulse_shadow;
animation-duration: inherit;
animation-iteration-count: inherit;
border-radius: 50%;
background: rgba($pulse-color, 1);
}
} }
@keyframes mx_Beta_bluePulse { @keyframes mx_Beta_bluePulse {
0% { 0% {
transform: scale(0.95); transform: scale(0.95);
box-shadow: 0 0 0 0 rgba($pulse-color, 0.7);
} }
70% { 70% {
transform: scale(1); transform: scale(1);
box-shadow: 0 0 0 10px rgba($pulse-color, 0);
} }
100% { 100% {
transform: scale(0.95); transform: scale(0.95);
box-shadow: 0 0 0 0 rgba($pulse-color, 0); }
}
@keyframes mx_Beta_bluePulse_shadow {
0% {
opacity: 0.7;
}
70% {
transform: scale(2.2);
opacity: 0;
}
100% {
opacity: 0;
} }
} }

View file

@ -28,6 +28,7 @@ limitations under the License.
left: 0; left: 0;
top: 2px; // alignment top: 2px; // alignment
background-image: url("$(res)/img/element-icons/warning-badge.svg"); background-image: url("$(res)/img/element-icons/warning-badge.svg");
background-size: contain;
} }
.mx_AccessSecretStorageDialog_reset_link { .mx_AccessSecretStorageDialog_reset_link {

View file

@ -484,8 +484,7 @@ $hover-select-border: 4px;
pre, code { pre, code {
font-family: $monospace-font-family !important; font-family: $monospace-font-family !important;
// deliberate constants as we're behind an invert filter background-color: $header-panel-bg-color;
color: #333;
} }
pre { pre {
@ -495,11 +494,6 @@ $hover-select-border: 4px;
overflow-x: overlay; overflow-x: overlay;
overflow-y: visible; overflow-y: visible;
} }
code {
// deliberate constants as we're behind an invert filter
background-color: #f8f8f8;
}
} }
.mx_EventTile_lineNumbers { .mx_EventTile_lineNumbers {

View file

@ -119,8 +119,6 @@ $voipcall-plinth-color: #394049;
$theme-button-bg-color: #e3e8f0; $theme-button-bg-color: #e3e8f0;
$dialpad-button-bg-color: #6F7882; $dialpad-button-bg-color: #6F7882;
;
$roomlist-button-bg-color: rgba(141, 151, 165, 0.2); // Buttons include the filter box, explore button, and sublist buttons $roomlist-button-bg-color: rgba(141, 151, 165, 0.2); // Buttons include the filter box, explore button, and sublist buttons
$roomlist-filter-active-bg-color: $bg-color; $roomlist-filter-active-bg-color: $bg-color;
@ -274,24 +272,7 @@ $composer-shadow-color: rgba(0, 0, 0, 0.28);
} }
// markdown overrides: // markdown overrides:
.mx_EventTile_content .markdown-body pre:hover {
border-color: #808080 !important; // inverted due to rules below
scrollbar-color: rgba(0, 0, 0, 0.2) transparent; // copied from light theme due to inversion below
// the code above works only in Firefox, this is for other browsers
// see https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-color
&::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, 0.2); // copied from light theme due to inversion below
}
}
.mx_EventTile_content .markdown-body { .mx_EventTile_content .markdown-body {
pre, code {
filter: invert(1);
}
pre code {
filter: none;
}
table { table {
tr { tr {
background-color: #000000; background-color: #000000;
@ -301,18 +282,9 @@ $composer-shadow-color: rgba(0, 0, 0, 0.28);
background-color: #080808; background-color: #080808;
} }
} }
blockquote {
color: #919191;
}
} }
// diff highlight colors // highlight.js overrides
// intentionally swapped to avoid inversion .hljs-tag {
.hljs-addition { color: inherit; // Without this they'd be weirdly blue which doesn't match the theme
background: #fdd;
}
.hljs-deletion {
background: #dfd;
} }

View file

@ -9,3 +9,4 @@
@import "_dark.scss"; @import "_dark.scss";
@import "../../light/css/_mods.scss"; @import "../../light/css/_mods.scss";
@import "../../../../res/css/_components.scss"; @import "../../../../res/css/_components.scss";
@import url("highlight.js/styles/atom-one-dark.css");

View file

@ -118,7 +118,7 @@ $voipcall-plinth-color: #394049;
$theme-button-bg-color: #e3e8f0; $theme-button-bg-color: #e3e8f0;
$dialpad-button-bg-color: #6F7882; $dialpad-button-bg-color: #6F7882;
;
$roomlist-button-bg-color: #1A1D23; // Buttons include the filter box, explore button, and sublist buttons $roomlist-button-bg-color: #1A1D23; // Buttons include the filter box, explore button, and sublist buttons
$roomlist-filter-active-bg-color: $roomlist-button-bg-color; $roomlist-filter-active-bg-color: $roomlist-button-bg-color;
@ -249,7 +249,7 @@ $composer-shadow-color: tranparent;
@define-mixin mx_DialogButton_secondary { @define-mixin mx_DialogButton_secondary {
// flip colours for the secondary ones // flip colours for the secondary ones
font-weight: 600; font-weight: 600;
border: 1px solid $accent-color ! important; border: 1px solid $accent-color !important;
color: $accent-color; color: $accent-color;
background-color: $button-secondary-bg-color; background-color: $button-secondary-bg-color;
} }
@ -267,18 +267,7 @@ $composer-shadow-color: tranparent;
} }
// markdown overrides: // markdown overrides:
.mx_EventTile_content .markdown-body pre:hover {
border-color: #808080 !important; // inverted due to rules below
}
.mx_EventTile_content .markdown-body { .mx_EventTile_content .markdown-body {
pre, code {
filter: invert(1);
}
pre code {
filter: none;
}
table { table {
tr { tr {
background-color: #000000; background-color: #000000;
@ -290,12 +279,7 @@ $composer-shadow-color: tranparent;
} }
} }
// diff highlight colors // highlight.js overrides:
// intentionally swapped to avoid inversion .hljs-tag {
.hljs-addition { color: inherit; // Without this they'd be weirdly blue which doesn't match the theme
background: #fdd;
}
.hljs-deletion {
background: #dfd;
} }

View file

@ -4,3 +4,4 @@
@import "../../legacy-light/css/_legacy-light.scss"; @import "../../legacy-light/css/_legacy-light.scss";
@import "_legacy-dark.scss"; @import "_legacy-dark.scss";
@import "../../../../res/css/_components.scss"; @import "../../../../res/css/_components.scss";
@import url("highlight.js/styles/atom-one-dark.css");

View file

@ -3,3 +3,4 @@
@import "_fonts.scss"; @import "_fonts.scss";
@import "_legacy-light.scss"; @import "_legacy-light.scss";
@import "../../../../res/css/_components.scss"; @import "../../../../res/css/_components.scss";
@import url("highlight.js/styles/atom-one-light.css");

View file

@ -4,3 +4,4 @@
@import "_light.scss"; @import "_light.scss";
@import "_mods.scss"; @import "_mods.scss";
@import "../../../../res/css/_components.scss"; @import "../../../../res/css/_components.scss";
@import url("highlight.js/styles/atom-one-light.css");

View file

@ -6,8 +6,8 @@ scripts/fetchdep.sh matrix-org matrix-js-sdk
pushd matrix-js-sdk pushd matrix-js-sdk
yarn link yarn link
yarn install $@ yarn install --pure-lockfile $@
popd popd
yarn link matrix-js-sdk yarn link matrix-js-sdk
yarn install $@ yarn install --pure-lockfile $@

View file

@ -13,13 +13,13 @@
scripts/fetchdep.sh matrix-org matrix-js-sdk scripts/fetchdep.sh matrix-org matrix-js-sdk
pushd matrix-js-sdk pushd matrix-js-sdk
yarn link yarn link
yarn install yarn install --pure-lockfile
popd popd
# Now set up the react-sdk # Now set up the react-sdk
yarn link matrix-js-sdk yarn link matrix-js-sdk
yarn link yarn link
yarn install yarn install --pure-lockfile
yarn reskindex yarn reskindex
# Finally, set up element-web # Finally, set up element-web
@ -27,6 +27,6 @@ scripts/fetchdep.sh vector-im element-web
pushd element-web pushd element-web
yarn link matrix-js-sdk yarn link matrix-js-sdk
yarn link matrix-react-sdk yarn link matrix-react-sdk
yarn install yarn install --pure-lockfile
yarn build:res yarn build:res
popd popd

View file

@ -46,6 +46,7 @@ import { VoiceRecordingStore } from "../stores/VoiceRecordingStore";
import PerformanceMonitor from "../performance"; import PerformanceMonitor from "../performance";
import UIStore from "../stores/UIStore"; import UIStore from "../stores/UIStore";
import { SetupEncryptionStore } from "../stores/SetupEncryptionStore"; import { SetupEncryptionStore } from "../stores/SetupEncryptionStore";
import { RoomScrollStateStore } from "../stores/RoomScrollStateStore";
declare global { declare global {
interface Window { interface Window {
@ -87,6 +88,7 @@ declare global {
mxPerformanceEntryNames: any; mxPerformanceEntryNames: any;
mxUIStore: UIStore; mxUIStore: UIStore;
mxSetupEncryptionStore?: SetupEncryptionStore; mxSetupEncryptionStore?: SetupEncryptionStore;
mxRoomScrollStateStore?: RoomScrollStateStore;
} }
interface Document { interface Document {

View file

@ -390,6 +390,7 @@ export class Analytics {
{ expl: _td('Your device resolution'), value: resolution }, { expl: _td('Your device resolution'), value: resolution },
]; ];
// FIXME: Using an import will result in test failures
const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog');
Modal.createTrackedDialog('Analytics Details', '', ErrorDialog, { Modal.createTrackedDialog('Analytics Details', '', ErrorDialog, {
title: _t('Analytics'), title: _t('Analytics'),

View file

@ -77,6 +77,7 @@ export default class AsyncWrapper extends React.Component<IProps, IState> {
const Component = this.state.component; const Component = this.state.component;
return <Component {...this.props} />; return <Component {...this.props} />;
} else if (this.state.error) { } else if (this.state.error) {
// FIXME: Using an import will result in test failures
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return <BaseDialog onFinished={this.props.onFinished} title={_t("Error")}> return <BaseDialog onFinished={this.props.onFinished} title={_t("Error")}>

View file

@ -49,8 +49,6 @@ const MAX_HEIGHT = 600;
const PHYS_HIDPI = [0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01]; const PHYS_HIDPI = [0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01];
export const BLURHASH_FIELD = "xyz.amorgan.blurhash"; // MSC2448 export const BLURHASH_FIELD = "xyz.amorgan.blurhash"; // MSC2448
const BLURHASH_X_COMPONENTS = 6;
const BLURHASH_Y_COMPONENTS = 6;
export class UploadCanceledError extends Error {} export class UploadCanceledError extends Error {}
@ -137,8 +135,9 @@ function createThumbnail(
imageData.data, imageData.data,
imageData.width, imageData.width,
imageData.height, imageData.height,
BLURHASH_X_COMPONENTS, // use 4 components on the longer dimension, if square then both
BLURHASH_Y_COMPONENTS, imageData.width >= imageData.height ? 4 : 3,
imageData.height >= imageData.width ? 4 : 3,
); );
canvas.toBlob(function(thumbnail) { canvas.toBlob(function(thumbnail) {
resolve({ resolve({
@ -419,6 +418,7 @@ export default class ContentMessages {
const isQuoting = Boolean(RoomViewStore.getQuotingEvent()); const isQuoting = Boolean(RoomViewStore.getQuotingEvent());
if (isQuoting) { if (isQuoting) {
// FIXME: Using an import will result in Element crashing
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
const { finished } = Modal.createTrackedDialog<[boolean]>('Upload Reply Warning', '', QuestionDialog, { const { finished } = Modal.createTrackedDialog<[boolean]>('Upload Reply Warning', '', QuestionDialog, {
title: _t('Replying With Files'), title: _t('Replying With Files'),
@ -453,6 +453,7 @@ export default class ContentMessages {
} }
if (tooBigFiles.length > 0) { if (tooBigFiles.length > 0) {
// FIXME: Using an import will result in Element crashing
const UploadFailureDialog = sdk.getComponent("dialogs.UploadFailureDialog"); const UploadFailureDialog = sdk.getComponent("dialogs.UploadFailureDialog");
const { finished } = Modal.createTrackedDialog<[boolean]>('Upload Failure', '', UploadFailureDialog, { const { finished } = Modal.createTrackedDialog<[boolean]>('Upload Failure', '', UploadFailureDialog, {
badFiles: tooBigFiles, badFiles: tooBigFiles,
@ -463,7 +464,6 @@ export default class ContentMessages {
if (!shouldContinue) return; if (!shouldContinue) return;
} }
const UploadConfirmDialog = sdk.getComponent("dialogs.UploadConfirmDialog");
let uploadAll = false; let uploadAll = false;
// Promise to complete before sending next file into room, used for synchronisation of file-sending // Promise to complete before sending next file into room, used for synchronisation of file-sending
// to match the order the files were specified in // to match the order the files were specified in
@ -471,6 +471,8 @@ export default class ContentMessages {
for (let i = 0; i < okFiles.length; ++i) { for (let i = 0; i < okFiles.length; ++i) {
const file = okFiles[i]; const file = okFiles[i];
if (!uploadAll) { if (!uploadAll) {
// FIXME: Using an import will result in Element crashing
const UploadConfirmDialog = sdk.getComponent("dialogs.UploadConfirmDialog");
const { finished } = Modal.createTrackedDialog<[boolean, boolean]>('Upload Files confirmation', const { finished } = Modal.createTrackedDialog<[boolean, boolean]>('Upload Files confirmation',
'', UploadConfirmDialog, { '', UploadConfirmDialog, {
file, file,
@ -606,6 +608,7 @@ export default class ContentMessages {
{ fileName: upload.fileName }, { fileName: upload.fileName },
); );
} }
// FIXME: Using an import will result in Element crashing
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Upload failed', '', ErrorDialog, { Modal.createTrackedDialog('Upload failed', '', ErrorDialog, {
title: _t('Upload Failed'), title: _t('Upload Failed'),

View file

@ -16,12 +16,12 @@ limitations under the License.
import { randomString } from "matrix-js-sdk/src/randomstring"; import { randomString } from "matrix-js-sdk/src/randomstring";
import { IContent } from "matrix-js-sdk/src/models/event"; import { IContent } from "matrix-js-sdk/src/models/event";
import { sleep } from "matrix-js-sdk/src/utils";
import { getCurrentLanguage } from './languageHandler'; import { getCurrentLanguage } from './languageHandler';
import PlatformPeg from './PlatformPeg'; import PlatformPeg from './PlatformPeg';
import SdkConfig from './SdkConfig'; import SdkConfig from './SdkConfig';
import { MatrixClientPeg } from "./MatrixClientPeg"; import { MatrixClientPeg } from "./MatrixClientPeg";
import { sleep } from "./utils/promise";
import RoomViewStore from "./stores/RoomViewStore"; import RoomViewStore from "./stores/RoomViewStore";
import { Action } from "./dispatcher/actions"; import { Action } from "./dispatcher/actions";

View file

@ -33,7 +33,6 @@ import Presence from './Presence';
import dis from './dispatcher/dispatcher'; import dis from './dispatcher/dispatcher';
import DMRoomMap from './utils/DMRoomMap'; import DMRoomMap from './utils/DMRoomMap';
import Modal from './Modal'; import Modal from './Modal';
import * as sdk from './index';
import ActiveWidgetStore from './stores/ActiveWidgetStore'; import ActiveWidgetStore from './stores/ActiveWidgetStore';
import PlatformPeg from "./PlatformPeg"; import PlatformPeg from "./PlatformPeg";
import { sendLoginRequest } from "./Login"; import { sendLoginRequest } from "./Login";
@ -52,6 +51,10 @@ import CallHandler from './CallHandler';
import LifecycleCustomisations from "./customisations/Lifecycle"; import LifecycleCustomisations from "./customisations/Lifecycle";
import ErrorDialog from "./components/views/dialogs/ErrorDialog"; import ErrorDialog from "./components/views/dialogs/ErrorDialog";
import { _t } from "./languageHandler"; import { _t } from "./languageHandler";
import LazyLoadingResyncDialog from "./components/views/dialogs/LazyLoadingResyncDialog";
import LazyLoadingDisabledDialog from "./components/views/dialogs/LazyLoadingDisabledDialog";
import SessionRestoreErrorDialog from "./components/views/dialogs/SessionRestoreErrorDialog";
import StorageEvictedDialog from "./components/views/dialogs/StorageEvictedDialog";
const HOMESERVER_URL_KEY = "mx_hs_url"; const HOMESERVER_URL_KEY = "mx_hs_url";
const ID_SERVER_URL_KEY = "mx_is_url"; const ID_SERVER_URL_KEY = "mx_is_url";
@ -238,8 +241,6 @@ export function handleInvalidStoreError(e: InvalidStoreError): Promise<void> {
return Promise.resolve().then(() => { return Promise.resolve().then(() => {
const lazyLoadEnabled = e.value; const lazyLoadEnabled = e.value;
if (lazyLoadEnabled) { if (lazyLoadEnabled) {
const LazyLoadingResyncDialog =
sdk.getComponent("views.dialogs.LazyLoadingResyncDialog");
return new Promise((resolve) => { return new Promise((resolve) => {
Modal.createDialog(LazyLoadingResyncDialog, { Modal.createDialog(LazyLoadingResyncDialog, {
onFinished: resolve, onFinished: resolve,
@ -250,8 +251,6 @@ export function handleInvalidStoreError(e: InvalidStoreError): Promise<void> {
// between LL/non-LL version on same host. // between LL/non-LL version on same host.
// as disabling LL when previously enabled // as disabling LL when previously enabled
// is a strong indicator of this (/develop & /app) // is a strong indicator of this (/develop & /app)
const LazyLoadingDisabledDialog =
sdk.getComponent("views.dialogs.LazyLoadingDisabledDialog");
return new Promise((resolve) => { return new Promise((resolve) => {
Modal.createDialog(LazyLoadingDisabledDialog, { Modal.createDialog(LazyLoadingDisabledDialog, {
onFinished: resolve, onFinished: resolve,
@ -451,9 +450,6 @@ export async function restoreFromLocalStorage(opts?: { ignoreGuest?: boolean }):
async function handleLoadSessionFailure(e: Error): Promise<boolean> { async function handleLoadSessionFailure(e: Error): Promise<boolean> {
console.error("Unable to load session", e); console.error("Unable to load session", e);
const SessionRestoreErrorDialog =
sdk.getComponent('views.dialogs.SessionRestoreErrorDialog');
const modal = Modal.createTrackedDialog('Session Restore Error', '', SessionRestoreErrorDialog, { const modal = Modal.createTrackedDialog('Session Restore Error', '', SessionRestoreErrorDialog, {
error: e.message, error: e.message,
}); });
@ -612,7 +608,6 @@ async function doSetLoggedIn(
} }
function showStorageEvictedDialog(): Promise<boolean> { function showStorageEvictedDialog(): Promise<boolean> {
const StorageEvictedDialog = sdk.getComponent('views.dialogs.StorageEvictedDialog');
return new Promise(resolve => { return new Promise(resolve => {
Modal.createTrackedDialog('Storage evicted', '', StorageEvictedDialog, { Modal.createTrackedDialog('Storage evicted', '', StorageEvictedDialog, {
onFinished: resolve, onFinished: resolve,

View file

@ -219,6 +219,7 @@ class _MatrixClientPeg implements IMatrixClientPeg {
} catch (e) { } catch (e) {
if (e && e.name === 'InvalidCryptoStoreError') { if (e && e.name === 'InvalidCryptoStoreError') {
// The js-sdk found a crypto DB too new for it to use // The js-sdk found a crypto DB too new for it to use
// FIXME: Using an import will result in test failures
const CryptoStoreTooNewDialog = const CryptoStoreTooNewDialog =
sdk.getComponent("views.dialogs.CryptoStoreTooNewDialog"); sdk.getComponent("views.dialogs.CryptoStoreTooNewDialog");
Modal.createDialog(CryptoStoreTooNewDialog); Modal.createDialog(CryptoStoreTooNewDialog);

View file

@ -18,10 +18,10 @@ limitations under the License.
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import classNames from 'classnames'; import classNames from 'classnames';
import { defer } from "matrix-js-sdk/src/utils";
import Analytics from './Analytics'; import Analytics from './Analytics';
import dis from './dispatcher/dispatcher'; import dis from './dispatcher/dispatcher';
import { defer } from './utils/promise';
import AsyncWrapper from './AsyncWrapper'; import AsyncWrapper from './AsyncWrapper';
const DIALOG_CONTAINER_ID = "mx_Dialog_Container"; const DIALOG_CONTAINER_ID = "mx_Dialog_Container";

View file

@ -27,7 +27,6 @@ import * as TextForEvent from './TextForEvent';
import Analytics from './Analytics'; import Analytics from './Analytics';
import * as Avatar from './Avatar'; import * as Avatar from './Avatar';
import dis from './dispatcher/dispatcher'; import dis from './dispatcher/dispatcher';
import * as sdk from './index';
import { _t } from './languageHandler'; import { _t } from './languageHandler';
import Modal from './Modal'; import Modal from './Modal';
import SettingsStore from "./settings/SettingsStore"; import SettingsStore from "./settings/SettingsStore";
@ -37,6 +36,7 @@ import { isPushNotifyDisabled } from "./settings/controllers/NotificationControl
import RoomViewStore from "./stores/RoomViewStore"; import RoomViewStore from "./stores/RoomViewStore";
import UserActivity from "./UserActivity"; import UserActivity from "./UserActivity";
import { mediaFromMxc } from "./customisations/Media"; import { mediaFromMxc } from "./customisations/Media";
import ErrorDialog from "./components/views/dialogs/ErrorDialog";
/* /*
* Dispatches: * Dispatches:
@ -240,7 +240,6 @@ export const Notifier = {
? _t('%(brand)s does not have permission to send you notifications - ' + ? _t('%(brand)s does not have permission to send you notifications - ' +
'please check your browser settings', { brand }) 'please check your browser settings', { brand })
: _t('%(brand)s was not given permission to send notifications - please try again', { brand }); : _t('%(brand)s was not given permission to send notifications - please try again', { brand });
const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog');
Modal.createTrackedDialog('Unable to enable Notifications', result, ErrorDialog, { Modal.createTrackedDialog('Unable to enable Notifications', result, ErrorDialog, {
title: _t('Unable to enable Notifications'), title: _t('Unable to enable Notifications'),
description, description,

View file

@ -22,13 +22,13 @@ import { User } from "matrix-js-sdk/src/models/user";
import { MatrixClientPeg } from './MatrixClientPeg'; import { MatrixClientPeg } from './MatrixClientPeg';
import MultiInviter, { CompletionStates } from './utils/MultiInviter'; import MultiInviter, { CompletionStates } from './utils/MultiInviter';
import Modal from './Modal'; import Modal from './Modal';
import * as sdk from './';
import { _t } from './languageHandler'; import { _t } from './languageHandler';
import InviteDialog, { KIND_DM, KIND_INVITE, Member } from "./components/views/dialogs/InviteDialog"; import InviteDialog, { KIND_DM, KIND_INVITE, Member } from "./components/views/dialogs/InviteDialog";
import CommunityPrototypeInviteDialog from "./components/views/dialogs/CommunityPrototypeInviteDialog"; import CommunityPrototypeInviteDialog from "./components/views/dialogs/CommunityPrototypeInviteDialog";
import { CommunityPrototypeStore } from "./stores/CommunityPrototypeStore"; import { CommunityPrototypeStore } from "./stores/CommunityPrototypeStore";
import BaseAvatar from "./components/views/avatars/BaseAvatar"; import BaseAvatar from "./components/views/avatars/BaseAvatar";
import { mediaFromMxc } from "./customisations/Media"; import { mediaFromMxc } from "./customisations/Media";
import ErrorDialog from "./components/views/dialogs/ErrorDialog";
export interface IInviteResult { export interface IInviteResult {
states: CompletionStates; states: CompletionStates;
@ -51,7 +51,6 @@ export function inviteMultipleToRoom(roomId: string, addresses: string[]): Promi
export function showStartChatInviteDialog(initialText = ""): void { export function showStartChatInviteDialog(initialText = ""): void {
// This dialog handles the room creation internally - we don't need to worry about it. // This dialog handles the room creation internally - we don't need to worry about it.
const InviteDialog = sdk.getComponent("dialogs.InviteDialog");
Modal.createTrackedDialog( Modal.createTrackedDialog(
'Start DM', '', InviteDialog, { kind: KIND_DM, initialText }, 'Start DM', '', InviteDialog, { kind: KIND_DM, initialText },
/*className=*/null, /*isPriority=*/false, /*isStatic=*/true, /*className=*/null, /*isPriority=*/false, /*isStatic=*/true,
@ -111,7 +110,6 @@ export function inviteUsersToRoom(roomId: string, userIds: string[]): Promise<vo
showAnyInviteErrors(result.states, room, result.inviter); showAnyInviteErrors(result.states, room, result.inviter);
}).catch((err) => { }).catch((err) => {
console.error(err.stack); console.error(err.stack);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Failed to invite', '', ErrorDialog, { Modal.createTrackedDialog('Failed to invite', '', ErrorDialog, {
title: _t("Failed to invite"), title: _t("Failed to invite"),
description: ((err && err.message) ? err.message : _t("Operation failed")), description: ((err && err.message) ? err.message : _t("Operation failed")),
@ -131,7 +129,6 @@ export function showAnyInviteErrors(
// Just get the first message because there was a fatal problem on the first // Just get the first message because there was a fatal problem on the first
// user. This usually means that no other users were attempted, making it // user. This usually means that no other users were attempted, making it
// pointless for us to list who failed exactly. // pointless for us to list who failed exactly.
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Failed to invite users to the room', '', ErrorDialog, { Modal.createTrackedDialog('Failed to invite users to the room', '', ErrorDialog, {
title: _t("Failed to invite users to the room:", { roomName: room.name }), title: _t("Failed to invite users to the room:", { roomName: room.name }),
description: inviter.getErrorText(failedUsers[0]), description: inviter.getErrorText(failedUsers[0]),
@ -178,7 +175,6 @@ export function showAnyInviteErrors(
</div> </div>
</div>; </div>;
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog("Some invites could not be sent", "", ErrorDialog, { Modal.createTrackedDialog("Some invites could not be sent", "", ErrorDialog, {
title: _t("Some invites couldn't be sent"), title: _t("Some invites couldn't be sent"),
description, description,

View file

@ -14,7 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { ICryptoCallbacks, ISecretStorageKeyInfo } from 'matrix-js-sdk/src/matrix'; import { ICryptoCallbacks } from 'matrix-js-sdk/src/matrix';
import { ISecretStorageKeyInfo } from 'matrix-js-sdk/src/crypto/api';
import { MatrixClient } from 'matrix-js-sdk/src/client'; import { MatrixClient } from 'matrix-js-sdk/src/client';
import Modal from './Modal'; import Modal from './Modal';
import * as sdk from './index'; import * as sdk from './index';
@ -354,6 +355,7 @@ export async function accessSecretStorage(func = async () => { }, forceReset = f
throw new Error("Secret storage creation canceled"); throw new Error("Secret storage creation canceled");
} }
} else { } else {
// FIXME: Using an import will result in test failures
const InteractiveAuthDialog = sdk.getComponent("dialogs.InteractiveAuthDialog"); const InteractiveAuthDialog = sdk.getComponent("dialogs.InteractiveAuthDialog");
await cli.bootstrapCrossSigning({ await cli.bootstrapCrossSigning({
authUploadDeviceSigningKeys: async (makeRequest) => { authUploadDeviceSigningKeys: async (makeRequest) => {

View file

@ -23,7 +23,6 @@ import { User } from "matrix-js-sdk/src/models/user";
import * as ContentHelpers from 'matrix-js-sdk/src/content-helpers'; import * as ContentHelpers from 'matrix-js-sdk/src/content-helpers';
import { MatrixClientPeg } from './MatrixClientPeg'; import { MatrixClientPeg } from './MatrixClientPeg';
import dis from './dispatcher/dispatcher'; import dis from './dispatcher/dispatcher';
import * as sdk from './index';
import { _t, _td } from './languageHandler'; import { _t, _td } from './languageHandler';
import Modal from './Modal'; import Modal from './Modal';
import MultiInviter from './utils/MultiInviter'; import MultiInviter from './utils/MultiInviter';
@ -50,6 +49,12 @@ import { UIFeature } from "./settings/UIFeature";
import { CHAT_EFFECTS } from "./effects"; import { CHAT_EFFECTS } from "./effects";
import CallHandler from "./CallHandler"; import CallHandler from "./CallHandler";
import { guessAndSetDMRoom } from "./Rooms"; import { guessAndSetDMRoom } from "./Rooms";
import UploadConfirmDialog from './components/views/dialogs/UploadConfirmDialog';
import ErrorDialog from './components/views/dialogs/ErrorDialog';
import DevtoolsDialog from './components/views/dialogs/DevtoolsDialog';
import RoomUpgradeWarningDialog from "./components/views/dialogs/RoomUpgradeWarningDialog";
import InfoDialog from "./components/views/dialogs/InfoDialog";
import SlashCommandHelpDialog from "./components/views/dialogs/SlashCommandHelpDialog";
// XXX: workaround for https://github.com/microsoft/TypeScript/issues/31816 // XXX: workaround for https://github.com/microsoft/TypeScript/issues/31816
interface HTMLInputEvent extends Event { interface HTMLInputEvent extends Event {
@ -63,7 +68,6 @@ const singleMxcUpload = async (): Promise<any> => {
fileSelector.onchange = (ev: HTMLInputEvent) => { fileSelector.onchange = (ev: HTMLInputEvent) => {
const file = ev.target.files[0]; const file = ev.target.files[0];
const UploadConfirmDialog = sdk.getComponent("dialogs.UploadConfirmDialog");
Modal.createTrackedDialog('Upload Files confirmation', '', UploadConfirmDialog, { Modal.createTrackedDialog('Upload Files confirmation', '', UploadConfirmDialog, {
file, file,
onFinished: (shouldContinue) => { onFinished: (shouldContinue) => {
@ -246,7 +250,6 @@ export const Commands = [
args: '<query>', args: '<query>',
description: _td('Searches DuckDuckGo for results'), description: _td('Searches DuckDuckGo for results'),
runFn: function() { runFn: function() {
const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog');
// TODO Don't explain this away, actually show a search UI here. // TODO Don't explain this away, actually show a search UI here.
Modal.createTrackedDialog('Slash Commands', '/ddg is not a command', ErrorDialog, { Modal.createTrackedDialog('Slash Commands', '/ddg is not a command', ErrorDialog, {
title: _t('/ddg is not a command'), title: _t('/ddg is not a command'),
@ -269,8 +272,6 @@ export const Commands = [
return reject(_t("You do not have the required permissions to use this command.")); return reject(_t("You do not have the required permissions to use this command."));
} }
const RoomUpgradeWarningDialog = sdk.getComponent("dialogs.RoomUpgradeWarningDialog");
const { finished } = Modal.createTrackedDialog('Slash Commands', 'upgrade room confirmation', const { finished } = Modal.createTrackedDialog('Slash Commands', 'upgrade room confirmation',
RoomUpgradeWarningDialog, { roomId: roomId, targetVersion: args }, /*className=*/null, RoomUpgradeWarningDialog, { roomId: roomId, targetVersion: args }, /*className=*/null,
/*isPriority=*/false, /*isStatic=*/true); /*isPriority=*/false, /*isStatic=*/true);
@ -314,7 +315,6 @@ export const Commands = [
if (checkForUpgradeFn) cli.removeListener('Room', checkForUpgradeFn); if (checkForUpgradeFn) cli.removeListener('Room', checkForUpgradeFn);
const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog');
Modal.createTrackedDialog('Slash Commands', 'room upgrade error', ErrorDialog, { Modal.createTrackedDialog('Slash Commands', 'room upgrade error', ErrorDialog, {
title: _t('Error upgrading room'), title: _t('Error upgrading room'),
description: _t( description: _t(
@ -434,7 +434,6 @@ export const Commands = [
const topic = topicEvents && topicEvents.getContent().topic; const topic = topicEvents && topicEvents.getContent().topic;
const topicHtml = topic ? linkifyAndSanitizeHtml(topic) : _t('This room has no topic.'); const topicHtml = topic ? linkifyAndSanitizeHtml(topic) : _t('This room has no topic.');
const InfoDialog = sdk.getComponent('dialogs.InfoDialog');
Modal.createTrackedDialog('Slash Commands', 'Topic', InfoDialog, { Modal.createTrackedDialog('Slash Commands', 'Topic', InfoDialog, {
title: room.name, title: room.name,
description: <div dangerouslySetInnerHTML={{ __html: topicHtml }} />, description: <div dangerouslySetInnerHTML={{ __html: topicHtml }} />,
@ -737,7 +736,6 @@ export const Commands = [
ignoredUsers.push(userId); // de-duped internally in the js-sdk ignoredUsers.push(userId); // de-duped internally in the js-sdk
return success( return success(
cli.setIgnoredUsers(ignoredUsers).then(() => { cli.setIgnoredUsers(ignoredUsers).then(() => {
const InfoDialog = sdk.getComponent('dialogs.InfoDialog');
Modal.createTrackedDialog('Slash Commands', 'User ignored', InfoDialog, { Modal.createTrackedDialog('Slash Commands', 'User ignored', InfoDialog, {
title: _t('Ignored user'), title: _t('Ignored user'),
description: <div> description: <div>
@ -768,7 +766,6 @@ export const Commands = [
if (index !== -1) ignoredUsers.splice(index, 1); if (index !== -1) ignoredUsers.splice(index, 1);
return success( return success(
cli.setIgnoredUsers(ignoredUsers).then(() => { cli.setIgnoredUsers(ignoredUsers).then(() => {
const InfoDialog = sdk.getComponent('dialogs.InfoDialog');
Modal.createTrackedDialog('Slash Commands', 'User unignored', InfoDialog, { Modal.createTrackedDialog('Slash Commands', 'User unignored', InfoDialog, {
title: _t('Unignored user'), title: _t('Unignored user'),
description: <div> description: <div>
@ -838,7 +835,6 @@ export const Commands = [
command: 'devtools', command: 'devtools',
description: _td('Opens the Developer Tools dialog'), description: _td('Opens the Developer Tools dialog'),
runFn: function(roomId) { runFn: function(roomId) {
const DevtoolsDialog = sdk.getComponent('dialogs.DevtoolsDialog');
Modal.createDialog(DevtoolsDialog, { roomId }); Modal.createDialog(DevtoolsDialog, { roomId });
return success(); return success();
}, },
@ -943,7 +939,6 @@ export const Commands = [
await cli.setDeviceVerified(userId, deviceId, true); await cli.setDeviceVerified(userId, deviceId, true);
// Tell the user we verified everything // Tell the user we verified everything
const InfoDialog = sdk.getComponent('dialogs.InfoDialog');
Modal.createTrackedDialog('Slash Commands', 'Verified key', InfoDialog, { Modal.createTrackedDialog('Slash Commands', 'Verified key', InfoDialog, {
title: _t('Verified key'), title: _t('Verified key'),
description: <div> description: <div>
@ -1000,8 +995,6 @@ export const Commands = [
command: "help", command: "help",
description: _td("Displays list of commands with usages and descriptions"), description: _td("Displays list of commands with usages and descriptions"),
runFn: function() { runFn: function() {
const SlashCommandHelpDialog = sdk.getComponent('dialogs.SlashCommandHelpDialog');
Modal.createTrackedDialog('Slash Commands', 'Help', SlashCommandHelpDialog); Modal.createTrackedDialog('Slash Commands', 'Help', SlashCommandHelpDialog);
return success(); return success();
}, },

View file

@ -189,6 +189,7 @@ export function dialogTermsInteractionCallback(
): Promise<string[]> { ): Promise<string[]> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
console.log("Terms that need agreement", policiesAndServicePairs); console.log("Terms that need agreement", policiesAndServicePairs);
// FIXME: Using an import will result in test failures
const TermsDialog = sdk.getComponent("views.dialogs.TermsDialog"); const TermsDialog = sdk.getComponent("views.dialogs.TermsDialog");
Modal.createTrackedDialog('Terms of Service', '', TermsDialog, { Modal.createTrackedDialog('Terms of Service', '', TermsDialog, {

View file

@ -17,10 +17,10 @@ limitations under the License.
import * as React from "react"; import * as React from "react";
import classNames from "classnames"; import classNames from "classnames";
import * as sdk from "../index";
import Modal from "../Modal"; import Modal from "../Modal";
import { _t, _td } from "../languageHandler"; import { _t, _td } from "../languageHandler";
import { isMac, Key } from "../Keyboard"; import { isMac, Key } from "../Keyboard";
import InfoDialog from "../components/views/dialogs/InfoDialog";
// TS: once languageHandler is TS we can probably inline this into the enum // TS: once languageHandler is TS we can probably inline this into the enum
_td("Navigation"); _td("Navigation");
@ -375,7 +375,6 @@ export const toggleDialog = () => {
</div>; </div>;
}); });
const InfoDialog = sdk.getComponent('dialogs.InfoDialog');
activeModal = Modal.createTrackedDialog("Keyboard Shortcuts", "", InfoDialog, { activeModal = Modal.createTrackedDialog("Keyboard Shortcuts", "", InfoDialog, {
className: "mx_KeyboardShortcutsDialog", className: "mx_KeyboardShortcutsDialog",
title: _t("Keyboard Shortcuts"), title: _t("Keyboard Shortcuts"),

View file

@ -19,13 +19,13 @@ import { asyncAction } from './actionCreators';
import Modal from '../Modal'; import Modal from '../Modal';
import * as Rooms from '../Rooms'; import * as Rooms from '../Rooms';
import { _t } from '../languageHandler'; import { _t } from '../languageHandler';
import * as sdk from '../index';
import { MatrixClient } from "matrix-js-sdk/src/client"; import { MatrixClient } from "matrix-js-sdk/src/client";
import { Room } from "matrix-js-sdk/src/models/room"; import { Room } from "matrix-js-sdk/src/models/room";
import { AsyncActionPayload } from "../dispatcher/payloads"; import { AsyncActionPayload } from "../dispatcher/payloads";
import RoomListStore from "../stores/room-list/RoomListStore"; import RoomListStore from "../stores/room-list/RoomListStore";
import { SortAlgorithm } from "../stores/room-list/algorithms/models"; import { SortAlgorithm } from "../stores/room-list/algorithms/models";
import { DefaultTagID } from "../stores/room-list/models"; import { DefaultTagID } from "../stores/room-list/models";
import ErrorDialog from '../components/views/dialogs/ErrorDialog';
export default class RoomListActions { export default class RoomListActions {
/** /**
@ -88,7 +88,6 @@ export default class RoomListActions {
return Rooms.guessAndSetDMRoom( return Rooms.guessAndSetDMRoom(
room, newTag === DefaultTagID.DM, room, newTag === DefaultTagID.DM,
).catch((err) => { ).catch((err) => {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
console.error("Failed to set direct chat tag " + err); console.error("Failed to set direct chat tag " + err);
Modal.createTrackedDialog('Failed to set direct chat tag', '', ErrorDialog, { Modal.createTrackedDialog('Failed to set direct chat tag', '', ErrorDialog, {
title: _t('Failed to set direct chat tag'), title: _t('Failed to set direct chat tag'),
@ -109,7 +108,6 @@ export default class RoomListActions {
const promiseToDelete = matrixClient.deleteRoomTag( const promiseToDelete = matrixClient.deleteRoomTag(
roomId, oldTag, roomId, oldTag,
).catch(function(err) { ).catch(function(err) {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
console.error("Failed to remove tag " + oldTag + " from room: " + err); console.error("Failed to remove tag " + oldTag + " from room: " + err);
Modal.createTrackedDialog('Failed to remove tag from room', '', ErrorDialog, { Modal.createTrackedDialog('Failed to remove tag from room', '', ErrorDialog, {
title: _t('Failed to remove tag %(tagName)s from room', { tagName: oldTag }), title: _t('Failed to remove tag %(tagName)s from room', { tagName: oldTag }),
@ -129,7 +127,6 @@ export default class RoomListActions {
metaData = metaData || {}; metaData = metaData || {};
const promiseToAdd = matrixClient.setRoomTag(roomId, newTag, metaData).catch(function(err) { const promiseToAdd = matrixClient.setRoomTag(roomId, newTag, metaData).catch(function(err) {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
console.error("Failed to add tag " + newTag + " to room: " + err); console.error("Failed to add tag " + newTag + " to room: " + err);
Modal.createTrackedDialog('Failed to add tag to room', '', ErrorDialog, { Modal.createTrackedDialog('Failed to add tag to room', '', ErrorDialog, {
title: _t('Failed to add tag %(tagName)s to room', { tagName: newTag }), title: _t('Failed to add tag %(tagName)s to room', { tagName: newTag }),

View file

@ -15,7 +15,6 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../../index';
import { _t } from '../../../../languageHandler'; import { _t } from '../../../../languageHandler';
import SdkConfig from '../../../../SdkConfig'; import SdkConfig from '../../../../SdkConfig';
import SettingsStore from "../../../../settings/SettingsStore"; import SettingsStore from "../../../../settings/SettingsStore";
@ -24,6 +23,9 @@ import Modal from '../../../../Modal';
import { formatBytes, formatCountLong } from "../../../../utils/FormattingUtils"; import { formatBytes, formatCountLong } from "../../../../utils/FormattingUtils";
import EventIndexPeg from "../../../../indexing/EventIndexPeg"; import EventIndexPeg from "../../../../indexing/EventIndexPeg";
import { SettingLevel } from "../../../../settings/SettingLevel"; import { SettingLevel } from "../../../../settings/SettingLevel";
import Field from '../../../../components/views/elements/Field';
import BaseDialog from "../../../../components/views/dialogs/BaseDialog";
import DialogButtons from "../../../../components/views/elements/DialogButtons";
interface IProps { interface IProps {
onFinished: (confirmed: boolean) => void; onFinished: (confirmed: boolean) => void;
@ -145,7 +147,6 @@ export default class ManageEventIndexDialog extends React.Component<IProps, ISta
render() { render() {
const brand = SdkConfig.get().brand; const brand = SdkConfig.get().brand;
const Field = sdk.getComponent('views.elements.Field');
let crawlerState; let crawlerState;
if (this.state.currentRoom === null) { if (this.state.currentRoom === null) {
@ -176,15 +177,12 @@ export default class ManageEventIndexDialog extends React.Component<IProps, ISta
<Field <Field
label={_t('Message downloading sleep time(ms)')} label={_t('Message downloading sleep time(ms)')}
type='number' type='number'
value={this.state.crawlerSleepTime} value={this.state.crawlerSleepTime.toString()}
onChange={this.onCrawlerSleepTimeChange} /> onChange={this.onCrawlerSleepTimeChange} />
</div> </div>
</div> </div>
); );
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return ( return (
<BaseDialog className='mx_ManageEventIndexDialog' <BaseDialog className='mx_ManageEventIndexDialog'
onFinished={this.props.onFinished} onFinished={this.props.onFinished}

View file

@ -22,12 +22,12 @@ import AutocompleteProvider from './AutocompleteProvider';
import { MatrixClientPeg } from '../MatrixClientPeg'; import { MatrixClientPeg } from '../MatrixClientPeg';
import QueryMatcher from './QueryMatcher'; import QueryMatcher from './QueryMatcher';
import { PillCompletion } from './Components'; import { PillCompletion } from './Components';
import * as sdk from '../index';
import { sortBy } from "lodash"; import { sortBy } from "lodash";
import { makeGroupPermalink } from "../utils/permalinks/Permalinks"; import { makeGroupPermalink } from "../utils/permalinks/Permalinks";
import { ICompletion, ISelectionRange } from "./Autocompleter"; import { ICompletion, ISelectionRange } from "./Autocompleter";
import FlairStore from "../stores/FlairStore"; import FlairStore from "../stores/FlairStore";
import { mediaFromMxc } from "../customisations/Media"; import { mediaFromMxc } from "../customisations/Media";
import BaseAvatar from '../components/views/avatars/BaseAvatar';
const COMMUNITY_REGEX = /\B\+\S*/g; const COMMUNITY_REGEX = /\B\+\S*/g;
@ -56,8 +56,6 @@ export default class CommunityProvider extends AutocompleteProvider {
force = false, force = false,
limit = -1, limit = -1,
): Promise<ICompletion[]> { ): Promise<ICompletion[]> {
const BaseAvatar = sdk.getComponent('views.avatars.BaseAvatar');
// Disable autocompletions when composing commands because of various issues // Disable autocompletions when composing commands because of various issues
// (see https://github.com/vector-im/element-web/issues/4762) // (see https://github.com/vector-im/element-web/issues/4762)
if (/^(\/join|\/leave)/.test(query)) { if (/^(\/join|\/leave)/.test(query)) {

View file

@ -21,8 +21,8 @@ import AutocompleteProvider from './AutocompleteProvider';
import { _t } from '../languageHandler'; import { _t } from '../languageHandler';
import { MatrixClientPeg } from '../MatrixClientPeg'; import { MatrixClientPeg } from '../MatrixClientPeg';
import { PillCompletion } from './Components'; import { PillCompletion } from './Components';
import * as sdk from '../index';
import { ICompletion, ISelectionRange } from "./Autocompleter"; import { ICompletion, ISelectionRange } from "./Autocompleter";
import RoomAvatar from '../components/views/avatars/RoomAvatar';
const AT_ROOM_REGEX = /@\S*/g; const AT_ROOM_REGEX = /@\S*/g;
@ -40,8 +40,6 @@ export default class NotifProvider extends AutocompleteProvider {
force = false, force = false,
limit = -1, limit = -1,
): Promise<ICompletion[]> { ): Promise<ICompletion[]> {
const RoomAvatar = sdk.getComponent('views.avatars.RoomAvatar');
const client = MatrixClientPeg.get(); const client = MatrixClientPeg.get();
if (!this.room.currentState.mayTriggerNotifOfType('room', client.credentials.userId)) return []; if (!this.room.currentState.mayTriggerNotifOfType('room', client.credentials.userId)) return [];

View file

@ -21,7 +21,6 @@ import React from 'react';
import { _t } from '../languageHandler'; import { _t } from '../languageHandler';
import AutocompleteProvider from './AutocompleteProvider'; import AutocompleteProvider from './AutocompleteProvider';
import { PillCompletion } from './Components'; import { PillCompletion } from './Components';
import * as sdk from '../index';
import QueryMatcher from './QueryMatcher'; import QueryMatcher from './QueryMatcher';
import { sortBy } from 'lodash'; import { sortBy } from 'lodash';
import { MatrixClientPeg } from '../MatrixClientPeg'; import { MatrixClientPeg } from '../MatrixClientPeg';
@ -33,6 +32,7 @@ import { RoomState } from "matrix-js-sdk/src/models/room-state";
import { EventTimeline } from "matrix-js-sdk/src/models/event-timeline"; import { EventTimeline } from "matrix-js-sdk/src/models/event-timeline";
import { makeUserPermalink } from "../utils/permalinks/Permalinks"; import { makeUserPermalink } from "../utils/permalinks/Permalinks";
import { ICompletion, ISelectionRange } from "./Autocompleter"; import { ICompletion, ISelectionRange } from "./Autocompleter";
import MemberAvatar from '../components/views/avatars/MemberAvatar';
const USER_REGEX = /\B@\S*/g; const USER_REGEX = /\B@\S*/g;
@ -108,8 +108,6 @@ export default class UserProvider extends AutocompleteProvider {
force = false, force = false,
limit = -1, limit = -1,
): Promise<ICompletion[]> { ): Promise<ICompletion[]> {
const MemberAvatar = sdk.getComponent('views.avatars.MemberAvatar');
// lazy-load user list into matcher // lazy-load user list into matcher
if (!this.users) this._makeUsers(); if (!this.users) this._makeUsers();

View file

@ -24,7 +24,6 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { Room } from 'matrix-js-sdk/src/models/room'; import { Room } from 'matrix-js-sdk/src/models/room';
import { TimelineWindow } from 'matrix-js-sdk/src/timeline-window'; import { TimelineWindow } from 'matrix-js-sdk/src/timeline-window';
import * as sdk from '../../index';
import { MatrixClientPeg } from '../../MatrixClientPeg'; import { MatrixClientPeg } from '../../MatrixClientPeg';
import EventIndexPeg from "../../indexing/EventIndexPeg"; import EventIndexPeg from "../../indexing/EventIndexPeg";
import { _t } from '../../languageHandler'; import { _t } from '../../languageHandler';
@ -34,6 +33,9 @@ import DesktopBuildsNotice, { WarningKind } from "../views/elements/DesktopBuild
import { replaceableComponent } from "../../utils/replaceableComponent"; import { replaceableComponent } from "../../utils/replaceableComponent";
import ResizeNotifier from '../../utils/ResizeNotifier'; import ResizeNotifier from '../../utils/ResizeNotifier';
import TimelinePanel from "./TimelinePanel";
import Spinner from "../views/elements/Spinner";
import { TileShape } from '../views/rooms/EventTile';
interface IProps { interface IProps {
roomId: string; roomId: string;
@ -237,8 +239,6 @@ class FilePanel extends React.Component<IProps, IState> {
} }
// wrap a TimelinePanel with the jump-to-event bits turned off. // wrap a TimelinePanel with the jump-to-event bits turned off.
const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
const Loader = sdk.getComponent("elements.Spinner");
const emptyState = (<div className="mx_RightPanel_empty mx_FilePanel_empty"> const emptyState = (<div className="mx_RightPanel_empty mx_FilePanel_empty">
<h2>{_t('No files visible in this room')}</h2> <h2>{_t('No files visible in this room')}</h2>
@ -264,7 +264,7 @@ class FilePanel extends React.Component<IProps, IState> {
timelineSet={this.state.timelineSet} timelineSet={this.state.timelineSet}
showUrlPreview = {false} showUrlPreview = {false}
onPaginationRequest={this.onPaginationRequest} onPaginationRequest={this.onPaginationRequest}
tileShape="file_grid" tileShape={TileShape.FileGrid}
resizeNotifier={this.props.resizeNotifier} resizeNotifier={this.props.resizeNotifier}
empty={emptyState} empty={emptyState}
/> />
@ -277,7 +277,7 @@ class FilePanel extends React.Component<IProps, IState> {
onClose={this.props.onClose} onClose={this.props.onClose}
previousPhase={RightPanelPhases.RoomSummary} previousPhase={RightPanelPhases.RoomSummary}
> >
<Loader /> <Spinner />
</BaseCard> </BaseCard>
); );
} }

View file

@ -36,7 +36,7 @@ import FlairStore from '../../stores/FlairStore';
import { showGroupAddRoomDialog } from '../../GroupAddressPicker'; import { showGroupAddRoomDialog } from '../../GroupAddressPicker';
import { makeGroupPermalink, makeUserPermalink } from "../../utils/permalinks/Permalinks"; import { makeGroupPermalink, makeUserPermalink } from "../../utils/permalinks/Permalinks";
import { Group } from "matrix-js-sdk/src/models/group"; import { Group } from "matrix-js-sdk/src/models/group";
import { sleep } from "../../utils/promise"; import { sleep } from "matrix-js-sdk/src/utils";
import RightPanelStore from "../../stores/RightPanelStore"; import RightPanelStore from "../../stores/RightPanelStore";
import AutoHideScrollbar from "./AutoHideScrollbar"; import AutoHideScrollbar from "./AutoHideScrollbar";
import { mediaFromMxc } from "../../customisations/Media"; import { mediaFromMxc } from "../../customisations/Media";

View file

@ -96,6 +96,7 @@ const HomePage: React.FC<IProps> = ({ justRegistered = false }) => {
const pageUrl = getHomePageUrl(config); const pageUrl = getHomePageUrl(config);
if (pageUrl) { if (pageUrl) {
// FIXME: Using an import will result in wrench-element-tests failures
const EmbeddedPage = sdk.getComponent('structures.EmbeddedPage'); const EmbeddedPage = sdk.getComponent('structures.EmbeddedPage');
return <EmbeddedPage className="mx_HomePage" url={pageUrl} scrollbar={true} />; return <EmbeddedPage className="mx_HomePage" url={pageUrl} scrollbar={true} />;
} }

View file

@ -24,7 +24,6 @@ import { Key } from '../../Keyboard';
import PageTypes from '../../PageTypes'; import PageTypes from '../../PageTypes';
import MediaDeviceHandler from '../../MediaDeviceHandler'; import MediaDeviceHandler from '../../MediaDeviceHandler';
import { fixupColorFonts } from '../../utils/FontManager'; import { fixupColorFonts } from '../../utils/FontManager';
import * as sdk from '../../index';
import dis from '../../dispatcher/dispatcher'; import dis from '../../dispatcher/dispatcher';
import { IMatrixClientCreds } from '../../MatrixClientPeg'; import { IMatrixClientCreds } from '../../MatrixClientPeg';
import SettingsStore from "../../settings/SettingsStore"; import SettingsStore from "../../settings/SettingsStore";
@ -59,6 +58,11 @@ import { replaceableComponent } from "../../utils/replaceableComponent";
import CallHandler, { CallHandlerEvent } from '../../CallHandler'; import CallHandler, { CallHandlerEvent } from '../../CallHandler';
import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call'; import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
import AudioFeedArrayForCall from '../views/voip/AudioFeedArrayForCall'; import AudioFeedArrayForCall from '../views/voip/AudioFeedArrayForCall';
import RoomView from './RoomView';
import ToastContainer from './ToastContainer';
import MyGroups from "./MyGroups";
import UserView from "./UserView";
import GroupView from "./GroupView";
// We need to fetch each pinned message individually (if we don't already have it) // We need to fetch each pinned message individually (if we don't already have it)
// so each pinned message may trigger a request. Limit the number per room for sanity. // so each pinned message may trigger a request. Limit the number per room for sanity.
@ -78,8 +82,8 @@ interface IProps {
hideToSRUsers: boolean; hideToSRUsers: boolean;
resizeNotifier: ResizeNotifier; resizeNotifier: ResizeNotifier;
// eslint-disable-next-line camelcase // eslint-disable-next-line camelcase
page_type: string; page_type?: string;
autoJoin: boolean; autoJoin?: boolean;
threepidInvite?: IThreepidInvite; threepidInvite?: IThreepidInvite;
roomOobData?: IOOBData; roomOobData?: IOOBData;
currentRoomId: string; currentRoomId: string;
@ -567,12 +571,6 @@ class LoggedInView extends React.Component<IProps, IState> {
}; };
render() { render() {
const RoomView = sdk.getComponent('structures.RoomView');
const UserView = sdk.getComponent('structures.UserView');
const GroupView = sdk.getComponent('structures.GroupView');
const MyGroups = sdk.getComponent('structures.MyGroups');
const ToastContainer = sdk.getComponent('structures.ToastContainer');
let pageElement; let pageElement;
switch (this.props.page_type) { switch (this.props.page_type) {

View file

@ -19,6 +19,8 @@ import { createClient } from "matrix-js-sdk/src/matrix";
import { InvalidStoreError } from "matrix-js-sdk/src/errors"; import { InvalidStoreError } from "matrix-js-sdk/src/errors";
import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { sleep, defer, IDeferred } from "matrix-js-sdk/src/utils";
// focus-visible is a Polyfill for the :focus-visible CSS pseudo-attribute used by _AccessibleButton.scss // focus-visible is a Polyfill for the :focus-visible CSS pseudo-attribute used by _AccessibleButton.scss
import 'focus-visible'; import 'focus-visible';
// what-input helps improve keyboard accessibility // what-input helps improve keyboard accessibility
@ -34,7 +36,6 @@ import dis from "../../dispatcher/dispatcher";
import Notifier from '../../Notifier'; import Notifier from '../../Notifier';
import Modal from "../../Modal"; import Modal from "../../Modal";
import * as sdk from '../../index';
import { showRoomInviteDialog, showStartChatInviteDialog } from '../../RoomInvite'; import { showRoomInviteDialog, showStartChatInviteDialog } from '../../RoomInvite';
import * as Rooms from '../../Rooms'; import * as Rooms from '../../Rooms';
import linkifyMatrix from "../../linkify-matrix"; import linkifyMatrix from "../../linkify-matrix";
@ -55,7 +56,6 @@ import DMRoomMap from '../../utils/DMRoomMap';
import ThemeWatcher from "../../settings/watchers/ThemeWatcher"; import ThemeWatcher from "../../settings/watchers/ThemeWatcher";
import { FontWatcher } from '../../settings/watchers/FontWatcher'; import { FontWatcher } from '../../settings/watchers/FontWatcher';
import { storeRoomAliasInCache } from '../../RoomAliasCache'; import { storeRoomAliasInCache } from '../../RoomAliasCache';
import { defer, IDeferred, sleep } from "../../utils/promise";
import ToastStore from "../../stores/ToastStore"; import ToastStore from "../../stores/ToastStore";
import * as StorageManager from "../../utils/StorageManager"; import * as StorageManager from "../../utils/StorageManager";
import type LoggedInViewType from "./LoggedInView"; import type LoggedInViewType from "./LoggedInView";
@ -84,9 +84,27 @@ import RoomListStore from "../../stores/room-list/RoomListStore";
import { RoomUpdateCause } from "../../stores/room-list/models"; import { RoomUpdateCause } from "../../stores/room-list/models";
import defaultDispatcher from "../../dispatcher/dispatcher"; import defaultDispatcher from "../../dispatcher/dispatcher";
import SecurityCustomisations from "../../customisations/Security"; import SecurityCustomisations from "../../customisations/Security";
import Spinner from "../views/elements/Spinner";
import QuestionDialog from "../views/dialogs/QuestionDialog";
import UserSettingsDialog from '../views/dialogs/UserSettingsDialog';
import CreateGroupDialog from '../views/dialogs/CreateGroupDialog';
import CreateRoomDialog from '../views/dialogs/CreateRoomDialog';
import RoomDirectory from './RoomDirectory';
import KeySignatureUploadFailedDialog from "../views/dialogs/KeySignatureUploadFailedDialog";
import IncomingSasDialog from "../views/dialogs/IncomingSasDialog";
import CompleteSecurity from "./auth/CompleteSecurity";
import LoggedInView from './LoggedInView';
import Welcome from "../views/auth/Welcome";
import ForgotPassword from "./auth/ForgotPassword";
import E2eSetup from "./auth/E2eSetup";
import Registration from './auth/Registration';
import Login from "./auth/Login";
import ErrorBoundary from '../views/elements/ErrorBoundary';
import VerificationRequestToast from '../views/toasts/VerificationRequestToast';
import PerformanceMonitor, { PerformanceEntryNames } from "../../performance"; import PerformanceMonitor, { PerformanceEntryNames } from "../../performance";
import UIStore, { UI_EVENTS } from "../../stores/UIStore"; import UIStore, { UI_EVENTS } from "../../stores/UIStore";
import SoftLogout from './auth/SoftLogout';
/** constants for MatrixChat.state.view */ /** constants for MatrixChat.state.view */
export enum Views { export enum Views {
@ -155,7 +173,12 @@ interface IRoomInfo {
/* eslint-enable camelcase */ /* eslint-enable camelcase */
interface IProps { // TODO type things better interface IProps { // TODO type things better
config: Record<string, any>; config: {
piwik: {
policyUrl: string;
};
[key: string]: any;
};
serverConfig?: ValidatedServerConfig; serverConfig?: ValidatedServerConfig;
onNewScreen: (screen: string, replaceLast: boolean) => void; onNewScreen: (screen: string, replaceLast: boolean) => void;
enableGuest?: boolean; enableGuest?: boolean;
@ -518,7 +541,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
onAction = (payload) => { onAction = (payload) => {
// console.log(`MatrixClientPeg.onAction: ${payload.action}`); // console.log(`MatrixClientPeg.onAction: ${payload.action}`);
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
// Start the onboarding process for certain actions // Start the onboarding process for certain actions
if (MatrixClientPeg.get() && MatrixClientPeg.get().isGuest() && if (MatrixClientPeg.get() && MatrixClientPeg.get().isGuest() &&
@ -612,8 +634,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
onFinished: (confirm) => { onFinished: (confirm) => {
if (confirm) { if (confirm) {
// FIXME: controller shouldn't be loading a view :( // FIXME: controller shouldn't be loading a view :(
const Loader = sdk.getComponent("elements.Spinner"); const modal = Modal.createDialog(Spinner, null, 'mx_Dialog_spinner');
const modal = Modal.createDialog(Loader, null, 'mx_Dialog_spinner');
MatrixClientPeg.get().leave(payload.room_id).then(() => { MatrixClientPeg.get().leave(payload.room_id).then(() => {
modal.close(); modal.close();
@ -649,7 +670,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
} }
case Action.ViewUserSettings: { case Action.ViewUserSettings: {
const tabPayload = payload as OpenToTabPayload; const tabPayload = payload as OpenToTabPayload;
const UserSettingsDialog = sdk.getComponent("dialogs.UserSettingsDialog");
Modal.createTrackedDialog('User settings', '', UserSettingsDialog, Modal.createTrackedDialog('User settings', '', UserSettingsDialog,
{ initialTabId: tabPayload.initialTabId }, { initialTabId: tabPayload.initialTabId },
/*className=*/null, /*isPriority=*/false, /*isStatic=*/true); /*className=*/null, /*isPriority=*/false, /*isStatic=*/true);
@ -662,11 +682,12 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
this.createRoom(payload.public, payload.defaultName); this.createRoom(payload.public, payload.defaultName);
break; break;
case 'view_create_group': { case 'view_create_group': {
let CreateGroupDialog = sdk.getComponent("dialogs.CreateGroupDialog"); const prototype = SettingsStore.getValue("feature_communities_v2_prototypes");
if (SettingsStore.getValue("feature_communities_v2_prototypes")) { Modal.createTrackedDialog(
CreateGroupDialog = CreateCommunityPrototypeDialog; 'Create Community',
} '',
Modal.createTrackedDialog('Create Community', '', CreateGroupDialog); prototype ? CreateCommunityPrototypeDialog : CreateGroupDialog,
);
break; break;
} }
case Action.ViewRoomDirectory: { case Action.ViewRoomDirectory: {
@ -676,7 +697,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
room_id: SpaceStore.instance.activeSpace.roomId, room_id: SpaceStore.instance.activeSpace.roomId,
}); });
} else { } else {
const RoomDirectory = sdk.getComponent("structures.RoomDirectory");
Modal.createTrackedDialog('Room directory', '', RoomDirectory, { Modal.createTrackedDialog('Room directory', '', RoomDirectory, {
initialText: payload.initialText, initialText: payload.initialText,
}, 'mx_RoomDirectory_dialogWrapper', false, true); }, 'mx_RoomDirectory_dialogWrapper', false, true);
@ -1018,7 +1038,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
} }
} }
const CreateRoomDialog = sdk.getComponent('dialogs.CreateRoomDialog');
const modal = Modal.createTrackedDialog('Create Room', '', CreateRoomDialog, { const modal = Modal.createTrackedDialog('Create Room', '', CreateRoomDialog, {
defaultPublic, defaultPublic,
defaultName, defaultName,
@ -1115,7 +1134,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
} }
private leaveRoom(roomId: string) { private leaveRoom(roomId: string) {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
const roomToLeave = MatrixClientPeg.get().getRoom(roomId); const roomToLeave = MatrixClientPeg.get().getRoom(roomId);
const warnings = this.leaveRoomWarnings(roomId); const warnings = this.leaveRoomWarnings(roomId);
@ -1142,8 +1160,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
const d = leaveRoomBehaviour(roomId); const d = leaveRoomBehaviour(roomId);
// FIXME: controller shouldn't be loading a view :( // FIXME: controller shouldn't be loading a view :(
const Loader = sdk.getComponent("elements.Spinner"); const modal = Modal.createDialog(Spinner, null, 'mx_Dialog_spinner');
const modal = Modal.createDialog(Loader, null, 'mx_Dialog_spinner');
d.finally(() => modal.close()); d.finally(() => modal.close());
dis.dispatch({ dis.dispatch({
@ -1438,7 +1455,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}); });
}); });
cli.on('no_consent', function(message, consentUri) { cli.on('no_consent', function(message, consentUri) {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
Modal.createTrackedDialog('No Consent Dialog', '', QuestionDialog, { Modal.createTrackedDialog('No Consent Dialog', '', QuestionDialog, {
title: _t('Terms and Conditions'), title: _t('Terms and Conditions'),
description: <div> description: <div>
@ -1547,8 +1563,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}); });
cli.on("crypto.keySignatureUploadFailure", (failures, source, continuation) => { cli.on("crypto.keySignatureUploadFailure", (failures, source, continuation) => {
const KeySignatureUploadFailedDialog =
sdk.getComponent('views.dialogs.KeySignatureUploadFailedDialog');
Modal.createTrackedDialog( Modal.createTrackedDialog(
'Failed to upload key signatures', 'Failed to upload key signatures',
'Failed to upload key signatures', 'Failed to upload key signatures',
@ -1558,7 +1572,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
cli.on("crypto.verification.request", request => { cli.on("crypto.verification.request", request => {
if (request.verifier) { if (request.verifier) {
const IncomingSasDialog = sdk.getComponent("views.dialogs.IncomingSasDialog");
Modal.createTrackedDialog('Incoming Verification', '', IncomingSasDialog, { Modal.createTrackedDialog('Incoming Verification', '', IncomingSasDialog, {
verifier: request.verifier, verifier: request.verifier,
}, null, /* priority = */ false, /* static = */ true); }, null, /* priority = */ false, /* static = */ true);
@ -1568,7 +1581,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
title: _t("Verification requested"), title: _t("Verification requested"),
icon: "verification", icon: "verification",
props: { request }, props: { request },
component: sdk.getComponent("toasts.VerificationRequestToast"), component: VerificationRequestToast,
priority: 90, priority: 90,
}); });
} }
@ -1976,21 +1989,18 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
let view = null; let view = null;
if (this.state.view === Views.LOADING) { if (this.state.view === Views.LOADING) {
const Spinner = sdk.getComponent('elements.Spinner');
view = ( view = (
<div className="mx_MatrixChat_splash"> <div className="mx_MatrixChat_splash">
<Spinner /> <Spinner />
</div> </div>
); );
} else if (this.state.view === Views.COMPLETE_SECURITY) { } else if (this.state.view === Views.COMPLETE_SECURITY) {
const CompleteSecurity = sdk.getComponent('structures.auth.CompleteSecurity');
view = ( view = (
<CompleteSecurity <CompleteSecurity
onFinished={this.onCompleteSecurityE2eSetupFinished} onFinished={this.onCompleteSecurityE2eSetupFinished}
/> />
); );
} else if (this.state.view === Views.E2E_SETUP) { } else if (this.state.view === Views.E2E_SETUP) {
const E2eSetup = sdk.getComponent('structures.auth.E2eSetup');
view = ( view = (
<E2eSetup <E2eSetup
onFinished={this.onCompleteSecurityE2eSetupFinished} onFinished={this.onCompleteSecurityE2eSetupFinished}
@ -2011,7 +2021,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
* we should go through and figure out what we actually need to pass down, as well * we should go through and figure out what we actually need to pass down, as well
* as using something like redux to avoid having a billion bits of state kicking around. * as using something like redux to avoid having a billion bits of state kicking around.
*/ */
const LoggedInView = sdk.getComponent('structures.LoggedInView');
view = ( view = (
<LoggedInView <LoggedInView
{...this.props} {...this.props}
@ -2019,14 +2028,12 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
ref={this.loggedInView} ref={this.loggedInView}
matrixClient={MatrixClientPeg.get()} matrixClient={MatrixClientPeg.get()}
onRoomCreated={this.onRoomCreated} onRoomCreated={this.onRoomCreated}
onCloseAllSettings={this.onCloseAllSettings}
onRegistered={this.onRegistered} onRegistered={this.onRegistered}
currentRoomId={this.state.currentRoomId} currentRoomId={this.state.currentRoomId}
/> />
); );
} else { } else {
// we think we are logged in, but are still waiting for the /sync to complete // we think we are logged in, but are still waiting for the /sync to complete
const Spinner = sdk.getComponent('elements.Spinner');
let errorBox; let errorBox;
if (this.state.syncError && !isStoreError) { if (this.state.syncError && !isStoreError) {
errorBox = <div className="mx_MatrixChat_syncError"> errorBox = <div className="mx_MatrixChat_syncError">
@ -2044,10 +2051,8 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
); );
} }
} else if (this.state.view === Views.WELCOME) { } else if (this.state.view === Views.WELCOME) {
const Welcome = sdk.getComponent('auth.Welcome');
view = <Welcome />; view = <Welcome />;
} else if (this.state.view === Views.REGISTER && SettingsStore.getValue(UIFeature.Registration)) { } else if (this.state.view === Views.REGISTER && SettingsStore.getValue(UIFeature.Registration)) {
const Registration = sdk.getComponent('structures.auth.Registration');
const email = ThreepidInviteStore.instance.pickBestInvite()?.toEmail; const email = ThreepidInviteStore.instance.pickBestInvite()?.toEmail;
view = ( view = (
<Registration <Registration
@ -2066,7 +2071,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
/> />
); );
} else if (this.state.view === Views.FORGOT_PASSWORD && SettingsStore.getValue(UIFeature.PasswordReset)) { } else if (this.state.view === Views.FORGOT_PASSWORD && SettingsStore.getValue(UIFeature.PasswordReset)) {
const ForgotPassword = sdk.getComponent('structures.auth.ForgotPassword');
view = ( view = (
<ForgotPassword <ForgotPassword
onComplete={this.onLoginClick} onComplete={this.onLoginClick}
@ -2077,7 +2081,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
); );
} else if (this.state.view === Views.LOGIN) { } else if (this.state.view === Views.LOGIN) {
const showPasswordReset = SettingsStore.getValue(UIFeature.PasswordReset); const showPasswordReset = SettingsStore.getValue(UIFeature.PasswordReset);
const Login = sdk.getComponent('structures.auth.Login');
view = ( view = (
<Login <Login
isSyncing={this.state.pendingInitialSync} isSyncing={this.state.pendingInitialSync}
@ -2093,7 +2096,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
/> />
); );
} else if (this.state.view === Views.SOFT_LOGOUT) { } else if (this.state.view === Views.SOFT_LOGOUT) {
const SoftLogout = sdk.getComponent('structures.auth.SoftLogout');
view = ( view = (
<SoftLogout <SoftLogout
realQueryParams={this.props.realQueryParams} realQueryParams={this.props.realQueryParams}
@ -2105,7 +2107,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
console.error(`Unknown view ${this.state.view}`); console.error(`Unknown view ${this.state.view}`);
} }
const ErrorBoundary = sdk.getComponent('elements.ErrorBoundary');
return <ErrorBoundary> return <ErrorBoundary>
{view} {view}
</ErrorBoundary>; </ErrorBoundary>;

View file

@ -34,7 +34,6 @@ import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks';
import ResizeNotifier from '../../utils/ResizeNotifier'; import ResizeNotifier from '../../utils/ResizeNotifier';
import ContentMessages from '../../ContentMessages'; import ContentMessages from '../../ContentMessages';
import Modal from '../../Modal'; import Modal from '../../Modal';
import * as sdk from '../../index';
import CallHandler, { PlaceCallType } from '../../CallHandler'; import CallHandler, { PlaceCallType } from '../../CallHandler';
import dis from '../../dispatcher/dispatcher'; import dis from '../../dispatcher/dispatcher';
import * as Rooms from '../../Rooms'; import * as Rooms from '../../Rooms';
@ -42,7 +41,7 @@ import eventSearch, { searchPagination } from '../../Searching';
import MainSplit from './MainSplit'; import MainSplit from './MainSplit';
import RightPanel from './RightPanel'; import RightPanel from './RightPanel';
import RoomViewStore from '../../stores/RoomViewStore'; import RoomViewStore from '../../stores/RoomViewStore';
import RoomScrollStateStore from '../../stores/RoomScrollStateStore'; import RoomScrollStateStore, { ScrollState } from '../../stores/RoomScrollStateStore';
import WidgetEchoStore from '../../stores/WidgetEchoStore'; import WidgetEchoStore from '../../stores/WidgetEchoStore';
import SettingsStore from "../../settings/SettingsStore"; import SettingsStore from "../../settings/SettingsStore";
import { Layout } from "../../settings/Layout"; import { Layout } from "../../settings/Layout";
@ -82,6 +81,14 @@ import { replaceableComponent } from "../../utils/replaceableComponent";
import UIStore from "../../stores/UIStore"; import UIStore from "../../stores/UIStore";
import EditorStateTransfer from "../../utils/EditorStateTransfer"; import EditorStateTransfer from "../../utils/EditorStateTransfer";
import { throttle } from "lodash"; import { throttle } from "lodash";
import ErrorDialog from '../views/dialogs/ErrorDialog';
import SearchResultTile from '../views/rooms/SearchResultTile';
import Spinner from "../views/elements/Spinner";
import UploadBar from './UploadBar';
import RoomStatusBar from "./RoomStatusBar";
import MessageComposer from '../views/rooms/MessageComposer';
import JumpToBottomButton from "../views/rooms/JumpToBottomButton";
import TopUnreadMessagesBar from "../views/rooms/TopUnreadMessagesBar";
const DEBUG = false; const DEBUG = false;
let debuglog = function(msg: string) {}; let debuglog = function(msg: string) {};
@ -1328,7 +1335,6 @@ export default class RoomView extends React.Component<IProps, IState> {
searchResults: results, searchResults: results,
}); });
}, (error) => { }, (error) => {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
console.error("Search failed", error); console.error("Search failed", error);
Modal.createTrackedDialog('Search failed', '', ErrorDialog, { Modal.createTrackedDialog('Search failed', '', ErrorDialog, {
title: _t("Search failed"), title: _t("Search failed"),
@ -1344,9 +1350,6 @@ export default class RoomView extends React.Component<IProps, IState> {
} }
private getSearchResultTiles() { private getSearchResultTiles() {
const SearchResultTile = sdk.getComponent('rooms.SearchResultTile');
const Spinner = sdk.getComponent("elements.Spinner");
// XXX: todo: merge overlapping results somehow? // XXX: todo: merge overlapping results somehow?
// XXX: why doesn't searching on name work? // XXX: why doesn't searching on name work?
@ -1466,7 +1469,6 @@ export default class RoomView extends React.Component<IProps, IState> {
console.error("Failed to reject invite: %s", error); console.error("Failed to reject invite: %s", error);
const msg = error.message ? error.message : JSON.stringify(error); const msg = error.message ? error.message : JSON.stringify(error);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Failed to reject invite', '', ErrorDialog, { Modal.createTrackedDialog('Failed to reject invite', '', ErrorDialog, {
title: _t("Failed to reject invite"), title: _t("Failed to reject invite"),
description: msg, description: msg,
@ -1500,7 +1502,6 @@ export default class RoomView extends React.Component<IProps, IState> {
console.error("Failed to reject invite: %s", error); console.error("Failed to reject invite: %s", error);
const msg = error.message ? error.message : JSON.stringify(error); const msg = error.message ? error.message : JSON.stringify(error);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Failed to reject invite', '', ErrorDialog, { Modal.createTrackedDialog('Failed to reject invite', '', ErrorDialog, {
title: _t("Failed to reject invite"), title: _t("Failed to reject invite"),
description: msg, description: msg,
@ -1577,7 +1578,7 @@ export default class RoomView extends React.Component<IProps, IState> {
// get the current scroll position of the room, so that it can be // get the current scroll position of the room, so that it can be
// restored when we switch back to it. // restored when we switch back to it.
// //
private getScrollState() { private getScrollState(): ScrollState {
const messagePanel = this.messagePanel; const messagePanel = this.messagePanel;
if (!messagePanel) return null; if (!messagePanel) return null;
@ -1834,10 +1835,8 @@ export default class RoomView extends React.Component<IProps, IState> {
let isStatusAreaExpanded = true; let isStatusAreaExpanded = true;
if (ContentMessages.sharedInstance().getCurrentUploads().length > 0) { if (ContentMessages.sharedInstance().getCurrentUploads().length > 0) {
const UploadBar = sdk.getComponent('structures.UploadBar');
statusBar = <UploadBar room={this.state.room} />; statusBar = <UploadBar room={this.state.room} />;
} else if (!this.state.searchResults) { } else if (!this.state.searchResults) {
const RoomStatusBar = sdk.getComponent('structures.RoomStatusBar');
isStatusAreaExpanded = this.state.statusBarVisible; isStatusAreaExpanded = this.state.statusBarVisible;
statusBar = <RoomStatusBar statusBar = <RoomStatusBar
room={this.state.room} room={this.state.room}
@ -1943,12 +1942,9 @@ export default class RoomView extends React.Component<IProps, IState> {
myMembership === 'join' && !this.state.searchResults myMembership === 'join' && !this.state.searchResults
); );
if (canSpeak) { if (canSpeak) {
const MessageComposer = sdk.getComponent('rooms.MessageComposer');
messageComposer = messageComposer =
<MessageComposer <MessageComposer
room={this.state.room} room={this.state.room}
callState={this.state.callState}
showApps={this.state.showApps}
e2eStatus={this.state.e2eStatus} e2eStatus={this.state.e2eStatus}
resizeNotifier={this.props.resizeNotifier} resizeNotifier={this.props.resizeNotifier}
replyToEvent={this.state.replyToEvent} replyToEvent={this.state.replyToEvent}
@ -2034,7 +2030,6 @@ export default class RoomView extends React.Component<IProps, IState> {
let topUnreadMessagesBar = null; let topUnreadMessagesBar = null;
// Do not show TopUnreadMessagesBar if we have search results showing, it makes no sense // Do not show TopUnreadMessagesBar if we have search results showing, it makes no sense
if (this.state.showTopUnreadMessagesBar && !this.state.searchResults) { if (this.state.showTopUnreadMessagesBar && !this.state.searchResults) {
const TopUnreadMessagesBar = sdk.getComponent('rooms.TopUnreadMessagesBar');
topUnreadMessagesBar = ( topUnreadMessagesBar = (
<TopUnreadMessagesBar onScrollUpClick={this.jumpToReadMarker} onCloseClick={this.forgetReadMarker} /> <TopUnreadMessagesBar onScrollUpClick={this.jumpToReadMarker} onCloseClick={this.forgetReadMarker} />
); );
@ -2042,7 +2037,6 @@ export default class RoomView extends React.Component<IProps, IState> {
let jumpToBottom; let jumpToBottom;
// Do not show JumpToBottomButton if we have search results showing, it makes no sense // Do not show JumpToBottomButton if we have search results showing, it makes no sense
if (!this.state.atEndOfLiveTimeline && !this.state.searchResults) { if (!this.state.atEndOfLiveTimeline && !this.state.searchResults) {
const JumpToBottomButton = sdk.getComponent('rooms.JumpToBottomButton');
jumpToBottom = (<JumpToBottomButton jumpToBottom = (<JumpToBottomButton
highlight={this.state.room.getUnreadNotificationCount(NotificationCountType.Highlight) > 0} highlight={this.state.room.getUnreadNotificationCount(NotificationCountType.Highlight) > 0}
numUnreadMessages={this.state.numUnreadMessages} numUnreadMessages={this.state.numUnreadMessages}

View file

@ -18,9 +18,9 @@ limitations under the License.
import * as React from "react"; import * as React from "react";
import { _t } from '../../languageHandler'; import { _t } from '../../languageHandler';
import * as sdk from "../../index";
import AutoHideScrollbar from './AutoHideScrollbar'; import AutoHideScrollbar from './AutoHideScrollbar';
import { replaceableComponent } from "../../utils/replaceableComponent"; import { replaceableComponent } from "../../utils/replaceableComponent";
import AccessibleButton from "../views/elements/AccessibleButton";
/** /**
* Represents a tab for the TabbedView. * Represents a tab for the TabbedView.
@ -82,8 +82,6 @@ export default class TabbedView extends React.Component<IProps, IState> {
} }
private _renderTabLabel(tab: Tab) { private _renderTabLabel(tab: Tab) {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
let classes = "mx_TabbedView_tabLabel "; let classes = "mx_TabbedView_tabLabel ";
const idx = this.props.tabs.indexOf(tab); const idx = this.props.tabs.indexOf(tab);

View file

@ -32,7 +32,6 @@ import RoomContext from "../../contexts/RoomContext";
import UserActivity from "../../UserActivity"; import UserActivity from "../../UserActivity";
import Modal from "../../Modal"; import Modal from "../../Modal";
import dis from "../../dispatcher/dispatcher"; import dis from "../../dispatcher/dispatcher";
import * as sdk from "../../index";
import { Key } from '../../Keyboard'; import { Key } from '../../Keyboard';
import Timer from '../../utils/Timer'; import Timer from '../../utils/Timer';
import shouldHideEvent from '../../shouldHideEvent'; import shouldHideEvent from '../../shouldHideEvent';
@ -47,6 +46,7 @@ import ResizeNotifier from "../../utils/ResizeNotifier";
import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks"; import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
import Spinner from "../views/elements/Spinner"; import Spinner from "../views/elements/Spinner";
import EditorStateTransfer from '../../utils/EditorStateTransfer'; import EditorStateTransfer from '../../utils/EditorStateTransfer';
import ErrorDialog from '../views/dialogs/ErrorDialog';
const PAGINATE_SIZE = 20; const PAGINATE_SIZE = 20;
const INITIAL_SIZE = 20; const INITIAL_SIZE = 20;
@ -1096,7 +1096,6 @@ class TimelinePanel extends React.Component<IProps, IState> {
console.error( console.error(
`Error loading timeline panel at ${eventId}: ${error}`, `Error loading timeline panel at ${eventId}: ${error}`,
); );
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
let onFinished; let onFinished;

View file

@ -15,39 +15,42 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import * as sdk from '../../../index'; import * as sdk from '../../../index';
import { SetupEncryptionStore, Phase } from '../../../stores/SetupEncryptionStore'; import { SetupEncryptionStore, Phase } from '../../../stores/SetupEncryptionStore';
import SetupEncryptionBody from "./SetupEncryptionBody"; import SetupEncryptionBody from "./SetupEncryptionBody";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
@replaceableComponent("structures.auth.CompleteSecurity") interface IProps {
export default class CompleteSecurity extends React.Component { onFinished: () => void;
static propTypes = { }
onFinished: PropTypes.func.isRequired,
};
constructor() { interface IState {
super(); phase: Phase;
}
@replaceableComponent("structures.auth.CompleteSecurity")
export default class CompleteSecurity extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props);
const store = SetupEncryptionStore.sharedInstance(); const store = SetupEncryptionStore.sharedInstance();
store.on("update", this._onStoreUpdate); store.on("update", this.onStoreUpdate);
store.start(); store.start();
this.state = { phase: store.phase }; this.state = { phase: store.phase };
} }
_onStoreUpdate = () => { private onStoreUpdate = (): void => {
const store = SetupEncryptionStore.sharedInstance(); const store = SetupEncryptionStore.sharedInstance();
this.setState({ phase: store.phase }); this.setState({ phase: store.phase });
}; };
componentWillUnmount() { public componentWillUnmount(): void {
const store = SetupEncryptionStore.sharedInstance(); const store = SetupEncryptionStore.sharedInstance();
store.off("update", this._onStoreUpdate); store.off("update", this.onStoreUpdate);
store.stop(); store.stop();
} }
render() { public render() {
const AuthPage = sdk.getComponent("auth.AuthPage"); const AuthPage = sdk.getComponent("auth.AuthPage");
const CompleteSecurityBody = sdk.getComponent("auth.CompleteSecurityBody"); const CompleteSecurityBody = sdk.getComponent("auth.CompleteSecurityBody");
const { phase } = this.state; const { phase } = this.state;

View file

@ -15,20 +15,19 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import AuthPage from '../../views/auth/AuthPage'; import AuthPage from '../../views/auth/AuthPage';
import CompleteSecurityBody from '../../views/auth/CompleteSecurityBody'; import CompleteSecurityBody from '../../views/auth/CompleteSecurityBody';
import CreateCrossSigningDialog from '../../views/dialogs/security/CreateCrossSigningDialog'; import CreateCrossSigningDialog from '../../views/dialogs/security/CreateCrossSigningDialog';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
@replaceableComponent("structures.auth.E2eSetup") interface IProps {
export default class E2eSetup extends React.Component { onFinished: () => void;
static propTypes = { accountPassword?: string;
onFinished: PropTypes.func.isRequired, tokenLogin?: boolean;
accountPassword: PropTypes.string, }
tokenLogin: PropTypes.bool,
};
@replaceableComponent("structures.auth.E2eSetup")
export default class E2eSetup extends React.Component<IProps> {
render() { render() {
return ( return (
<AuthPage> <AuthPage>

View file

@ -17,7 +17,6 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { _t, _td } from '../../../languageHandler'; import { _t, _td } from '../../../languageHandler';
import * as sdk from '../../../index'; import * as sdk from '../../../index';
import Modal from "../../../Modal"; import Modal from "../../../Modal";
@ -31,27 +30,50 @@ import PassphraseField from '../../views/auth/PassphraseField';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import { PASSWORD_MIN_SCORE } from '../../views/auth/RegistrationForm'; import { PASSWORD_MIN_SCORE } from '../../views/auth/RegistrationForm';
// Phases import { IValidationResult } from "../../views/elements/Validation";
// Show the forgot password inputs
const PHASE_FORGOT = 1; enum Phase {
// Email is in the process of being sent // Show the forgot password inputs
const PHASE_SENDING_EMAIL = 2; Forgot = 1,
// Email has been sent // Email is in the process of being sent
const PHASE_EMAIL_SENT = 3; SendingEmail = 2,
// User has clicked the link in email and completed reset // Email has been sent
const PHASE_DONE = 4; EmailSent = 3,
// User has clicked the link in email and completed reset
Done = 4,
}
interface IProps {
serverConfig: ValidatedServerConfig;
onServerConfigChange: (serverConfig: ValidatedServerConfig) => void;
onLoginClick?: () => void;
onComplete: () => void;
}
interface IState {
phase: Phase;
email: string;
password: string;
password2: string;
errorText: string;
// We perform liveliness checks later, but for now suppress the errors.
// We also track the server dead errors independently of the regular errors so
// that we can render it differently, and override any other error the user may
// be seeing.
serverIsAlive: boolean;
serverErrorIsFatal: boolean;
serverDeadError: string;
passwordFieldValid: boolean;
}
@replaceableComponent("structures.auth.ForgotPassword") @replaceableComponent("structures.auth.ForgotPassword")
export default class ForgotPassword extends React.Component { export default class ForgotPassword extends React.Component<IProps, IState> {
static propTypes = { private reset: PasswordReset;
serverConfig: PropTypes.instanceOf(ValidatedServerConfig).isRequired,
onServerConfigChange: PropTypes.func.isRequired,
onLoginClick: PropTypes.func,
onComplete: PropTypes.func.isRequired,
};
state = { state = {
phase: PHASE_FORGOT, phase: Phase.Forgot,
email: "", email: "",
password: "", password: "",
password2: "", password2: "",
@ -64,30 +86,31 @@ export default class ForgotPassword extends React.Component {
serverIsAlive: true, serverIsAlive: true,
serverErrorIsFatal: false, serverErrorIsFatal: false,
serverDeadError: "", serverDeadError: "",
passwordFieldValid: false,
}; };
constructor(props) { constructor(props: IProps) {
super(props); super(props);
CountlyAnalytics.instance.track("onboarding_forgot_password_begin"); CountlyAnalytics.instance.track("onboarding_forgot_password_begin");
} }
componentDidMount() { public componentDidMount() {
this.reset = null; this.reset = null;
this._checkServerLiveliness(this.props.serverConfig); this.checkServerLiveliness(this.props.serverConfig);
} }
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event // TODO: [REACT-WARNING] Replace with appropriate lifecycle event
// eslint-disable-next-line camelcase // eslint-disable-next-line camelcase
UNSAFE_componentWillReceiveProps(newProps) { public UNSAFE_componentWillReceiveProps(newProps: IProps): void {
if (newProps.serverConfig.hsUrl === this.props.serverConfig.hsUrl && if (newProps.serverConfig.hsUrl === this.props.serverConfig.hsUrl &&
newProps.serverConfig.isUrl === this.props.serverConfig.isUrl) return; newProps.serverConfig.isUrl === this.props.serverConfig.isUrl) return;
// Do a liveliness check on the new URLs // Do a liveliness check on the new URLs
this._checkServerLiveliness(newProps.serverConfig); this.checkServerLiveliness(newProps.serverConfig);
} }
async _checkServerLiveliness(serverConfig) { private async checkServerLiveliness(serverConfig): Promise<void> {
try { try {
await AutoDiscoveryUtils.validateServerConfigWithStaticUrls( await AutoDiscoveryUtils.validateServerConfigWithStaticUrls(
serverConfig.hsUrl, serverConfig.hsUrl,
@ -98,28 +121,28 @@ export default class ForgotPassword extends React.Component {
serverIsAlive: true, serverIsAlive: true,
}); });
} catch (e) { } catch (e) {
this.setState(AutoDiscoveryUtils.authComponentStateForError(e, "forgot_password")); this.setState(AutoDiscoveryUtils.authComponentStateForError(e, "forgot_password") as IState);
} }
} }
submitPasswordReset(email, password) { public submitPasswordReset(email: string, password: string): void {
this.setState({ this.setState({
phase: PHASE_SENDING_EMAIL, phase: Phase.SendingEmail,
}); });
this.reset = new PasswordReset(this.props.serverConfig.hsUrl, this.props.serverConfig.isUrl); this.reset = new PasswordReset(this.props.serverConfig.hsUrl, this.props.serverConfig.isUrl);
this.reset.resetPassword(email, password).then(() => { this.reset.resetPassword(email, password).then(() => {
this.setState({ this.setState({
phase: PHASE_EMAIL_SENT, phase: Phase.EmailSent,
}); });
}, (err) => { }, (err) => {
this.showErrorDialog(_t('Failed to send email') + ": " + err.message); this.showErrorDialog(_t('Failed to send email') + ": " + err.message);
this.setState({ this.setState({
phase: PHASE_FORGOT, phase: Phase.Forgot,
}); });
}); });
} }
onVerify = async ev => { private onVerify = async (ev: React.MouseEvent): Promise<void> => {
ev.preventDefault(); ev.preventDefault();
if (!this.reset) { if (!this.reset) {
console.error("onVerify called before submitPasswordReset!"); console.error("onVerify called before submitPasswordReset!");
@ -127,17 +150,17 @@ export default class ForgotPassword extends React.Component {
} }
try { try {
await this.reset.checkEmailLinkClicked(); await this.reset.checkEmailLinkClicked();
this.setState({ phase: PHASE_DONE }); this.setState({ phase: Phase.Done });
} catch (err) { } catch (err) {
this.showErrorDialog(err.message); this.showErrorDialog(err.message);
} }
}; };
onSubmitForm = async ev => { private onSubmitForm = async (ev: React.FormEvent): Promise<void> => {
ev.preventDefault(); ev.preventDefault();
// refresh the server errors, just in case the server came back online // refresh the server errors, just in case the server came back online
await this._checkServerLiveliness(this.props.serverConfig); await this.checkServerLiveliness(this.props.serverConfig);
await this['password_field'].validate({ allowEmpty: false }); await this['password_field'].validate({ allowEmpty: false });
@ -172,27 +195,27 @@ export default class ForgotPassword extends React.Component {
} }
}; };
onInputChanged = (stateKey, ev) => { private onInputChanged = (stateKey: string, ev: React.FormEvent<HTMLInputElement>) => {
this.setState({ this.setState({
[stateKey]: ev.target.value, [stateKey]: ev.currentTarget.value,
}); } as any);
}; };
onLoginClick = ev => { private onLoginClick = (ev: React.MouseEvent): void => {
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
this.props.onLoginClick(); this.props.onLoginClick();
}; };
showErrorDialog(body, title) { public showErrorDialog(description: string, title?: string) {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Forgot Password Error', '', ErrorDialog, { Modal.createTrackedDialog('Forgot Password Error', '', ErrorDialog, {
title: title, title,
description: body, description,
}); });
} }
onPasswordValidate(result) { private onPasswordValidate(result: IValidationResult) {
this.setState({ this.setState({
passwordFieldValid: result.valid, passwordFieldValid: result.valid,
}); });
@ -316,16 +339,16 @@ export default class ForgotPassword extends React.Component {
let resetPasswordJsx; let resetPasswordJsx;
switch (this.state.phase) { switch (this.state.phase) {
case PHASE_FORGOT: case Phase.Forgot:
resetPasswordJsx = this.renderForgot(); resetPasswordJsx = this.renderForgot();
break; break;
case PHASE_SENDING_EMAIL: case Phase.SendingEmail:
resetPasswordJsx = this.renderSendingEmail(); resetPasswordJsx = this.renderSendingEmail();
break; break;
case PHASE_EMAIL_SENT: case Phase.EmailSent:
resetPasswordJsx = this.renderEmailSent(); resetPasswordJsx = this.renderEmailSent();
break; break;
case PHASE_DONE: case Phase.Done:
resetPasswordJsx = this.renderDone(); resetPasswordJsx = this.renderDone();
break; break;
} }

View file

@ -18,7 +18,6 @@ import React, { ReactNode } from 'react';
import { MatrixError } from "matrix-js-sdk/src/http-api"; import { MatrixError } from "matrix-js-sdk/src/http-api";
import { _t, _td } from '../../../languageHandler'; import { _t, _td } from '../../../languageHandler';
import * as sdk from '../../../index';
import Login, { ISSOFlow, LoginFlow } from '../../../Login'; import Login, { ISSOFlow, LoginFlow } from '../../../Login';
import SdkConfig from '../../../SdkConfig'; import SdkConfig from '../../../SdkConfig';
import { messageForResourceLimitError } from '../../../utils/ErrorUtils'; import { messageForResourceLimitError } from '../../../utils/ErrorUtils';
@ -36,6 +35,8 @@ import Spinner from "../../views/elements/Spinner";
import SSOButtons from "../../views/elements/SSOButtons"; import SSOButtons from "../../views/elements/SSOButtons";
import ServerPicker from "../../views/elements/ServerPicker"; import ServerPicker from "../../views/elements/ServerPicker";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import AuthBody from "../../views/auth/AuthBody";
import AuthHeader from "../../views/auth/AuthHeader";
// These are used in several places, and come from the js-sdk's autodiscovery // These are used in several places, and come from the js-sdk's autodiscovery
// stuff. We define them here so that they'll be picked up by i18n. // stuff. We define them here so that they'll be picked up by i18n.
@ -541,8 +542,6 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
}; };
render() { render() {
const AuthHeader = sdk.getComponent("auth.AuthHeader");
const AuthBody = sdk.getComponent("auth.AuthBody");
const loader = this.isBusy() && !this.state.busyLoggingIn ? const loader = this.isBusy() && !this.state.busyLoggingIn ?
<div className="mx_Login_loader"><Spinner /></div> : null; <div className="mx_Login_loader"><Spinner /></div> : null;

View file

@ -18,19 +18,24 @@ import { createClient } from 'matrix-js-sdk/src/matrix';
import React, { ReactNode } from 'react'; import React, { ReactNode } from 'react';
import { MatrixClient } from "matrix-js-sdk/src/client"; import { MatrixClient } from "matrix-js-sdk/src/client";
import * as sdk from '../../../index';
import { _t, _td } from '../../../languageHandler'; import { _t, _td } from '../../../languageHandler';
import { messageForResourceLimitError } from '../../../utils/ErrorUtils'; import { messageForResourceLimitError } from '../../../utils/ErrorUtils';
import AutoDiscoveryUtils, { ValidatedServerConfig } from "../../../utils/AutoDiscoveryUtils"; import AutoDiscoveryUtils, { ValidatedServerConfig } from "../../../utils/AutoDiscoveryUtils";
import classNames from "classnames"; import classNames from "classnames";
import * as Lifecycle from '../../../Lifecycle'; import * as Lifecycle from '../../../Lifecycle';
import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { IMatrixClientCreds, MatrixClientPeg } from "../../../MatrixClientPeg";
import AuthPage from "../../views/auth/AuthPage"; import AuthPage from "../../views/auth/AuthPage";
import Login, { ISSOFlow } from "../../../Login"; import Login, { ISSOFlow } from "../../../Login";
import dis from "../../../dispatcher/dispatcher"; import dis from "../../../dispatcher/dispatcher";
import SSOButtons from "../../views/elements/SSOButtons"; import SSOButtons from "../../views/elements/SSOButtons";
import ServerPicker from '../../views/elements/ServerPicker'; import ServerPicker from '../../views/elements/ServerPicker';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import RegistrationForm from '../../views/auth/RegistrationForm';
import AccessibleButton from '../../views/elements/AccessibleButton';
import AuthBody from "../../views/auth/AuthBody";
import AuthHeader from "../../views/auth/AuthHeader";
import InteractiveAuth from "../InteractiveAuth";
import Spinner from "../../views/elements/Spinner";
interface IProps { interface IProps {
serverConfig: ValidatedServerConfig; serverConfig: ValidatedServerConfig;
@ -47,13 +52,7 @@ interface IProps {
// - The user's password, if available and applicable (may be cached in memory // - The user's password, if available and applicable (may be cached in memory
// for a short time so the user is not required to re-enter their password // for a short time so the user is not required to re-enter their password
// for operations like uploading cross-signing keys). // for operations like uploading cross-signing keys).
onLoggedIn(params: { onLoggedIn(params: IMatrixClientCreds, password: string): void;
userId: string;
deviceId: string;
homeserverUrl: string;
identityServerUrl?: string;
accessToken: string;
}, password: string): void;
makeRegistrationUrl(params: { makeRegistrationUrl(params: {
/* eslint-disable camelcase */ /* eslint-disable camelcase */
client_secret: string; client_secret: string;
@ -246,7 +245,7 @@ export default class Registration extends React.Component<IProps, IState> {
} }
} }
private onFormSubmit = formVals => { private onFormSubmit = async (formVals): Promise<void> => {
this.setState({ this.setState({
errorText: "", errorText: "",
busy: true, busy: true,
@ -442,10 +441,6 @@ export default class Registration extends React.Component<IProps, IState> {
}; };
private renderRegisterComponent() { private renderRegisterComponent() {
const InteractiveAuth = sdk.getComponent('structures.InteractiveAuth');
const Spinner = sdk.getComponent('elements.Spinner');
const RegistrationForm = sdk.getComponent('auth.RegistrationForm');
if (this.state.matrixClient && this.state.doingUIAuth) { if (this.state.matrixClient && this.state.doingUIAuth) {
return <InteractiveAuth return <InteractiveAuth
matrixClient={this.state.matrixClient} matrixClient={this.state.matrixClient}
@ -516,10 +511,6 @@ export default class Registration extends React.Component<IProps, IState> {
} }
render() { render() {
const AuthHeader = sdk.getComponent('auth.AuthHeader');
const AuthBody = sdk.getComponent("auth.AuthBody");
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
let errorText; let errorText;
const err = this.state.errorText; const err = this.state.errorText;
if (err) { if (err) {

View file

@ -21,7 +21,7 @@ import Modal from '../../../Modal';
import VerificationRequestDialog from '../../views/dialogs/VerificationRequestDialog'; import VerificationRequestDialog from '../../views/dialogs/VerificationRequestDialog';
import { SetupEncryptionStore, Phase } from '../../../stores/SetupEncryptionStore'; import { SetupEncryptionStore, Phase } from '../../../stores/SetupEncryptionStore';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import { ISecretStorageKeyInfo } from 'matrix-js-sdk'; import { ISecretStorageKeyInfo } from 'matrix-js-sdk/src/crypto/api';
import EncryptionPanel from "../../views/right_panel/EncryptionPanel"; import EncryptionPanel from "../../views/right_panel/EncryptionPanel";
import AccessibleButton from '../../views/elements/AccessibleButton'; import AccessibleButton from '../../views/elements/AccessibleButton';
import Spinner from '../../views/elements/Spinner'; import Spinner from '../../views/elements/Spinner';

View file

@ -16,7 +16,6 @@ limitations under the License.
import React from 'react'; import React from 'react';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import * as sdk from '../../../index';
import dis from '../../../dispatcher/dispatcher'; import dis from '../../../dispatcher/dispatcher';
import * as Lifecycle from '../../../Lifecycle'; import * as Lifecycle from '../../../Lifecycle';
import Modal from '../../../Modal'; import Modal from '../../../Modal';
@ -26,6 +25,12 @@ import AuthPage from "../../views/auth/AuthPage";
import { SSO_HOMESERVER_URL_KEY, SSO_ID_SERVER_URL_KEY } from "../../../BasePlatform"; import { SSO_HOMESERVER_URL_KEY, SSO_ID_SERVER_URL_KEY } from "../../../BasePlatform";
import SSOButtons from "../../views/elements/SSOButtons"; import SSOButtons from "../../views/elements/SSOButtons";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import ConfirmWipeDeviceDialog from '../../views/dialogs/ConfirmWipeDeviceDialog';
import Field from '../../views/elements/Field';
import AccessibleButton from '../../views/elements/AccessibleButton';
import Spinner from "../../views/elements/Spinner";
import AuthHeader from "../../views/auth/AuthHeader";
import AuthBody from "../../views/auth/AuthBody";
const LOGIN_VIEW = { const LOGIN_VIEW = {
LOADING: 1, LOADING: 1,
@ -94,7 +99,6 @@ export default class SoftLogout extends React.Component<IProps, IState> {
} }
onClearAll = () => { onClearAll = () => {
const ConfirmWipeDeviceDialog = sdk.getComponent('dialogs.ConfirmWipeDeviceDialog');
Modal.createTrackedDialog('Clear Data', 'Soft Logout', ConfirmWipeDeviceDialog, { Modal.createTrackedDialog('Clear Data', 'Soft Logout', ConfirmWipeDeviceDialog, {
onFinished: (wipeData) => { onFinished: (wipeData) => {
if (!wipeData) return; if (!wipeData) return;
@ -202,7 +206,6 @@ export default class SoftLogout extends React.Component<IProps, IState> {
private renderSignInSection() { private renderSignInSection() {
if (this.state.loginView === LOGIN_VIEW.LOADING) { if (this.state.loginView === LOGIN_VIEW.LOADING) {
const Spinner = sdk.getComponent("elements.Spinner");
return <Spinner />; return <Spinner />;
} }
@ -214,9 +217,6 @@ export default class SoftLogout extends React.Component<IProps, IState> {
} }
if (this.state.loginView === LOGIN_VIEW.PASSWORD) { if (this.state.loginView === LOGIN_VIEW.PASSWORD) {
const Field = sdk.getComponent("elements.Field");
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
let error = null; let error = null;
if (this.state.errorText) { if (this.state.errorText) {
error = <span className='mx_Login_error'>{this.state.errorText}</span>; error = <span className='mx_Login_error'>{this.state.errorText}</span>;
@ -286,10 +286,6 @@ export default class SoftLogout extends React.Component<IProps, IState> {
} }
render() { render() {
const AuthHeader = sdk.getComponent("auth.AuthHeader");
const AuthBody = sdk.getComponent("auth.AuthBody");
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
return ( return (
<AuthPage> <AuthPage>
<AuthHeader /> <AuthHeader />

View file

@ -18,7 +18,6 @@ import React, { ChangeEvent, createRef, FormEvent, MouseEvent } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { MatrixClient } from "matrix-js-sdk/src/client"; import { MatrixClient } from "matrix-js-sdk/src/client";
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import AccessibleButton from "../elements/AccessibleButton"; import AccessibleButton from "../elements/AccessibleButton";
@ -26,6 +25,8 @@ import Spinner from "../elements/Spinner";
import CountlyAnalytics from "../../../CountlyAnalytics"; import CountlyAnalytics from "../../../CountlyAnalytics";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import { LocalisedPolicy, Policies } from '../../../Terms'; import { LocalisedPolicy, Policies } from '../../../Terms';
import Field from '../elements/Field';
import CaptchaForm from "./CaptchaForm";
/* This file contains a collection of components which are used by the /* This file contains a collection of components which are used by the
* InteractiveAuth to prompt the user to enter the information needed * InteractiveAuth to prompt the user to enter the information needed
@ -164,8 +165,7 @@ export class PasswordAuthEntry extends React.Component<IAuthEntryProps, IPasswor
let submitButtonOrSpinner; let submitButtonOrSpinner;
if (this.props.busy) { if (this.props.busy) {
const Loader = sdk.getComponent("elements.Spinner"); submitButtonOrSpinner = <Spinner />;
submitButtonOrSpinner = <Loader />;
} else { } else {
submitButtonOrSpinner = ( submitButtonOrSpinner = (
<input type="submit" <input type="submit"
@ -185,8 +185,6 @@ export class PasswordAuthEntry extends React.Component<IAuthEntryProps, IPasswor
); );
} }
const Field = sdk.getComponent('elements.Field');
return ( return (
<div> <div>
<p>{ _t("Confirm your identity by entering your account password below.") }</p> <p>{ _t("Confirm your identity by entering your account password below.") }</p>
@ -236,13 +234,11 @@ export class RecaptchaAuthEntry extends React.Component<IRecaptchaAuthEntryProps
render() { render() {
if (this.props.busy) { if (this.props.busy) {
const Loader = sdk.getComponent("elements.Spinner"); return <Spinner />;
return <Loader />;
} }
let errorText = this.props.errorText; let errorText = this.props.errorText;
const CaptchaForm = sdk.getComponent("views.auth.CaptchaForm");
let sitePublicKey; let sitePublicKey;
if (!this.props.stageParams || !this.props.stageParams.public_key) { if (!this.props.stageParams || !this.props.stageParams.public_key) {
errorText = _t( errorText = _t(
@ -390,8 +386,7 @@ export class TermsAuthEntry extends React.Component<ITermsAuthEntryProps, ITerms
render() { render() {
if (this.props.busy) { if (this.props.busy) {
const Loader = sdk.getComponent("elements.Spinner"); return <Spinner />;
return <Loader />;
} }
const checkboxes = []; const checkboxes = [];
@ -590,8 +585,7 @@ export class MsisdnAuthEntry extends React.Component<IMsisdnAuthEntryProps, IMsi
render() { render() {
if (this.state.requestingToken) { if (this.state.requestingToken) {
const Loader = sdk.getComponent("elements.Spinner"); return <Spinner />;
return <Loader />;
} else { } else {
const enableSubmit = Boolean(this.state.token); const enableSubmit = Boolean(this.state.token);
const submitClasses = classNames({ const submitClasses = classNames({

View file

@ -17,7 +17,6 @@ limitations under the License.
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import * as Email from '../../../email'; import * as Email from '../../../email';
import { looksValid as phoneNumberLooksValid } from '../../../phonenumber'; import { looksValid as phoneNumberLooksValid } from '../../../phonenumber';
import Modal from '../../../Modal'; import Modal from '../../../Modal';
@ -31,6 +30,7 @@ import CountlyAnalytics from "../../../CountlyAnalytics";
import Field from '../elements/Field'; import Field from '../elements/Field';
import RegistrationEmailPromptDialog from '../dialogs/RegistrationEmailPromptDialog'; import RegistrationEmailPromptDialog from '../dialogs/RegistrationEmailPromptDialog';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import CountryDropdown from "./CountryDropdown";
enum RegistrationField { enum RegistrationField {
Email = "field_email", Email = "field_email",
@ -471,7 +471,6 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
if (!this.showPhoneNumber()) { if (!this.showPhoneNumber()) {
return null; return null;
} }
const CountryDropdown = sdk.getComponent('views.auth.CountryDropdown');
const phoneLabel = this.authStepIsRequired('m.login.msisdn') ? const phoneLabel = this.authStepIsRequired('m.login.msisdn') ?
_t("Phone") : _t("Phone") :
_t("Phone (optional)"); _t("Phone (optional)");

View file

@ -18,6 +18,7 @@ import React, { ReactNode, useContext, useMemo, useState } from "react";
import classNames from "classnames"; import classNames from "classnames";
import { Room } from "matrix-js-sdk/src/models/room"; import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixClient } from "matrix-js-sdk/src/client"; import { MatrixClient } from "matrix-js-sdk/src/client";
import { sleep } from "matrix-js-sdk/src/utils";
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import { IDialogProps } from "./IDialogProps"; import { IDialogProps } from "./IDialogProps";
@ -29,7 +30,6 @@ import RoomAvatar from "../avatars/RoomAvatar";
import { getDisplayAliasForRoom } from "../../../Rooms"; import { getDisplayAliasForRoom } from "../../../Rooms";
import AccessibleButton from "../elements/AccessibleButton"; import AccessibleButton from "../elements/AccessibleButton";
import AutoHideScrollbar from "../../structures/AutoHideScrollbar"; import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
import { sleep } from "../../../utils/promise";
import DMRoomMap from "../../../utils/DMRoomMap"; import DMRoomMap from "../../../utils/DMRoomMap";
import { calculateRoomVia } from "../../../utils/permalinks/Permalinks"; import { calculateRoomVia } from "../../../utils/permalinks/Permalinks";
import StyledCheckbox from "../elements/StyledCheckbox"; import StyledCheckbox from "../elements/StyledCheckbox";

View file

@ -19,6 +19,7 @@ limitations under the License.
import React, { createRef } from 'react'; import React, { createRef } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { sleep } from "matrix-js-sdk/src/utils";
import { _t, _td } from '../../../languageHandler'; import { _t, _td } from '../../../languageHandler';
import * as sdk from '../../../index'; import * as sdk from '../../../index';
@ -30,7 +31,6 @@ import * as Email from '../../../email';
import IdentityAuthClient from '../../../IdentityAuthClient'; import IdentityAuthClient from '../../../IdentityAuthClient';
import { getDefaultIdentityServerUrl, useDefaultIdentityServer } from '../../../utils/IdentityServerUtils'; import { getDefaultIdentityServerUrl, useDefaultIdentityServer } from '../../../utils/IdentityServerUtils';
import { abbreviateUrl } from '../../../utils/UrlUtils'; import { abbreviateUrl } from '../../../utils/UrlUtils';
import { sleep } from "../../../utils/promise";
import { Key } from "../../../Keyboard"; import { Key } from "../../../Keyboard";
import { Action } from "../../../dispatcher/actions"; import { Action } from "../../../dispatcher/actions";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";

View file

@ -15,11 +15,11 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import { SettingLevel } from "../../../settings/SettingLevel"; import { SettingLevel } from "../../../settings/SettingLevel";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import BaseDialog from "./BaseDialog";
interface IProps { interface IProps {
unknownProfileUsers: Array<{ unknownProfileUsers: Array<{
@ -50,8 +50,6 @@ export default class AskInviteAnywayDialog extends React.Component<IProps> {
}; };
public render() { public render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const errorList = this.props.unknownProfileUsers const errorList = this.props.unknownProfileUsers
.map(address => <li key={address.userId}>{address.userId}: {address.errorText}</li>); .map(address => <li key={address.userId}>{address.userId}: {address.errorText}</li>);

View file

@ -18,13 +18,17 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import SdkConfig from '../../../SdkConfig'; import SdkConfig from '../../../SdkConfig';
import Modal from '../../../Modal'; import Modal from '../../../Modal';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import sendBugReport, { downloadBugReport } from '../../../rageshake/submit-rageshake'; import sendBugReport, { downloadBugReport } from '../../../rageshake/submit-rageshake';
import AccessibleButton from "../elements/AccessibleButton"; import AccessibleButton from "../elements/AccessibleButton";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import QuestionDialog from "./QuestionDialog";
import BaseDialog from "./BaseDialog";
import Field from '../elements/Field';
import Spinner from "../elements/Spinner";
import DialogButtons from "../elements/DialogButtons";
interface IProps { interface IProps {
onFinished: (success: boolean) => void; onFinished: (success: boolean) => void;
@ -93,7 +97,6 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
}).then(() => { }).then(() => {
if (!this.unmounted) { if (!this.unmounted) {
this.props.onFinished(false); this.props.onFinished(false);
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
// N.B. first param is passed to piwik and so doesn't want i18n // N.B. first param is passed to piwik and so doesn't want i18n
Modal.createTrackedDialog('Bug report sent', '', QuestionDialog, { Modal.createTrackedDialog('Bug report sent', '', QuestionDialog, {
title: _t('Logs sent'), title: _t('Logs sent'),
@ -160,11 +163,6 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
}; };
public render() { public render() {
const Loader = sdk.getComponent("elements.Spinner");
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
const Field = sdk.getComponent('elements.Field');
let error = null; let error = null;
if (this.state.err) { if (this.state.err) {
error = <div className="error"> error = <div className="error">
@ -176,7 +174,7 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
if (this.state.busy) { if (this.state.busy) {
progress = ( progress = (
<div className="progress"> <div className="progress">
<Loader /> <Spinner />
{this.state.progress} ... {this.state.progress} ...
</div> </div>
); );

View file

@ -16,9 +16,10 @@ Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import request from 'browser-request'; import request from 'browser-request';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import QuestionDialog from "./QuestionDialog";
import Spinner from "../elements/Spinner";
interface IProps { interface IProps {
newVersion: string; newVersion: string;
@ -65,9 +66,6 @@ export default class ChangelogDialog extends React.Component<IProps> {
} }
public render() { public render() {
const Spinner = sdk.getComponent('views.elements.Spinner');
const QuestionDialog = sdk.getComponent('dialogs.QuestionDialog');
const logs = REPOS.map(repo => { const logs = REPOS.map(repo => {
let content; let content;
if (this.state[repo] == null) { if (this.state[repo] == null) {

View file

@ -15,9 +15,12 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import ConfirmRedactDialog from './ConfirmRedactDialog';
import ErrorDialog from './ErrorDialog';
import BaseDialog from "./BaseDialog";
import Spinner from "../elements/Spinner";
interface IProps { interface IProps {
redact: () => Promise<void>; redact: () => Promise<void>;
@ -73,7 +76,6 @@ export default class ConfirmAndWaitRedactDialog extends React.PureComponent<IPro
public render() { public render() {
if (this.state.isRedacting) { if (this.state.isRedacting) {
if (this.state.redactionErrorCode) { if (this.state.redactionErrorCode) {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
const code = this.state.redactionErrorCode; const code = this.state.redactionErrorCode;
return ( return (
<ErrorDialog <ErrorDialog
@ -83,8 +85,6 @@ export default class ConfirmAndWaitRedactDialog extends React.PureComponent<IPro
/> />
); );
} else { } else {
const BaseDialog = sdk.getComponent("dialogs.BaseDialog");
const Spinner = sdk.getComponent('elements.Spinner');
return ( return (
<BaseDialog <BaseDialog
onFinished={this.props.onFinished} onFinished={this.props.onFinished}
@ -95,7 +95,6 @@ export default class ConfirmAndWaitRedactDialog extends React.PureComponent<IPro
); );
} }
} else { } else {
const ConfirmRedactDialog = sdk.getComponent("dialogs.ConfirmRedactDialog");
return <ConfirmRedactDialog onFinished={this.onParentFinished} />; return <ConfirmRedactDialog onFinished={this.onParentFinished} />;
} }
} }

View file

@ -15,9 +15,9 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import TextInputDialog from "./TextInputDialog";
interface IProps { interface IProps {
onFinished: (success: boolean) => void; onFinished: (success: boolean) => void;
@ -29,7 +29,6 @@ interface IProps {
@replaceableComponent("views.dialogs.ConfirmRedactDialog") @replaceableComponent("views.dialogs.ConfirmRedactDialog")
export default class ConfirmRedactDialog extends React.Component<IProps> { export default class ConfirmRedactDialog extends React.Component<IProps> {
render() { render() {
const TextInputDialog = sdk.getComponent('views.dialogs.TextInputDialog');
return ( return (
<TextInputDialog onFinished={this.props.onFinished} <TextInputDialog onFinished={this.props.onFinished}
title={_t("Confirm Removal")} title={_t("Confirm Removal")}

View file

@ -17,11 +17,14 @@ limitations under the License.
import React from 'react'; import React from 'react';
import { MatrixClient } from 'matrix-js-sdk/src/client'; import { MatrixClient } from 'matrix-js-sdk/src/client';
import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import { GroupMemberType } from '../../../groups'; import { GroupMemberType } from '../../../groups';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import { mediaFromMxc } from "../../../customisations/Media"; import { mediaFromMxc } from "../../../customisations/Media";
import MemberAvatar from '../avatars/MemberAvatar';
import BaseAvatar from '../avatars/BaseAvatar';
import BaseDialog from "./BaseDialog";
import DialogButtons from "../elements/DialogButtons";
interface IProps { interface IProps {
// matrix-js-sdk (room) member object. Supply either this or 'groupMember' // matrix-js-sdk (room) member object. Supply either this or 'groupMember'
@ -67,11 +70,6 @@ export default class ConfirmUserActionDialog extends React.Component<IProps> {
}; };
public render() { public render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
const MemberAvatar = sdk.getComponent("views.avatars.MemberAvatar");
const BaseAvatar = sdk.getComponent("views.avatars.BaseAvatar");
const confirmButtonClass = this.props.danger ? 'danger' : ''; const confirmButtonClass = this.props.danger ? 'danger' : '';
let reasonBox; let reasonBox;

View file

@ -16,8 +16,9 @@ limitations under the License.
import React from 'react'; import React from 'react';
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import * as sdk from "../../../index";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import BaseDialog from "./BaseDialog";
import DialogButtons from "../elements/DialogButtons";
interface IProps { interface IProps {
onFinished: (success: boolean) => void; onFinished: (success: boolean) => void;
@ -34,9 +35,6 @@ export default class ConfirmWipeDeviceDialog extends React.Component<IProps> {
}; };
render() { render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return ( return (
<BaseDialog <BaseDialog
className='mx_ConfirmWipeDeviceDialog' className='mx_ConfirmWipeDeviceDialog'

View file

@ -15,11 +15,12 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import dis from '../../../dispatcher/dispatcher'; import dis from '../../../dispatcher/dispatcher';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import { MatrixClientPeg } from '../../../MatrixClientPeg'; import { MatrixClientPeg } from '../../../MatrixClientPeg';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import BaseDialog from "./BaseDialog";
import Spinner from "../elements/Spinner";
interface IProps { interface IProps {
onFinished: (success: boolean) => void; onFinished: (success: boolean) => void;
@ -106,9 +107,6 @@ export default class CreateGroupDialog extends React.Component<IProps, IState> {
}; };
render() { render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const Spinner = sdk.getComponent('elements.Spinner');
if (this.state.creating) { if (this.state.creating) {
return <Spinner />; return <Spinner />;
} }

View file

@ -16,21 +16,22 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import dis from '../../../dispatcher/dispatcher'; import dis from '../../../dispatcher/dispatcher';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import SdkConfig from '../../../SdkConfig'; import SdkConfig from '../../../SdkConfig';
import Modal from '../../../Modal'; import Modal from '../../../Modal';
import BaseDialog from "./BaseDialog";
import DialogButtons from "../elements/DialogButtons";
import QuestionDialog from "./QuestionDialog";
interface IProps { interface IProps {
onFinished: (success: boolean) => void; onFinished: (success: boolean) => void;
} }
export default (props: IProps) => { const CryptoStoreTooNewDialog: React.FC<IProps> = (props: IProps) => {
const brand = SdkConfig.get().brand; const brand = SdkConfig.get().brand;
const _onLogoutClicked = () => { const _onLogoutClicked = () => {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
Modal.createTrackedDialog('Logout e2e db too new', '', QuestionDialog, { Modal.createTrackedDialog('Logout e2e db too new', '', QuestionDialog, {
title: _t("Sign out"), title: _t("Sign out"),
description: _t( description: _t(
@ -58,8 +59,6 @@ export default (props: IProps) => {
{ brand }, { brand },
); );
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return (<BaseDialog className="mx_CryptoStoreTooNewDialog" return (<BaseDialog className="mx_CryptoStoreTooNewDialog"
contentId='mx_Dialog_content' contentId='mx_Dialog_content'
title={_t("Incompatible Database")} title={_t("Incompatible Database")}
@ -79,3 +78,5 @@ export default (props: IProps) => {
</DialogButtons> </DialogButtons>
</BaseDialog>); </BaseDialog>);
}; };
export default CryptoStoreTooNewDialog;

View file

@ -17,7 +17,6 @@ limitations under the License.
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import Analytics from '../../../Analytics'; import Analytics from '../../../Analytics';
import { MatrixClientPeg } from '../../../MatrixClientPeg'; import { MatrixClientPeg } from '../../../MatrixClientPeg';
import * as Lifecycle from '../../../Lifecycle'; import * as Lifecycle from '../../../Lifecycle';
@ -26,6 +25,7 @@ import InteractiveAuth, { ERROR_USER_CANCELLED } from "../../structures/Interact
import { DEFAULT_PHASE, PasswordAuthEntry, SSOAuthEntry } from "../auth/InteractiveAuthEntryComponents"; import { DEFAULT_PHASE, PasswordAuthEntry, SSOAuthEntry } from "../auth/InteractiveAuthEntryComponents";
import StyledCheckbox from "../elements/StyledCheckbox"; import StyledCheckbox from "../elements/StyledCheckbox";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import BaseDialog from "./BaseDialog";
interface IProps { interface IProps {
onFinished: (success: boolean) => void; onFinished: (success: boolean) => void;
@ -165,8 +165,6 @@ export default class DeactivateAccountDialog extends React.Component<IProps, ISt
} }
public render() { public render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
let error = null; let error = null;
if (this.state.errStr) { if (this.state.errStr) {
error = <div className="error"> error = <div className="error">

View file

@ -16,7 +16,6 @@ limitations under the License.
*/ */
import React, { useState, useEffect, ChangeEvent, MouseEvent } from 'react'; import React, { useState, useEffect, ChangeEvent, MouseEvent } from 'react';
import * as sdk from '../../../index';
import SyntaxHighlight from '../elements/SyntaxHighlight'; import SyntaxHighlight from '../elements/SyntaxHighlight';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import Field from "../elements/Field"; import Field from "../elements/Field";
@ -42,6 +41,8 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
import { Room } from "matrix-js-sdk/src/models/room"; import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { SettingLevel } from '../../../settings/SettingLevel'; import { SettingLevel } from '../../../settings/SettingLevel';
import BaseDialog from "./BaseDialog";
import TruncatedList from "../elements/TruncatedList";
interface IGenericEditorProps { interface IGenericEditorProps {
onBack: () => void; onBack: () => void;
@ -369,7 +370,6 @@ class FilteredList extends React.PureComponent<IFilteredListProps, IFilteredList
}; };
render() { render() {
const TruncatedList = sdk.getComponent("elements.TruncatedList");
return <div> return <div>
<Field label={_t('Filter results')} autoFocus={true} size={64} <Field label={_t('Filter results')} autoFocus={true} size={64}
type="text" autoComplete="off" value={this.props.query} onChange={this.onQuery} type="text" autoComplete="off" value={this.props.query} onChange={this.onQuery}
@ -1261,7 +1261,6 @@ export default class DevtoolsDialog extends React.PureComponent<IProps, IState>
</React.Fragment>; </React.Fragment>;
} }
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
return ( return (
<BaseDialog className="mx_QuestionDialog" onFinished={this.props.onFinished} title={_t('Developer Tools')}> <BaseDialog className="mx_QuestionDialog" onFinished={this.props.onFinished} title={_t('Developer Tools')}>
{ body } { body }

View file

@ -26,9 +26,9 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import BaseDialog from "./BaseDialog";
interface IProps { interface IProps {
onFinished: (success: boolean) => void; onFinished: (success: boolean) => void;
@ -57,7 +57,6 @@ export default class ErrorDialog extends React.Component<IProps, IState> {
}; };
public render() { public render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
return ( return (
<BaseDialog <BaseDialog
className="mx_ErrorDialog" className="mx_ErrorDialog"

View file

@ -18,7 +18,6 @@ import React, { createRef } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { _t, _td } from "../../../languageHandler"; import { _t, _td } from "../../../languageHandler";
import * as sdk from "../../../index";
import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { MatrixClientPeg } from "../../../MatrixClientPeg";
import { makeRoomPermalink, makeUserPermalink } from "../../../utils/permalinks/Permalinks"; import { makeRoomPermalink, makeUserPermalink } from "../../../utils/permalinks/Permalinks";
import DMRoomMap from "../../../utils/DMRoomMap"; import DMRoomMap from "../../../utils/DMRoomMap";
@ -65,6 +64,9 @@ import { copyPlaintext, selectText } from "../../../utils/strings";
import * as ContextMenu from "../../structures/ContextMenu"; import * as ContextMenu from "../../structures/ContextMenu";
import { toRightOf } from "../../structures/ContextMenu"; import { toRightOf } from "../../structures/ContextMenu";
import GenericTextContextMenu from "../context_menus/GenericTextContextMenu"; import GenericTextContextMenu from "../context_menus/GenericTextContextMenu";
import QuestionDialog from "./QuestionDialog";
import Spinner from "../elements/Spinner";
import BaseDialog from "./BaseDialog";
// we have a number of types defined from the Matrix spec which can't reasonably be altered here. // we have a number of types defined from the Matrix spec which can't reasonably be altered here.
/* eslint-disable camelcase */ /* eslint-disable camelcase */
@ -1046,7 +1048,6 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
if (this.unmounted) return; if (this.unmounted) return;
if (failed.length > 0) { if (failed.length > 0) {
const QuestionDialog = sdk.getComponent('dialogs.QuestionDialog');
Modal.createTrackedDialog('Invite Paste Fail', '', QuestionDialog, { Modal.createTrackedDialog('Invite Paste Fail', '', QuestionDialog, {
title: _t('Failed to find the following users'), title: _t('Failed to find the following users'),
description: _t( description: _t(
@ -1158,7 +1159,6 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
const toRender = sourceMembers.slice(0, showNum); const toRender = sourceMembers.slice(0, showNum);
const hasMore = toRender.length < sourceMembers.length; const hasMore = toRender.length < sourceMembers.length;
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
let showMore = null; let showMore = null;
if (hasMore) { if (hasMore) {
showMore = ( showMore = (
@ -1269,10 +1269,6 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
}; };
render() { render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
const Spinner = sdk.getComponent("elements.Spinner");
let spinner = null; let spinner = null;
if (this.state.busy) { if (this.state.busy) {
spinner = <Spinner w={20} h={20} />; spinner = <Spinner w={20} h={20} />;

View file

@ -15,7 +15,6 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import { ensureDMExists } from "../../../createRoom"; import { ensureDMExists } from "../../../createRoom";
import { IDialogProps } from "./IDialogProps"; import { IDialogProps } from "./IDialogProps";
@ -26,6 +25,10 @@ import Markdown from '../../../Markdown';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import StyledRadioButton from "../elements/StyledRadioButton"; import StyledRadioButton from "../elements/StyledRadioButton";
import BaseDialog from "./BaseDialog";
import DialogButtons from "../elements/DialogButtons";
import Field from "../elements/Field";
import Spinner from "../elements/Spinner";
interface IProps extends IDialogProps { interface IProps extends IDialogProps {
mxEvent: MatrixEvent; mxEvent: MatrixEvent;
@ -239,11 +242,6 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
}; };
render() { render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
const Loader = sdk.getComponent('elements.Spinner');
const Field = sdk.getComponent('elements.Field');
let error = null; let error = null;
if (this.state.err) { if (this.state.err) {
error = <div className="error"> error = <div className="error">
@ -255,7 +253,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
if (this.state.busy) { if (this.state.busy) {
progress = ( progress = (
<div className="progress"> <div className="progress">
<Loader /> <Spinner />
</div> </div>
); );
} }

View file

@ -24,12 +24,12 @@ import GeneralRoomSettingsTab from "../settings/tabs/room/GeneralRoomSettingsTab
import SecurityRoomSettingsTab from "../settings/tabs/room/SecurityRoomSettingsTab"; import SecurityRoomSettingsTab from "../settings/tabs/room/SecurityRoomSettingsTab";
import NotificationSettingsTab from "../settings/tabs/room/NotificationSettingsTab"; import NotificationSettingsTab from "../settings/tabs/room/NotificationSettingsTab";
import BridgeSettingsTab from "../settings/tabs/room/BridgeSettingsTab"; import BridgeSettingsTab from "../settings/tabs/room/BridgeSettingsTab";
import * as sdk from "../../../index";
import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { MatrixClientPeg } from "../../../MatrixClientPeg";
import dis from "../../../dispatcher/dispatcher"; import dis from "../../../dispatcher/dispatcher";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import { UIFeature } from "../../../settings/UIFeature"; import { UIFeature } from "../../../settings/UIFeature";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import BaseDialog from "./BaseDialog";
export const ROOM_GENERAL_TAB = "ROOM_GENERAL_TAB"; export const ROOM_GENERAL_TAB = "ROOM_GENERAL_TAB";
export const ROOM_SECURITY_TAB = "ROOM_SECURITY_TAB"; export const ROOM_SECURITY_TAB = "ROOM_SECURITY_TAB";
@ -119,8 +119,6 @@ export default class RoomSettingsDialog extends React.Component<IProps> {
} }
render() { render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const roomName = MatrixClientPeg.get().getRoom(this.props.roomId).name; const roomName = MatrixClientPeg.get().getRoom(this.props.roomId).name;
return ( return (
<BaseDialog <BaseDialog

View file

@ -22,7 +22,6 @@ import { User } from "matrix-js-sdk/src/models/user";
import { Group } from "matrix-js-sdk/src/models/group"; import { Group } from "matrix-js-sdk/src/models/group";
import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import QRCode from "../elements/QRCode"; import QRCode from "../elements/QRCode";
import { RoomPermalinkCreator, makeGroupPermalink, makeUserPermalink } from "../../../utils/permalinks/Permalinks"; import { RoomPermalinkCreator, makeGroupPermalink, makeUserPermalink } from "../../../utils/permalinks/Permalinks";
@ -35,6 +34,8 @@ import { IDialogProps } from "./IDialogProps";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import { UIFeature } from "../../../settings/UIFeature"; import { UIFeature } from "../../../settings/UIFeature";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import BaseDialog from "./BaseDialog";
import GenericTextContextMenu from "../context_menus/GenericTextContextMenu.js";
const socials = [ const socials = [
{ {
@ -119,7 +120,6 @@ export default class ShareDialog extends React.PureComponent<IProps, IState> {
const successful = await copyPlaintext(this.getUrl()); const successful = await copyPlaintext(this.getUrl());
const buttonRect = target.getBoundingClientRect(); const buttonRect = target.getBoundingClientRect();
const GenericTextContextMenu = sdk.getComponent('context_menus.GenericTextContextMenu');
const { close } = ContextMenu.createMenu(GenericTextContextMenu, { const { close } = ContextMenu.createMenu(GenericTextContextMenu, {
...toRightOf(buttonRect, 2), ...toRightOf(buttonRect, 2),
message: successful ? _t('Copied!') : _t('Failed to copy'), message: successful ? _t('Copied!') : _t('Failed to copy'),
@ -230,7 +230,6 @@ export default class ShareDialog extends React.PureComponent<IProps, IState> {
</>; </>;
} }
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
return <BaseDialog return <BaseDialog
title={title} title={title}
className='mx_ShareDialog' className='mx_ShareDialog'

View file

@ -16,11 +16,12 @@ limitations under the License.
import url from 'url'; import url from 'url';
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import { _t, pickBestLanguage } from '../../../languageHandler'; import { _t, pickBestLanguage } from '../../../languageHandler';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import { SERVICE_TYPES } from "matrix-js-sdk/src/service-types"; import { SERVICE_TYPES } from "matrix-js-sdk/src/service-types";
import DialogButtons from "../elements/DialogButtons";
import BaseDialog from "./BaseDialog";
interface ITermsCheckboxProps { interface ITermsCheckboxProps {
onChange: (url: string, checked: boolean) => void; onChange: (url: string, checked: boolean) => void;
@ -117,9 +118,6 @@ export default class TermsDialog extends React.PureComponent<ITermsDialogProps,
}; };
public render() { public render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
const rows = []; const rows = [];
for (const policiesAndService of this.props.policiesAndServicePairs) { for (const policiesAndService of this.props.policiesAndServicePairs) {
const parsedBaseUrl = url.parse(policiesAndService.service.baseUrl); const parsedBaseUrl = url.parse(policiesAndService.service.baseUrl);

View file

@ -16,11 +16,12 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import filesize from "filesize"; import filesize from "filesize";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import { getBlobSafeMimeType } from '../../../utils/blobs'; import { getBlobSafeMimeType } from '../../../utils/blobs';
import BaseDialog from "./BaseDialog";
import DialogButtons from "../elements/DialogButtons";
interface IProps { interface IProps {
file: File; file: File;
@ -67,9 +68,6 @@ export default class UploadConfirmDialog extends React.Component<IProps> {
}; };
render() { render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
let title; let title;
if (this.props.totalFiles > 1 && this.props.currentIndex !== undefined) { if (this.props.totalFiles > 1 && this.props.currentIndex !== undefined) {
title = _t( title = _t(

View file

@ -28,11 +28,11 @@ import PreferencesUserSettingsTab from "../settings/tabs/user/PreferencesUserSet
import VoiceUserSettingsTab from "../settings/tabs/user/VoiceUserSettingsTab"; import VoiceUserSettingsTab from "../settings/tabs/user/VoiceUserSettingsTab";
import HelpUserSettingsTab from "../settings/tabs/user/HelpUserSettingsTab"; import HelpUserSettingsTab from "../settings/tabs/user/HelpUserSettingsTab";
import FlairUserSettingsTab from "../settings/tabs/user/FlairUserSettingsTab"; import FlairUserSettingsTab from "../settings/tabs/user/FlairUserSettingsTab";
import * as sdk from "../../../index";
import SdkConfig from "../../../SdkConfig"; import SdkConfig from "../../../SdkConfig";
import MjolnirUserSettingsTab from "../settings/tabs/user/MjolnirUserSettingsTab"; import MjolnirUserSettingsTab from "../settings/tabs/user/MjolnirUserSettingsTab";
import { UIFeature } from "../../../settings/UIFeature"; import { UIFeature } from "../../../settings/UIFeature";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import BaseDialog from "./BaseDialog";
export enum UserTab { export enum UserTab {
General = "USER_GENERAL_TAB", General = "USER_GENERAL_TAB",
@ -162,8 +162,6 @@ export default class UserSettingsDialog extends React.Component<IProps, IState>
} }
render() { render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
return ( return (
<BaseDialog <BaseDialog
className='mx_UserSettingsDialog' className='mx_UserSettingsDialog'

View file

@ -17,7 +17,7 @@ limitations under the License.
import { debounce } from "lodash"; import { debounce } from "lodash";
import classNames from 'classnames'; import classNames from 'classnames';
import React, { ChangeEvent, FormEvent } from 'react'; import React, { ChangeEvent, FormEvent } from 'react';
import { ISecretStorageKeyInfo } from "matrix-js-sdk/src"; import { ISecretStorageKeyInfo } from "matrix-js-sdk/src/crypto/api";
import * as sdk from '../../../../index'; import * as sdk from '../../../../index';
import { MatrixClientPeg } from '../../../../MatrixClientPeg'; import { MatrixClientPeg } from '../../../../MatrixClientPeg';

View file

@ -16,8 +16,9 @@ limitations under the License.
import React from 'react'; import React from 'react';
import { _t } from "../../../../languageHandler"; import { _t } from "../../../../languageHandler";
import * as sdk from "../../../../index";
import { replaceableComponent } from "../../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../../utils/replaceableComponent";
import BaseDialog from "../BaseDialog";
import DialogButtons from "../../elements/DialogButtons";
interface IProps { interface IProps {
onFinished: (success: boolean) => void; onFinished: (success: boolean) => void;
@ -34,9 +35,6 @@ export default class ConfirmDestroyCrossSigningDialog extends React.Component<IP
}; };
render() { render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return ( return (
<BaseDialog <BaseDialog
className='mx_ConfirmDestroyCrossSigningDialog' className='mx_ConfirmDestroyCrossSigningDialog'

View file

@ -1,56 +0,0 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import { decode } from "blurhash";
interface IProps {
blurhash: string;
width: number;
height: number;
}
export default class BlurhashPlaceholder extends React.PureComponent<IProps> {
private canvas: React.RefObject<HTMLCanvasElement> = React.createRef();
public componentDidMount() {
this.draw();
}
public componentDidUpdate() {
this.draw();
}
private draw() {
if (!this.canvas.current) return;
try {
const { width, height } = this.props;
const pixels = decode(this.props.blurhash, Math.ceil(width), Math.ceil(height));
const ctx = this.canvas.current.getContext("2d");
const imgData = ctx.createImageData(width, height);
imgData.data.set(pixels);
ctx.putImageData(imgData, 0, 0);
} catch (e) {
console.error("Error rendering blurhash: ", e);
}
}
public render() {
return <canvas height={this.props.height} width={this.props.width} ref={this.canvas} />;
}
}

View file

@ -260,6 +260,7 @@ export default class Field extends React.PureComponent<PropShapes, IState> {
}); });
// Handle displaying feedback on validity // Handle displaying feedback on validity
// FIXME: Using an import will result in test failures
const Tooltip = sdk.getComponent("elements.Tooltip"); const Tooltip = sdk.getComponent("elements.Tooltip");
let fieldTooltip; let fieldTooltip;
if (tooltipContent || this.state.feedback) { if (tooltipContent || this.state.feedback) {

View file

@ -24,7 +24,7 @@ import FocusLock from "react-focus-lock";
import MemberAvatar from "../avatars/MemberAvatar"; import MemberAvatar from "../avatars/MemberAvatar";
import { ContextMenuTooltipButton } from "../../../accessibility/context_menu/ContextMenuTooltipButton"; import { ContextMenuTooltipButton } from "../../../accessibility/context_menu/ContextMenuTooltipButton";
import MessageContextMenu from "../context_menus/MessageContextMenu"; import MessageContextMenu from "../context_menus/MessageContextMenu";
import { aboveLeftOf, ContextMenu } from '../../structures/ContextMenu'; import { aboveLeftOf } from '../../structures/ContextMenu';
import MessageTimestamp from "../messages/MessageTimestamp"; import MessageTimestamp from "../messages/MessageTimestamp";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import { formatFullDate } from "../../../DateUtils"; import { formatFullDate } from "../../../DateUtils";
@ -122,7 +122,7 @@ export default class ImageView extends React.Component<IProps, IState> {
const image = this.image.current; const image = this.image.current;
const imageWrapper = this.imageWrapper.current; const imageWrapper = this.imageWrapper.current;
const rotation = inputRotation || this.state.rotation; const rotation = inputRotation ?? this.state.rotation;
const imageIsNotFlipped = rotation % 180 === 0; const imageIsNotFlipped = rotation % 180 === 0;
@ -304,17 +304,13 @@ export default class ImageView extends React.Component<IProps, IState> {
let contextMenu = null; let contextMenu = null;
if (this.state.contextMenuDisplayed) { if (this.state.contextMenuDisplayed) {
contextMenu = ( contextMenu = (
<ContextMenu <MessageContextMenu
{...aboveLeftOf(this.contextMenuButton.current.getBoundingClientRect())} {...aboveLeftOf(this.contextMenuButton.current.getBoundingClientRect())}
mxEvent={this.props.mxEvent}
permalinkCreator={this.props.permalinkCreator}
onFinished={this.onCloseContextMenu} onFinished={this.onCloseContextMenu}
> onCloseDialog={this.props.onFinished}
<MessageContextMenu />
mxEvent={this.props.mxEvent}
permalinkCreator={this.props.permalinkCreator}
onFinished={this.onCloseContextMenu}
onCloseDialog={this.props.onFinished}
/>
</ContextMenu>
); );
} }

View file

@ -17,11 +17,11 @@ limitations under the License.
import React from 'react'; import React from 'react';
import Dropdown from "../../views/elements/Dropdown"; import Dropdown from "../../views/elements/Dropdown";
import * as sdk from '../../../index';
import PlatformPeg from "../../../PlatformPeg"; import PlatformPeg from "../../../PlatformPeg";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import Spinner from "./Spinner";
function languageMatchesSearchQuery(query, language) { function languageMatchesSearchQuery(query, language) {
if (language.label.toUpperCase().includes(query.toUpperCase())) return true; if (language.label.toUpperCase().includes(query.toUpperCase())) return true;
@ -84,7 +84,6 @@ export default class SpellCheckLanguagesDropdown extends React.Component<SpellCh
render() { render() {
if (this.state.languages === null) { if (this.state.languages === null) {
const Spinner = sdk.getComponent('elements.Spinner');
return <Spinner />; return <Spinner />;
} }

View file

@ -17,7 +17,7 @@ limitations under the License.
import React from "react"; import React from "react";
import classNames from "classnames"; import classNames from "classnames";
import * as sdk from "../../../index"; import AccessibleButton from "./AccessibleButton";
interface IProps { interface IProps {
// Whether or not this toggle is in the 'on' position. // Whether or not this toggle is in the 'on' position.
@ -43,7 +43,6 @@ export default ({ checked, disabled = false, onChange, ...props }: IProps) => {
"mx_ToggleSwitch_enabled": !disabled, "mx_ToggleSwitch_enabled": !disabled,
}); });
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
return ( return (
<AccessibleButton {...props} <AccessibleButton {...props}
className={classes} className={classes}

View file

@ -16,11 +16,11 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import Tooltip from './Tooltip';
interface IProps { interface IProps {
helpText: string; helpText: React.ReactNode | string;
} }
interface IState { interface IState {
@ -49,7 +49,6 @@ export default class TooltipButton extends React.Component<IProps, IState> {
}; };
render() { render() {
const Tooltip = sdk.getComponent("elements.Tooltip");
const tip = this.state.hover ? <Tooltip const tip = this.state.hover ? <Tooltip
className="mx_TooltipButton_container" className="mx_TooltipButton_container"
tooltipClassName="mx_TooltipButton_helpText" tooltipClassName="mx_TooltipButton_helpText"

View file

@ -33,7 +33,7 @@ export const EMOJI_HEIGHT = 37;
export const EMOJIS_PER_ROW = 8; export const EMOJIS_PER_ROW = 8;
interface IProps { interface IProps {
selectedEmojis: Set<string>; selectedEmojis?: Set<string>;
showQuickReactions?: boolean; showQuickReactions?: boolean;
onChoose(unicode: string): boolean; onChoose(unicode: string): boolean;
} }

View file

@ -18,6 +18,7 @@ limitations under the License.
import React, { createRef } from 'react'; import React, { createRef } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Blurhash } from "react-blurhash";
import MFileBody from './MFileBody'; import MFileBody from './MFileBody';
import Modal from '../../../Modal'; import Modal from '../../../Modal';
@ -29,7 +30,6 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext";
import InlineSpinner from '../elements/InlineSpinner'; import InlineSpinner from '../elements/InlineSpinner';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import { mediaFromContent } from "../../../customisations/Media"; import { mediaFromContent } from "../../../customisations/Media";
import BlurhashPlaceholder from "../elements/BlurhashPlaceholder";
import { BLURHASH_FIELD } from "../../../ContentMessages"; import { BLURHASH_FIELD } from "../../../ContentMessages";
@replaceableComponent("views.messages.MImageBody") @replaceableComponent("views.messages.MImageBody")
@ -436,7 +436,7 @@ export default class MImageBody extends React.Component {
// Overidden by MStickerBody // Overidden by MStickerBody
getPlaceholder(width, height) { getPlaceholder(width, height) {
const blurhash = this.props.mxEvent.getContent().info[BLURHASH_FIELD]; const blurhash = this.props.mxEvent.getContent().info[BLURHASH_FIELD];
if (blurhash) return <BlurhashPlaceholder blurhash={blurhash} width={width} height={height} />; if (blurhash) return <Blurhash hash={blurhash} width={width} height={height} />;
return <div className="mx_MImageBody_thumbnail_spinner"> return <div className="mx_MImageBody_thumbnail_spinner">
<InlineSpinner w={32} h={32} /> <InlineSpinner w={32} h={32} />
</div>; </div>;

View file

@ -17,7 +17,6 @@ limitations under the License.
import React from 'react'; import React from 'react';
import { MatrixEvent } from 'matrix-js-sdk/src'; import { MatrixEvent } from 'matrix-js-sdk/src';
import { MatrixClientPeg } from '../../../MatrixClientPeg'; import { MatrixClientPeg } from '../../../MatrixClientPeg';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import { getNameForEventRoom, userLabelForEventRoom } import { getNameForEventRoom, userLabelForEventRoom }
from '../../../utils/KeyVerificationStateObserver'; from '../../../utils/KeyVerificationStateObserver';
@ -26,6 +25,7 @@ import { RightPanelPhases } from "../../../stores/RightPanelStorePhases";
import { Action } from "../../../dispatcher/actions"; import { Action } from "../../../dispatcher/actions";
import EventTileBubble from "./EventTileBubble"; import EventTileBubble from "./EventTileBubble";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import AccessibleButton from '../elements/AccessibleButton';
interface IProps { interface IProps {
mxEvent: MatrixEvent; mxEvent: MatrixEvent;
@ -115,8 +115,6 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
} }
public render() { public render() {
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
const { mxEvent } = this.props; const { mxEvent } = this.props;
const request = mxEvent.verificationRequest; const request = mxEvent.verificationRequest;

View file

@ -24,7 +24,7 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
interface IProps { interface IProps {
mxEvent: MatrixEvent; mxEvent: MatrixEvent;
onClick(): void; onClick?(): void;
enableFlair: boolean; enableFlair: boolean;
} }

View file

@ -16,13 +16,13 @@ limitations under the License.
import React from "react"; import React from "react";
import * as sdk from "../../../index";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { User } from "matrix-js-sdk/src/models/user"; import { User } from "matrix-js-sdk/src/models/user";
import AccessibleButton from "../elements/AccessibleButton";
import Spinner from "../elements/Spinner";
export const PendingActionSpinner = ({ text }) => { export const PendingActionSpinner = ({ text }) => {
const Spinner = sdk.getComponent('elements.Spinner');
return <div className="mx_EncryptionInfo_spinner"> return <div className="mx_EncryptionInfo_spinner">
<Spinner /> <Spinner />
{ text } { text }
@ -64,7 +64,6 @@ const EncryptionInfo: React.FC<IProps> = ({
} }
content = <PendingActionSpinner text={text} />; content = <PendingActionSpinner text={text} />;
} else { } else {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
content = ( content = (
<AccessibleButton kind="primary" className="mx_UserInfo_wideButton" onClick={onStartVerification}> <AccessibleButton kind="primary" className="mx_UserInfo_wideButton" onClick={onStartVerification}>
{_t("Start Verification")} {_t("Start Verification")}

View file

@ -81,6 +81,7 @@ const EncryptionPanel: React.FC<IProps> = (props: IProps) => {
const changeHandler = useCallback(() => { const changeHandler = useCallback(() => {
// handle transitions -> cancelled for mismatches which fire a modal instead of showing a card // handle transitions -> cancelled for mismatches which fire a modal instead of showing a card
if (request && request.cancelled && MISMATCHES.includes(request.cancellationCode)) { if (request && request.cancelled && MISMATCHES.includes(request.cancellationCode)) {
// FIXME: Using an import will result in test failures
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog("Verification failed", "insecure", ErrorDialog, { Modal.createTrackedDialog("Verification failed", "insecure", ErrorDialog, {
headerImage: require("../../../../res/img/e2e/warning.svg"), headerImage: require("../../../../res/img/e2e/warning.svg"),

View file

@ -17,7 +17,6 @@ limitations under the License.
import React from "react"; import React from "react";
import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { MatrixClientPeg } from "../../../MatrixClientPeg";
import * as sdk from '../../../index';
import { verificationMethods } from 'matrix-js-sdk/src/crypto'; import { verificationMethods } from 'matrix-js-sdk/src/crypto';
import { SCAN_QR_CODE_METHOD } from "matrix-js-sdk/src/crypto/verification/QRCode"; import { SCAN_QR_CODE_METHOD } from "matrix-js-sdk/src/crypto/verification/QRCode";
import { VerificationRequest } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; import { VerificationRequest } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
@ -38,6 +37,8 @@ import {
} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
import Spinner from "../elements/Spinner"; import Spinner from "../elements/Spinner";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import AccessibleButton from "../elements/AccessibleButton";
import VerificationShowSas from "../verification/VerificationShowSas";
// XXX: Should be defined in matrix-js-sdk // XXX: Should be defined in matrix-js-sdk
enum VerificationPhase { enum VerificationPhase {
@ -81,7 +82,6 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
const { member, request } = this.props; const { member, request } = this.props;
const showSAS: boolean = request.otherPartySupportsMethod(verificationMethods.SAS); const showSAS: boolean = request.otherPartySupportsMethod(verificationMethods.SAS);
const showQR: boolean = request.otherPartySupportsMethod(SCAN_QR_CODE_METHOD); const showQR: boolean = request.otherPartySupportsMethod(SCAN_QR_CODE_METHOD);
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const brand = SdkConfig.get().brand; const brand = SdkConfig.get().brand;
const noCommonMethodError: JSX.Element = !showSAS && !showQR ? const noCommonMethodError: JSX.Element = !showSAS && !showQR ?
@ -195,7 +195,6 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
private renderQRReciprocatePhase() { private renderQRReciprocatePhase() {
const { member, request } = this.props; const { member, request } = this.props;
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
const description = request.isSelfVerification ? const description = request.isSelfVerification ?
_t("Almost there! Is your other session showing the same shield?") : _t("Almost there! Is your other session showing the same shield?") :
_t("Almost there! Is %(displayName)s showing the same shield?", { _t("Almost there! Is %(displayName)s showing the same shield?", {
@ -265,7 +264,6 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
}); });
} }
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
return ( return (
<div className="mx_UserInfo_container mx_VerificationPanel_verified_section"> <div className="mx_UserInfo_container mx_VerificationPanel_verified_section">
<h3>{_t("Verified")}</h3> <h3>{_t("Verified")}</h3>
@ -282,8 +280,6 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
private renderCancelledPhase() { private renderCancelledPhase() {
const { member, request } = this.props; const { member, request } = this.props;
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
let startAgainInstruction: string; let startAgainInstruction: string;
if (request.isSelfVerification) { if (request.isSelfVerification) {
startAgainInstruction = _t("Start verification again from the notification."); startAgainInstruction = _t("Start verification again from the notification.");
@ -332,7 +328,6 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
case verificationMethods.RECIPROCATE_QR_CODE: case verificationMethods.RECIPROCATE_QR_CODE:
return this.renderQRReciprocatePhase(); return this.renderQRReciprocatePhase();
case verificationMethods.SAS: { case verificationMethods.SAS: {
const VerificationShowSas = sdk.getComponent('views.verification.VerificationShowSas');
const emojis = this.state.sasEvent ? const emojis = this.state.sasEvent ?
<VerificationShowSas <VerificationShowSas
displayName={displayName} displayName={displayName}

View file

@ -711,6 +711,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
} }
public insertMention(userId: string): void { public insertMention(userId: string): void {
this.modifiedFlag = true;
const { model } = this.props; const { model } = this.props;
const { partCreator } = model; const { partCreator } = model;
const member = this.props.room.getMember(userId); const member = this.props.room.getMember(userId);
@ -729,6 +730,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
} }
public insertQuotedMessage(event: MatrixEvent): void { public insertQuotedMessage(event: MatrixEvent): void {
this.modifiedFlag = true;
const { model } = this.props; const { model } = this.props;
const { partCreator } = model; const { partCreator } = model;
const quoteParts = parseEvent(event, partCreator, { isQuotedMessage: true }); const quoteParts = parseEvent(event, partCreator, { isQuotedMessage: true });
@ -744,6 +746,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
} }
public insertPlaintext(text: string): void { public insertPlaintext(text: string): void {
this.modifiedFlag = true;
const { model } = this.props; const { model } = this.props;
const { partCreator } = model; const { partCreator } = model;
const caret = this.getCaret(); const caret = this.getCaret();

View file

@ -131,11 +131,12 @@ export default class EditMessageComposer extends React.Component<IProps, IState>
super(props); super(props);
this.context = context; // otherwise React will only set it prior to render due to type def above this.context = context; // otherwise React will only set it prior to render due to type def above
const isRestored = this.createEditorModel();
const ev = this.props.editState.getEvent();
this.state = { this.state = {
saveDisabled: true, saveDisabled: !isRestored || !this.isContentModified(createEditContent(this.model, ev)["m.new_content"]),
}; };
this.createEditorModel();
window.addEventListener("beforeunload", this.saveStoredEditorState); window.addEventListener("beforeunload", this.saveStoredEditorState);
this.dispatcherRef = dis.register(this.onAction); this.dispatcherRef = dis.register(this.onAction);
} }
@ -230,12 +231,12 @@ export default class EditMessageComposer extends React.Component<IProps, IState>
} }
} }
private saveStoredEditorState(): void { private saveStoredEditorState = (): void => {
const item = SendHistoryManager.createItem(this.model); const item = SendHistoryManager.createItem(this.model);
this.clearPreviousEdit(); this.clearPreviousEdit();
localStorage.setItem(this.editorRoomKey, this.props.editState.getEvent().getId()); localStorage.setItem(this.editorRoomKey, this.props.editState.getEvent().getId());
localStorage.setItem(this.editorStateKey, JSON.stringify(item)); localStorage.setItem(this.editorStateKey, JSON.stringify(item));
} };
private isSlashCommand(): boolean { private isSlashCommand(): boolean {
const parts = this.model.parts; const parts = this.model.parts;
@ -256,10 +257,9 @@ export default class EditMessageComposer extends React.Component<IProps, IState>
private isContentModified(newContent: IContent): boolean { private isContentModified(newContent: IContent): boolean {
// if nothing has changed then bail // if nothing has changed then bail
const oldContent = this.props.editState.getEvent().getContent(); const oldContent = this.props.editState.getEvent().getContent();
if (!this.editorRef.current?.isModified() || if (oldContent["msgtype"] === newContent["msgtype"] && oldContent["body"] === newContent["body"] &&
(oldContent["msgtype"] === newContent["msgtype"] && oldContent["body"] === newContent["body"] &&
oldContent["format"] === newContent["format"] && oldContent["format"] === newContent["format"] &&
oldContent["formatted_body"] === newContent["formatted_body"])) { oldContent["formatted_body"] === newContent["formatted_body"]) {
return false; return false;
} }
return true; return true;
@ -410,36 +410,27 @@ export default class EditMessageComposer extends React.Component<IProps, IState>
dis.unregister(this.dispatcherRef); dis.unregister(this.dispatcherRef);
} }
private createEditorModel(): void { private createEditorModel(): boolean {
const { editState } = this.props; const { editState } = this.props;
const room = this.getRoom(); const room = this.getRoom();
const partCreator = new CommandPartCreator(room, this.context); const partCreator = new CommandPartCreator(room, this.context);
let parts; let parts;
let isRestored = false;
if (editState.hasEditorState()) { if (editState.hasEditorState()) {
// if restoring state from a previous editor, // if restoring state from a previous editor,
// restore serialized parts from the state // restore serialized parts from the state
parts = editState.getSerializedParts().map(p => partCreator.deserializePart(p)); parts = editState.getSerializedParts().map(p => partCreator.deserializePart(p));
} else { } else {
//otherwise, either restore serialized parts from localStorage or parse the body of the event // otherwise, either restore serialized parts from localStorage or parse the body of the event
parts = this.restoreStoredEditorState(partCreator) || parseEvent(editState.getEvent(), partCreator); const restoredParts = this.restoreStoredEditorState(partCreator);
parts = restoredParts || parseEvent(editState.getEvent(), partCreator);
isRestored = !!restoredParts;
} }
this.model = new EditorModel(parts, partCreator); this.model = new EditorModel(parts, partCreator);
this.saveStoredEditorState(); this.saveStoredEditorState();
}
private getInitialCaretPosition(): CaretPosition { return isRestored;
const { editState } = this.props;
let caretPosition;
if (editState.hasEditorState() && editState.getCaret()) {
// if restoring state from a previous editor,
// restore caret position from the state
const caret = editState.getCaret();
caretPosition = this.model.positionForOffset(caret.offset, caret.atNodeEnd);
} else {
// otherwise, set it at the end
caretPosition = this.model.getPositionAtEnd();
}
return caretPosition;
} }
private onChange = (): void => { private onChange = (): void => {

View file

@ -48,6 +48,13 @@ import NotificationBadge from "./NotificationBadge";
import CallEventGrouper from "../../structures/CallEventGrouper"; import CallEventGrouper from "../../structures/CallEventGrouper";
import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInsertPayload"; import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInsertPayload";
import { Action } from '../../../dispatcher/actions'; import { Action } from '../../../dispatcher/actions';
import MemberAvatar from '../avatars/MemberAvatar';
import SenderProfile from '../messages/SenderProfile';
import MessageTimestamp from '../messages/MessageTimestamp';
import TooltipButton from '../elements/TooltipButton';
import ReadReceiptMarker from "./ReadReceiptMarker";
import MessageActionBar from "../messages/MessageActionBar";
import ReactionsRow from '../messages/ReactionsRow';
const eventTileTypes = { const eventTileTypes = {
[EventType.RoomMessage]: 'messages.MessageEvent', [EventType.RoomMessage]: 'messages.MessageEvent',
@ -667,7 +674,6 @@ export default class EventTile extends React.Component<IProps, IState> {
); );
} }
const ReadReceiptMarker = sdk.getComponent('rooms.ReadReceiptMarker');
const avatars = []; const avatars = [];
const receiptOffset = 15; const receiptOffset = 15;
let left = 0; let left = 0;
@ -734,7 +740,7 @@ export default class EventTile extends React.Component<IProps, IState> {
); );
} }
onSenderProfileClick = event => { onSenderProfileClick = () => {
const mxEvent = this.props.mxEvent; const mxEvent = this.props.mxEvent;
dis.dispatch<ComposerInsertPayload>({ dis.dispatch<ComposerInsertPayload>({
action: Action.ComposerInsert, action: Action.ComposerInsert,
@ -842,10 +848,6 @@ export default class EventTile extends React.Component<IProps, IState> {
}; };
render() { render() {
const MessageTimestamp = sdk.getComponent('messages.MessageTimestamp');
const SenderProfile = sdk.getComponent('messages.SenderProfile');
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
//console.info("EventTile showUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview); //console.info("EventTile showUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview);
const content = this.props.mxEvent.getContent(); const content = this.props.mxEvent.getContent();
@ -989,7 +991,6 @@ export default class EventTile extends React.Component<IProps, IState> {
} }
} }
const MessageActionBar = sdk.getComponent('messages.MessageActionBar');
const actionBar = !isEditing ? <MessageActionBar const actionBar = !isEditing ? <MessageActionBar
mxEvent={this.props.mxEvent} mxEvent={this.props.mxEvent}
reactions={this.state.reactions} reactions={this.state.reactions}
@ -1029,7 +1030,6 @@ export default class EventTile extends React.Component<IProps, IState> {
{ 'requestLink': (sub) => <a onClick={this.onRequestKeysClick}>{ sub }</a> }, { 'requestLink': (sub) => <a onClick={this.onRequestKeysClick}>{ sub }</a> },
); );
const TooltipButton = sdk.getComponent('elements.TooltipButton');
const keyRequestInfo = isEncryptionFailure && !isRedacted ? const keyRequestInfo = isEncryptionFailure && !isRedacted ?
<div className="mx_EventTile_keyRequestInfo"> <div className="mx_EventTile_keyRequestInfo">
<span className="mx_EventTile_keyRequestInfo_text"> <span className="mx_EventTile_keyRequestInfo_text">
@ -1040,7 +1040,6 @@ export default class EventTile extends React.Component<IProps, IState> {
let reactionsRow; let reactionsRow;
if (!isRedacted) { if (!isRedacted) {
const ReactionsRow = sdk.getComponent('messages.ReactionsRow');
reactionsRow = <ReactionsRow reactionsRow = <ReactionsRow
mxEvent={this.props.mxEvent} mxEvent={this.props.mxEvent}
reactions={this.state.reactions} reactions={this.state.reactions}

View file

@ -17,7 +17,6 @@ import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import { MatrixClientPeg } from '../../../MatrixClientPeg'; import { MatrixClientPeg } from '../../../MatrixClientPeg';
import * as sdk from '../../../index';
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { Room } from "matrix-js-sdk/src/models/room"; import { Room } from "matrix-js-sdk/src/models/room";
import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { RoomMember } from "matrix-js-sdk/src/models/room-member";
@ -44,13 +43,14 @@ import SendMessageComposer from "./SendMessageComposer";
import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInsertPayload"; import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInsertPayload";
import { Action } from "../../../dispatcher/actions"; import { Action } from "../../../dispatcher/actions";
import EditorModel from "../../../editor/model"; import EditorModel from "../../../editor/model";
import EmojiPicker from '../emojipicker/EmojiPicker';
import MemberStatusMessageAvatar from "../avatars/MemberStatusMessageAvatar";
interface IComposerAvatarProps { interface IComposerAvatarProps {
me: object; me: object;
} }
function ComposerAvatar(props: IComposerAvatarProps) { function ComposerAvatar(props: IComposerAvatarProps) {
const MemberStatusMessageAvatar = sdk.getComponent('avatars.MemberStatusMessageAvatar');
return <div className="mx_MessageComposer_avatar"> return <div className="mx_MessageComposer_avatar">
<MemberStatusMessageAvatar member={props.me} width={24} height={24} /> <MemberStatusMessageAvatar member={props.me} width={24} height={24} />
</div>; </div>;
@ -76,7 +76,6 @@ const EmojiButton = ({ addEmoji }) => {
let contextMenu; let contextMenu;
if (menuDisplayed) { if (menuDisplayed) {
const buttonRect = button.current.getBoundingClientRect(); const buttonRect = button.current.getBoundingClientRect();
const EmojiPicker = sdk.getComponent('emojipicker.EmojiPicker');
contextMenu = <ContextMenu {...aboveLeftOf(buttonRect)} onFinished={closeMenu} managed={false}> contextMenu = <ContextMenu {...aboveLeftOf(buttonRect)} onFinished={closeMenu} managed={false}>
<EmojiPicker onChoose={addEmoji} showQuickReactions={true} /> <EmojiPicker onChoose={addEmoji} showQuickReactions={true} />
</ContextMenu>; </ContextMenu>;
@ -366,15 +365,12 @@ export default class MessageComposer extends React.Component<IProps, IState> {
]; ];
if (!this.state.tombstone && this.state.canSendMessages) { if (!this.state.tombstone && this.state.canSendMessages) {
const SendMessageComposer = sdk.getComponent("rooms.SendMessageComposer");
controls.push( controls.push(
<SendMessageComposer <SendMessageComposer
ref={(c) => this.messageComposerInput = c} ref={(c) => this.messageComposerInput = c}
key="controls_input" key="controls_input"
room={this.props.room} room={this.props.room}
placeholder={this.renderPlaceholderText()} placeholder={this.renderPlaceholderText()}
resizeNotifier={this.props.resizeNotifier}
permalinkCreator={this.props.permalinkCreator} permalinkCreator={this.props.permalinkCreator}
replyToEvent={this.props.replyToEvent} replyToEvent={this.props.replyToEvent}
onChange={this.onChange} onChange={this.onChange}

View file

@ -20,13 +20,14 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { Room } from "matrix-js-sdk/src/models/room"; import { Room } from "matrix-js-sdk/src/models/room";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import dis from "../../../dispatcher/dispatcher"; import dis from "../../../dispatcher/dispatcher";
import * as sdk from "../../../index";
import Modal from "../../../Modal"; import Modal from "../../../Modal";
import { isValid3pidInvite } from "../../../RoomInvite"; import { isValid3pidInvite } from "../../../RoomInvite";
import RoomAvatar from "../avatars/RoomAvatar"; import RoomAvatar from "../avatars/RoomAvatar";
import RoomName from "../elements/RoomName"; import RoomName from "../elements/RoomName";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import ErrorDialog from '../dialogs/ErrorDialog';
import AccessibleButton from '../elements/AccessibleButton';
interface IProps { interface IProps {
event: MatrixEvent; event: MatrixEvent;
@ -104,7 +105,6 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
// Revert echo because of error // Revert echo because of error
this.setState({ invited: true }); this.setState({ invited: true });
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Revoke 3pid invite failed', '', ErrorDialog, { Modal.createTrackedDialog('Revoke 3pid invite failed', '', ErrorDialog, {
title: _t("Failed to revoke invite"), title: _t("Failed to revoke invite"),
description: _t( description: _t(
@ -119,8 +119,6 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
}; };
render() { render() {
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
let adminTools = null; let adminTools = null;
if (this.state.canKick && this.state.invited) { if (this.state.canKick && this.state.invited) {
adminTools = ( adminTools = (

View file

@ -16,15 +16,14 @@ limitations under the License.
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import { SettingLevel } from "../../../settings/SettingLevel"; import { SettingLevel } from "../../../settings/SettingLevel";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import SettingsFlag from '../elements/SettingsFlag';
const SETTING_MANUALLY_VERIFY_ALL_SESSIONS = "e2ee.manuallyVerifyAllSessions"; const SETTING_MANUALLY_VERIFY_ALL_SESSIONS = "e2ee.manuallyVerifyAllSessions";
const E2eAdvancedPanel = props => { const E2eAdvancedPanel = props => {
const SettingsFlag = sdk.getComponent('views.elements.SettingsFlag');
return <div className="mx_SettingsTab_section"> return <div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{_t("Encryption")}</span> <span className="mx_SettingsTab_subheading">{_t("Encryption")}</span>

View file

@ -18,7 +18,6 @@ import React from 'react';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import SdkConfig from "../../../SdkConfig"; import SdkConfig from "../../../SdkConfig";
import * as sdk from '../../../index';
import Modal from '../../../Modal'; import Modal from '../../../Modal';
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import AccessibleButton from "../elements/AccessibleButton"; import AccessibleButton from "../elements/AccessibleButton";
@ -27,6 +26,7 @@ import EventIndexPeg from "../../../indexing/EventIndexPeg";
import { SettingLevel } from "../../../settings/SettingLevel"; import { SettingLevel } from "../../../settings/SettingLevel";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import SeshatResetDialog from '../dialogs/SeshatResetDialog'; import SeshatResetDialog from '../dialogs/SeshatResetDialog';
import InlineSpinner from '../elements/InlineSpinner';
interface IState { interface IState {
enabling: boolean; enabling: boolean;
@ -147,7 +147,6 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
render() { render() {
let eventIndexingSettings = null; let eventIndexingSettings = null;
const InlineSpinner = sdk.getComponent('elements.InlineSpinner');
const brand = SdkConfig.get().brand; const brand = SdkConfig.get().brand;
if (EventIndexPeg.get() !== null) { if (EventIndexPeg.get() !== null) {

View file

@ -17,7 +17,6 @@ limitations under the License.
import url from 'url'; import url from 'url';
import React from 'react'; import React from 'react';
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import * as sdk from '../../../index';
import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { MatrixClientPeg } from "../../../MatrixClientPeg";
import Modal from '../../../Modal'; import Modal from '../../../Modal';
import dis from "../../../dispatcher/dispatcher"; import dis from "../../../dispatcher/dispatcher";
@ -28,6 +27,10 @@ import { getDefaultIdentityServerUrl, doesIdentityServerHaveTerms } from '../../
import { timeout } from "../../../utils/promise"; import { timeout } from "../../../utils/promise";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import { ActionPayload } from '../../../dispatcher/payloads'; import { ActionPayload } from '../../../dispatcher/payloads';
import InlineSpinner from '../elements/InlineSpinner';
import AccessibleButton from '../elements/AccessibleButton';
import Field from '../elements/Field';
import QuestionDialog from "../dialogs/QuestionDialog";
// We'll wait up to this long when checking for 3PID bindings on the IS. // We'll wait up to this long when checking for 3PID bindings on the IS.
const REACHABILITY_TIMEOUT = 10000; // ms const REACHABILITY_TIMEOUT = 10000; // ms
@ -126,7 +129,6 @@ export default class SetIdServer extends React.Component<IProps, IState> {
private getTooltip = () => { private getTooltip = () => {
if (this.state.checking) { if (this.state.checking) {
const InlineSpinner = sdk.getComponent('views.elements.InlineSpinner');
return <div> return <div>
<InlineSpinner /> <InlineSpinner />
{ _t("Checking server") } { _t("Checking server") }
@ -217,7 +219,6 @@ export default class SetIdServer extends React.Component<IProps, IState> {
}; };
private showNoTermsWarning(fullUrl) { private showNoTermsWarning(fullUrl) {
const QuestionDialog = sdk.getComponent("views.dialogs.QuestionDialog");
const { finished } = Modal.createTrackedDialog('No Terms Warning', '', QuestionDialog, { const { finished } = Modal.createTrackedDialog('No Terms Warning', '', QuestionDialog, {
title: _t("Identity server has no terms of service"), title: _t("Identity server has no terms of service"),
description: ( description: (
@ -319,7 +320,6 @@ export default class SetIdServer extends React.Component<IProps, IState> {
message = unboundMessage; message = unboundMessage;
} }
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
const { finished } = Modal.createTrackedDialog('Identity Server Bound Warning', '', QuestionDialog, { const { finished } = Modal.createTrackedDialog('Identity Server Bound Warning', '', QuestionDialog, {
title, title,
description: message, description: message,
@ -352,8 +352,6 @@ export default class SetIdServer extends React.Component<IProps, IState> {
}; };
render() { render() {
const AccessibleButton = sdk.getComponent('views.elements.AccessibleButton');
const Field = sdk.getComponent('elements.Field');
const idServerUrl = this.state.currentClientIdServer; const idServerUrl = this.state.currentClientIdServer;
let sectionTitle; let sectionTitle;
let bodyText; let bodyText;
@ -398,7 +396,6 @@ export default class SetIdServer extends React.Component<IProps, IState> {
discoButtonContent = _t("Do not use an identity server"); discoButtonContent = _t("Do not use an identity server");
} }
if (this.state.disconnectBusy) { if (this.state.disconnectBusy) {
const InlineSpinner = sdk.getComponent('views.elements.InlineSpinner');
discoButtonContent = <InlineSpinner />; discoButtonContent = <InlineSpinner />;
} }
discoSection = <div> discoSection = <div>

View file

@ -17,15 +17,25 @@ limitations under the License.
import React from 'react'; import React from 'react';
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import { IntegrationManagers } from "../../../integrations/IntegrationManagers"; import { IntegrationManagers } from "../../../integrations/IntegrationManagers";
import { IntegrationManagerInstance } from "../../../integrations/IntegrationManagerInstance";
import * as sdk from '../../../index'; import * as sdk from '../../../index';
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import { SettingLevel } from "../../../settings/SettingLevel"; import { SettingLevel } from "../../../settings/SettingLevel";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
interface IProps {
}
interface IState {
currentManager: IntegrationManagerInstance;
provisioningEnabled: boolean;
}
@replaceableComponent("views.settings.SetIntegrationManager") @replaceableComponent("views.settings.SetIntegrationManager")
export default class SetIntegrationManager extends React.Component { export default class SetIntegrationManager extends React.Component<IProps, IState> {
constructor() { constructor(props: IProps) {
super(); super(props);
const currentManager = IntegrationManagers.sharedInstance().getPrimaryManager(); const currentManager = IntegrationManagers.sharedInstance().getPrimaryManager();
@ -35,7 +45,7 @@ export default class SetIntegrationManager extends React.Component {
}; };
} }
onProvisioningToggled = () => { private onProvisioningToggled = (): void => {
const current = this.state.provisioningEnabled; const current = this.state.provisioningEnabled;
SettingsStore.setValue("integrationProvisioning", null, SettingLevel.ACCOUNT, !current).catch(err => { SettingsStore.setValue("integrationProvisioning", null, SettingLevel.ACCOUNT, !current).catch(err => {
console.error("Error changing integration manager provisioning"); console.error("Error changing integration manager provisioning");
@ -46,7 +56,7 @@ export default class SetIntegrationManager extends React.Component {
this.setState({ provisioningEnabled: !current }); this.setState({ provisioningEnabled: !current });
}; };
render() { public render(): React.ReactNode {
const ToggleSwitch = sdk.getComponent("views.elements.ToggleSwitch"); const ToggleSwitch = sdk.getComponent("views.elements.ToggleSwitch");
const currentManager = this.state.currentManager; const currentManager = this.state.currentManager;

View file

@ -17,7 +17,6 @@ limitations under the License.
import React from 'react'; import React from 'react';
import { _t, _td } from "../../../../../languageHandler"; import { _t, _td } from "../../../../../languageHandler";
import { MatrixClientPeg } from "../../../../../MatrixClientPeg"; import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
import * as sdk from "../../../../..";
import AccessibleButton from "../../../elements/AccessibleButton"; import AccessibleButton from "../../../elements/AccessibleButton";
import Modal from "../../../../../Modal"; import Modal from "../../../../../Modal";
import { replaceableComponent } from "../../../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../../../utils/replaceableComponent";
@ -26,6 +25,8 @@ import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { RoomState } from "matrix-js-sdk/src/models/room-state"; import { RoomState } from "matrix-js-sdk/src/models/room-state";
import { compare } from "../../../../../utils/strings"; import { compare } from "../../../../../utils/strings";
import ErrorDialog from '../../../dialogs/ErrorDialog';
import PowerSelector from "../../../elements/PowerSelector";
const plEventsToLabels = { const plEventsToLabels = {
// These will be translated for us later. // These will be translated for us later.
@ -76,7 +77,6 @@ interface IBannedUserProps {
export class BannedUser extends React.Component<IBannedUserProps> { export class BannedUser extends React.Component<IBannedUserProps> {
private onUnbanClick = (e) => { private onUnbanClick = (e) => {
MatrixClientPeg.get().unban(this.props.member.roomId, this.props.member.userId).catch((err) => { MatrixClientPeg.get().unban(this.props.member.roomId, this.props.member.userId).catch((err) => {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
console.error("Failed to unban: " + err); console.error("Failed to unban: " + err);
Modal.createTrackedDialog('Failed to unban', '', ErrorDialog, { Modal.createTrackedDialog('Failed to unban', '', ErrorDialog, {
title: _t('Error'), title: _t('Error'),
@ -176,7 +176,6 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
client.sendStateEvent(this.props.roomId, "m.room.power_levels", plContent).catch(e => { client.sendStateEvent(this.props.roomId, "m.room.power_levels", plContent).catch(e => {
console.error(e); console.error(e);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Power level requirement change failed', '', ErrorDialog, { Modal.createTrackedDialog('Power level requirement change failed', '', ErrorDialog, {
title: _t('Error changing power level requirement'), title: _t('Error changing power level requirement'),
description: _t( description: _t(
@ -203,7 +202,6 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
client.sendStateEvent(this.props.roomId, "m.room.power_levels", plContent).catch(e => { client.sendStateEvent(this.props.roomId, "m.room.power_levels", plContent).catch(e => {
console.error(e); console.error(e);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Power level change failed', '', ErrorDialog, { Modal.createTrackedDialog('Power level change failed', '', ErrorDialog, {
title: _t('Error changing power level'), title: _t('Error changing power level'),
description: _t( description: _t(
@ -215,8 +213,6 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
}; };
render() { render() {
const PowerSelector = sdk.getComponent('elements.PowerSelector');
const client = MatrixClientPeg.get(); const client = MatrixClientPeg.get();
const room = client.getRoom(this.props.roomId); const room = client.getRoom(this.props.roomId);
const plEvent = room.currentState.getStateEvents('m.room.power_levels', ''); const plEvent = room.currentState.getStateEvents('m.room.power_levels', '');

View file

@ -18,7 +18,6 @@ import React from 'react';
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { _t } from "../../../../../languageHandler"; import { _t } from "../../../../../languageHandler";
import { MatrixClientPeg } from "../../../../../MatrixClientPeg"; import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
import * as sdk from "../../../../..";
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch"; import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
import Modal from "../../../../../Modal"; import Modal from "../../../../../Modal";
import QuestionDialog from "../../../dialogs/QuestionDialog"; import QuestionDialog from "../../../dialogs/QuestionDialog";
@ -27,6 +26,7 @@ import { SettingLevel } from "../../../../../settings/SettingLevel";
import SettingsStore from "../../../../../settings/SettingsStore"; import SettingsStore from "../../../../../settings/SettingsStore";
import { UIFeature } from "../../../../../settings/UIFeature"; import { UIFeature } from "../../../../../settings/UIFeature";
import { replaceableComponent } from "../../../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../../../utils/replaceableComponent";
import SettingsFlag from '../../../elements/SettingsFlag';
// Knock and private are reserved keywords which are not yet implemented. // Knock and private are reserved keywords which are not yet implemented.
export enum JoinRule { export enum JoinRule {
@ -385,8 +385,6 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
} }
render() { render() {
const SettingsFlag = sdk.getComponent("elements.SettingsFlag");
const client = MatrixClientPeg.get(); const client = MatrixClientPeg.get();
const room = client.getRoom(this.props.roomId); const room = client.getRoom(this.props.roomId);
const isEncrypted = this.state.encrypted; const isEncrypted = this.state.encrypted;

Some files were not shown because too many files have changed in this diff Show more