Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into t3chguy/electron_settings

# Conflicts:
#	src/components/structures/UserSettings.js
#	src/i18n/strings/en_EN.json

First time using JetBrains Merge Tool, MAY HAVE GONE HORRIBLY WRONG

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2017-05-30 23:54:57 +01:00
commit dcd99ac3de
57 changed files with 1861 additions and 321 deletions

View file

@ -95,7 +95,7 @@ var FilePanel = React.createClass({
</div>;
} else if (this.noRoom) {
return <div className="mx_FilePanel mx_RoomView_messageListWrapper">
<div className="mx_RoomView_empty">You must join the room to see its files</div>
<div className="mx_RoomView_empty">{_t("You must join the room to see its files")}</div>
</div>;
}

View file

@ -20,6 +20,8 @@ import q from 'q';
import React from 'react';
import Matrix from "matrix-js-sdk";
import Analytics from "../../Analytics";
import UserSettingsStore from '../../UserSettingsStore';
import MatrixClientPeg from "../../MatrixClientPeg";
import PlatformPeg from "../../PlatformPeg";
import SdkConfig from "../../SdkConfig";
@ -189,6 +191,8 @@ module.exports = React.createClass({
componentWillMount: function() {
SdkConfig.put(this.props.config);
if (!UserSettingsStore.getLocalSetting('analyticsOptOut', false)) Analytics.enable();
// Used by _viewRoom before getting state from sync
this.firstSyncComplete = false;
this.firstSyncPromise = q.defer();
@ -699,9 +703,9 @@ module.exports = React.createClass({
modal.close();
console.error("Failed to leave room " + roomId + " " + err);
Modal.createDialog(ErrorDialog, {
title: "Failed to leave room",
title: _t("Failed to leave room"),
description: (err && err.message ? err.message :
"Server may be unavailable, overloaded, or you hit a bug."),
_t("Server may be unavailable, overloaded, or you hit a bug.")),
});
});
}
@ -1002,6 +1006,7 @@ module.exports = React.createClass({
if (this.props.onNewScreen) {
this.props.onNewScreen(screen);
}
Analytics.trackPageChange();
},
onAliasClick: function(event, alias) {

View file

@ -1496,49 +1496,48 @@ module.exports = React.createClass({
const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
if (!this.state.room) {
if (this.state.roomLoading) {
return (
<div className="mx_RoomView">
<Loader />
</div>
);
if (this.state.roomLoading) {
return (
<div className="mx_RoomView">
<Loader />
</div>
);
} else {
var inviterName = undefined;
if (this.props.oobData) {
inviterName = this.props.oobData.inviterName;
}
var invitedEmail = undefined;
if (this.props.thirdPartyInvite) {
invitedEmail = this.props.thirdPartyInvite.invitedEmail;
}
else {
var inviterName = undefined;
if (this.props.oobData) {
inviterName = this.props.oobData.inviterName;
}
var invitedEmail = undefined;
if (this.props.thirdPartyInvite) {
invitedEmail = this.props.thirdPartyInvite.invitedEmail;
}
// We have no room object for this room, only the ID.
// We've got to this room by following a link, possibly a third party invite.
var room_alias = this.props.roomAddress[0] == '#' ? this.props.roomAddress : null;
return (
<div className="mx_RoomView">
<RoomHeader ref="header"
room={this.state.room}
oobData={this.props.oobData}
collapsedRhs={ this.props.collapsedRhs }
// We have no room object for this room, only the ID.
// We've got to this room by following a link, possibly a third party invite.
var room_alias = this.props.roomAddress[0] == '#' ? this.props.roomAddress : null;
return (
<div className="mx_RoomView">
<RoomHeader ref="header"
room={this.state.room}
oobData={this.props.oobData}
collapsedRhs={ this.props.collapsedRhs }
/>
<div className="mx_RoomView_auxPanel">
<RoomPreviewBar onJoinClick={ this.onJoinButtonClicked }
onForgetClick={ this.onForgetClick }
onRejectClick={ this.onRejectThreepidInviteButtonClicked }
canPreview={ false } error={ this.state.roomLoadError }
roomAlias={room_alias}
spinner={this.state.joining}
inviterName={inviterName}
invitedEmail={invitedEmail}
room={this.state.room}
/>
<div className="mx_RoomView_auxPanel">
<RoomPreviewBar onJoinClick={ this.onJoinButtonClicked }
onForgetClick={ this.onForgetClick }
onRejectClick={ this.onRejectThreepidInviteButtonClicked }
canPreview={ false } error={ this.state.roomLoadError }
roomAlias={room_alias}
spinner={this.state.joining}
inviterName={inviterName}
invitedEmail={invitedEmail}
room={this.state.room}
/>
</div>
<div className="mx_RoomView_messagePanel"></div>
</div>
);
}
<div className="mx_RoomView_messagePanel"></div>
</div>
);
}
}
var myUserId = MatrixClientPeg.get().credentials.userId;
@ -1622,13 +1621,15 @@ module.exports = React.createClass({
}
let aux = null;
if (this.state.forwardingEvent !== null) {
aux = <ForwardMessage onCancelClick={this.onCancelClick} currentRoomId={this.state.room.roomId} mxEvent={this.state.forwardingEvent} />;
} else if (this.state.editingRoomSettings) {
let hideCancel = false;
if (this.state.editingRoomSettings) {
aux = <RoomSettings ref="room_settings" onSaveClick={this.onSettingsSaveClick} onCancelClick={this.onCancelClick} room={this.state.room} />;
} else if (this.state.uploadingRoomSettings) {
aux = <Loader/>;
} else if (this.state.forwardingEvent !== null) {
aux = <ForwardMessage onCancelClick={this.onCancelClick} currentRoomId={this.state.room.roomId} mxEvent={this.state.forwardingEvent} />;
} else if (this.state.searching) {
hideCancel = true; // has own cancel
aux = <SearchBar ref="search_bar" searchInProgress={this.state.searchInProgress } onCancelClick={this.onCancelSearchClick} onSearch={this.onSearch}/>;
} else if (!myMember || myMember.membership !== "join") {
// We do have a room object for this room, but we're not currently in it.
@ -1641,6 +1642,7 @@ module.exports = React.createClass({
if (this.props.thirdPartyInvite) {
invitedEmail = this.props.thirdPartyInvite.invitedEmail;
}
hideCancel = true;
aux = (
<RoomPreviewBar onJoinClick={this.onJoinButtonClicked}
onForgetClick={ this.onForgetClick }
@ -1787,13 +1789,10 @@ module.exports = React.createClass({
onSearchClick={this.onSearchClick}
onSettingsClick={this.onSettingsClick}
onSaveClick={this.onSettingsSaveClick}
onCancelClick={aux ? this.onCancelClick : null}
onForgetClick={
(myMember && myMember.membership === "leave") ? this.onForgetClick : null
}
onLeaveClick={
(myMember && myMember.membership === "join") ? this.onLeaveClick : null
} />
onCancelClick={(aux && !hideCancel) ? this.onCancelClick : null}
onForgetClick={(myMember && myMember.membership === "leave") ? this.onForgetClick : null}
onLeaveClick={(myMember && myMember.membership === "join") ? this.onLeaveClick : null}
/>
{ auxPanel }
{ topUnreadMessagesBar }
{ messagePanel }

View file

@ -28,6 +28,7 @@ const GeminiScrollbar = require('react-gemini-scrollbar');
const Email = require('../../email');
const AddThreepid = require('../../AddThreepid');
const SdkConfig = require('../../SdkConfig');
import Analytics from '../../Analytics';
import AccessibleButton from '../views/elements/AccessibleButton';
import { _t } from '../../languageHandler';
import * as languageHandler from '../../languageHandler';
@ -90,12 +91,25 @@ const SETTINGS_LABELS = [
*/
];
const ANALYTICS_SETTINGS_LABELS = [
{
id: 'analyticsOptOut',
label: 'Opt out of analytics',
fn: function(checked) {
Analytics[checked ? 'disable' : 'enable']();
},
},
];
// Warning: Each "label" string below must be added to i18n/strings/en_EN.json,
// since they will be translated when rendered.
const CRYPTO_SETTINGS_LABELS = [
{
id: 'blacklistUnverifiedDevices',
label: 'Never send encrypted messages to unverified devices from this device',
fn: function(checked) {
MatrixClientPeg.get().setGlobalBlacklistUnverifiedDevices(checked);
},
},
// XXX: this is here for documentation; the actual setting is managed via RoomSettings
// {
@ -207,7 +221,6 @@ module.exports = React.createClass({
const {ipcRenderer} = require('electron');
ipcRenderer.on('settings', this._electronSettings);
ipcRenderer.send('settings_get');
}
@ -616,7 +629,12 @@ module.exports = React.createClass({
<input id={ setting.id }
type="checkbox"
defaultChecked={ this._syncedSettings[setting.id] }
onChange={ (e) => UserSettingsStore.setSyncedSetting(setting.id, e.target.checked) }
onChange={
(e) => {
UserSettingsStore.setSyncedSetting(setting.id, e.target.checked);
if (setting.fn) setting.fn(e.target.checked);
}
}
/>
<label htmlFor={ setting.id }>
{ _t(setting.label) }
@ -692,7 +710,6 @@ module.exports = React.createClass({
},
_renderLocalSetting: function(setting) {
const client = MatrixClientPeg.get();
return <div className="mx_UserSettings_toggle" key={ setting.id }>
<input id={ setting.id }
type="checkbox"
@ -700,11 +717,9 @@ module.exports = React.createClass({
onChange={
(e) => {
UserSettingsStore.setLocalSetting(setting.id, e.target.checked);
if (setting.id === 'blacklistUnverifiedDevices') { // XXX: this is a bit ugly
client.setGlobalBlacklistUnverifiedDevices(e.target.checked);
}
if (setting.fn) setting.fn(e.target.checked);
}
}
}
/>
<label htmlFor={ setting.id }>
{ _t(setting.label) }
@ -739,6 +754,16 @@ module.exports = React.createClass({
);
},
_renderAnalyticsControl: function() {
return <div>
<h3>{ _t('Analytics') }</h3>
<div className="mx_UserSettings_section">
{_t('Riot collects anonymous analytics to allow us to improve the application.')}
{ANALYTICS_SETTINGS_LABELS.map( this._renderLocalSetting )}
</div>
</div>;
},
_renderLabs: function() {
// default to enabled if undefined
if (this.props.enableLabs === false) return null;
@ -821,7 +846,7 @@ module.exports = React.createClass({
reject = (
<AccessibleButton className="mx_UserSettings_button danger"
onClick={this._onRejectAllInvitesClicked.bind(this, invitedRooms)}>
Reject all {invitedRooms.length} invites
{_t("Reject all %(invitedRooms)s invites", {invitedRooms: invitedRooms.length})}
</AccessibleButton>
);
}
@ -1061,6 +1086,8 @@ module.exports = React.createClass({
{PlatformPeg.get().isElectron() && this._renderElectronSettings()}
{this._renderAnalyticsControl()}
<h3>{ _t("Advanced") }</h3>
<div className="mx_UserSettings_section">