Merge remote-tracking branch 'origin/develop' into dbkr/udd_no_auto_show

This commit is contained in:
David Baker 2017-11-16 15:59:16 +00:00
commit 196eafdc7f
58 changed files with 645 additions and 336 deletions

View file

@ -54,7 +54,7 @@ export default React.createClass({
const deviceInfo = r[userId][deviceId];
if(!deviceInfo) {
if (!deviceInfo) {
console.warn(`No details found for device ${userId}:${deviceId}`);
this.props.onFinished(false);

View file

@ -18,7 +18,7 @@ import React from 'react';
import sdk from '../../../index';
import SdkConfig from '../../../SdkConfig';
import Modal from '../../../Modal';
import { _t, _tJsx } from '../../../languageHandler';
import { _t } from '../../../languageHandler';
export default React.createClass({
@ -45,9 +45,10 @@ export default React.createClass({
if (SdkConfig.get().bug_report_endpoint_url) {
bugreport = (
<p>
{ _tJsx(
{ _t(
"Otherwise, <a>click here</a> to send a bug report.",
/<a>(.*?)<\/a>/, (sub) => <a onClick={this._sendBugReport} key="bugreport" href='#'>{ sub }</a>,
{},
{ 'a': (sub) => <a onClick={this._sendBugReport} key="bugreport" href='#'>{ sub }</a> },
) }
</p>
);

View file

@ -21,7 +21,7 @@ import sdk from '../../../index';
import MatrixClientPeg from '../../../MatrixClientPeg';
import classnames from 'classnames';
import KeyCode from '../../../KeyCode';
import { _t, _tJsx } from '../../../languageHandler';
import { _t } from '../../../languageHandler';
// The amount of time to wait for further changes to the input username before
// sending a request to the server
@ -267,24 +267,21 @@ export default React.createClass({
</div>
{ usernameIndicator }
<p>
{ _tJsx(
{ _t(
'This will be your account name on the <span></span> ' +
'homeserver, or you can pick a <a>different server</a>.',
[
/<span><\/span>/,
/<a>(.*?)<\/a>/,
],
[
(sub) => <span>{ this.props.homeserverUrl }</span>,
(sub) => <a href="#" onClick={this.props.onDifferentServerClicked}>{ sub }</a>,
],
{},
{
'span': <span>{ this.props.homeserverUrl }</span>,
'a': (sub) => <a href="#" onClick={this.props.onDifferentServerClicked}>{ sub }</a>,
},
) }
</p>
<p>
{ _tJsx(
{ _t(
'If you already have a Matrix account you can <a>log in</a> instead.',
/<a>(.*?)<\/a>/,
[(sub) => <a href="#" onClick={this.props.onLoginClick}>{ sub }</a>],
{},
{ 'a': (sub) => <a href="#" onClick={this.props.onLoginClick}>{ sub }</a> },
) }
</p>
{ auth }

View file

@ -19,9 +19,9 @@ export default class AppPermission extends React.Component {
const searchParams = new URLSearchParams(wurl.search);
if(this.isScalarWurl(wurl) && searchParams && searchParams.get('url')) {
if (this.isScalarWurl(wurl) && searchParams && searchParams.get('url')) {
curl = url.parse(searchParams.get('url'));
if(curl) {
if (curl) {
curl.search = curl.query = "";
curlString = curl.format();
}
@ -34,7 +34,7 @@ export default class AppPermission extends React.Component {
}
isScalarWurl(wurl) {
if(wurl && wurl.hostname && (
if (wurl && wurl.hostname && (
wurl.hostname === 'scalar.vector.im' ||
wurl.hostname === 'scalar-staging.riot.im' ||
wurl.hostname === 'scalar-develop.riot.im' ||

View file

@ -22,6 +22,7 @@ import React from 'react';
import MatrixClientPeg from '../../../MatrixClientPeg';
import PlatformPeg from '../../../PlatformPeg';
import ScalarAuthClient from '../../../ScalarAuthClient';
import TintableSvgButton from './TintableSvgButton';
import SdkConfig from '../../../SdkConfig';
import Modal from '../../../Modal';
import { _t, _td } from '../../../languageHandler';
@ -283,7 +284,7 @@ export default React.createClass({
formatAppTileName() {
let appTileName = "No name";
if(this.props.name && this.props.name.trim()) {
if (this.props.name && this.props.name.trim()) {
appTileName = this.props.name.trim();
}
return appTileName;
@ -371,9 +372,9 @@ export default React.createClass({
// editing is done in scalar
const showEditButton = Boolean(this._scalarClient && this._canUserModify());
const deleteWidgetLabel = this._deleteWidgetLabel();
let deleteIcon = 'img/cancel.svg';
let deleteClasses = 'mx_filterFlipColor mx_AppTileMenuBarWidget';
if(this._canUserModify()) {
let deleteIcon = 'img/cancel_green.svg';
let deleteClasses = 'mx_AppTileMenuBarWidget';
if (this._canUserModify()) {
deleteIcon = 'img/icon-delete-pink.svg';
deleteClasses += ' mx_AppTileMenuBarWidgetDelete';
}
@ -384,22 +385,23 @@ export default React.createClass({
<b>{ this.formatAppTileName() }</b>
<span className="mx_AppTileMenuBarWidgets">
{ /* Edit widget */ }
{ showEditButton && <img
{ showEditButton && <TintableSvgButton
src="img/edit_green.svg"
className="mx_AppTileMenuBarWidget mx_AppTileMenuBarWidgetPadding"
width="8" height="8"
alt={_t('Edit')}
title={_t('Edit')}
onClick={this._onEditClick}
width="10"
height="10"
/> }
{ /* Delete widget */ }
<img src={deleteIcon}
className={deleteClasses}
width="8" height="8"
alt={_t(deleteWidgetLabel)}
title={_t(deleteWidgetLabel)}
onClick={this._onDeleteClick}
<TintableSvgButton
src={deleteIcon}
className={deleteClasses}
title={_t(deleteWidgetLabel)}
onClick={this._onDeleteClick}
width="10"
height="10"
/>
</span>
</div>

View file

@ -41,8 +41,8 @@ export default class LanguageDropdown extends React.Component {
componentWillMount() {
languageHandler.getAllLanguagesFromJson().then((langs) => {
langs.sort(function(a, b) {
if(a.label < b.label) return -1;
if(a.label > b.label) return 1;
if (a.label < b.label) return -1;
if (a.label > b.label) return 1;
return 0;
});
this.setState({langs});
@ -57,7 +57,7 @@ export default class LanguageDropdown extends React.Component {
const language = SettingsStore.getValue("language", null, /*excludeDefault:*/true);
if (language) {
this.props.onOptionChange(language);
}else {
} else {
const language = languageHandler.normalizeLanguageKey(languageHandler.getLanguageFromBrowser());
this.props.onOptionChange(language);
}

View file

@ -216,7 +216,7 @@ module.exports = React.createClass({
// are there only to show translators to non-English languages
// that the verb is conjugated to plural or singular Subject.
let res = null;
switch(t) {
switch (t) {
case "joined":
res = (userCount > 1)
? _t("%(severalUsers)sjoined %(count)s times", { severalUsers: "", count: repeats })
@ -304,7 +304,7 @@ module.exports = React.createClass({
return items[0];
} else if (remaining > 0) {
items = items.slice(0, itemLimit);
return _t("%(items)s and %(count)s others", { items: items.join(', '), count: remaining } )
return _t("%(items)s and %(count)s others", { items: items.join(', '), count: remaining } );
} else {
const lastItem = items.pop();
return _t("%(items)s and %(lastItem)s", { items: items.join(', '), lastItem: lastItem });

View file

@ -0,0 +1,61 @@
/*
Copyright 2017 New Vector Ltd
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 PropTypes from 'prop-types';
import TintableSvg from './TintableSvg';
export default class TintableSvgButton extends React.Component {
constructor(props) {
super(props);
}
render() {
let classes = "mx_TintableSvgButton";
if (this.props.className) {
classes += " " + this.props.className;
}
return (
<span
width={this.props.width}
height={this.props.height}
className={classes}>
<TintableSvg
src={this.props.src}
width={this.props.width}
height={this.props.height}
></TintableSvg>
<span
title={this.props.title}
onClick={this.props.onClick} />
</span>
);
}
}
TintableSvgButton.propTypes = {
src: PropTypes.string,
title: PropTypes.string,
className: PropTypes.string,
width: PropTypes.string.isRequired,
height: PropTypes.string.isRequired,
onClick: PropTypes.func,
};
TintableSvgButton.defaultProps = {
onClick: function() {},
};

View file

@ -18,7 +18,7 @@ limitations under the License.
import React from 'react';
import ReactDOM from 'react-dom';
import { _t, _tJsx } from '../../../languageHandler';
import { _t } from '../../../languageHandler';
const DIV_ID = 'mx_recaptcha';
@ -67,10 +67,10 @@ module.exports = React.createClass({
// * jumping straight to a hosted captcha page (but we don't support that yet)
// * embedding the captcha in an iframe (if that works)
// * using a better captcha lib
ReactDOM.render(_tJsx(
ReactDOM.render(_t(
"Robot check is currently unavailable on desktop - please use a <a>web browser</a>",
/<a>(.*?)<\/a>/,
(sub) => { return <a href='https://riot.im/app'>{ sub }</a>; }), warning);
{},
{ 'a': (sub) => { return <a href='https://riot.im/app'>{ sub }</a>; }}), warning);
this.refs.recaptchaContainer.appendChild(warning);
} else {
const scriptTag = document.createElement('script');

View file

@ -20,7 +20,7 @@ import url from 'url';
import classnames from 'classnames';
import sdk from '../../../index';
import { _t, _tJsx } from '../../../languageHandler';
import { _t } from '../../../languageHandler';
/* This file contains a collection of components which are used by the
* InteractiveAuth to prompt the user to enter the information needed
@ -256,7 +256,10 @@ export const EmailIdentityAuthEntry = React.createClass({
} else {
return (
<div>
<p>{ _tJsx("An email has been sent to %(emailAddress)s", /%\(emailAddress\)s/, (sub) => <i>{this.props.inputs.emailAddress}</i>) }</p>
<p>{ _t("An email has been sent to %(emailAddress)s",
{ emailAddress: (sub) => <i>{ this.props.inputs.emailAddress }</i> },
) }
</p>
<p>{ _t("Please check your email to continue registration.") }</p>
</div>
);
@ -370,7 +373,10 @@ export const MsisdnAuthEntry = React.createClass({
});
return (
<div>
<p>{ _tJsx("A text message has been sent to %(msisdn)s", /%\(msisdn\)s/, (sub) => <i>{this._msisdn}</i>) }</p>
<p>{ _t("A text message has been sent to %(msisdn)s",
{ msisdn: <i>this._msisdn</i> },
) }
</p>
<p>{ _t("Please enter the code it contains:") }</p>
<div className="mx_InteractiveAuthEntryComponents_msisdnWrapper">
<form onSubmit={this._onFormSubmit}>

View file

@ -122,7 +122,7 @@ class PasswordLogin extends React.Component {
mx_Login_field_disabled: disabled,
};
switch(loginType) {
switch (loginType) {
case PasswordLogin.LOGIN_FIELD_EMAIL:
classes.mx_Login_email = true;
return <input
@ -144,9 +144,9 @@ class PasswordLogin extends React.Component {
type="text"
name="username" // make it a little easier for browser's remember-password
onChange={this.onUsernameChanged}
placeholder={ SdkConfig.get().disable_custom_urls ?
placeholder={SdkConfig.get().disable_custom_urls ?
_t("Username on %(hs)s", {
hs: this.props.hsUrl.replace(/^https?:\/\//, '')
hs: this.props.hsUrl.replace(/^https?:\/\//, ''),
}) : _t("User name")}
value={this.state.username}
autoFocus

View file

@ -282,7 +282,7 @@ module.exports = React.createClass({
const emailSection = (
<div>
<input type="text" ref="email"
autoFocus={true} placeholder={ emailPlaceholder }
autoFocus={true} placeholder={emailPlaceholder}
defaultValue={this.props.defaultEmail}
className={this._classForField(FIELD_EMAIL, 'mx_Login_field')}
onBlur={function() {self.validateField(FIELD_EMAIL);}}

View file

@ -17,7 +17,7 @@ limitations under the License.
import React from 'react';
import MatrixClientPeg from '../../../MatrixClientPeg';
import { ContentRepo } from 'matrix-js-sdk';
import { _t, _tJsx } from '../../../languageHandler';
import { _t } from '../../../languageHandler';
import sdk from '../../../index';
import Modal from '../../../Modal';
import AccessibleButton from '../elements/AccessibleButton';
@ -67,24 +67,17 @@ module.exports = React.createClass({
'crop',
);
// it sucks that _tJsx doesn't support normal _t substitutions :((
return (
<div className="mx_RoomAvatarEvent">
{ _tJsx('%(senderDisplayName)s changed the room avatar to <img/>',
[
/%\(senderDisplayName\)s/,
/<img\/>/,
],
[
(sub) => senderDisplayName,
(sub) =>
<AccessibleButton key="avatar" className="mx_RoomAvatarEvent_avatar"
onClick={this.onAvatarClick.bind(this, name)}>
<BaseAvatar width={14} height={14} url={url}
name={name} />
</AccessibleButton>,
],
)
{ _t('%(senderDisplayName)s changed the room avatar to <img/>',
{ senderDisplayName: senderDisplayName },
{
'img': () =>
<AccessibleButton key="avatar" className="mx_RoomAvatarEvent_avatar"
onClick={this.onAvatarClick.bind(this, name)}>
<BaseAvatar width={14} height={14} url={url} name={name} />
</AccessibleButton>,
})
}
</div>
);

View file

@ -19,7 +19,7 @@
import React from 'react';
import sdk from '../../../index';
import Flair from '../elements/Flair.js';
import { _tJsx } from '../../../languageHandler';
import { _t, substitute } from '../../../languageHandler';
export default function SenderProfile(props) {
const EmojiText = sdk.getComponent('elements.EmojiText');
@ -42,22 +42,28 @@ export default function SenderProfile(props) {
: null,
];
let content = '';
if(props.text) {
// Replace senderName, and wrap surrounding text in spans with the right class
content = _tJsx(props.text, /^(.*)\%\(senderName\)s(.*)$/m, (p1, p2) => [
p1 ? <span className='mx_SenderProfile_aux'>{ p1 }</span> : null,
nameElem,
p2 ? <span className='mx_SenderProfile_aux'>{ p2 }</span> : null,
]);
let content;
if (props.text) {
content = _t(props.text, { senderName: () => nameElem });
} else {
content = nameElem;
// There is nothing to translate here, so call substitute() instead
content = substitute('%(senderName)s', { senderName: () => nameElem });
}
// The text surrounding the user name must be wrapped in order for it to have the correct opacity.
// It is not possible to wrap the whole thing, because the user name might contain flair which should
// be shown at full opacity. Sadly CSS does not make it possible to "reset" opacity so we have to do it
// in parts like this. Sometimes CSS makes me a sad panda :-(
// XXX: This could be avoided if the actual colour is set, rather than faking it with opacity
return (
<div className="mx_SenderProfile" dir="auto" onClick={props.onClick}>
{ content }
{ content.props.children[0] ?
<span className='mx_SenderProfile_aux'>{ content.props.children[0] }</span> : ''
}
{ content.props.children[1] }
{ content.props.children[2] ?
<span className='mx_SenderProfile_aux'>{ content.props.children[2] }</span> : ''
}
</div>
);
}

View file

@ -17,7 +17,7 @@ limitations under the License.
const React = require('react');
const sdk = require("../../../index");
import { _t, _tJsx } from '../../../languageHandler';
import { _t, _td } from '../../../languageHandler';
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
@ -42,11 +42,11 @@ module.exports = React.createClass({
let previewsForAccount = null;
if (SettingsStore.getValueAt(SettingLevel.ACCOUNT, "urlPreviewsEnabled")) {
previewsForAccount = (
_tJsx("You have <a>enabled</a> URL previews by default.", /<a>(.*?)<\/a>/, (sub)=><a href="#/settings">{ sub }</a>)
_t("You have <a>enabled</a> URL previews by default.", {}, { 'a': (sub)=><a href="#/settings">{ sub }</a> })
);
} else {
previewsForAccount = (
_tJsx("You have <a>disabled</a> URL previews by default.", /<a>(.*?)<\/a>/, (sub)=><a href="#/settings">{ sub }</a>)
_t("You have <a>disabled</a> URL previews by default.", {}, { 'a': (sub)=><a href="#/settings">{ sub }</a> })
);
}
@ -63,14 +63,14 @@ module.exports = React.createClass({
</label>
);
} else {
let str = "URL previews are enabled by default for participants in this room.";
let str = _td("URL previews are enabled by default for participants in this room.");
if (!SettingsStore.getValueAt(SettingLevel.ROOM, "urlPreviewsEnabled")) {
str = "URL previews are disabled by default for participants in this room.";
str = _td("URL previews are disabled by default for participants in this room.");
}
previewsForRoom = (<label>{ _t(str) }</label>);
}
let previewsForRoomAccount = (
const previewsForRoomAccount = (
<SettingsFlag name="urlPreviewsEnabled"
level={SettingLevel.ROOM_ACCOUNT}
roomId={this.props.room.roomId}

View file

@ -133,7 +133,7 @@ module.exports = React.createClass({
'$matrix_avatar_url': user ? MatrixClientPeg.get().mxcUrlToHttp(user.avatarUrl) : '',
};
if(app.data) {
if (app.data) {
Object.keys(app.data).forEach((key) => {
params['$' + key] = app.data[key];
});
@ -177,7 +177,7 @@ module.exports = React.createClass({
_canUserModify: function() {
try {
return WidgetUtils.canUserModifyWidgets(this.props.room.roomId);
} catch(err) {
} catch (err) {
console.error(err);
return false;
}

View file

@ -21,7 +21,7 @@ import sdk from '../../../index';
import dis from "../../../dispatcher";
import ObjectUtils from '../../../ObjectUtils';
import AppsDrawer from './AppsDrawer';
import { _t, _tJsx} from '../../../languageHandler';
import { _t } from '../../../languageHandler';
module.exports = React.createClass({
@ -99,13 +99,13 @@ module.exports = React.createClass({
supportedText = _t(" (unsupported)");
} else {
joinNode = (<span>
{ _tJsx(
{ _t(
"Join as <voiceText>voice</voiceText> or <videoText>video</videoText>.",
[/<voiceText>(.*?)<\/voiceText>/, /<videoText>(.*?)<\/videoText>/],
[
(sub) => <a onClick={(event)=>{ this.onConferenceNotificationClick(event, 'voice');}} href="#">{ sub }</a>,
(sub) => <a onClick={(event)=>{ this.onConferenceNotificationClick(event, 'video');}} href="#">{ sub }</a>,
],
{},
{
'voiceText': (sub) => <a onClick={(event)=>{ this.onConferenceNotificationClick(event, 'voice');}} href="#">{ sub }</a>,
'videoText': (sub) => <a onClick={(event)=>{ this.onConferenceNotificationClick(event, 'video');}} href="#">{ sub }</a>,
},
) }
</span>);
}

View file

@ -33,22 +33,30 @@ const ObjectUtils = require('../../../ObjectUtils');
const eventTileTypes = {
'm.room.message': 'messages.MessageEvent',
'm.room.member': 'messages.TextualEvent',
'm.call.invite': 'messages.TextualEvent',
'm.call.answer': 'messages.TextualEvent',
'm.call.hangup': 'messages.TextualEvent',
};
const stateEventTileTypes = {
'm.room.member': 'messages.TextualEvent',
'm.room.name': 'messages.TextualEvent',
'm.room.avatar': 'messages.RoomAvatarEvent',
'm.room.topic': 'messages.TextualEvent',
'm.room.third_party_invite': 'messages.TextualEvent',
'm.room.history_visibility': 'messages.TextualEvent',
'm.room.encryption': 'messages.TextualEvent',
'm.room.topic': 'messages.TextualEvent',
'm.room.power_levels': 'messages.TextualEvent',
'm.room.pinned_events' : 'messages.TextualEvent',
'm.room.pinned_events': 'messages.TextualEvent',
'im.vector.modular.widgets': 'messages.TextualEvent',
};
function getHandlerTile(ev) {
const type = ev.getType();
return ev.isState() ? stateEventTileTypes[type] : eventTileTypes[type];
}
const MAX_READ_AVATARS = 5;
// Our component structure for EventTiles on the timeline is:
@ -433,7 +441,7 @@ module.exports = withMatrixClient(React.createClass({
// Info messages are basically information about commands processed on a room
const isInfoMessage = (eventType !== 'm.room.message');
const EventTileType = sdk.getComponent(eventTileTypes[eventType]);
const EventTileType = sdk.getComponent(getHandlerTile(this.props.mxEvent));
// This shouldn't happen: the caller should check we support this type
// before trying to instantiate us
if (!EventTileType) {
@ -600,8 +608,10 @@ module.exports = withMatrixClient(React.createClass({
module.exports.haveTileForEvent = function(e) {
// Only messages have a tile (black-rectangle) if redacted
if (e.isRedacted() && e.getType() !== 'm.room.message') return false;
if (eventTileTypes[e.getType()] == undefined) return false;
if (eventTileTypes[e.getType()] == 'messages.TextualEvent') {
const handler = getHandlerTile(e);
if (handler === undefined) return false;
if (handler === 'messages.TextualEvent') {
return TextForEvent.textForEvent(e) !== '';
} else {
return true;

View file

@ -562,7 +562,7 @@ module.exports = withMatrixClient(React.createClass({
onMemberAvatarClick: function() {
const member = this.props.member;
const avatarUrl = member.user ? member.user.avatarUrl : member.events.member.getContent().avatar_url;
if(!avatarUrl) return;
if (!avatarUrl) return;
const httpUrl = this.props.matrixClient.mxcUrlToHttp(avatarUrl);
const ImageView = sdk.getComponent("elements.ImageView");

View file

@ -111,10 +111,10 @@ export default class MessageComposer extends React.Component {
</div>
),
onFinished: (shouldUpload) => {
if(shouldUpload) {
if (shouldUpload) {
// MessageComposer shouldn't have to rely on its parent passing in a callback to upload a file
if (files) {
for(let i=0; i<files.length; i++) {
for (let i=0; i<files.length; i++) {
this.props.uploadFile(files[i]);
}
}

View file

@ -427,7 +427,7 @@ export default class MessageComposerInput extends React.Component {
if (SettingsStore.getValue('MessageComposerInput.autoReplaceEmoji')) {
// The first matched group includes just the matched plaintext emoji
const emojiMatch = REGEX_EMOJI_WHITESPACE.exec(text.slice(0, currentStartOffset));
if(emojiMatch) {
if (emojiMatch) {
// plaintext -> hex unicode
const emojiUc = asciiList[emojiMatch[1]];
// hex unicode -> shortname -> actual unicode
@ -689,7 +689,7 @@ export default class MessageComposerInput extends React.Component {
}
const currentBlockType = RichUtils.getCurrentBlockType(this.state.editorState);
if(
if (
['code-block', 'blockquote', 'unordered-list-item', 'ordered-list-item']
.includes(currentBlockType)
) {

View file

@ -389,7 +389,7 @@ module.exports = React.createClass({
let rightRow;
let manageIntegsButton;
if(this.props.room && this.props.room.roomId && this.props.inRoom) {
if (this.props.room && this.props.room.roomId && this.props.inRoom) {
manageIntegsButton = <ManageIntegsButton
roomId={this.props.room.roomId}
/>;

View file

@ -18,12 +18,10 @@ limitations under the License.
'use strict';
const React = require("react");
const ReactDOM = require("react-dom");
import { _t, _tJsx } from '../../../languageHandler';
import { _t } from '../../../languageHandler';
const GeminiScrollbar = require('react-gemini-scrollbar');
const MatrixClientPeg = require("../../../MatrixClientPeg");
const CallHandler = require('../../../CallHandler');
const RoomListSorter = require("../../../RoomListSorter");
const Unread = require('../../../Unread');
const dis = require("../../../dispatcher");
const sdk = require('../../../index');
const rate_limited_func = require('../../../ratelimitedfunc');
@ -486,28 +484,25 @@ module.exports = React.createClass({
const RoomDirectoryButton = sdk.getComponent('elements.RoomDirectoryButton');
const CreateRoomButton = sdk.getComponent('elements.CreateRoomButton');
const TintableSvg = sdk.getComponent('elements.TintableSvg');
switch (section) {
case 'im.vector.fake.direct':
return <div className="mx_RoomList_emptySubListTip">
{ _tJsx(
{ _t(
"Press <StartChatButton> to start a chat with someone",
[/<StartChatButton>/],
[
(sub) => <StartChatButton size="16" callout={true} />,
],
{},
{ 'StartChatButton': <StartChatButton size="16" callout={true} /> },
) }
</div>;
case 'im.vector.fake.recent':
return <div className="mx_RoomList_emptySubListTip">
{ _tJsx(
{ _t(
"You're not in any rooms yet! Press <CreateRoomButton> to make a room or"+
" <RoomDirectoryButton> to browse the directory",
[/<CreateRoomButton>/, /<RoomDirectoryButton>/],
[
(sub) => <CreateRoomButton size="16" callout={true} />,
(sub) => <RoomDirectoryButton size="16" callout={true} />,
],
{},
{
'CreateRoomButton': <CreateRoomButton size="16" callout={true} />,
'RoomDirectoryButton': <RoomDirectoryButton size="16" callout={true} />,
},
) }
</div>;
}

View file

@ -21,7 +21,7 @@ const React = require('react');
const sdk = require('../../../index');
const MatrixClientPeg = require('../../../MatrixClientPeg');
import { _t, _tJsx } from '../../../languageHandler';
import { _t } from '../../../languageHandler';
module.exports = React.createClass({
displayName: 'RoomPreviewBar',
@ -135,13 +135,13 @@ module.exports = React.createClass({
{ _t('You have been invited to join this room by %(inviterName)s', {inviterName: this.props.inviterName}) }
</div>
<div className="mx_RoomPreviewBar_join_text">
{ _tJsx(
{ _t(
'Would you like to <acceptText>accept</acceptText> or <declineText>decline</declineText> this invitation?',
[/<acceptText>(.*?)<\/acceptText>/, /<declineText>(.*?)<\/declineText>/],
[
(sub) => <a onClick={this.props.onJoinClick}>{ sub }</a>,
(sub) => <a onClick={this.props.onRejectClick}>{ sub }</a>,
],
{},
{
'acceptText': (sub) => <a onClick={this.props.onJoinClick}>{ sub }</a>,
'declineText': (sub) => <a onClick={this.props.onRejectClick}>{ sub }</a>,
},
) }
</div>
{ emailMatchBlock }
@ -165,13 +165,13 @@ module.exports = React.createClass({
let actionText;
if (kicked) {
if(roomName) {
if (roomName) {
actionText = _t("You have been kicked from %(roomName)s by %(userName)s.", {roomName: roomName, userName: kickerName});
} else {
actionText = _t("You have been kicked from this room by %(userName)s.", {userName: kickerName});
}
} else if (banned) {
if(roomName) {
if (roomName) {
actionText = _t("You have been banned from %(roomName)s by %(userName)s.", {roomName: roomName, userName: kickerName});
} else {
actionText = _t("You have been banned from this room by %(userName)s.", {userName: kickerName});
@ -211,9 +211,9 @@ module.exports = React.createClass({
<div className="mx_RoomPreviewBar_join_text">
{ name ? _t('You are trying to access %(roomName)s.', {roomName: name}) : _t('You are trying to access a room.') }
<br />
{ _tJsx("<a>Click here</a> to join the discussion!",
/<a>(.*?)<\/a>/,
(sub) => <a onClick={this.props.onJoinClick}><b>{ sub }</b></a>,
{ _t("<a>Click here</a> to join the discussion!",
{},
{ 'a': (sub) => <a onClick={this.props.onJoinClick}><b>{ sub }</b></a> },
) }
</div>
</div>

View file

@ -17,7 +17,7 @@ limitations under the License.
import Promise from 'bluebird';
import React from 'react';
import { _t, _tJsx, _td } from '../../../languageHandler';
import { _t, _td } from '../../../languageHandler';
import MatrixClientPeg from '../../../MatrixClientPeg';
import sdk from '../../../index';
import Modal from '../../../Modal';
@ -309,9 +309,9 @@ module.exports = React.createClass({
}
// url preview settings
let ps = this.saveUrlPreviewSettings();
const ps = this.saveUrlPreviewSettings();
if (ps.length > 0) {
ps.map(p => promises.push(p));
ps.map((p) => promises.push(p));
}
// related groups
@ -584,7 +584,7 @@ module.exports = React.createClass({
const roomState = this.props.room.currentState;
const isEncrypted = cli.isRoomEncrypted(this.props.room.roomId);
let settings = (
const settings = (
<SettingsFlag name="blacklistUnverifiedDevices"
level={SettingLevel.ROOM_DEVICE}
roomId={this.props.room.roomId}
@ -628,9 +628,7 @@ module.exports = React.createClass({
const ColorSettings = sdk.getComponent("room_settings.ColorSettings");
const UrlPreviewSettings = sdk.getComponent("room_settings.UrlPreviewSettings");
const RelatedGroupSettings = sdk.getComponent("room_settings.RelatedGroupSettings");
const EditableText = sdk.getComponent('elements.EditableText');
const PowerSelector = sdk.getComponent('elements.PowerSelector');
const Loader = sdk.getComponent("elements.Spinner");
const cli = MatrixClientPeg.get();
const roomState = this.props.room.currentState;
@ -749,9 +747,9 @@ module.exports = React.createClass({
}
});
var tagsSection = null;
let tagsSection = null;
if (canSetTag || self.state.tags) {
var tagsSection =
tagsSection =
<div className="mx_RoomSettings_tags">
{ _t("Tagged as: ") }{ canSetTag ?
(tags.map(function(tag, i) {
@ -781,10 +779,10 @@ module.exports = React.createClass({
if (this.state.join_rule === "public" && aliasCount == 0) {
addressWarning =
<div className="mx_RoomSettings_warning">
{ _tJsx(
{ _t(
'To link to a room it must have <a>an address</a>.',
/<a>(.*?)<\/a>/,
(sub) => <a href="#addresses">{ sub }</a>,
{},
{ 'a': (sub) => <a href="#addresses">{ sub }</a> },
) }
</div>;
}
@ -931,7 +929,7 @@ module.exports = React.createClass({
{ Object.keys(events_levels).map(function(event_type, i) {
let label = plEventsToLabels[event_type];
if (label) label = _t(label);
else label = _tJsx("To send events of type <eventType/>, you must be a", /<eventType\/>/, () => <code>{ event_type }</code>);
else label = _t("To send events of type <eventType/>, you must be a", {}, { 'eventType': <code>{ event_type }</code> });
return (
<div className="mx_RoomSettings_powerLevel" key={event_type}>
<span className="mx_RoomSettings_powerLevelKey">{ label } </span>

View file

@ -54,7 +54,7 @@ module.exports = React.createClass({
},
getInitialState: function() {
return({
return ({
hover: false,
badgeHover: false,
menuDisplayed: false,

View file

@ -39,7 +39,7 @@ module.exports = React.createClass({
},
onResize: function(e) {
if(this.props.onResize) {
if (this.props.onResize) {
this.props.onResize(e);
}
},