Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into t3chguy/app_load4
This commit is contained in:
commit
e06b5f8cf3
18 changed files with 184 additions and 128 deletions
|
@ -94,7 +94,6 @@
|
||||||
@import "./views/elements/_AccessibleButton.scss";
|
@import "./views/elements/_AccessibleButton.scss";
|
||||||
@import "./views/elements/_AddressSelector.scss";
|
@import "./views/elements/_AddressSelector.scss";
|
||||||
@import "./views/elements/_AddressTile.scss";
|
@import "./views/elements/_AddressTile.scss";
|
||||||
@import "./views/elements/_ButtonPlaceholder.scss";
|
|
||||||
@import "./views/elements/_DirectorySearchBox.scss";
|
@import "./views/elements/_DirectorySearchBox.scss";
|
||||||
@import "./views/elements/_Dropdown.scss";
|
@import "./views/elements/_Dropdown.scss";
|
||||||
@import "./views/elements/_EditableItemList.scss";
|
@import "./views/elements/_EditableItemList.scss";
|
||||||
|
|
|
@ -26,6 +26,50 @@ limitations under the License.
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_CompleteSecurity_clients {
|
||||||
|
width: max-content;
|
||||||
|
margin: 36px auto 0;
|
||||||
|
|
||||||
|
.mx_CompleteSecurity_clients_desktop, .mx_CompleteSecurity_clients_mobile {
|
||||||
|
position: relative;
|
||||||
|
width: 160px;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 64px;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
height: 48px;
|
||||||
|
width: 48px;
|
||||||
|
left: 56px;
|
||||||
|
top: 0;
|
||||||
|
background-color: $muted-fg-color;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-size: contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_CompleteSecurity_clients_desktop {
|
||||||
|
margin-right: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_CompleteSecurity_clients_desktop::before {
|
||||||
|
mask-image: url('$(res)/img/feather-customised/monitor.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_CompleteSecurity_clients_mobile::before {
|
||||||
|
mask-image: url('$(res)/img/feather-customised/smartphone.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 16px;
|
||||||
|
font-size: $font-12px;
|
||||||
|
color: $muted-fg-color;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.mx_CompleteSecurity_heroIcon {
|
.mx_CompleteSecurity_heroIcon {
|
||||||
width: 128px;
|
width: 128px;
|
||||||
height: 128px;
|
height: 128px;
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.mx_ButtonPlaceholder {
|
|
||||||
font-size: $font-14px;
|
|
||||||
font-weight: 600;
|
|
||||||
padding: 7px 18px;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center;
|
|
||||||
color: $authpage-secondary-color;
|
|
||||||
}
|
|
5
res/img/feather-customised/monitor.svg
Normal file
5
res/img/feather-customised/monitor.svg
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 5C2 3.89543 2.89543 3 4 3H20C21.1046 3 22 3.89543 22 5V15C22 16.1046 21.1046 17 20 17H4C2.89543 17 2 16.1046 2 15V5Z" stroke="#2E2F32" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M8 21H16" stroke="#2E2F32" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M12 17V21" stroke="#2E2F32" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 510 B |
4
res/img/feather-customised/smartphone.svg
Normal file
4
res/img/feather-customised/smartphone.svg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 4C5 2.89543 5.89543 2 7 2H17C18.1046 2 19 2.89543 19 4V20C19 21.1046 18.1046 22 17 22H7C5.89543 22 5 21.1046 5 20V4Z" stroke="#2E2F32" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<circle cx="12" cy="18" r="1" fill="#2E2F32"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 386 B |
|
@ -446,7 +446,8 @@ export function bodyToHtml(content, highlights, opts={}) {
|
||||||
// their username. Permalinks (links in pills) can be any URL
|
// their username. Permalinks (links in pills) can be any URL
|
||||||
// now, so we just check for an HTTP-looking thing.
|
// now, so we just check for an HTTP-looking thing.
|
||||||
(
|
(
|
||||||
content.formatted_body == undefined ||
|
strippedBody === safeBody || // replies have the html fallbacks, account for that here
|
||||||
|
content.formatted_body === undefined ||
|
||||||
(!content.formatted_body.includes("http:") &&
|
(!content.formatted_body.includes("http:") &&
|
||||||
!content.formatted_body.includes("https:"))
|
!content.formatted_body.includes("https:"))
|
||||||
);
|
);
|
||||||
|
|
|
@ -83,7 +83,15 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
this._fetchBackupInfo();
|
this._fetchBackupInfo();
|
||||||
this._queryKeyUploadAuth();
|
if (this.state.accountPassword) {
|
||||||
|
// If we have an account password in memory, let's simplify and
|
||||||
|
// assume it means password auth is also supported for device
|
||||||
|
// signing key upload as well. This avoids hitting the server to
|
||||||
|
// test auth flows, which may be slow under high load.
|
||||||
|
this.state.canUploadKeysWithPasswordOnly = true;
|
||||||
|
} else {
|
||||||
|
this._queryKeyUploadAuth();
|
||||||
|
}
|
||||||
|
|
||||||
MatrixClientPeg.get().on('crypto.keyBackupStatus', this._onKeyBackupStatusChange);
|
MatrixClientPeg.get().on('crypto.keyBackupStatus', this._onKeyBackupStatusChange);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ export default class AutocompleteProvider {
|
||||||
commandRegex = this.forcedCommandRegex || /\S+/g;
|
commandRegex = this.forcedCommandRegex || /\S+/g;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commandRegex === null) {
|
if (!commandRegex) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ export default class UserProvider extends AutocompleteProvider {
|
||||||
const MemberAvatar = sdk.getComponent('views.avatars.MemberAvatar');
|
const MemberAvatar = sdk.getComponent('views.avatars.MemberAvatar');
|
||||||
|
|
||||||
// lazy-load user list into matcher
|
// lazy-load user list into matcher
|
||||||
if (this.users === null) this._makeUsers();
|
if (!this.users) this._makeUsers();
|
||||||
|
|
||||||
let completions = [];
|
let completions = [];
|
||||||
const {command, range} = this.getCurrentCommand(rawQuery, selection, force);
|
const {command, range} = this.getCurrentCommand(rawQuery, selection, force);
|
||||||
|
@ -158,7 +158,7 @@ export default class UserProvider extends AutocompleteProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
onUserSpoke(user: RoomMember) {
|
onUserSpoke(user: RoomMember) {
|
||||||
if (this.users === null) return;
|
if (!this.users) return;
|
||||||
if (!user) return;
|
if (!user) return;
|
||||||
if (user.userId === MatrixClientPeg.get().credentials.userId) return;
|
if (user.userId === MatrixClientPeg.get().credentials.userId) return;
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ export default class CompleteSecurity extends React.Component {
|
||||||
|
|
||||||
if (phase === PHASE_INTRO) {
|
if (phase === PHASE_INTRO) {
|
||||||
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_warning" />;
|
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_warning" />;
|
||||||
title = _t("Verify this session");
|
title = _t("Verify this login");
|
||||||
} else if (phase === PHASE_DONE) {
|
} else if (phase === PHASE_DONE) {
|
||||||
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_verified" />;
|
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_verified" />;
|
||||||
title = _t("Session verified");
|
title = _t("Session verified");
|
||||||
|
@ -69,7 +69,7 @@ export default class CompleteSecurity extends React.Component {
|
||||||
title = _t("Are you sure?");
|
title = _t("Are you sure?");
|
||||||
} else if (phase === PHASE_BUSY) {
|
} else if (phase === PHASE_BUSY) {
|
||||||
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_warning" />;
|
icon = <span className="mx_CompleteSecurity_headerIcon mx_E2EIcon_warning" />;
|
||||||
title = _t("Verify this session");
|
title = _t("Verify this login");
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Unknown phase ${phase}`);
|
throw new Error(`Unknown phase ${phase}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,31 +108,35 @@ export default class SetupEncryptionBody extends React.Component {
|
||||||
member={MatrixClientPeg.get().getUser(this.state.verificationRequest.otherUserId)}
|
member={MatrixClientPeg.get().getUser(this.state.verificationRequest.otherUserId)}
|
||||||
/>;
|
/>;
|
||||||
} else if (phase === PHASE_INTRO) {
|
} else if (phase === PHASE_INTRO) {
|
||||||
const ButtonPlaceholder = sdk.getComponent("elements.ButtonPlaceholder");
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>{_t(
|
<p>{_t(
|
||||||
"Use an existing session to verify this one, " +
|
"Confirm your identity by verifying this login from one of your other sessions, " +
|
||||||
"granting it access to encrypted messages.",
|
"granting it access to encrypted messages.",
|
||||||
)}</p>
|
)}</p>
|
||||||
<p>{_t(
|
<p>{_t(
|
||||||
"If you can’t access one, <button>use your recovery key or recovery passphrase.</button>",
|
"This requires the latest Riot on your other devices:",
|
||||||
{}, {
|
)}</p>
|
||||||
button: sub => <AccessibleButton element="span"
|
|
||||||
className="mx_linkButton"
|
<div className="mx_CompleteSecurity_clients">
|
||||||
onClick={this._onUsePassphraseClick}
|
<div className="mx_CompleteSecurity_clients_desktop">
|
||||||
>
|
<div>Riot Web</div>
|
||||||
{sub}
|
<div>Riot Desktop</div>
|
||||||
</AccessibleButton>,
|
</div>
|
||||||
})}</p>
|
<div className="mx_CompleteSecurity_clients_mobile">
|
||||||
|
<div>Riot iOS</div>
|
||||||
|
<div>Riot X for Android</div>
|
||||||
|
</div>
|
||||||
|
<p>{_t("or another cross-signing capable Matrix client")}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="mx_CompleteSecurity_actionRow">
|
<div className="mx_CompleteSecurity_actionRow">
|
||||||
<AccessibleButton
|
<AccessibleButton kind="link" onClick={this.onSkipClick}>
|
||||||
kind="danger"
|
{_t("Use Recovery Passphrase or Key")}
|
||||||
onClick={this.onSkipClick}
|
</AccessibleButton>
|
||||||
>
|
<AccessibleButton kind="danger" onClick={this.onSkipClick}>
|
||||||
{_t("Skip")}
|
{_t("Skip")}
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
<ButtonPlaceholder>{_t("Use your other device to continue…")}</ButtonPlaceholder>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -150,7 +154,7 @@ export default class SetupEncryptionBody extends React.Component {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="mx_CompleteSecurity_heroIcon mx_E2EIcon_verified"></div>
|
<div className="mx_CompleteSecurity_heroIcon mx_E2EIcon_verified" />
|
||||||
{message}
|
{message}
|
||||||
<div className="mx_CompleteSecurity_actionRow">
|
<div className="mx_CompleteSecurity_actionRow">
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
|
|
|
@ -102,11 +102,15 @@ export default createReactClass({
|
||||||
"No identity server is configured so you cannot add an email address in order to " +
|
"No identity server is configured so you cannot add an email address in order to " +
|
||||||
"reset your password in the future.",
|
"reset your password in the future.",
|
||||||
);
|
);
|
||||||
} else {
|
} else if (this._showEmail()) {
|
||||||
desc = _t(
|
desc = _t(
|
||||||
"If you don't specify an email address, you won't be able to reset your password. " +
|
"If you don't specify an email address, you won't be able to reset your password. " +
|
||||||
"Are you sure?",
|
"Are you sure?",
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
// user can't set an e-mail so don't prompt them to
|
||||||
|
self._doSubmit(ev);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||||
|
|
|
@ -26,30 +26,6 @@ import { _t } from '../../../languageHandler';
|
||||||
import InteractiveAuth, {ERROR_USER_CANCELLED} from "../../structures/InteractiveAuth";
|
import InteractiveAuth, {ERROR_USER_CANCELLED} from "../../structures/InteractiveAuth";
|
||||||
import {DEFAULT_PHASE, PasswordAuthEntry, SSOAuthEntry} from "../auth/InteractiveAuthEntryComponents";
|
import {DEFAULT_PHASE, PasswordAuthEntry, SSOAuthEntry} from "../auth/InteractiveAuthEntryComponents";
|
||||||
|
|
||||||
const dialogAesthetics = {
|
|
||||||
[SSOAuthEntry.PHASE_PREAUTH]: {
|
|
||||||
body: _t("Confirm your account deactivation by using Single Sign On to prove your identity."),
|
|
||||||
continueText: _t("Single Sign On"),
|
|
||||||
continueKind: "danger",
|
|
||||||
},
|
|
||||||
[SSOAuthEntry.PHASE_POSTAUTH]: {
|
|
||||||
body: _t("Are you sure you want to deactivate your account? This is irreversible."),
|
|
||||||
continueText: _t("Confirm account deactivation"),
|
|
||||||
continueKind: "danger",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is the same as aestheticsForStagePhases in InteractiveAuthDialog minus the `title`
|
|
||||||
const DEACTIVATE_AESTHETICS = {
|
|
||||||
[SSOAuthEntry.LOGIN_TYPE]: dialogAesthetics,
|
|
||||||
[SSOAuthEntry.UNSTABLE_LOGIN_TYPE]: dialogAesthetics,
|
|
||||||
[PasswordAuthEntry.LOGIN_TYPE]: {
|
|
||||||
[DEFAULT_PHASE]: {
|
|
||||||
body: _t("To continue, please enter your password:"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class DeactivateAccountDialog extends React.Component {
|
export default class DeactivateAccountDialog extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -84,6 +60,30 @@ export default class DeactivateAccountDialog extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
_onStagePhaseChange = (stage, phase) => {
|
_onStagePhaseChange = (stage, phase) => {
|
||||||
|
const dialogAesthetics = {
|
||||||
|
[SSOAuthEntry.PHASE_PREAUTH]: {
|
||||||
|
body: _t("Confirm your account deactivation by using Single Sign On to prove your identity."),
|
||||||
|
continueText: _t("Single Sign On"),
|
||||||
|
continueKind: "danger",
|
||||||
|
},
|
||||||
|
[SSOAuthEntry.PHASE_POSTAUTH]: {
|
||||||
|
body: _t("Are you sure you want to deactivate your account? This is irreversible."),
|
||||||
|
continueText: _t("Confirm account deactivation"),
|
||||||
|
continueKind: "danger",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is the same as aestheticsForStagePhases in InteractiveAuthDialog minus the `title`
|
||||||
|
const DEACTIVATE_AESTHETICS = {
|
||||||
|
[SSOAuthEntry.LOGIN_TYPE]: dialogAesthetics,
|
||||||
|
[SSOAuthEntry.UNSTABLE_LOGIN_TYPE]: dialogAesthetics,
|
||||||
|
[PasswordAuthEntry.LOGIN_TYPE]: {
|
||||||
|
[DEFAULT_PHASE]: {
|
||||||
|
body: _t("To continue, please enter your password:"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const aesthetics = DEACTIVATE_AESTHETICS[stage];
|
const aesthetics = DEACTIVATE_AESTHETICS[stage];
|
||||||
let bodyText = null;
|
let bodyText = null;
|
||||||
let continueText = null;
|
let continueText = null;
|
||||||
|
|
|
@ -1,19 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default function ButtonPlaceholder(props) {
|
|
||||||
return <div className="mx_ButtonPlaceholder">{props.children}</div>;
|
|
||||||
}
|
|
|
@ -259,7 +259,7 @@ export default class Autocomplete extends React.PureComponent<IProps, IState> {
|
||||||
const selectedCompletion = this.refs[`completion${this.state.selectionOffset}`];
|
const selectedCompletion = this.refs[`completion${this.state.selectionOffset}`];
|
||||||
if (selectedCompletion && this.containerRef.current) {
|
if (selectedCompletion && this.containerRef.current) {
|
||||||
const domNode = ReactDOM.findDOMNode(selectedCompletion);
|
const domNode = ReactDOM.findDOMNode(selectedCompletion);
|
||||||
const offsetTop = domNode && domNode.offsetTop;
|
const offsetTop = domNode && (domNode as HTMLElement).offsetTop;
|
||||||
if (offsetTop > this.containerRef.current.scrollTop + this.containerRef.current.offsetHeight ||
|
if (offsetTop > this.containerRef.current.scrollTop + this.containerRef.current.offsetHeight ||
|
||||||
offsetTop < this.containerRef.current.scrollTop) {
|
offsetTop < this.containerRef.current.scrollTop) {
|
||||||
this.containerRef.current.scrollTop = offsetTop - this.containerRef.current.offsetTop;
|
this.containerRef.current.scrollTop = offsetTop - this.containerRef.current.offsetTop;
|
||||||
|
|
|
@ -25,11 +25,13 @@ import Analytics from "../../../../../Analytics";
|
||||||
import Modal from "../../../../../Modal";
|
import Modal from "../../../../../Modal";
|
||||||
import * as sdk from "../../../../..";
|
import * as sdk from "../../../../..";
|
||||||
import {sleep} from "../../../../../utils/promise";
|
import {sleep} from "../../../../../utils/promise";
|
||||||
|
import dis from "../../../../../dispatcher";
|
||||||
|
|
||||||
export class IgnoredUser extends React.Component {
|
export class IgnoredUser extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
userId: PropTypes.string.isRequired,
|
userId: PropTypes.string.isRequired,
|
||||||
onUnignored: PropTypes.func.isRequired,
|
onUnignored: PropTypes.func.isRequired,
|
||||||
|
inProgress: PropTypes.bool.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
_onUnignoreClicked = (e) => {
|
_onUnignoreClicked = (e) => {
|
||||||
|
@ -40,7 +42,7 @@ export class IgnoredUser extends React.Component {
|
||||||
const id = `mx_SecurityUserSettingsTab_ignoredUser_${this.props.userId}`;
|
const id = `mx_SecurityUserSettingsTab_ignoredUser_${this.props.userId}`;
|
||||||
return (
|
return (
|
||||||
<div className='mx_SecurityUserSettingsTab_ignoredUser'>
|
<div className='mx_SecurityUserSettingsTab_ignoredUser'>
|
||||||
<AccessibleButton onClick={this._onUnignoreClicked} kind='primary_sm' aria-describedby={id}>
|
<AccessibleButton onClick={this._onUnignoreClicked} kind='primary_sm' aria-describedby={id} disabled={this.props.inProgress}>
|
||||||
{ _t('Unignore') }
|
{ _t('Unignore') }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
<span id={id}>{ this.props.userId }</span>
|
<span id={id}>{ this.props.userId }</span>
|
||||||
|
@ -58,9 +60,29 @@ export default class SecurityUserSettingsTab extends React.Component {
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
ignoredUserIds: MatrixClientPeg.get().getIgnoredUsers(),
|
ignoredUserIds: MatrixClientPeg.get().getIgnoredUsers(),
|
||||||
|
waitingUnignored: [],
|
||||||
managingInvites: false,
|
managingInvites: false,
|
||||||
invitedRoomAmt: invitedRooms.length,
|
invitedRoomAmt: invitedRooms.length,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this._onAction = this._onAction.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_onAction({action}) {
|
||||||
|
if (action === "ignore_state_changed") {
|
||||||
|
const ignoredUserIds = MatrixClientPeg.get().getIgnoredUsers();
|
||||||
|
const newWaitingUnignored = this.state.waitingUnignored.filter(e=> ignoredUserIds.includes(e));
|
||||||
|
this.setState({ignoredUserIds, waitingUnignored: newWaitingUnignored});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.dispatcherRef = dis.register(this._onAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
dis.unregister(this.dispatcherRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateBlacklistDevicesFlag = (checked) => {
|
_updateBlacklistDevicesFlag = (checked) => {
|
||||||
|
@ -86,16 +108,15 @@ export default class SecurityUserSettingsTab extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
_onUserUnignored = async (userId) => {
|
_onUserUnignored = async (userId) => {
|
||||||
// Don't use this.state to get the ignored user list as it might be
|
const {ignoredUserIds, waitingUnignored} = this.state;
|
||||||
// ever so slightly outdated. Instead, prefer to get a fresh list and
|
const currentlyIgnoredUserIds = ignoredUserIds.filter(e => !waitingUnignored.includes(e));
|
||||||
// update that.
|
|
||||||
const ignoredUsers = MatrixClientPeg.get().getIgnoredUsers();
|
const index = currentlyIgnoredUserIds.indexOf(userId);
|
||||||
const index = ignoredUsers.indexOf(userId);
|
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
ignoredUsers.splice(index, 1);
|
currentlyIgnoredUserIds.splice(index, 1);
|
||||||
MatrixClientPeg.get().setIgnoredUsers(ignoredUsers);
|
this.setState(({waitingUnignored}) => ({waitingUnignored: [...waitingUnignored, userId]}));
|
||||||
|
MatrixClientPeg.get().setIgnoredUsers(currentlyIgnoredUserIds);
|
||||||
}
|
}
|
||||||
this.setState({ignoredUsers});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_getInvitedRooms = () => {
|
_getInvitedRooms = () => {
|
||||||
|
@ -201,10 +222,17 @@ export default class SecurityUserSettingsTab extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderIgnoredUsers() {
|
_renderIgnoredUsers() {
|
||||||
if (!this.state.ignoredUserIds || this.state.ignoredUserIds.length === 0) return null;
|
const {waitingUnignored, ignoredUserIds} = this.state;
|
||||||
|
|
||||||
const userIds = this.state.ignoredUserIds
|
if (!ignoredUserIds || ignoredUserIds.length === 0) return null;
|
||||||
.map((u) => <IgnoredUser userId={u} onUnignored={this._onUserUnignored} key={u} />);
|
|
||||||
|
const userIds = ignoredUserIds
|
||||||
|
.map((u) => <IgnoredUser
|
||||||
|
userId={u}
|
||||||
|
onUnignored={this._onUserUnignored}
|
||||||
|
key={u}
|
||||||
|
inProgress={waitingUnignored.includes(u)}
|
||||||
|
/>);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='mx_SettingsTab_section'>
|
<div className='mx_SettingsTab_section'>
|
||||||
|
|
|
@ -1580,12 +1580,12 @@
|
||||||
"You've previously used a newer version of Riot on %(host)s. To use this version again with end to end encryption, you will need to sign out and back in again. ": "You've previously used a newer version of Riot on %(host)s. To use this version again with end to end encryption, you will need to sign out and back in again. ",
|
"You've previously used a newer version of Riot on %(host)s. To use this version again with end to end encryption, you will need to sign out and back in again. ": "You've previously used a newer version of Riot on %(host)s. To use this version again with end to end encryption, you will need to sign out and back in again. ",
|
||||||
"Incompatible Database": "Incompatible Database",
|
"Incompatible Database": "Incompatible Database",
|
||||||
"Continue With Encryption Disabled": "Continue With Encryption Disabled",
|
"Continue With Encryption Disabled": "Continue With Encryption Disabled",
|
||||||
|
"Server did not require any authentication": "Server did not require any authentication",
|
||||||
|
"Server did not return valid authentication information.": "Server did not return valid authentication information.",
|
||||||
"Confirm your account deactivation by using Single Sign On to prove your identity.": "Confirm your account deactivation by using Single Sign On to prove your identity.",
|
"Confirm your account deactivation by using Single Sign On to prove your identity.": "Confirm your account deactivation by using Single Sign On to prove your identity.",
|
||||||
"Are you sure you want to deactivate your account? This is irreversible.": "Are you sure you want to deactivate your account? This is irreversible.",
|
"Are you sure you want to deactivate your account? This is irreversible.": "Are you sure you want to deactivate your account? This is irreversible.",
|
||||||
"Confirm account deactivation": "Confirm account deactivation",
|
"Confirm account deactivation": "Confirm account deactivation",
|
||||||
"To continue, please enter your password:": "To continue, please enter your password:",
|
"To continue, please enter your password:": "To continue, please enter your password:",
|
||||||
"Server did not require any authentication": "Server did not require any authentication",
|
|
||||||
"Server did not return valid authentication information.": "Server did not return valid authentication information.",
|
|
||||||
"There was a problem communicating with the server. Please try again.": "There was a problem communicating with the server. Please try again.",
|
"There was a problem communicating with the server. Please try again.": "There was a problem communicating with the server. Please try again.",
|
||||||
"This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. <b>This action is irreversible.</b>": "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. <b>This action is irreversible.</b>",
|
"This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. <b>This action is irreversible.</b>": "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. <b>This action is irreversible.</b>",
|
||||||
"Deactivating your account <b>does not by default cause us to forget messages you have sent.</b> If you would like us to forget your messages, please tick the box below.": "Deactivating your account <b>does not by default cause us to forget messages you have sent.</b> If you would like us to forget your messages, please tick the box below.",
|
"Deactivating your account <b>does not by default cause us to forget messages you have sent.</b> If you would like us to forget your messages, please tick the box below.": "Deactivating your account <b>does not by default cause us to forget messages you have sent.</b> If you would like us to forget your messages, please tick the box below.",
|
||||||
|
@ -2067,6 +2067,7 @@
|
||||||
"Uploading %(filename)s and %(count)s others|zero": "Uploading %(filename)s",
|
"Uploading %(filename)s and %(count)s others|zero": "Uploading %(filename)s",
|
||||||
"Uploading %(filename)s and %(count)s others|one": "Uploading %(filename)s and %(count)s other",
|
"Uploading %(filename)s and %(count)s others|one": "Uploading %(filename)s and %(count)s other",
|
||||||
"Could not load user profile": "Could not load user profile",
|
"Could not load user profile": "Could not load user profile",
|
||||||
|
"Verify this login": "Verify this login",
|
||||||
"Session verified": "Session verified",
|
"Session verified": "Session verified",
|
||||||
"Failed to send email": "Failed to send email",
|
"Failed to send email": "Failed to send email",
|
||||||
"The email address linked to your account must be entered.": "The email address linked to your account must be entered.",
|
"The email address linked to your account must be entered.": "The email address linked to your account must be entered.",
|
||||||
|
@ -2120,9 +2121,10 @@
|
||||||
"You can now close this window or <a>log in</a> to your new account.": "You can now close this window or <a>log in</a> to your new account.",
|
"You can now close this window or <a>log in</a> to your new account.": "You can now close this window or <a>log in</a> to your new account.",
|
||||||
"Registration Successful": "Registration Successful",
|
"Registration Successful": "Registration Successful",
|
||||||
"Create your account": "Create your account",
|
"Create your account": "Create your account",
|
||||||
"Use an existing session to verify this one, granting it access to encrypted messages.": "Use an existing session to verify this one, granting it access to encrypted messages.",
|
"Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.",
|
||||||
"If you can’t access one, <button>use your recovery key or recovery passphrase.</button>": "If you can’t access one, <button>use your recovery key or recovery passphrase.</button>",
|
"This requires the latest Riot on your other devices:": "This requires the latest Riot on your other devices:",
|
||||||
"Use your other device to continue…": "Use your other device to continue…",
|
"or another cross-signing capable Matrix client": "or another cross-signing capable Matrix client",
|
||||||
|
"Use Recovery Passphrase or Key": "Use Recovery Passphrase or Key",
|
||||||
"Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.",
|
"Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.",
|
||||||
"Your new session is now verified. Other users will see it as trusted.": "Your new session is now verified. Other users will see it as trusted.",
|
"Your new session is now verified. Other users will see it as trusted.": "Your new session is now verified. Other users will see it as trusted.",
|
||||||
"Without completing security on this session, it won’t have access to encrypted messages.": "Without completing security on this session, it won’t have access to encrypted messages.",
|
"Without completing security on this session, it won’t have access to encrypted messages.": "Without completing security on this session, it won’t have access to encrypted messages.",
|
||||||
|
|
|
@ -642,7 +642,7 @@ enable_registration: true
|
||||||
# Explicitly disable asking for MSISDNs from the registration
|
# Explicitly disable asking for MSISDNs from the registration
|
||||||
# flow (overrides registrations_require_3pid if MSISDNs are set as required)
|
# flow (overrides registrations_require_3pid if MSISDNs are set as required)
|
||||||
#
|
#
|
||||||
#disable_msisdn_registration: true
|
disable_msisdn_registration: false
|
||||||
|
|
||||||
# Mandate that users are only allowed to associate certain formats of
|
# Mandate that users are only allowed to associate certain formats of
|
||||||
# 3PIDs with accounts on this server.
|
# 3PIDs with accounts on this server.
|
||||||
|
@ -882,22 +882,22 @@ password_config:
|
||||||
# If your SMTP server requires authentication, the optional smtp_user &
|
# If your SMTP server requires authentication, the optional smtp_user &
|
||||||
# smtp_pass variables should be used
|
# smtp_pass variables should be used
|
||||||
#
|
#
|
||||||
#email:
|
email:
|
||||||
# enable_notifs: false
|
enable_notifs: false
|
||||||
# smtp_host: "localhost"
|
smtp_host: "localhost"
|
||||||
# smtp_port: 25
|
smtp_port: 25
|
||||||
# smtp_user: "exampleusername"
|
smtp_user: "exampleusername"
|
||||||
# smtp_pass: "examplepassword"
|
smtp_pass: "examplepassword"
|
||||||
# require_transport_security: False
|
require_transport_security: False
|
||||||
# notif_from: "Your Friendly %(app)s Home Server <noreply@example.com>"
|
notif_from: "Your Friendly %(app)s Home Server <noreply@example.com>"
|
||||||
# app_name: Matrix
|
app_name: Matrix
|
||||||
# # if template_dir is unset, uses the example templates that are part of
|
# if template_dir is unset, uses the example templates that are part of
|
||||||
# # the Synapse distribution.
|
# the Synapse distribution.
|
||||||
# #template_dir: res/templates
|
#template_dir: res/templates
|
||||||
# notif_template_html: notif_mail.html
|
notif_template_html: notif_mail.html
|
||||||
# notif_template_text: notif_mail.txt
|
notif_template_text: notif_mail.txt
|
||||||
# notif_for_new_users: True
|
notif_for_new_users: True
|
||||||
# riot_base_url: "http://localhost/riot"
|
riot_base_url: "http://localhost/riot"
|
||||||
|
|
||||||
|
|
||||||
#password_providers:
|
#password_providers:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue