Merge remote-tracking branch 'upstream/develop' into feature/remember-server/17739
This commit is contained in:
commit
f78ede9324
112 changed files with 568 additions and 674 deletions
|
@ -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",
|
||||||
|
@ -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",
|
||||||
|
|
|
@ -201,6 +201,7 @@
|
||||||
@import "./views/rooms/_GroupLayout.scss";
|
@import "./views/rooms/_GroupLayout.scss";
|
||||||
@import "./views/rooms/_IRCLayout.scss";
|
@import "./views/rooms/_IRCLayout.scss";
|
||||||
@import "./views/rooms/_JumpToBottomButton.scss";
|
@import "./views/rooms/_JumpToBottomButton.scss";
|
||||||
|
@import "./views/rooms/_LinkPreviewGroup.scss";
|
||||||
@import "./views/rooms/_LinkPreviewWidget.scss";
|
@import "./views/rooms/_LinkPreviewWidget.scss";
|
||||||
@import "./views/rooms/_MemberInfo.scss";
|
@import "./views/rooms/_MemberInfo.scss";
|
||||||
@import "./views/rooms/_MemberList.scss";
|
@import "./views/rooms/_MemberList.scss";
|
||||||
|
|
|
@ -477,8 +477,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 {
|
||||||
|
@ -488,11 +487,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 {
|
||||||
|
|
38
res/css/views/rooms/_LinkPreviewGroup.scss
Normal file
38
res/css/views/rooms/_LinkPreviewGroup.scss
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.mx_LinkPreviewGroup {
|
||||||
|
.mx_LinkPreviewGroup_hide {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
flex: 0 0 40px;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover .mx_LinkPreviewGroup_hide img,
|
||||||
|
.mx_LinkPreviewGroup_hide.focus-visible:focus img {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .mx_AccessibleButton {
|
||||||
|
color: $accent-color;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,12 +33,16 @@ limitations under the License.
|
||||||
.mx_LinkPreviewWidget_caption {
|
.mx_LinkPreviewWidget_caption {
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
|
overflow-x: hidden; // cause it to wrap rather than clip
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LinkPreviewWidget_title {
|
.mx_LinkPreviewWidget_title {
|
||||||
display: inline;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_LinkPreviewWidget_siteName {
|
.mx_LinkPreviewWidget_siteName {
|
||||||
|
@ -49,22 +53,9 @@ limitations under the License.
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
.mx_LinkPreviewWidget_cancel {
|
-webkit-box-orient: vertical;
|
||||||
cursor: pointer;
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
flex: 0 0 40px;
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_LinkPreviewWidget:hover .mx_LinkPreviewWidget_cancel img,
|
|
||||||
.mx_LinkPreviewWidget_cancel.focus-visible:focus img {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MatrixChat_useCompactLayout {
|
.mx_MatrixChat_useCompactLayout {
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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 $@
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
|
@ -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")}>
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
|
@ -160,7 +160,8 @@ export default class DeviceListener {
|
||||||
// which result in account data changes affecting checks below.
|
// which result in account data changes affecting checks below.
|
||||||
if (
|
if (
|
||||||
ev.getType().startsWith('m.secret_storage.') ||
|
ev.getType().startsWith('m.secret_storage.') ||
|
||||||
ev.getType().startsWith('m.cross_signing.')
|
ev.getType().startsWith('m.cross_signing.') ||
|
||||||
|
ev.getType() === 'm.megolm_backup.v1'
|
||||||
) {
|
) {
|
||||||
this._recheck();
|
this._recheck();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
|
@ -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();
|
||||||
},
|
},
|
||||||
|
|
|
@ -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, {
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
|
@ -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 }),
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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 [];
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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} />;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -36,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";
|
||||||
|
@ -85,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 {
|
||||||
|
@ -156,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;
|
||||||
|
@ -519,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() &&
|
||||||
|
@ -613,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();
|
||||||
|
@ -650,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);
|
||||||
|
@ -663,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: {
|
||||||
|
@ -677,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);
|
||||||
|
@ -1019,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,
|
||||||
|
@ -1116,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);
|
||||||
|
|
||||||
|
@ -1143,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({
|
||||||
|
@ -1439,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>
|
||||||
|
@ -1548,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',
|
||||||
|
@ -1559,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);
|
||||||
|
@ -1569,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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1977,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}
|
||||||
|
@ -2012,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}
|
||||||
|
@ -2020,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">
|
||||||
|
@ -2045,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
|
||||||
|
@ -2067,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}
|
||||||
|
@ -2078,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}
|
||||||
|
@ -2094,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}
|
||||||
|
@ -2106,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>;
|
||||||
|
|
|
@ -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';
|
||||||
|
@ -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,
|
||||||
|
@ -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}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ enum Phase {
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
serverConfig: ValidatedServerConfig;
|
serverConfig: ValidatedServerConfig;
|
||||||
onServerConfigChange: () => void;
|
onServerConfigChange: (serverConfig: ValidatedServerConfig) => void;
|
||||||
onLoginClick?: () => void;
|
onLoginClick?: () => void;
|
||||||
onComplete: () => void;
|
onComplete: () => void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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 />
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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)");
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||||
Copyright 2015, 2016, 2018, 2019, 2021 The Matrix.org Foundation C.I.C.
|
Copyright 2015 - 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -16,12 +16,11 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import { EventStatus, MatrixEvent } from 'matrix-js-sdk/src/models/event';
|
||||||
import { EventStatus } from 'matrix-js-sdk/src/models/event';
|
import { EventType, RelationType } from "matrix-js-sdk/src/@types/event";
|
||||||
|
|
||||||
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 } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import Modal from '../../../Modal';
|
import Modal from '../../../Modal';
|
||||||
import Resend from '../../../Resend';
|
import Resend from '../../../Resend';
|
||||||
|
@ -29,53 +28,65 @@ import SettingsStore from '../../../settings/SettingsStore';
|
||||||
import { isUrlPermitted } from '../../../HtmlUtils';
|
import { isUrlPermitted } from '../../../HtmlUtils';
|
||||||
import { isContentActionable } from '../../../utils/EventUtils';
|
import { isContentActionable } from '../../../utils/EventUtils';
|
||||||
import IconizedContextMenu, { IconizedContextMenuOption, IconizedContextMenuOptionList } from './IconizedContextMenu';
|
import IconizedContextMenu, { IconizedContextMenuOption, IconizedContextMenuOptionList } from './IconizedContextMenu';
|
||||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
|
||||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
import { ReadPinsEventId } from "../right_panel/PinnedMessagesCard";
|
import { ReadPinsEventId } from "../right_panel/PinnedMessagesCard";
|
||||||
import ForwardDialog from "../dialogs/ForwardDialog";
|
import ForwardDialog from "../dialogs/ForwardDialog";
|
||||||
import { Action } from "../../../dispatcher/actions";
|
import { Action } from "../../../dispatcher/actions";
|
||||||
|
import ReportEventDialog from '../dialogs/ReportEventDialog';
|
||||||
|
import ViewSource from '../../structures/ViewSource';
|
||||||
|
import ConfirmRedactDialog from '../dialogs/ConfirmRedactDialog';
|
||||||
|
import ErrorDialog from '../dialogs/ErrorDialog';
|
||||||
|
import ShareDialog from '../dialogs/ShareDialog';
|
||||||
|
import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks";
|
||||||
|
|
||||||
export function canCancel(eventStatus) {
|
export function canCancel(eventStatus: EventStatus): boolean {
|
||||||
return eventStatus === EventStatus.QUEUED || eventStatus === EventStatus.NOT_SENT;
|
return eventStatus === EventStatus.QUEUED || eventStatus === EventStatus.NOT_SENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IEventTileOps {
|
||||||
|
isWidgetHidden(): boolean;
|
||||||
|
unhideWidget(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
/* the MatrixEvent associated with the context menu */
|
||||||
|
mxEvent: MatrixEvent;
|
||||||
|
/* an optional EventTileOps implementation that can be used to unhide preview widgets */
|
||||||
|
eventTileOps?: IEventTileOps;
|
||||||
|
permalinkCreator?: RoomPermalinkCreator;
|
||||||
|
/* an optional function to be called when the user clicks collapse thread, if not provided hide button */
|
||||||
|
collapseReplyThread?(): void;
|
||||||
|
/* callback called when the menu is dismissed */
|
||||||
|
onFinished(): void;
|
||||||
|
/* if the menu is inside a dialog, we sometimes need to close that dialog after click (forwarding) */
|
||||||
|
onCloseDialog?(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
canRedact: boolean;
|
||||||
|
canPin: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
@replaceableComponent("views.context_menus.MessageContextMenu")
|
@replaceableComponent("views.context_menus.MessageContextMenu")
|
||||||
export default class MessageContextMenu extends React.Component {
|
export default class MessageContextMenu extends React.Component<IProps, IState> {
|
||||||
static propTypes = {
|
|
||||||
/* the MatrixEvent associated with the context menu */
|
|
||||||
mxEvent: PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
/* an optional EventTileOps implementation that can be used to unhide preview widgets */
|
|
||||||
eventTileOps: PropTypes.object,
|
|
||||||
|
|
||||||
/* an optional function to be called when the user clicks collapse thread, if not provided hide button */
|
|
||||||
collapseReplyThread: PropTypes.func,
|
|
||||||
|
|
||||||
/* callback called when the menu is dismissed */
|
|
||||||
onFinished: PropTypes.func,
|
|
||||||
|
|
||||||
/* if the menu is inside a dialog, we sometimes need to close that dialog after click (forwarding) */
|
|
||||||
onCloseDialog: PropTypes.func,
|
|
||||||
};
|
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
canRedact: false,
|
canRedact: false,
|
||||||
canPin: false,
|
canPin: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
MatrixClientPeg.get().on('RoomMember.powerLevel', this._checkPermissions);
|
MatrixClientPeg.get().on('RoomMember.powerLevel', this.checkPermissions);
|
||||||
this._checkPermissions();
|
this.checkPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
if (cli) {
|
if (cli) {
|
||||||
cli.removeListener('RoomMember.powerLevel', this._checkPermissions);
|
cli.removeListener('RoomMember.powerLevel', this.checkPermissions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_checkPermissions = () => {
|
private checkPermissions = (): void => {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const room = cli.getRoom(this.props.mxEvent.getRoomId());
|
const room = cli.getRoom(this.props.mxEvent.getRoomId());
|
||||||
|
|
||||||
|
@ -93,7 +104,7 @@ export default class MessageContextMenu extends React.Component {
|
||||||
this.setState({ canRedact, canPin });
|
this.setState({ canRedact, canPin });
|
||||||
};
|
};
|
||||||
|
|
||||||
_isPinned() {
|
private isPinned(): boolean {
|
||||||
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||||
const pinnedEvent = room.currentState.getStateEvents(EventType.RoomPinnedEvents, '');
|
const pinnedEvent = room.currentState.getStateEvents(EventType.RoomPinnedEvents, '');
|
||||||
if (!pinnedEvent) return false;
|
if (!pinnedEvent) return false;
|
||||||
|
@ -101,38 +112,35 @@ export default class MessageContextMenu extends React.Component {
|
||||||
return content.pinned && Array.isArray(content.pinned) && content.pinned.includes(this.props.mxEvent.getId());
|
return content.pinned && Array.isArray(content.pinned) && content.pinned.includes(this.props.mxEvent.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
onResendReactionsClick = () => {
|
private onResendReactionsClick = (): void => {
|
||||||
for (const reaction of this._getUnsentReactions()) {
|
for (const reaction of this.getUnsentReactions()) {
|
||||||
Resend.resend(reaction);
|
Resend.resend(reaction);
|
||||||
}
|
}
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
onReportEventClick = () => {
|
private onReportEventClick = (): void => {
|
||||||
const ReportEventDialog = sdk.getComponent("dialogs.ReportEventDialog");
|
|
||||||
Modal.createTrackedDialog('Report Event', '', ReportEventDialog, {
|
Modal.createTrackedDialog('Report Event', '', ReportEventDialog, {
|
||||||
mxEvent: this.props.mxEvent,
|
mxEvent: this.props.mxEvent,
|
||||||
}, 'mx_Dialog_reportEvent');
|
}, 'mx_Dialog_reportEvent');
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
onViewSourceClick = () => {
|
private onViewSourceClick = (): void => {
|
||||||
const ViewSource = sdk.getComponent('structures.ViewSource');
|
|
||||||
Modal.createTrackedDialog('View Event Source', '', ViewSource, {
|
Modal.createTrackedDialog('View Event Source', '', ViewSource, {
|
||||||
mxEvent: this.props.mxEvent,
|
mxEvent: this.props.mxEvent,
|
||||||
}, 'mx_Dialog_viewsource');
|
}, 'mx_Dialog_viewsource');
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
onRedactClick = () => {
|
private onRedactClick = (): void => {
|
||||||
const ConfirmRedactDialog = sdk.getComponent("dialogs.ConfirmRedactDialog");
|
|
||||||
Modal.createTrackedDialog('Confirm Redact Dialog', '', ConfirmRedactDialog, {
|
Modal.createTrackedDialog('Confirm Redact Dialog', '', ConfirmRedactDialog, {
|
||||||
onFinished: async (proceed, reason) => {
|
onFinished: async (proceed: boolean, reason?: string) => {
|
||||||
if (!proceed) return;
|
if (!proceed) return;
|
||||||
|
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
try {
|
try {
|
||||||
if (this.props.onCloseDialog) this.props.onCloseDialog();
|
this.props.onCloseDialog?.();
|
||||||
await cli.redactEvent(
|
await cli.redactEvent(
|
||||||
this.props.mxEvent.getRoomId(),
|
this.props.mxEvent.getRoomId(),
|
||||||
this.props.mxEvent.getId(),
|
this.props.mxEvent.getId(),
|
||||||
|
@ -145,7 +153,6 @@ export default class MessageContextMenu extends React.Component {
|
||||||
// (e.g. no errcode or statusCode) as in that case the redactions end up in the
|
// (e.g. no errcode or statusCode) as in that case the redactions end up in the
|
||||||
// detached queue and we show the room status bar to allow retry
|
// detached queue and we show the room status bar to allow retry
|
||||||
if (typeof code !== "undefined") {
|
if (typeof code !== "undefined") {
|
||||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
||||||
// display error message stating you couldn't delete this.
|
// display error message stating you couldn't delete this.
|
||||||
Modal.createTrackedDialog('You cannot delete this message', '', ErrorDialog, {
|
Modal.createTrackedDialog('You cannot delete this message', '', ErrorDialog, {
|
||||||
title: _t('Error'),
|
title: _t('Error'),
|
||||||
|
@ -158,7 +165,7 @@ export default class MessageContextMenu extends React.Component {
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
onForwardClick = () => {
|
private onForwardClick = (): void => {
|
||||||
Modal.createTrackedDialog('Forward Message', '', ForwardDialog, {
|
Modal.createTrackedDialog('Forward Message', '', ForwardDialog, {
|
||||||
matrixClient: MatrixClientPeg.get(),
|
matrixClient: MatrixClientPeg.get(),
|
||||||
event: this.props.mxEvent,
|
event: this.props.mxEvent,
|
||||||
|
@ -167,12 +174,12 @@ export default class MessageContextMenu extends React.Component {
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
onPinClick = () => {
|
private onPinClick = (): void => {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const room = cli.getRoom(this.props.mxEvent.getRoomId());
|
const room = cli.getRoom(this.props.mxEvent.getRoomId());
|
||||||
const eventId = this.props.mxEvent.getId();
|
const eventId = this.props.mxEvent.getId();
|
||||||
|
|
||||||
const pinnedIds = room?.currentState?.getStateEvents(EventType.RoomPinnedEvents, "")?.pinned || [];
|
const pinnedIds = room?.currentState?.getStateEvents(EventType.RoomPinnedEvents, "")?.getContent().pinned || [];
|
||||||
if (pinnedIds.includes(eventId)) {
|
if (pinnedIds.includes(eventId)) {
|
||||||
pinnedIds.splice(pinnedIds.indexOf(eventId), 1);
|
pinnedIds.splice(pinnedIds.indexOf(eventId), 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -188,18 +195,16 @@ export default class MessageContextMenu extends React.Component {
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
closeMenu = () => {
|
private closeMenu = (): void => {
|
||||||
if (this.props.onFinished) this.props.onFinished();
|
this.props.onFinished();
|
||||||
};
|
};
|
||||||
|
|
||||||
onUnhidePreviewClick = () => {
|
private onUnhidePreviewClick = (): void => {
|
||||||
if (this.props.eventTileOps) {
|
this.props.eventTileOps?.unhideWidget();
|
||||||
this.props.eventTileOps.unhideWidget();
|
|
||||||
}
|
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
onQuoteClick = () => {
|
private onQuoteClick = (): void => {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: Action.ComposerInsert,
|
action: Action.ComposerInsert,
|
||||||
event: this.props.mxEvent,
|
event: this.props.mxEvent,
|
||||||
|
@ -207,9 +212,8 @@ export default class MessageContextMenu extends React.Component {
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
onPermalinkClick = (e) => {
|
private onPermalinkClick = (e: React.MouseEvent): void => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const ShareDialog = sdk.getComponent("dialogs.ShareDialog");
|
|
||||||
Modal.createTrackedDialog('share room message dialog', '', ShareDialog, {
|
Modal.createTrackedDialog('share room message dialog', '', ShareDialog, {
|
||||||
target: this.props.mxEvent,
|
target: this.props.mxEvent,
|
||||||
permalinkCreator: this.props.permalinkCreator,
|
permalinkCreator: this.props.permalinkCreator,
|
||||||
|
@ -217,30 +221,27 @@ export default class MessageContextMenu extends React.Component {
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
onCollapseReplyThreadClick = () => {
|
private onCollapseReplyThreadClick = (): void => {
|
||||||
this.props.collapseReplyThread();
|
this.props.collapseReplyThread();
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
_getReactions(filter) {
|
private getReactions(filter: (e: MatrixEvent) => boolean): MatrixEvent[] {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const room = cli.getRoom(this.props.mxEvent.getRoomId());
|
const room = cli.getRoom(this.props.mxEvent.getRoomId());
|
||||||
const eventId = this.props.mxEvent.getId();
|
const eventId = this.props.mxEvent.getId();
|
||||||
return room.getPendingEvents().filter(e => {
|
return room.getPendingEvents().filter(e => {
|
||||||
const relation = e.getRelation();
|
const relation = e.getRelation();
|
||||||
return relation &&
|
return relation?.rel_type === RelationType.Annotation && relation.event_id === eventId && filter(e);
|
||||||
relation.rel_type === "m.annotation" &&
|
|
||||||
relation.event_id === eventId &&
|
|
||||||
filter(e);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_getPendingReactions() {
|
private getPendingReactions(): MatrixEvent[] {
|
||||||
return this._getReactions(e => canCancel(e.status));
|
return this.getReactions(e => canCancel(e.status));
|
||||||
}
|
}
|
||||||
|
|
||||||
_getUnsentReactions() {
|
private getUnsentReactions(): MatrixEvent[] {
|
||||||
return this._getReactions(e => e.status === EventStatus.NOT_SENT);
|
return this.getReactions(e => e.status === EventStatus.NOT_SENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -248,16 +249,17 @@ export default class MessageContextMenu extends React.Component {
|
||||||
const me = cli.getUserId();
|
const me = cli.getUserId();
|
||||||
const mxEvent = this.props.mxEvent;
|
const mxEvent = this.props.mxEvent;
|
||||||
const eventStatus = mxEvent.status;
|
const eventStatus = mxEvent.status;
|
||||||
const unsentReactionsCount = this._getUnsentReactions().length;
|
const unsentReactionsCount = this.getUnsentReactions().length;
|
||||||
let resendReactionsButton;
|
|
||||||
let redactButton;
|
let resendReactionsButton: JSX.Element;
|
||||||
let forwardButton;
|
let redactButton: JSX.Element;
|
||||||
let pinButton;
|
let forwardButton: JSX.Element;
|
||||||
let unhidePreviewButton;
|
let pinButton: JSX.Element;
|
||||||
let externalURLButton;
|
let unhidePreviewButton: JSX.Element;
|
||||||
let quoteButton;
|
let externalURLButton: JSX.Element;
|
||||||
let collapseReplyThread;
|
let quoteButton: JSX.Element;
|
||||||
let redactItemList;
|
let collapseReplyThread: JSX.Element;
|
||||||
|
let redactItemList: JSX.Element;
|
||||||
|
|
||||||
// status is SENT before remote-echo, null after
|
// status is SENT before remote-echo, null after
|
||||||
const isSent = !eventStatus || eventStatus === EventStatus.SENT;
|
const isSent = !eventStatus || eventStatus === EventStatus.SENT;
|
||||||
|
@ -296,7 +298,7 @@ export default class MessageContextMenu extends React.Component {
|
||||||
pinButton = (
|
pinButton = (
|
||||||
<IconizedContextMenuOption
|
<IconizedContextMenuOption
|
||||||
iconClassName="mx_MessageContextMenu_iconPin"
|
iconClassName="mx_MessageContextMenu_iconPin"
|
||||||
label={ this._isPinned() ? _t('Unpin') : _t('Pin') }
|
label={ this.isPinned() ? _t('Unpin') : _t('Pin') }
|
||||||
onClick={this.onPinClick}
|
onClick={this.onPinClick}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -327,16 +329,20 @@ export default class MessageContextMenu extends React.Component {
|
||||||
if (this.props.permalinkCreator) {
|
if (this.props.permalinkCreator) {
|
||||||
permalink = this.props.permalinkCreator.forEvent(this.props.mxEvent.getId());
|
permalink = this.props.permalinkCreator.forEvent(this.props.mxEvent.getId());
|
||||||
}
|
}
|
||||||
// XXX: if we use room ID, we should also include a server where the event can be found (other than in the domain of the event ID)
|
|
||||||
const permalinkButton = (
|
const permalinkButton = (
|
||||||
<IconizedContextMenuOption
|
<IconizedContextMenuOption
|
||||||
iconClassName="mx_MessageContextMenu_iconPermalink"
|
iconClassName="mx_MessageContextMenu_iconPermalink"
|
||||||
onClick={this.onPermalinkClick}
|
onClick={this.onPermalinkClick}
|
||||||
label= {_t('Share')}
|
label= {_t('Share')}
|
||||||
element="a"
|
element="a"
|
||||||
href={permalink}
|
{
|
||||||
target="_blank"
|
// XXX: Typescript signature for AccessibleButton doesn't work properly for non-inputs like `a`
|
||||||
rel="noreferrer noopener"
|
...{
|
||||||
|
href: permalink,
|
||||||
|
target: "_blank",
|
||||||
|
rel: "noreferrer noopener",
|
||||||
|
}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -351,8 +357,8 @@ export default class MessageContextMenu extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bridges can provide a 'external_url' to link back to the source.
|
// Bridges can provide a 'external_url' to link back to the source.
|
||||||
if (typeof (mxEvent.event.content.external_url) === "string" &&
|
if (typeof (mxEvent.getContent().external_url) === "string" &&
|
||||||
isUrlPermitted(mxEvent.event.content.external_url)
|
isUrlPermitted(mxEvent.getContent().external_url)
|
||||||
) {
|
) {
|
||||||
externalURLButton = (
|
externalURLButton = (
|
||||||
<IconizedContextMenuOption
|
<IconizedContextMenuOption
|
||||||
|
@ -360,9 +366,14 @@ export default class MessageContextMenu extends React.Component {
|
||||||
onClick={this.closeMenu}
|
onClick={this.closeMenu}
|
||||||
label={ _t('Source URL') }
|
label={ _t('Source URL') }
|
||||||
element="a"
|
element="a"
|
||||||
target="_blank"
|
{
|
||||||
rel="noreferrer noopener"
|
// XXX: Typescript signature for AccessibleButton doesn't work properly for non-inputs like `a`
|
||||||
href={mxEvent.event.content.external_url}
|
...{
|
||||||
|
target: "_blank",
|
||||||
|
rel: "noreferrer noopener",
|
||||||
|
href: mxEvent.getContent().external_url,
|
||||||
|
}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -377,7 +388,7 @@ export default class MessageContextMenu extends React.Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let reportEventButton;
|
let reportEventButton: JSX.Element;
|
||||||
if (mxEvent.getSender() !== me) {
|
if (mxEvent.getSender() !== me) {
|
||||||
reportEventButton = (
|
reportEventButton = (
|
||||||
<IconizedContextMenuOption
|
<IconizedContextMenuOption
|
|
@ -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>);
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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 />;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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} />;
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React, { ReactHTML } from 'react';
|
||||||
|
|
||||||
import { Key } from '../../../Keyboard';
|
import { Key } from '../../../Keyboard';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
@ -29,7 +29,7 @@ export type ButtonEvent = React.MouseEvent<Element> | React.KeyboardEvent<Elemen
|
||||||
*/
|
*/
|
||||||
interface IProps extends React.InputHTMLAttributes<Element> {
|
interface IProps extends React.InputHTMLAttributes<Element> {
|
||||||
inputRef?: React.Ref<Element>;
|
inputRef?: React.Ref<Element>;
|
||||||
element?: string;
|
element?: keyof ReactHTML;
|
||||||
// The kind of button, similar to how Bootstrap works.
|
// The kind of button, similar to how Bootstrap works.
|
||||||
// See available classes for AccessibleButton for options.
|
// See available classes for AccessibleButton for options.
|
||||||
kind?: string;
|
kind?: string;
|
||||||
|
@ -122,7 +122,7 @@ export default function AccessibleButton({
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessibleButton.defaultProps = {
|
AccessibleButton.defaultProps = {
|
||||||
element: 'div',
|
element: 'div' as keyof ReactHTML,
|
||||||
role: 'button',
|
role: 'button',
|
||||||
tabIndex: 0,
|
tabIndex: 0,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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} />;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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";
|
||||||
|
@ -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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ interface IProps {
|
||||||
value: string;
|
value: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
|
disabled?: boolean;
|
||||||
onChange?(value: string): void;
|
onChange?(value: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +69,7 @@ export default class RoomAliasField extends React.PureComponent<IProps, IState>
|
||||||
onChange={this.onChange}
|
onChange={this.onChange}
|
||||||
value={this.props.value.substring(1, this.props.value.length - this.props.domain.length - 1)}
|
value={this.props.value.substring(1, this.props.value.length - this.props.domain.length - 1)}
|
||||||
maxLength={maxlength}
|
maxLength={maxlength}
|
||||||
|
disabled={this.props.disabled}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ import Spoiler from "../elements/Spoiler";
|
||||||
import QuestionDialog from "../dialogs/QuestionDialog";
|
import QuestionDialog from "../dialogs/QuestionDialog";
|
||||||
import MessageEditHistoryDialog from "../dialogs/MessageEditHistoryDialog";
|
import MessageEditHistoryDialog from "../dialogs/MessageEditHistoryDialog";
|
||||||
import EditMessageComposer from '../rooms/EditMessageComposer';
|
import EditMessageComposer from '../rooms/EditMessageComposer';
|
||||||
import LinkPreviewWidget from '../rooms/LinkPreviewWidget';
|
import LinkPreviewGroup from '../rooms/LinkPreviewGroup';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
/* the MatrixEvent to show */
|
/* the MatrixEvent to show */
|
||||||
|
@ -294,14 +294,8 @@ export default class TextualBody extends React.Component<IProps, IState> {
|
||||||
// pass only the first child which is the event tile otherwise this recurses on edited events
|
// pass only the first child which is the event tile otherwise this recurses on edited events
|
||||||
let links = this.findLinks([this.contentRef.current]);
|
let links = this.findLinks([this.contentRef.current]);
|
||||||
if (links.length) {
|
if (links.length) {
|
||||||
// de-duplicate the links after stripping hashes as they don't affect the preview
|
// de-duplicate the links using a set here maintains the order
|
||||||
// using a set here maintains the order
|
links = Array.from(new Set(links));
|
||||||
links = Array.from(new Set(links.map(link => {
|
|
||||||
const url = new URL(link);
|
|
||||||
url.hash = "";
|
|
||||||
return url.toString();
|
|
||||||
})));
|
|
||||||
|
|
||||||
this.setState({ links });
|
this.setState({ links });
|
||||||
|
|
||||||
// lazy-load the hidden state of the preview widget from localstorage
|
// lazy-load the hidden state of the preview widget from localstorage
|
||||||
|
@ -530,15 +524,12 @@ export default class TextualBody extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
let widgets;
|
let widgets;
|
||||||
if (this.state.links.length && !this.state.widgetHidden && this.props.showUrlPreview) {
|
if (this.state.links.length && !this.state.widgetHidden && this.props.showUrlPreview) {
|
||||||
widgets = this.state.links.map((link)=>{
|
widgets = <LinkPreviewGroup
|
||||||
return <LinkPreviewWidget
|
links={this.state.links}
|
||||||
key={link}
|
mxEvent={this.props.mxEvent}
|
||||||
link={link}
|
onCancelClick={this.onCancelClick}
|
||||||
mxEvent={this.props.mxEvent}
|
onHeightChanged={this.props.onHeightChanged}
|
||||||
onCancelClick={this.onCancelClick}
|
/>;
|
||||||
onHeightChanged={this.props.onHeightChanged}
|
|
||||||
/>;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (content.msgtype) {
|
switch (content.msgtype) {
|
||||||
|
|
|
@ -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")}
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -47,6 +47,13 @@ import { StaticNotificationState } from "../../../stores/notifications/StaticNot
|
||||||
import NotificationBadge from "./NotificationBadge";
|
import NotificationBadge from "./NotificationBadge";
|
||||||
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',
|
||||||
|
@ -666,7 +673,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;
|
||||||
|
@ -733,7 +739,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,
|
||||||
|
@ -841,10 +847,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();
|
||||||
|
@ -987,7 +989,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}
|
||||||
|
@ -1027,7 +1028,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">
|
||||||
|
@ -1038,7 +1038,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}
|
||||||
|
|
76
src/components/views/rooms/LinkPreviewGroup.tsx
Normal file
76
src/components/views/rooms/LinkPreviewGroup.tsx
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
|
|
||||||
|
import { useStateToggle } from "../../../hooks/useStateToggle";
|
||||||
|
import LinkPreviewWidget from "./LinkPreviewWidget";
|
||||||
|
import AccessibleButton from "../elements/AccessibleButton";
|
||||||
|
import { _t } from "../../../languageHandler";
|
||||||
|
|
||||||
|
const INITIAL_NUM_PREVIEWS = 2;
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
links: string[]; // the URLs to be previewed
|
||||||
|
mxEvent: MatrixEvent; // the Event associated with the preview
|
||||||
|
onCancelClick?(): void; // called when the preview's cancel ('hide') button is clicked
|
||||||
|
onHeightChanged?(): void; // called when the preview's contents has loaded
|
||||||
|
}
|
||||||
|
|
||||||
|
const LinkPreviewGroup: React.FC<IProps> = ({ links, mxEvent, onCancelClick, onHeightChanged }) => {
|
||||||
|
const [expanded, toggleExpanded] = useStateToggle();
|
||||||
|
useEffect(() => {
|
||||||
|
onHeightChanged();
|
||||||
|
}, [onHeightChanged, expanded]);
|
||||||
|
|
||||||
|
const shownLinks = expanded ? links : links.slice(0, INITIAL_NUM_PREVIEWS);
|
||||||
|
|
||||||
|
let toggleButton;
|
||||||
|
if (links.length > INITIAL_NUM_PREVIEWS) {
|
||||||
|
toggleButton = <AccessibleButton onClick={toggleExpanded}>
|
||||||
|
{ expanded
|
||||||
|
? _t("Collapse")
|
||||||
|
: _t("Show %(count)s other previews", { count: links.length - shownLinks.length }) }
|
||||||
|
</AccessibleButton>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div className="mx_LinkPreviewGroup">
|
||||||
|
{ shownLinks.map((link, i) => (
|
||||||
|
<LinkPreviewWidget key={link} link={link} mxEvent={mxEvent} onHeightChanged={onHeightChanged}>
|
||||||
|
{ i === 0 ? (
|
||||||
|
<AccessibleButton
|
||||||
|
className="mx_LinkPreviewGroup_hide"
|
||||||
|
onClick={onCancelClick}
|
||||||
|
aria-label={_t("Close preview")}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
className="mx_filterFlipColor"
|
||||||
|
alt=""
|
||||||
|
role="presentation"
|
||||||
|
src={require("../../../../res/img/cancel.svg")}
|
||||||
|
width="18"
|
||||||
|
height="18"
|
||||||
|
/>
|
||||||
|
</AccessibleButton>
|
||||||
|
): undefined }
|
||||||
|
</LinkPreviewWidget>
|
||||||
|
)) }
|
||||||
|
{ toggleButton }
|
||||||
|
</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LinkPreviewGroup;
|
|
@ -1,6 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2016 OpenMarket Ltd
|
Copyright 2016 - 2021 The Matrix.org Foundation C.I.C.
|
||||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -16,26 +15,33 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { createRef } from 'react';
|
import React, { createRef } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { AllHtmlEntities } from 'html-entities';
|
import { AllHtmlEntities } from 'html-entities';
|
||||||
|
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
|
||||||
|
import { IPreviewUrlResponse } from 'matrix-js-sdk/src/client';
|
||||||
|
|
||||||
import { linkifyElement } from '../../../HtmlUtils';
|
import { linkifyElement } from '../../../HtmlUtils';
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||||
import * as sdk from "../../../index";
|
|
||||||
import Modal from "../../../Modal";
|
import Modal from "../../../Modal";
|
||||||
import * as ImageUtils from "../../../ImageUtils";
|
import * as ImageUtils from "../../../ImageUtils";
|
||||||
import { _t } from "../../../languageHandler";
|
|
||||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
import { mediaFromMxc } from "../../../customisations/Media";
|
import { mediaFromMxc } from "../../../customisations/Media";
|
||||||
|
import ImageView from '../elements/ImageView';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
link: string; // the URL being previewed
|
||||||
|
mxEvent: MatrixEvent; // the Event associated with the preview
|
||||||
|
onHeightChanged(): void; // called when the preview's contents has loaded
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
preview?: IPreviewUrlResponse;
|
||||||
|
}
|
||||||
|
|
||||||
@replaceableComponent("views.rooms.LinkPreviewWidget")
|
@replaceableComponent("views.rooms.LinkPreviewWidget")
|
||||||
export default class LinkPreviewWidget extends React.Component {
|
export default class LinkPreviewWidget extends React.Component<IProps, IState> {
|
||||||
static propTypes = {
|
private unmounted = false;
|
||||||
link: PropTypes.string.isRequired, // the URL being previewed
|
private readonly description = createRef<HTMLDivElement>();
|
||||||
mxEvent: PropTypes.object.isRequired, // the Event associated with the preview
|
|
||||||
onCancelClick: PropTypes.func, // called when the preview's cancel ('hide') button is clicked
|
|
||||||
onHeightChanged: PropTypes.func, // called when the preview's contents has loaded
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -44,31 +50,25 @@ export default class LinkPreviewWidget extends React.Component {
|
||||||
preview: null,
|
preview: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.unmounted = false;
|
MatrixClientPeg.get().getUrlPreview(this.props.link, this.props.mxEvent.getTs()).then((preview) => {
|
||||||
MatrixClientPeg.get().getUrlPreview(this.props.link, this.props.mxEvent.getTs()).then((res)=>{
|
|
||||||
if (this.unmounted) {
|
if (this.unmounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setState(
|
this.setState({ preview }, this.props.onHeightChanged);
|
||||||
{ preview: res },
|
}, (error) => {
|
||||||
this.props.onHeightChanged,
|
|
||||||
);
|
|
||||||
}, (error)=>{
|
|
||||||
console.error("Failed to get URL preview: " + error);
|
console.error("Failed to get URL preview: " + error);
|
||||||
});
|
});
|
||||||
|
|
||||||
this._description = createRef();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (this._description.current) {
|
if (this.description.current) {
|
||||||
linkifyElement(this._description.current);
|
linkifyElement(this.description.current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
if (this._description.current) {
|
if (this.description.current) {
|
||||||
linkifyElement(this._description.current);
|
linkifyElement(this.description.current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,11 +76,10 @@ export default class LinkPreviewWidget extends React.Component {
|
||||||
this.unmounted = true;
|
this.unmounted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
onImageClick = ev => {
|
private onImageClick = ev => {
|
||||||
const p = this.state.preview;
|
const p = this.state.preview;
|
||||||
if (ev.button != 0 || ev.metaKey) return;
|
if (ev.button != 0 || ev.metaKey) return;
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
const ImageView = sdk.getComponent("elements.ImageView");
|
|
||||||
|
|
||||||
let src = p["og:image"];
|
let src = p["og:image"];
|
||||||
if (src && src.startsWith("mxc://")) {
|
if (src && src.startsWith("mxc://")) {
|
||||||
|
@ -136,21 +135,17 @@ export default class LinkPreviewWidget extends React.Component {
|
||||||
// opaque string. This does not allow any HTML to be injected into the DOM.
|
// opaque string. This does not allow any HTML to be injected into the DOM.
|
||||||
const description = AllHtmlEntities.decode(p["og:description"] || "");
|
const description = AllHtmlEntities.decode(p["og:description"] || "");
|
||||||
|
|
||||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_LinkPreviewWidget">
|
<div className="mx_LinkPreviewWidget">
|
||||||
{ img }
|
{ img }
|
||||||
<div className="mx_LinkPreviewWidget_caption">
|
<div className="mx_LinkPreviewWidget_caption">
|
||||||
<div className="mx_LinkPreviewWidget_title"><a href={this.props.link} target="_blank" rel="noreferrer noopener">{ p["og:title"] }</a></div>
|
<div className="mx_LinkPreviewWidget_title"><a href={this.props.link} target="_blank" rel="noreferrer noopener">{ p["og:title"] }</a></div>
|
||||||
<div className="mx_LinkPreviewWidget_siteName">{ p["og:site_name"] ? (" - " + p["og:site_name"]) : null }</div>
|
<div className="mx_LinkPreviewWidget_siteName">{ p["og:site_name"] ? (" - " + p["og:site_name"]) : null }</div>
|
||||||
<div className="mx_LinkPreviewWidget_description" ref={this._description}>
|
<div className="mx_LinkPreviewWidget_description" ref={this.description}>
|
||||||
{ description }
|
{ description }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<AccessibleButton className="mx_LinkPreviewWidget_cancel" onClick={this.props.onCancelClick} aria-label={_t("Close preview")}>
|
{ this.props.children }
|
||||||
<img className="mx_filterFlipColor" alt="" role="presentation"
|
|
||||||
src={require("../../../../res/img/cancel.svg")} width="18" height="18" />
|
|
||||||
</AccessibleButton>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -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}
|
||||||
|
|
|
@ -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 = (
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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', '');
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -22,7 +22,6 @@ import AccessibleTooltipButton from '../../../elements/AccessibleTooltipButton';
|
||||||
import SdkConfig from "../../../../../SdkConfig";
|
import SdkConfig from "../../../../../SdkConfig";
|
||||||
import createRoom from "../../../../../createRoom";
|
import createRoom from "../../../../../createRoom";
|
||||||
import Modal from "../../../../../Modal";
|
import Modal from "../../../../../Modal";
|
||||||
import * as sdk from "../../../../..";
|
|
||||||
import PlatformPeg from "../../../../../PlatformPeg";
|
import PlatformPeg from "../../../../../PlatformPeg";
|
||||||
import * as KeyboardShortcuts from "../../../../../accessibility/KeyboardShortcuts";
|
import * as KeyboardShortcuts from "../../../../../accessibility/KeyboardShortcuts";
|
||||||
import UpdateCheckButton from "../../UpdateCheckButton";
|
import UpdateCheckButton from "../../UpdateCheckButton";
|
||||||
|
@ -30,6 +29,8 @@ import { replaceableComponent } from "../../../../../utils/replaceableComponent"
|
||||||
import { copyPlaintext } from "../../../../../utils/strings";
|
import { copyPlaintext } 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 BugReportDialog from '../../../dialogs/BugReportDialog';
|
||||||
|
import GenericTextContextMenu from "../../../context_menus/GenericTextContextMenu";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
closeSettingsFn: () => void;
|
closeSettingsFn: () => void;
|
||||||
|
@ -81,10 +82,6 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
|
||||||
};
|
};
|
||||||
|
|
||||||
private onBugReport = (e) => {
|
private onBugReport = (e) => {
|
||||||
const BugReportDialog = sdk.getComponent("dialogs.BugReportDialog");
|
|
||||||
if (!BugReportDialog) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Modal.createTrackedDialog('Bug Report Dialog', '', BugReportDialog, {});
|
Modal.createTrackedDialog('Bug Report Dialog', '', BugReportDialog, {});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -171,7 +168,6 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
|
||||||
|
|
||||||
const successful = await copyPlaintext(MatrixClientPeg.get().getAccessToken());
|
const successful = await copyPlaintext(MatrixClientPeg.get().getAccessToken());
|
||||||
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'),
|
||||||
|
|
|
@ -22,8 +22,11 @@ import { ListRule } from "../../../../../mjolnir/ListRule";
|
||||||
import { BanList, RULE_SERVER, RULE_USER } from "../../../../../mjolnir/BanList";
|
import { BanList, RULE_SERVER, RULE_USER } from "../../../../../mjolnir/BanList";
|
||||||
import Modal from "../../../../../Modal";
|
import Modal from "../../../../../Modal";
|
||||||
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
|
||||||
import * as sdk from "../../../../../index";
|
|
||||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||||
|
import ErrorDialog from "../../../dialogs/ErrorDialog";
|
||||||
|
import QuestionDialog from "../../../dialogs/QuestionDialog";
|
||||||
|
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||||
|
import Field from "../../../elements/Field";
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
busy: boolean;
|
busy: boolean;
|
||||||
|
@ -68,7 +71,6 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
||||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
||||||
Modal.createTrackedDialog('Failed to add Mjolnir rule', '', ErrorDialog, {
|
Modal.createTrackedDialog('Failed to add Mjolnir rule', '', ErrorDialog, {
|
||||||
title: _t('Error adding ignored user/server'),
|
title: _t('Error adding ignored user/server'),
|
||||||
description: _t('Something went wrong. Please try again or view your console for hints.'),
|
description: _t('Something went wrong. Please try again or view your console for hints.'),
|
||||||
|
@ -90,7 +92,6 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
||||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
||||||
Modal.createTrackedDialog('Failed to subscribe to Mjolnir list', '', ErrorDialog, {
|
Modal.createTrackedDialog('Failed to subscribe to Mjolnir list', '', ErrorDialog, {
|
||||||
title: _t('Error subscribing to list'),
|
title: _t('Error subscribing to list'),
|
||||||
description: _t('Please verify the room ID or address and try again.'),
|
description: _t('Please verify the room ID or address and try again.'),
|
||||||
|
@ -108,7 +109,6 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
||||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
||||||
Modal.createTrackedDialog('Failed to remove Mjolnir rule', '', ErrorDialog, {
|
Modal.createTrackedDialog('Failed to remove Mjolnir rule', '', ErrorDialog, {
|
||||||
title: _t('Error removing ignored user/server'),
|
title: _t('Error removing ignored user/server'),
|
||||||
description: _t('Something went wrong. Please try again or view your console for hints.'),
|
description: _t('Something went wrong. Please try again or view your console for hints.'),
|
||||||
|
@ -126,7 +126,6 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
||||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
||||||
Modal.createTrackedDialog('Failed to unsubscribe from Mjolnir list', '', ErrorDialog, {
|
Modal.createTrackedDialog('Failed to unsubscribe from Mjolnir list', '', ErrorDialog, {
|
||||||
title: _t('Error unsubscribing from list'),
|
title: _t('Error unsubscribing from list'),
|
||||||
description: _t('Please try again or view your console for hints.'),
|
description: _t('Please try again or view your console for hints.'),
|
||||||
|
@ -137,8 +136,6 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
||||||
}
|
}
|
||||||
|
|
||||||
private viewListRules(list: BanList) {
|
private viewListRules(list: BanList) {
|
||||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
|
||||||
|
|
||||||
const room = MatrixClientPeg.get().getRoom(list.roomId);
|
const room = MatrixClientPeg.get().getRoom(list.roomId);
|
||||||
const name = room ? room.name : list.roomId;
|
const name = room ? room.name : list.roomId;
|
||||||
|
|
||||||
|
@ -168,8 +165,6 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderPersonalBanListRules() {
|
private renderPersonalBanListRules() {
|
||||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
|
||||||
|
|
||||||
const list = Mjolnir.sharedInstance().getPersonalList();
|
const list = Mjolnir.sharedInstance().getPersonalList();
|
||||||
const rules = list ? [...list.userRules, ...list.serverRules] : [];
|
const rules = list ? [...list.userRules, ...list.serverRules] : [];
|
||||||
if (!list || rules.length <= 0) return <i>{_t("You have not ignored anyone.")}</i>;
|
if (!list || rules.length <= 0) return <i>{_t("You have not ignored anyone.")}</i>;
|
||||||
|
@ -199,8 +194,6 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderSubscribedBanLists() {
|
private renderSubscribedBanLists() {
|
||||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
|
||||||
|
|
||||||
const personalList = Mjolnir.sharedInstance().getPersonalList();
|
const personalList = Mjolnir.sharedInstance().getPersonalList();
|
||||||
const lists = Mjolnir.sharedInstance().lists.filter(b => {
|
const lists = Mjolnir.sharedInstance().lists.filter(b => {
|
||||||
return personalList? personalList.roomId !== b.roomId : true;
|
return personalList? personalList.roomId !== b.roomId : true;
|
||||||
|
@ -241,8 +234,6 @@ export default class MjolnirUserSettingsTab extends React.Component<{}, IState>
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const Field = sdk.getComponent('elements.Field');
|
|
||||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
|
||||||
const brand = SdkConfig.get().brand;
|
const brand = SdkConfig.get().brand;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -20,10 +20,10 @@ import { _t } from "../../../../../languageHandler";
|
||||||
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
|
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
|
||||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||||
import Field from "../../../elements/Field";
|
import Field from "../../../elements/Field";
|
||||||
import * as sdk from "../../../../..";
|
|
||||||
import PlatformPeg from "../../../../../PlatformPeg";
|
import PlatformPeg from "../../../../../PlatformPeg";
|
||||||
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
||||||
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../../../utils/replaceableComponent";
|
||||||
|
import SettingsFlag from '../../../elements/SettingsFlag';
|
||||||
import * as KeyboardShortcuts from "../../../../../accessibility/KeyboardShortcuts";
|
import * as KeyboardShortcuts from "../../../../../accessibility/KeyboardShortcuts";
|
||||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||||
|
|
||||||
|
@ -184,7 +184,6 @@ export default class PreferencesUserSettingsTab extends React.Component<{}, ISta
|
||||||
};
|
};
|
||||||
|
|
||||||
private renderGroup(settingIds: string[]): React.ReactNodeArray {
|
private renderGroup(settingIds: string[]): React.ReactNodeArray {
|
||||||
const SettingsFlag = sdk.getComponent("views.elements.SettingsFlag");
|
|
||||||
return settingIds.filter(SettingsStore.isEnabled).map(i => {
|
return settingIds.filter(SettingsStore.isEnabled).map(i => {
|
||||||
return <SettingsFlag key={i} name={i} level={SettingLevel.ACCOUNT} />;
|
return <SettingsFlag key={i} name={i} level={SettingLevel.ACCOUNT} />;
|
||||||
});
|
});
|
||||||
|
|
|
@ -220,6 +220,7 @@ const SpaceCreateMenu = ({ onFinished }) => {
|
||||||
value={alias}
|
value={alias}
|
||||||
placeholder={name ? nameToAlias(name, domain) : _t("e.g. my-space")}
|
placeholder={name ? nameToAlias(name, domain) : _t("e.g. my-space")}
|
||||||
label={_t("Address")}
|
label={_t("Address")}
|
||||||
|
disabled={busy}
|
||||||
/>
|
/>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ const SpaceSettingsGeneralTab = ({ matrixClient: cli, space, onFinished }: IProp
|
||||||
|
|
||||||
{ error && <div className="mx_SpaceRoomView_errorText">{ error }</div> }
|
{ error && <div className="mx_SpaceRoomView_errorText">{ error }</div> }
|
||||||
|
|
||||||
<SpaceFeedbackPrompt onClick={() => onFinished(false)} />
|
<SpaceFeedbackPrompt />
|
||||||
|
|
||||||
<div className="mx_SettingsTab_section">
|
<div className="mx_SettingsTab_section">
|
||||||
<SpaceBasicSettings
|
<SpaceBasicSettings
|
||||||
|
|
|
@ -21,7 +21,6 @@ import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||||
|
|
||||||
import { MatrixClientPeg } from './MatrixClientPeg';
|
import { MatrixClientPeg } from './MatrixClientPeg';
|
||||||
import Modal from './Modal';
|
import Modal from './Modal';
|
||||||
import * as sdk from './index';
|
|
||||||
import { _t } from './languageHandler';
|
import { _t } from './languageHandler';
|
||||||
import dis from "./dispatcher/dispatcher";
|
import dis from "./dispatcher/dispatcher";
|
||||||
import * as Rooms from "./Rooms";
|
import * as Rooms from "./Rooms";
|
||||||
|
@ -37,6 +36,8 @@ import { makeSpaceParentEvent } from "./utils/space";
|
||||||
import { Action } from "./dispatcher/actions";
|
import { Action } from "./dispatcher/actions";
|
||||||
import { ICreateRoomOpts } from "matrix-js-sdk/src/@types/requests";
|
import { ICreateRoomOpts } from "matrix-js-sdk/src/@types/requests";
|
||||||
import { Preset, Visibility } from "matrix-js-sdk/src/@types/partials";
|
import { Preset, Visibility } from "matrix-js-sdk/src/@types/partials";
|
||||||
|
import ErrorDialog from "./components/views/dialogs/ErrorDialog";
|
||||||
|
import Spinner from "./components/views/elements/Spinner";
|
||||||
|
|
||||||
// we define a number of interfaces which take their names from the js-sdk
|
// we define a number of interfaces which take their names from the js-sdk
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
|
@ -80,9 +81,6 @@ export default function createRoom(opts: IOpts): Promise<string | null> {
|
||||||
|
|
||||||
const startTime = CountlyAnalytics.getTimestamp();
|
const startTime = CountlyAnalytics.getTimestamp();
|
||||||
|
|
||||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
||||||
const Loader = sdk.getComponent("elements.Spinner");
|
|
||||||
|
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
if (client.isGuest()) {
|
if (client.isGuest()) {
|
||||||
dis.dispatch({ action: 'require_registration' });
|
dis.dispatch({ action: 'require_registration' });
|
||||||
|
@ -153,7 +151,7 @@ export default function createRoom(opts: IOpts): Promise<string | null> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let modal;
|
let modal;
|
||||||
if (opts.spinner) modal = Modal.createDialog(Loader, null, 'mx_Dialog_spinner');
|
if (opts.spinner) modal = Modal.createDialog(Spinner, null, 'mx_Dialog_spinner');
|
||||||
|
|
||||||
let roomId;
|
let roomId;
|
||||||
return client.createRoom(createOpts).finally(function() {
|
return client.createRoom(createOpts).finally(function() {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue