Merge remote-tracking branch 'origin/develop' into travis/skinning/pt3-easy-comps

This commit is contained in:
Travis Ralston 2021-03-09 09:33:19 -07:00
commit 5b3367d44e
24 changed files with 73 additions and 65 deletions

View File

@ -22,9 +22,18 @@ limitations under the License.
float: right;
}
.mx_ViewSource_label_bottom {
.mx_ViewSource_separator {
clear: both;
border-bottom: 1px solid #e5e5e5;
padding-top: 0.7em;
padding-bottom: 0.7em;
}
.mx_ViewSource_heading {
font-size: $font-17px;
font-weight: 400;
color: $primary-fg-color;
margin-top: 0.7em;
}
.mx_ViewSource pre {
@ -34,3 +43,7 @@ limitations under the License.
word-wrap: break-word;
white-space: pre-wrap;
}
.mx_ViewSource_details {
margin-top: 0.8em;
}

View File

@ -21,7 +21,7 @@ $left-gutter: 64px;
.mx_EventTile {
> .mx_SenderProfile {
line-height: $font-20px;
padding-left: $left-gutter;
margin-left: $left-gutter;
}
> .mx_EventTile_line {

View File

@ -630,7 +630,7 @@ export default class CallHandler {
logger.debug("Mapped real room " + roomId + " to room ID " + mappedRoomId);
const timeUntilTurnCresExpire = MatrixClientPeg.get().getTurnServersExpiry() - Date.now();
console.log("Current turn creds expire in " + timeUntilTurnCresExpire + " seconds");
console.log("Current turn creds expire in " + timeUntilTurnCresExpire + " ms");
const call = createNewMatrixCall(MatrixClientPeg.get(), mappedRoomId);
this.calls.set(roomId, call);

View File

@ -23,7 +23,7 @@ class Skinner {
if (!name) throw new Error(`Invalid component name: ${name}`);
if (this.components === null) {
throw new Error(
"Attempted to get a component before a skin has been loaded."+
`Attempted to get a component (${name}) before a skin has been loaded.`+
" This is probably because either:"+
" a) Your app has not called sdk.loadSkin(), or"+
" b) A component has called getComponent at the root level",

View File

@ -441,15 +441,14 @@ export const Commands = [
}),
new Command({
command: 'invite',
args: '<user-id>',
args: '<user-id> [<reason>]',
description: _td('Invites user with given id to current room'),
runFn: function(roomId, args) {
if (args) {
const matches = args.match(/^(\S+)$/);
if (matches) {
const [address, reason] = args.split(/\s+(.+)/);
if (address) {
// We use a MultiInviter to re-use the invite logic, even though
// we're only inviting one user.
const address = matches[1];
// If we need an identity server but don't have one, things
// get a bit more complex here, but we try to show something
// meaningful.
@ -490,7 +489,7 @@ export const Commands = [
}
const inviter = new MultiInviter(roomId);
return success(prom.then(() => {
return inviter.invite([address]);
return inviter.invite([address], reason);
}).then(() => {
if (inviter.getCompletionState(address) !== "invited") {
throw new Error(inviter.getErrorText(address));

View File

@ -16,8 +16,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
import React from 'react';
import PropTypes from 'prop-types';
import request from 'browser-request';

View File

@ -31,20 +31,49 @@ export default class ViewSource extends React.Component {
onFinished: PropTypes.func.isRequired,
roomId: PropTypes.string.isRequired,
eventId: PropTypes.string.isRequired,
isEncrypted: PropTypes.bool.isRequired,
decryptedContent: PropTypes.object,
};
render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
return (
<BaseDialog className="mx_ViewSource" onFinished={this.props.onFinished} title={_t('View Source')}>
<div className="mx_ViewSource_label_left">Room ID: { this.props.roomId }</div>
<div className="mx_ViewSource_label_right">Event ID: { this.props.eventId }</div>
<div className="mx_ViewSource_label_bottom" />
<div className="mx_Dialog_content">
let content;
if (this.props.isEncrypted) {
content = <>
<details open className="mx_ViewSource_details">
<summary>
<span className="mx_ViewSource_heading">{_t("Decrypted event source")}</span>
</summary>
<SyntaxHighlight className="json">
{ JSON.stringify(this.props.decryptedContent, null, 2) }
</SyntaxHighlight>
</details>
<details className="mx_ViewSource_details">
<summary>
<span className="mx_ViewSource_heading">{_t("Original event source")}</span>
</summary>
<SyntaxHighlight className="json">
{ JSON.stringify(this.props.content, null, 2) }
</SyntaxHighlight>
</details>
</>;
} else {
content = <>
<div className="mx_ViewSource_heading">{_t("Original event source")}</div>
<SyntaxHighlight className="json">
{ JSON.stringify(this.props.content, null, 2) }
</SyntaxHighlight>
</>;
}
return (
<BaseDialog className="mx_ViewSource" onFinished={this.props.onFinished} title={_t('View Source')}>
<div className="mx_Dialog_content">
<div className="mx_ViewSource_label_left">Room ID: { this.props.roomId }</div>
<div className="mx_ViewSource_label_left">Event ID: { this.props.eventId }</div>
<div className="mx_ViewSource_separator" />
{ content }
</div>
</BaseDialog>
);

View File

@ -14,8 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
import React from 'react';
import {replaceableComponent} from "../../../utils/replaceableComponent";

View File

@ -14,8 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
import React from 'react';
import {replaceableComponent} from "../../../utils/replaceableComponent";

View File

@ -14,8 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
import React from 'react';
import {replaceableComponent} from "../../../utils/replaceableComponent";

View File

@ -132,18 +132,9 @@ export default class MessageContextMenu extends React.Component {
roomId: ev.getRoomId(),
eventId: ev.getId(),
content: ev.event,
}, 'mx_Dialog_viewsource');
this.closeMenu();
};
onViewClearSourceClick = () => {
const ev = this.props.mxEvent.replacingEvent() || this.props.mxEvent;
const ViewSource = sdk.getComponent('structures.ViewSource');
Modal.createTrackedDialog('View Clear Event Source', '', ViewSource, {
roomId: ev.getRoomId(),
eventId: ev.getId(),
isEncrypted: ev.isEncrypted(),
// FIXME: _clearEvent is private
content: ev._clearEvent,
decryptedContent: ev._clearEvent,
}, 'mx_Dialog_viewsource');
this.closeMenu();
};
@ -311,7 +302,6 @@ export default class MessageContextMenu extends React.Component {
let cancelButton;
let forwardButton;
let pinButton;
let viewClearSourceButton;
let unhidePreviewButton;
let externalURLButton;
let quoteButton;
@ -391,14 +381,6 @@ export default class MessageContextMenu extends React.Component {
</MenuItem>
);
if (mxEvent.getType() !== mxEvent.getWireType()) {
viewClearSourceButton = (
<MenuItem className="mx_MessageContextMenu_field" onClick={this.onViewClearSourceClick}>
{ _t('View Decrypted Source') }
</MenuItem>
);
}
if (this.props.eventTileOps) {
if (this.props.eventTileOps.isWidgetHidden()) {
unhidePreviewButton = (
@ -483,7 +465,6 @@ export default class MessageContextMenu extends React.Component {
{ forwardButton }
{ pinButton }
{ viewSourceButton }
{ viewClearSourceButton }
{ unhidePreviewButton }
{ permalinkButton }
{ quoteButton }

View File

@ -118,7 +118,7 @@ export default class RoomSettingsDialog extends React.Component {
return (
<BaseDialog className='mx_RoomSettingsDialog' hasCancel={true}
onFinished={this.props.onFinished} title={_t("Room Settings - %(roomName)s", {roomName})}>
<div className='ms_SettingsDialog_content'>
<div className='mx_SettingsDialog_content'>
<TabbedView tabs={this._getTabs()} />
</div>
</BaseDialog>

View File

@ -157,7 +157,7 @@ export default class UserSettingsDialog extends React.Component {
return (
<BaseDialog className='mx_UserSettingsDialog' hasCancel={true}
onFinished={this.props.onFinished} title={_t("Settings")}>
<div className='ms_SettingsDialog_content'>
<div className='mx_SettingsDialog_content'>
<TabbedView tabs={this._getTabs()} initialTabId={this.props.initialTabId} />
</div>
</BaseDialog>

View File

@ -14,8 +14,6 @@
limitations under the License.
*/
'use strict';
import React from 'react';
import PropTypes from 'prop-types';
import FlairStore from '../../../stores/FlairStore';

View File

@ -79,6 +79,9 @@ export default class EditHistoryMessage extends React.PureComponent {
roomId: this.props.mxEvent.getRoomId(),
eventId: this.props.mxEvent.getId(),
content: this.props.mxEvent.event,
isEncrypted: this.props.mxEvent.isEncrypted(),
// FIXME: _clearEvent is private
decryptedContent: this.props.mxEvent._clearEvent,
}, 'mx_Dialog_viewsource');
};

View File

@ -14,8 +14,6 @@
limitations under the License.
*/
'use strict';
import React from 'react';
import MFileBody from './MFileBody';

View File

@ -2395,7 +2395,6 @@
"Cancel Sending": "Cancel Sending",
"Forward Message": "Forward Message",
"Pin Message": "Pin Message",
"View Decrypted Source": "View Decrypted Source",
"Unhide Preview": "Unhide Preview",
"Share Permalink": "Share Permalink",
"Share Message": "Share Message",
@ -2656,6 +2655,8 @@
"User menu": "User menu",
"Community and user menu": "Community and user menu",
"Could not load user profile": "Could not load user profile",
"Decrypted event source": "Decrypted event source",
"Original event source": "Original event source",
"Verify this login": "Verify this login",
"Session verified": "Session verified",
"Failed to send email": "Failed to send email",

View File

@ -15,8 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
import { _td } from '../languageHandler';
import {StandardActions} from "./StandardActions";
import {PushRuleVectorState} from "./PushRuleVectorState";

View File

@ -15,8 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict';
export * from "./NotificationUtils";
export * from "./PushRuleVectorState";
export * from "./VectorPushRulesDefinitions";

View File

@ -15,8 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
"use strict";
// polyfill textencoder if necessary
import * as TextEncodingUtf8 from 'text-encoding-utf-8';
let TextEncoder = window.TextEncoder;

View File

@ -53,13 +53,15 @@ export default class MultiInviter {
* instance of the class.
*
* @param {array} addrs Array of addresses to invite
* @param {string} reason Reason for inviting (optional)
* @returns {Promise} Resolved when all invitations in the queue are complete
*/
invite(addrs) {
invite(addrs, reason) {
if (this.addrs.length > 0) {
throw new Error("Already inviting/invited");
}
this.addrs.push(...addrs);
this.reason = reason;
for (const addr of this.addrs) {
if (getAddressType(addr) === null) {
@ -123,7 +125,7 @@ export default class MultiInviter {
}
}
return MatrixClientPeg.get().invite(roomId, addr);
return MatrixClientPeg.get().invite(roomId, addr, undefined, this.reason);
} else {
throw new Error('Unsupported address');
}

View File

@ -30,9 +30,11 @@ import * as sdk from '../index';
* @param {string} name The dot-path name of the component being replaced.
* @param {React.Component} origComponent The component that can be replaced
* with a skinned version. If no skinned version is available, this component
* will be used.
* will be used. Note that this is automatically provided to the function and
* thus is optional for purposes of types.
* @returns {ClassDecorator} The decorator.
*/
export function replaceableComponent(name: string, origComponent: React.Component) {
export function replaceableComponent(name: string, origComponent?: React.Component): ClassDecorator {
// Decorators return a function to override the class (origComponent). This
// ultimately assumes that `getComponent()` won't throw an error and instead
// return a falsey value like `null` when the skin doesn't have a component.

View File

@ -1,5 +1,3 @@
"use strict";
import React from 'react';
import {MatrixClientPeg as peg} from '../src/MatrixClientPeg';
import dis from '../src/dispatcher/dispatcher';

View File

@ -14,8 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
"use strict";
import {TextEncoder} from "util";
import nodeCrypto from "crypto";
import { Crypto } from "@peculiar/webcrypto";