Merge branch 'develop' into rav/handle_received_room_key_requests
This commit is contained in:
commit
c1151fd31c
35 changed files with 2638 additions and 244 deletions
|
@ -39,7 +39,7 @@ import PageTypes from '../../PageTypes';
|
|||
import createRoom from "../../createRoom";
|
||||
import * as UDEHandler from '../../UnknownDeviceErrorHandler';
|
||||
import KeyRequestHandler from '../../KeyRequestHandler';
|
||||
import { _t } from '../../languageHandler';
|
||||
import { _t, getCurrentLanguage } from '../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'MatrixChat',
|
||||
|
@ -685,8 +685,12 @@ module.exports = React.createClass({
|
|||
|
||||
const roomToLeave = MatrixClientPeg.get().getRoom(roomId);
|
||||
Modal.createDialog(QuestionDialog, {
|
||||
title: "Leave room",
|
||||
description: <span>Are you sure you want to leave the room <i>{roomToLeave.name}</i>?</span>,
|
||||
title: _t("Leave room"),
|
||||
description: (
|
||||
<span>
|
||||
{_t("Are you sure you want to leave the room '%(roomName)s'?", {roomName: roomToLeave.name})}
|
||||
</span>
|
||||
),
|
||||
onFinished: (shouldLeave) => {
|
||||
if (shouldLeave) {
|
||||
const d = MatrixClientPeg.get().leave(roomId);
|
||||
|
@ -792,7 +796,7 @@ module.exports = React.createClass({
|
|||
this._teamToken = teamToken;
|
||||
dis.dispatch({action: 'view_home_page'});
|
||||
} else if (this._is_registered) {
|
||||
if (this.props.config.welcomeUserId) {
|
||||
if (this.props.config.welcomeUserId && getCurrentLanguage().startsWith("en")) {
|
||||
createRoom({dmUserId: this.props.config.welcomeUserId});
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -90,6 +90,9 @@ module.exports = React.createClass({
|
|||
|
||||
// show timestamps always
|
||||
alwaysShowTimestamps: React.PropTypes.bool,
|
||||
|
||||
// hide redacted events as per old behaviour
|
||||
hideRedactions: React.PropTypes.bool,
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
|
@ -463,6 +466,8 @@ module.exports = React.createClass({
|
|||
continuation = false;
|
||||
}
|
||||
|
||||
if (mxEv.isRedacted() && this.props.hideRedactions) return ret;
|
||||
|
||||
var eventId = mxEv.getId();
|
||||
var highlight = (eventId == this.props.highlightedEventId);
|
||||
|
||||
|
|
|
@ -131,6 +131,8 @@ var TimelinePanel = React.createClass({
|
|||
}
|
||||
}
|
||||
|
||||
const syncedSettings = UserSettingsStore.getSyncedSettings();
|
||||
|
||||
return {
|
||||
events: [],
|
||||
timelineLoading: true, // track whether our room timeline is loading
|
||||
|
@ -175,10 +177,13 @@ var TimelinePanel = React.createClass({
|
|||
clientSyncState: MatrixClientPeg.get().getSyncState(),
|
||||
|
||||
// should the event tiles have twelve hour times
|
||||
isTwelveHour: UserSettingsStore.getSyncedSetting('showTwelveHourTimestamps'),
|
||||
isTwelveHour: syncedSettings.showTwelveHourTimestamps,
|
||||
|
||||
// always show timestamps on event tiles?
|
||||
alwaysShowTimestamps: UserSettingsStore.getSyncedSetting('alwaysShowTimestamps'),
|
||||
alwaysShowTimestamps: syncedSettings.alwaysShowTimestamps,
|
||||
|
||||
// hide redacted events as per old behaviour
|
||||
hideRedactions: syncedSettings.hideRedactions,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -915,7 +920,7 @@ var TimelinePanel = React.createClass({
|
|||
});
|
||||
};
|
||||
}
|
||||
var message = (error.errcode == 'M_FORBIDDEN')
|
||||
var message = (error.errcode == 'M_FORBIDDEN')
|
||||
? _t("Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question") + "."
|
||||
: _t("Tried to load a specific point in this room's timeline, but was unable to find it") + ".";
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
|
@ -1113,26 +1118,27 @@ var TimelinePanel = React.createClass({
|
|||
);
|
||||
return (
|
||||
<MessagePanel ref="messagePanel"
|
||||
hidden={ this.props.hidden }
|
||||
backPaginating={ this.state.backPaginating }
|
||||
forwardPaginating={ forwardPaginating }
|
||||
events={ this.state.events }
|
||||
highlightedEventId={ this.props.highlightedEventId }
|
||||
readMarkerEventId={ this.state.readMarkerEventId }
|
||||
readMarkerVisible={ this.state.readMarkerVisible }
|
||||
suppressFirstDateSeparator={ this.state.canBackPaginate }
|
||||
showUrlPreview = { this.props.showUrlPreview }
|
||||
manageReadReceipts = { this.props.manageReadReceipts }
|
||||
ourUserId={ MatrixClientPeg.get().credentials.userId }
|
||||
stickyBottom={ stickyBottom }
|
||||
onScroll={ this.onMessageListScroll }
|
||||
onFillRequest={ this.onMessageListFillRequest }
|
||||
onUnfillRequest={ this.onMessageListUnfillRequest }
|
||||
opacity={ this.props.opacity }
|
||||
isTwelveHour={ this.state.isTwelveHour }
|
||||
alwaysShowTimestamps={ this.state.alwaysShowTimestamps }
|
||||
className={ this.props.className }
|
||||
tileShape={ this.props.tileShape }
|
||||
hidden={ this.props.hidden }
|
||||
hideRedactions={ this.state.hideRedactions }
|
||||
backPaginating={ this.state.backPaginating }
|
||||
forwardPaginating={ forwardPaginating }
|
||||
events={ this.state.events }
|
||||
highlightedEventId={ this.props.highlightedEventId }
|
||||
readMarkerEventId={ this.state.readMarkerEventId }
|
||||
readMarkerVisible={ this.state.readMarkerVisible }
|
||||
suppressFirstDateSeparator={ this.state.canBackPaginate }
|
||||
showUrlPreview = { this.props.showUrlPreview }
|
||||
manageReadReceipts = { this.props.manageReadReceipts }
|
||||
ourUserId={ MatrixClientPeg.get().credentials.userId }
|
||||
stickyBottom={ stickyBottom }
|
||||
onScroll={ this.onMessageListScroll }
|
||||
onFillRequest={ this.onMessageListFillRequest }
|
||||
onUnfillRequest={ this.onMessageListUnfillRequest }
|
||||
opacity={ this.props.opacity }
|
||||
isTwelveHour={ this.state.isTwelveHour }
|
||||
alwaysShowTimestamps={ this.state.alwaysShowTimestamps }
|
||||
className={ this.props.className }
|
||||
tileShape={ this.props.tileShape }
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -84,6 +84,10 @@ const SETTINGS_LABELS = [
|
|||
id: 'useCompactLayout',
|
||||
label: 'Use compact timeline layout',
|
||||
},
|
||||
{
|
||||
id: 'hideRedactions',
|
||||
label: 'Hide removed messages',
|
||||
},
|
||||
/*
|
||||
{
|
||||
id: 'useFixedWidthFont',
|
||||
|
@ -715,8 +719,8 @@ module.exports = React.createClass({
|
|||
<h3>{ _t("Cryptography") }</h3>
|
||||
<div className="mx_UserSettings_section mx_UserSettings_cryptoSection">
|
||||
<ul>
|
||||
<li><label>Device ID:</label> <span><code>{deviceId}</code></span></li>
|
||||
<li><label>Device key:</label> <span><code><b>{identityKey}</b></code></span></li>
|
||||
<li><label>{_t("Device ID:")}</label> <span><code>{deviceId}</code></span></li>
|
||||
<li><label>{_t("Device key:")}</label> <span><code><b>{identityKey}</b></code></span></li>
|
||||
</ul>
|
||||
{ importExportButtons }
|
||||
</div>
|
||||
|
@ -773,6 +777,8 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_renderAnalyticsControl: function() {
|
||||
if (!SdkConfig.get().piwik) return <div/>;
|
||||
|
||||
return <div>
|
||||
<h3>{ _t('Analytics') }</h3>
|
||||
<div className="mx_UserSettings_section">
|
||||
|
|
|
@ -229,7 +229,7 @@ module.exports = React.createClass({
|
|||
<div className="mx_Login_error">
|
||||
</div>
|
||||
<a className="mx_Login_create" onClick={this.props.onLoginClick} href="#">
|
||||
Return to login
|
||||
{_t('Return to login screen')}
|
||||
</a>
|
||||
<a className="mx_Login_create" onClick={this.props.onRegisterClick} href="#">
|
||||
{ _t('Create an account') }
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
import React from 'react';
|
||||
import sdk from '../../../index';
|
||||
import dis from '../../../dispatcher';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import DMRoomMap from '../../../utils/DMRoomMap';
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
|
@ -86,7 +87,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
|
|||
<div className="mx_RoomTile_avatar">
|
||||
<img src="img/create-big.svg" width="26" height="26" />
|
||||
</div>
|
||||
<div className={labelClasses}><i>{_("Start new chat")}</i></div>
|
||||
<div className={labelClasses}><i>{_t("Start new chat")}</i></div>
|
||||
</AccessibleButton>;
|
||||
|
||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||
|
|
|
@ -490,7 +490,7 @@ module.exports = React.createClass({
|
|||
var error;
|
||||
var addressSelector;
|
||||
if (this.state.error) {
|
||||
error = <div className="mx_ChatInviteDialog_error">You have entered an invalid contact. Try using their Matrix ID or email address.</div>;
|
||||
error = <div className="mx_ChatInviteDialog_error">{_t("You have entered an invalid contact. Try using their Matrix ID or email address.")}</div>;
|
||||
} else {
|
||||
const addressSelectorHeader = <div className="mx_ChatInviteDialog_addressSelectHeader">
|
||||
Searching known users
|
||||
|
|
|
@ -60,10 +60,10 @@ module.exports = React.createClass({
|
|||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button className="mx_Dialog_primary" onClick={this.props.onFinished} autoFocus={true}>
|
||||
Cancel
|
||||
{_t("Cancel")}
|
||||
</button>
|
||||
<button onClick={this.onRegisterClicked}>
|
||||
Register
|
||||
{_t("Register")}
|
||||
</button>
|
||||
</div>
|
||||
</BaseDialog>
|
||||
|
|
|
@ -51,7 +51,7 @@ export default React.createClass({
|
|||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||
const cancelButton = this.props.hasCancelButton ? (
|
||||
<button onClick={this.onCancel}>
|
||||
Cancel
|
||||
{_t("Cancel")}
|
||||
</button>
|
||||
) : null;
|
||||
return (
|
||||
|
|
|
@ -18,6 +18,7 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import * as Roles from '../../../Roles';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
var LEVEL_ROLE_MAP = {};
|
||||
var reverseRoles = {};
|
||||
|
@ -116,7 +117,7 @@ module.exports = React.createClass({
|
|||
text: Roles.textualPowerLevel(level, 0),
|
||||
}
|
||||
});
|
||||
options.push({ value: "Custom", text: "Custom level" });
|
||||
options.push({ value: "Custom", text: _t("Custom level") });
|
||||
options = options.map((op) => {
|
||||
return <option value={op.value} key={op.value}>{op.text}</option>;
|
||||
});
|
||||
|
|
|
@ -129,8 +129,8 @@ export const PasswordAuthEntry = React.createClass({
|
|||
|
||||
return (
|
||||
<div>
|
||||
<p>To continue, please enter your password.</p>
|
||||
<p>Password:</p>
|
||||
<p>{_t("To continue, please enter your password.")}</p>
|
||||
<p>{_t("Password:")}</p>
|
||||
<form onSubmit={this._onSubmit}>
|
||||
<input
|
||||
ref="passwordField"
|
||||
|
@ -380,7 +380,7 @@ export const MsisdnAuthEntry = React.createClass({
|
|||
onChange={this._onTokenChange}
|
||||
/>
|
||||
<br />
|
||||
<input type="submit" value="Submit"
|
||||
<input type="submit" value={_t("Submit")}
|
||||
className={submitClasses}
|
||||
disabled={!enableSubmit}
|
||||
/>
|
||||
|
|
|
@ -150,7 +150,7 @@ class PasswordLogin extends React.Component {
|
|||
type="text"
|
||||
name="phoneNumber"
|
||||
onChange={this.onPhoneNumberChanged}
|
||||
placeholder="Mobile phone number"
|
||||
placeholder={_t("Mobile phone number")}
|
||||
value={this.state.phoneNumber}
|
||||
autoFocus
|
||||
/>
|
||||
|
|
|
@ -282,7 +282,7 @@ module.exports = React.createClass({
|
|||
const emailSection = (
|
||||
<div>
|
||||
<input type="text" ref="email"
|
||||
autoFocus={true} placeholder="Email address (optional)"
|
||||
autoFocus={true} placeholder={_t("Email address (optional)")}
|
||||
defaultValue={this.props.defaultEmail}
|
||||
className={this._classForField(FIELD_EMAIL, 'mx_Login_field')}
|
||||
onBlur={function() {self.validateField(FIELD_EMAIL);}}
|
||||
|
@ -321,7 +321,7 @@ module.exports = React.createClass({
|
|||
showPrefix={true}
|
||||
/>
|
||||
<input type="text" ref="phoneNumber"
|
||||
placeholder="Mobile phone number (optional)"
|
||||
placeholder={_t("Mobile phone number (optional)")}
|
||||
defaultValue={this.props.defaultPhoneNumber}
|
||||
className={this._classForField(
|
||||
FIELD_PHONE_NUMBER,
|
||||
|
@ -339,9 +339,9 @@ module.exports = React.createClass({
|
|||
<input className="mx_Login_submit" type="submit" value="Register" />
|
||||
);
|
||||
|
||||
let placeholderUserName = "User name";
|
||||
let placeholderUserName = _t("User name");
|
||||
if (this.props.guestUsername) {
|
||||
placeholderUserName += " (default: " + this.props.guestUsername + ")";
|
||||
placeholderUserName += " " + _t("(default: %(userName)s)", {userName: this.props.guestUsername});
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -356,15 +356,15 @@ module.exports = React.createClass({
|
|||
onBlur={function() {self.validateField(FIELD_USERNAME);}} />
|
||||
<br />
|
||||
{ this.props.guestUsername ?
|
||||
<div className="mx_Login_fieldLabel">Setting a user name will create a fresh account</div> : null
|
||||
<div className="mx_Login_fieldLabel">{_t("Setting a user name will create a fresh account")}</div> : null
|
||||
}
|
||||
<input type="password" ref="password"
|
||||
className={this._classForField(FIELD_PASSWORD, 'mx_Login_field')}
|
||||
onBlur={function() {self.validateField(FIELD_PASSWORD);}}
|
||||
placeholder="Password" defaultValue={this.props.defaultPassword} />
|
||||
placeholder={_t("Password")} defaultValue={this.props.defaultPassword} />
|
||||
<br />
|
||||
<input type="password" ref="passwordConfirm"
|
||||
placeholder="Confirm password"
|
||||
placeholder={_t("Confirm password")}
|
||||
className={this._classForField(FIELD_PASSWORD_CONFIRM, 'mx_Login_field')}
|
||||
onBlur={function() {self.validateField(FIELD_PASSWORD_CONFIRM);}}
|
||||
defaultValue={this.props.defaultPassword} />
|
||||
|
|
|
@ -230,7 +230,7 @@ module.exports = React.createClass({
|
|||
remote_aliases_section = (
|
||||
<div>
|
||||
<div className="mx_RoomSettings_aliasLabel">
|
||||
Remote addresses for this room:
|
||||
{_t("Remote addresses for this room:")}
|
||||
</div>
|
||||
<div className="mx_RoomSettings_aliasesTable">
|
||||
{ this.state.remoteDomains.map((domain, i) => {
|
||||
|
|
|
@ -20,7 +20,7 @@ var MatrixClientPeg = require('../../../MatrixClientPeg');
|
|||
var sdk = require("../../../index");
|
||||
var Modal = require("../../../Modal");
|
||||
var UserSettingsStore = require('../../../UserSettingsStore');
|
||||
import { _t } from '../../../languageHandler';
|
||||
import { _t, _tJsx } from '../../../languageHandler';
|
||||
|
||||
|
||||
module.exports = React.createClass({
|
||||
|
@ -131,12 +131,24 @@ module.exports = React.createClass({
|
|||
</label>;
|
||||
}
|
||||
|
||||
let urlPreviewText = null;
|
||||
if (UserSettingsStore.getUrlPreviewsDisabled()) {
|
||||
urlPreviewText = (
|
||||
_tJsx("You have <a>disabled</a> URL previews by default.", /<a>(.*?)<\/a>/, (sub)=><a href="#/settings">{sub}</a>)
|
||||
);
|
||||
}
|
||||
else {
|
||||
urlPreviewText = (
|
||||
_tJsx("You have <a>enabled</a> URL previews by default.", /<a>(.*?)<\/a>/, (sub)=><a href="#/settings">{sub}</a>)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_RoomSettings_toggles">
|
||||
<h3>{_t("URL Previews")}</h3>
|
||||
|
||||
<label>
|
||||
You have <a href="#/settings">{ UserSettingsStore.getUrlPreviewsDisabled() ? 'disabled' : 'enabled' }</a> URL previews by default.
|
||||
{urlPreviewText}
|
||||
</label>
|
||||
{ disableRoomPreviewUrls }
|
||||
<label>
|
||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import sdk from '../../../index';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
export default class MemberDeviceInfo extends React.Component {
|
||||
render() {
|
||||
|
@ -49,7 +50,7 @@ export default class MemberDeviceInfo extends React.Component {
|
|||
// add the deviceId as a titletext to help with debugging
|
||||
return (
|
||||
<div className="mx_MemberDeviceInfo"
|
||||
title={"device id: " + this.props.device.deviceId} >
|
||||
title={_t("device id: ") + this.props.device.deviceId} >
|
||||
<div className="mx_MemberDeviceInfo_deviceInfo">
|
||||
<div className="mx_MemberDeviceInfo_deviceId">
|
||||
{deviceName}
|
||||
|
|
|
@ -188,7 +188,11 @@ module.exports = React.createClass({
|
|||
'm.room.name', user_id
|
||||
);
|
||||
|
||||
save_button = <AccessibleButton className="mx_RoomHeader_textButton" onClick={this.props.onSaveClick}>Save</AccessibleButton>;
|
||||
save_button = (
|
||||
<AccessibleButton className="mx_RoomHeader_textButton" onClick={this.props.onSaveClick}>
|
||||
{_t("Save")}
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.onCancelClick) {
|
||||
|
|
|
@ -726,7 +726,7 @@ module.exports = React.createClass({
|
|||
if (canSetTag || self.state.tags) {
|
||||
var tagsSection =
|
||||
<div className="mx_RoomSettings_tags">
|
||||
Tagged as: { canSetTag ?
|
||||
{_t("Tagged as: ")}{ canSetTag ?
|
||||
(tags.map(function(tag, i) {
|
||||
return (<label key={ i }>
|
||||
<input type="checkbox"
|
||||
|
@ -844,7 +844,7 @@ module.exports = React.createClass({
|
|||
<input type="checkbox" disabled={ !roomState.mayClientSendStateEvent("m.room.aliases", cli) }
|
||||
onChange={ this._onToggle.bind(this, "isRoomPublished", true, false)}
|
||||
checked={this.state.isRoomPublished}/>
|
||||
List this room in { MatrixClientPeg.get().getDomain() }'s room directory?
|
||||
{_t("List this room in %(domain)s's room directory?", { domain: MatrixClientPeg.get().getDomain() })}
|
||||
</label>
|
||||
</div>
|
||||
<div className="mx_RoomSettings_settings">
|
||||
|
@ -854,7 +854,7 @@ module.exports = React.createClass({
|
|||
disabled={ !roomState.mayClientSendStateEvent("m.room.history_visibility", cli) }
|
||||
checked={historyVisibility === "world_readable"}
|
||||
onChange={this._onHistoryRadioToggle} />
|
||||
Anyone
|
||||
{_t("Anyone")}
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="historyVis" value="shared"
|
||||
|
|
|
@ -18,6 +18,7 @@ limitations under the License.
|
|||
|
||||
var React = require('react');
|
||||
var sdk = require('../../../index');
|
||||
import { _t } from "../../../languageHandler";
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RoomTopicEditor',
|
||||
|
@ -43,7 +44,7 @@ module.exports = React.createClass({
|
|||
<EditableText ref="editor"
|
||||
className="mx_RoomHeader_topic mx_RoomHeader_editable"
|
||||
placeholderClassName="mx_RoomHeader_placeholder"
|
||||
placeholder="Add a topic"
|
||||
placeholder={_t("Add a topic")}
|
||||
blurToCancel={ false }
|
||||
initialValue={ this._initialTopic }/>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue