Merge pull request #1461 from matrix-org/luke/lint-almighty
Run eslint --fix
This commit is contained in:
commit
013c0c56a7
136 changed files with 2540 additions and 2657 deletions
|
@ -63,23 +63,22 @@ import dis from './dispatcher';
|
|||
global.mxCalls = {
|
||||
//room_id: MatrixCall
|
||||
};
|
||||
var calls = global.mxCalls;
|
||||
var ConferenceHandler = null;
|
||||
const calls = global.mxCalls;
|
||||
let ConferenceHandler = null;
|
||||
|
||||
var audioPromises = {};
|
||||
const audioPromises = {};
|
||||
|
||||
function play(audioId) {
|
||||
// TODO: Attach an invisible element for this instead
|
||||
// which listens?
|
||||
var audio = document.getElementById(audioId);
|
||||
const audio = document.getElementById(audioId);
|
||||
if (audio) {
|
||||
if (audioPromises[audioId]) {
|
||||
audioPromises[audioId] = audioPromises[audioId].then(()=>{
|
||||
audio.load();
|
||||
return audio.play();
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
audioPromises[audioId] = audio.play();
|
||||
}
|
||||
}
|
||||
|
@ -88,12 +87,11 @@ function play(audioId) {
|
|||
function pause(audioId) {
|
||||
// TODO: Attach an invisible element for this instead
|
||||
// which listens?
|
||||
var audio = document.getElementById(audioId);
|
||||
const audio = document.getElementById(audioId);
|
||||
if (audio) {
|
||||
if (audioPromises[audioId]) {
|
||||
audioPromises[audioId] = audioPromises[audioId].then(()=>audio.pause());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// pause doesn't actually return a promise, but might as well do this for symmetry with play();
|
||||
audioPromises[audioId] = audio.pause();
|
||||
}
|
||||
|
@ -125,38 +123,32 @@ function _setCallListeners(call) {
|
|||
if (newState === "ringing") {
|
||||
_setCallState(call, call.roomId, "ringing");
|
||||
pause("ringbackAudio");
|
||||
}
|
||||
else if (newState === "invite_sent") {
|
||||
} else if (newState === "invite_sent") {
|
||||
_setCallState(call, call.roomId, "ringback");
|
||||
play("ringbackAudio");
|
||||
}
|
||||
else if (newState === "ended" && oldState === "connected") {
|
||||
} else if (newState === "ended" && oldState === "connected") {
|
||||
_setCallState(undefined, call.roomId, "ended");
|
||||
pause("ringbackAudio");
|
||||
play("callendAudio");
|
||||
}
|
||||
else if (newState === "ended" && oldState === "invite_sent" &&
|
||||
} else if (newState === "ended" && oldState === "invite_sent" &&
|
||||
(call.hangupParty === "remote" ||
|
||||
(call.hangupParty === "local" && call.hangupReason === "invite_timeout")
|
||||
)) {
|
||||
_setCallState(call, call.roomId, "busy");
|
||||
pause("ringbackAudio");
|
||||
play("busyAudio");
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createTrackedDialog('Call Handler', 'Call Timeout', ErrorDialog, {
|
||||
title: _t('Call Timeout'),
|
||||
description: _t('The remote side failed to pick up') + '.',
|
||||
});
|
||||
}
|
||||
else if (oldState === "invite_sent") {
|
||||
} else if (oldState === "invite_sent") {
|
||||
_setCallState(call, call.roomId, "stop_ringback");
|
||||
pause("ringbackAudio");
|
||||
}
|
||||
else if (oldState === "ringing") {
|
||||
} else if (oldState === "ringing") {
|
||||
_setCallState(call, call.roomId, "stop_ringing");
|
||||
pause("ringbackAudio");
|
||||
}
|
||||
else if (newState === "connected") {
|
||||
} else if (newState === "connected") {
|
||||
_setCallState(call, call.roomId, "connected");
|
||||
pause("ringbackAudio");
|
||||
}
|
||||
|
@ -165,14 +157,13 @@ function _setCallListeners(call) {
|
|||
|
||||
function _setCallState(call, roomId, status) {
|
||||
console.log(
|
||||
"Call state in %s changed to %s (%s)", roomId, status, (call ? call.call_state : "-")
|
||||
"Call state in %s changed to %s (%s)", roomId, status, (call ? call.call_state : "-"),
|
||||
);
|
||||
calls[roomId] = call;
|
||||
|
||||
if (status === "ringing") {
|
||||
play("ringAudio");
|
||||
}
|
||||
else if (call && call.call_state === "ringing") {
|
||||
} else if (call && call.call_state === "ringing") {
|
||||
pause("ringAudio");
|
||||
}
|
||||
|
||||
|
@ -192,14 +183,12 @@ function _onAction(payload) {
|
|||
_setCallState(newCall, newCall.roomId, "ringback");
|
||||
if (payload.type === 'voice') {
|
||||
newCall.placeVoiceCall();
|
||||
}
|
||||
else if (payload.type === 'video') {
|
||||
} else if (payload.type === 'video') {
|
||||
newCall.placeVideoCall(
|
||||
payload.remote_element,
|
||||
payload.local_element
|
||||
payload.local_element,
|
||||
);
|
||||
}
|
||||
else if (payload.type === 'screensharing') {
|
||||
} else if (payload.type === 'screensharing') {
|
||||
const screenCapErrorString = PlatformPeg.get().screenCaptureErrorString();
|
||||
if (screenCapErrorString) {
|
||||
_setCallState(undefined, newCall.roomId, "ended");
|
||||
|
@ -213,10 +202,9 @@ function _onAction(payload) {
|
|||
}
|
||||
newCall.placeScreenSharingCall(
|
||||
payload.remote_element,
|
||||
payload.local_element
|
||||
payload.local_element,
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
console.error("Unknown conf call type: %s", payload.type);
|
||||
}
|
||||
}
|
||||
|
@ -255,21 +243,19 @@ function _onAction(payload) {
|
|||
description: _t('You cannot place a call with yourself.'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
else if (members.length === 2) {
|
||||
} else if (members.length === 2) {
|
||||
console.log("Place %s call in %s", payload.type, payload.room_id);
|
||||
const call = Matrix.createNewMatrixCall(MatrixClientPeg.get(), payload.room_id, {
|
||||
forceTURN: UserSettingsStore.getLocalSetting('webRtcForceTURN', false),
|
||||
});
|
||||
placeCall(call);
|
||||
}
|
||||
else { // > 2
|
||||
} else { // > 2
|
||||
dis.dispatch({
|
||||
action: "place_conference_call",
|
||||
room_id: payload.room_id,
|
||||
type: payload.type,
|
||||
remote_element: payload.remote_element,
|
||||
local_element: payload.local_element
|
||||
local_element: payload.local_element,
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
@ -280,15 +266,13 @@ function _onAction(payload) {
|
|||
Modal.createTrackedDialog('Call Handler', 'Conference call unsupported client', ErrorDialog, {
|
||||
description: _t('Conference calls are not supported in this client'),
|
||||
});
|
||||
}
|
||||
else if (!MatrixClientPeg.get().supportsVoip()) {
|
||||
} else if (!MatrixClientPeg.get().supportsVoip()) {
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createTrackedDialog('Call Handler', 'VoIP is unsupported', ErrorDialog, {
|
||||
title: _t('VoIP is unsupported'),
|
||||
description: _t('You cannot place VoIP calls in this browser.'),
|
||||
});
|
||||
}
|
||||
else if (MatrixClientPeg.get().isRoomEncrypted(payload.room_id)) {
|
||||
} else if (MatrixClientPeg.get().isRoomEncrypted(payload.room_id)) {
|
||||
// Conference calls are implemented by sending the media to central
|
||||
// server which combines the audio from all the participants together
|
||||
// into a single stream. This is incompatible with end-to-end encryption
|
||||
|
@ -299,16 +283,15 @@ function _onAction(payload) {
|
|||
Modal.createTrackedDialog('Call Handler', 'Conference calls unsupported e2e', ErrorDialog, {
|
||||
description: _t('Conference calls are not supported in encrypted rooms'),
|
||||
});
|
||||
}
|
||||
else {
|
||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
} else {
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
Modal.createTrackedDialog('Call Handler', 'Conference calling in development', QuestionDialog, {
|
||||
title: _t('Warning!'),
|
||||
description: _t('Conference calling is in development and may not be reliable.'),
|
||||
onFinished: confirm=>{
|
||||
onFinished: (confirm)=>{
|
||||
if (confirm) {
|
||||
ConferenceHandler.createNewMatrixCall(
|
||||
MatrixClientPeg.get(), payload.room_id
|
||||
MatrixClientPeg.get(), payload.room_id,
|
||||
).done(function(call) {
|
||||
placeCall(call);
|
||||
}, function(err) {
|
||||
|
@ -357,7 +340,7 @@ function _onAction(payload) {
|
|||
_setCallState(calls[payload.room_id], payload.room_id, "connected");
|
||||
dis.dispatch({
|
||||
action: "view_room",
|
||||
room_id: payload.room_id
|
||||
room_id: payload.room_id,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
@ -368,9 +351,9 @@ if (!global.mxCallHandler) {
|
|||
dis.register(_onAction);
|
||||
}
|
||||
|
||||
var callHandler = {
|
||||
const callHandler = {
|
||||
getCallForRoom: function(roomId) {
|
||||
var call = module.exports.getCall(roomId);
|
||||
let call = module.exports.getCall(roomId);
|
||||
if (call) return call;
|
||||
|
||||
if (ConferenceHandler) {
|
||||
|
@ -386,8 +369,8 @@ var callHandler = {
|
|||
},
|
||||
|
||||
getAnyActiveCall: function() {
|
||||
var roomsWithCalls = Object.keys(calls);
|
||||
for (var i = 0; i < roomsWithCalls.length; i++) {
|
||||
const roomsWithCalls = Object.keys(calls);
|
||||
for (let i = 0; i < roomsWithCalls.length; i++) {
|
||||
if (calls[roomsWithCalls[i]] &&
|
||||
calls[roomsWithCalls[i]].call_state !== "ended") {
|
||||
return calls[roomsWithCalls[i]];
|
||||
|
@ -402,7 +385,7 @@ var callHandler = {
|
|||
|
||||
getConferenceHandler: function() {
|
||||
return ConferenceHandler;
|
||||
}
|
||||
},
|
||||
};
|
||||
// Only things in here which actually need to be global are the
|
||||
// calls list (done separately) and making sure we only register
|
||||
|
|
|
@ -17,14 +17,14 @@ limitations under the License.
|
|||
'use strict';
|
||||
|
||||
import Promise from 'bluebird';
|
||||
var extend = require('./extend');
|
||||
var dis = require('./dispatcher');
|
||||
var MatrixClientPeg = require('./MatrixClientPeg');
|
||||
var sdk = require('./index');
|
||||
const extend = require('./extend');
|
||||
const dis = require('./dispatcher');
|
||||
const MatrixClientPeg = require('./MatrixClientPeg');
|
||||
const sdk = require('./index');
|
||||
import { _t } from './languageHandler';
|
||||
var Modal = require('./Modal');
|
||||
const Modal = require('./Modal');
|
||||
|
||||
var encrypt = require("browser-encrypt-attachment");
|
||||
const encrypt = require("browser-encrypt-attachment");
|
||||
|
||||
// Polyfill for Canvas.toBlob API using Canvas.toDataURL
|
||||
require("blueimp-canvas-to-blob");
|
||||
|
@ -54,8 +54,8 @@ const MAX_HEIGHT = 600;
|
|||
function createThumbnail(element, inputWidth, inputHeight, mimeType) {
|
||||
const deferred = Promise.defer();
|
||||
|
||||
var targetWidth = inputWidth;
|
||||
var targetHeight = inputHeight;
|
||||
let targetWidth = inputWidth;
|
||||
let targetHeight = inputHeight;
|
||||
if (targetHeight > MAX_HEIGHT) {
|
||||
targetWidth = Math.floor(targetWidth * (MAX_HEIGHT / targetHeight));
|
||||
targetHeight = MAX_HEIGHT;
|
||||
|
@ -81,7 +81,7 @@ function createThumbnail(element, inputWidth, inputHeight, mimeType) {
|
|||
w: inputWidth,
|
||||
h: inputHeight,
|
||||
},
|
||||
thumbnail: thumbnail
|
||||
thumbnail: thumbnail,
|
||||
});
|
||||
}, mimeType);
|
||||
|
||||
|
@ -129,12 +129,12 @@ function loadImageElement(imageFile) {
|
|||
* @return {Promise} A promise that resolves with the attachment info.
|
||||
*/
|
||||
function infoForImageFile(matrixClient, roomId, imageFile) {
|
||||
var thumbnailType = "image/png";
|
||||
let thumbnailType = "image/png";
|
||||
if (imageFile.type == "image/jpeg") {
|
||||
thumbnailType = "image/jpeg";
|
||||
}
|
||||
|
||||
var imageInfo;
|
||||
let imageInfo;
|
||||
return loadImageElement(imageFile).then(function(img) {
|
||||
return createThumbnail(img, img.width, img.height, thumbnailType);
|
||||
}).then(function(result) {
|
||||
|
@ -191,7 +191,7 @@ function loadVideoElement(videoFile) {
|
|||
function infoForVideoFile(matrixClient, roomId, videoFile) {
|
||||
const thumbnailType = "image/jpeg";
|
||||
|
||||
var videoInfo;
|
||||
let videoInfo;
|
||||
return loadVideoElement(videoFile).then(function(video) {
|
||||
return createThumbnail(video, video.videoWidth, video.videoHeight, thumbnailType);
|
||||
}).then(function(result) {
|
||||
|
@ -286,7 +286,7 @@ class ContentMessages {
|
|||
body: file.name || 'Attachment',
|
||||
info: {
|
||||
size: file.size,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// if we have a mime type for the file, add it to the message metadata
|
||||
|
@ -297,10 +297,10 @@ class ContentMessages {
|
|||
const def = Promise.defer();
|
||||
if (file.type.indexOf('image/') == 0) {
|
||||
content.msgtype = 'm.image';
|
||||
infoForImageFile(matrixClient, roomId, file).then(imageInfo=>{
|
||||
infoForImageFile(matrixClient, roomId, file).then((imageInfo)=>{
|
||||
extend(content.info, imageInfo);
|
||||
def.resolve();
|
||||
}, error=>{
|
||||
}, (error)=>{
|
||||
console.error(error);
|
||||
content.msgtype = 'm.file';
|
||||
def.resolve();
|
||||
|
@ -310,10 +310,10 @@ class ContentMessages {
|
|||
def.resolve();
|
||||
} else if (file.type.indexOf('video/') == 0) {
|
||||
content.msgtype = 'm.video';
|
||||
infoForVideoFile(matrixClient, roomId, file).then(videoInfo=>{
|
||||
infoForVideoFile(matrixClient, roomId, file).then((videoInfo)=>{
|
||||
extend(content.info, videoInfo);
|
||||
def.resolve();
|
||||
}, error=>{
|
||||
}, (error)=>{
|
||||
content.msgtype = 'm.file';
|
||||
def.resolve();
|
||||
});
|
||||
|
@ -331,7 +331,7 @@ class ContentMessages {
|
|||
this.inprogress.push(upload);
|
||||
dis.dispatch({action: 'upload_started'});
|
||||
|
||||
var error;
|
||||
let error;
|
||||
|
||||
function onProgress(ev) {
|
||||
upload.total = ev.total;
|
||||
|
@ -355,11 +355,11 @@ class ContentMessages {
|
|||
}, function(err) {
|
||||
error = err;
|
||||
if (!upload.canceled) {
|
||||
var desc = _t('The file \'%(fileName)s\' failed to upload', {fileName: upload.fileName}) + '.';
|
||||
let desc = _t('The file \'%(fileName)s\' failed to upload', {fileName: upload.fileName}) + '.';
|
||||
if (err.http_status == 413) {
|
||||
desc = _t('The file \'%(fileName)s\' exceeds this home server\'s size limit for uploads', {fileName: upload.fileName});
|
||||
}
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createTrackedDialog('Upload failed', '', ErrorDialog, {
|
||||
title: _t('Upload Failed'),
|
||||
description: desc,
|
||||
|
@ -367,8 +367,8 @@ class ContentMessages {
|
|||
}
|
||||
}).finally(() => {
|
||||
const inprogressKeys = Object.keys(this.inprogress);
|
||||
for (var i = 0; i < this.inprogress.length; ++i) {
|
||||
var k = inprogressKeys[i];
|
||||
for (let i = 0; i < this.inprogress.length; ++i) {
|
||||
const k = inprogressKeys[i];
|
||||
if (this.inprogress[k].promise === upload.promise) {
|
||||
this.inprogress.splice(k, 1);
|
||||
break;
|
||||
|
@ -376,8 +376,7 @@ class ContentMessages {
|
|||
}
|
||||
if (error) {
|
||||
dis.dispatch({action: 'upload_failed', upload: upload});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dis.dispatch({action: 'upload_finished', upload: upload});
|
||||
}
|
||||
});
|
||||
|
@ -389,9 +388,9 @@ class ContentMessages {
|
|||
|
||||
cancelUpload(promise) {
|
||||
const inprogressKeys = Object.keys(this.inprogress);
|
||||
var upload;
|
||||
for (var i = 0; i < this.inprogress.length; ++i) {
|
||||
var k = inprogressKeys[i];
|
||||
let upload;
|
||||
for (let i = 0; i < this.inprogress.length; ++i) {
|
||||
const k = inprogressKeys[i];
|
||||
if (this.inprogress[k].promise === promise) {
|
||||
upload = this.inprogress[k];
|
||||
break;
|
||||
|
|
|
@ -17,10 +17,10 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var sanitizeHtml = require('sanitize-html');
|
||||
var highlight = require('highlight.js');
|
||||
var linkifyMatrix = require('./linkify-matrix');
|
||||
const React = require('react');
|
||||
const sanitizeHtml = require('sanitize-html');
|
||||
const highlight = require('highlight.js');
|
||||
const linkifyMatrix = require('./linkify-matrix');
|
||||
import escape from 'lodash/escape';
|
||||
import emojione from 'emojione';
|
||||
import classNames from 'classnames';
|
||||
|
@ -66,8 +66,7 @@ function unicodeToImage(str) {
|
|||
if ( (typeof unicodeChar === 'undefined') || (unicodeChar === '') || (!(unicodeChar in emojione.jsEscapeMap)) ) {
|
||||
// if the unicodeChar doesnt exist just return the entire match
|
||||
return unicodeChar;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// get the unicode codepoint from the actual char
|
||||
unicode = emojione.jsEscapeMap[unicodeChar];
|
||||
|
||||
|
@ -183,21 +182,19 @@ const sanitizeHtmlParams = {
|
|||
if (attribs.href) {
|
||||
attribs.target = '_blank'; // by default
|
||||
|
||||
var m;
|
||||
let m;
|
||||
// FIXME: horrible duplication with linkify-matrix
|
||||
m = attribs.href.match(linkifyMatrix.VECTOR_URL_PATTERN);
|
||||
if (m) {
|
||||
attribs.href = m[1];
|
||||
delete attribs.target;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
m = attribs.href.match(linkifyMatrix.MATRIXTO_URL_PATTERN);
|
||||
if (m) {
|
||||
var entity = m[1];
|
||||
const entity = m[1];
|
||||
if (entity[0] === '@') {
|
||||
attribs.href = '#/user/' + entity;
|
||||
}
|
||||
else if (entity[0] === '#' || entity[0] === '!') {
|
||||
} else if (entity[0] === '#' || entity[0] === '!') {
|
||||
attribs.href = '#/room/' + entity;
|
||||
}
|
||||
delete attribs.target;
|
||||
|
@ -205,7 +202,7 @@ const sanitizeHtmlParams = {
|
|||
}
|
||||
}
|
||||
attribs.rel = 'noopener'; // https://mathiasbynens.github.io/rel-noopener/
|
||||
return { tagName: tagName, attribs : attribs };
|
||||
return { tagName: tagName, attribs: attribs };
|
||||
},
|
||||
'img': function(tagName, attribs) {
|
||||
// Strip out imgs that aren't `mxc` here instead of using allowedSchemesByTag
|
||||
|
@ -224,7 +221,7 @@ const sanitizeHtmlParams = {
|
|||
'code': function(tagName, attribs) {
|
||||
if (typeof attribs.class !== 'undefined') {
|
||||
// Filter out all classes other than ones starting with language- for syntax highlighting.
|
||||
let classes = attribs.class.split(/\s+/).filter(function(cl) {
|
||||
const classes = attribs.class.split(/\s+/).filter(function(cl) {
|
||||
return cl.startsWith('language-');
|
||||
});
|
||||
attribs.class = classes.join(' ');
|
||||
|
@ -287,11 +284,11 @@ class BaseHighlighter {
|
|||
* TextHighlighter).
|
||||
*/
|
||||
applyHighlights(safeSnippet, safeHighlights) {
|
||||
var lastOffset = 0;
|
||||
var offset;
|
||||
var nodes = [];
|
||||
let lastOffset = 0;
|
||||
let offset;
|
||||
let nodes = [];
|
||||
|
||||
var safeHighlight = safeHighlights[0];
|
||||
const safeHighlight = safeHighlights[0];
|
||||
while ((offset = safeSnippet.toLowerCase().indexOf(safeHighlight.toLowerCase(), lastOffset)) >= 0) {
|
||||
// handle preamble
|
||||
if (offset > lastOffset) {
|
||||
|
@ -301,7 +298,7 @@ class BaseHighlighter {
|
|||
|
||||
// do highlight. use the original string rather than safeHighlight
|
||||
// to preserve the original casing.
|
||||
var endOffset = offset + safeHighlight.length;
|
||||
const endOffset = offset + safeHighlight.length;
|
||||
nodes.push(this._processSnippet(safeSnippet.substring(offset, endOffset), true));
|
||||
|
||||
lastOffset = endOffset;
|
||||
|
@ -319,8 +316,7 @@ class BaseHighlighter {
|
|||
if (safeHighlights[1]) {
|
||||
// recurse into this range to check for the next set of highlight matches
|
||||
return this.applyHighlights(safeSnippet, safeHighlights.slice(1));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// no more highlights to be found, just return the unhighlighted string
|
||||
return [this._processSnippet(safeSnippet, false)];
|
||||
}
|
||||
|
@ -341,7 +337,7 @@ class HtmlHighlighter extends BaseHighlighter {
|
|||
return snippet;
|
||||
}
|
||||
|
||||
var span = "<span class=\""+this.highlightClass+"\">"
|
||||
let span = "<span class=\""+this.highlightClass+"\">"
|
||||
+ snippet + "</span>";
|
||||
|
||||
if (this.highlightLink) {
|
||||
|
@ -366,15 +362,15 @@ class TextHighlighter extends BaseHighlighter {
|
|||
* returns a React node
|
||||
*/
|
||||
_processSnippet(snippet, highlight) {
|
||||
var key = this._key++;
|
||||
const key = this._key++;
|
||||
|
||||
var node =
|
||||
<span key={key} className={highlight ? this.highlightClass : null }>
|
||||
let node =
|
||||
<span key={key} className={highlight ? this.highlightClass : null}>
|
||||
{ snippet }
|
||||
</span>;
|
||||
|
||||
if (highlight && this.highlightLink) {
|
||||
node = <a key={key} href={this.highlightLink}>{node}</a>;
|
||||
node = <a key={key} href={this.highlightLink}>{ node }</a>;
|
||||
}
|
||||
|
||||
return node;
|
||||
|
@ -393,20 +389,20 @@ class TextHighlighter extends BaseHighlighter {
|
|||
export function bodyToHtml(content, highlights, opts) {
|
||||
opts = opts || {};
|
||||
|
||||
var isHtml = (content.format === "org.matrix.custom.html");
|
||||
let body = isHtml ? content.formatted_body : escape(content.body);
|
||||
const isHtml = (content.format === "org.matrix.custom.html");
|
||||
const body = isHtml ? content.formatted_body : escape(content.body);
|
||||
|
||||
let bodyHasEmoji = false;
|
||||
|
||||
var safeBody;
|
||||
let safeBody;
|
||||
// XXX: We sanitize the HTML whilst also highlighting its text nodes, to avoid accidentally trying
|
||||
// to highlight HTML tags themselves. However, this does mean that we don't highlight textnodes which
|
||||
// are interrupted by HTML tags (not that we did before) - e.g. foo<span/>bar won't get highlighted
|
||||
// by an attempt to search for 'foobar'. Then again, the search query probably wouldn't work either
|
||||
try {
|
||||
if (highlights && highlights.length > 0) {
|
||||
var highlighter = new HtmlHighlighter("mx_EventTile_searchHighlight", opts.highlightLink);
|
||||
var safeHighlights = highlights.map(function(highlight) {
|
||||
const highlighter = new HtmlHighlighter("mx_EventTile_searchHighlight", opts.highlightLink);
|
||||
const safeHighlights = highlights.map(function(highlight) {
|
||||
return sanitizeHtml(highlight, sanitizeHtmlParams);
|
||||
});
|
||||
// XXX: hacky bodge to temporarily apply a textFilter to the sanitizeHtmlParams structure.
|
||||
|
@ -417,16 +413,15 @@ export function bodyToHtml(content, highlights, opts) {
|
|||
safeBody = sanitizeHtml(body, sanitizeHtmlParams);
|
||||
bodyHasEmoji = containsEmoji(body);
|
||||
if (bodyHasEmoji) safeBody = unicodeToImage(safeBody);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
delete sanitizeHtmlParams.textFilter;
|
||||
}
|
||||
|
||||
let emojiBody = false;
|
||||
if (bodyHasEmoji) {
|
||||
EMOJI_REGEX.lastIndex = 0;
|
||||
let contentBodyTrimmed = content.body !== undefined ? content.body.trim() : '';
|
||||
let match = EMOJI_REGEX.exec(contentBodyTrimmed);
|
||||
const contentBodyTrimmed = content.body !== undefined ? content.body.trim() : '';
|
||||
const match = EMOJI_REGEX.exec(contentBodyTrimmed);
|
||||
emojiBody = match && match[0] && match[0].length === contentBodyTrimmed.length;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,13 +42,12 @@ module.exports = {
|
|||
// no scaling needs to be applied
|
||||
return fullHeight;
|
||||
}
|
||||
var widthMulti = thumbWidth / fullWidth;
|
||||
var heightMulti = thumbHeight / fullHeight;
|
||||
const widthMulti = thumbWidth / fullWidth;
|
||||
const heightMulti = thumbHeight / fullHeight;
|
||||
if (widthMulti < heightMulti) {
|
||||
// width is the dominant dimension so scaling will be fixed on that
|
||||
return Math.floor(widthMulti * fullHeight);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// height is the dominant dimension so scaling will be fixed on that
|
||||
return Math.floor(heightMulti * fullHeight);
|
||||
}
|
||||
|
|
16
src/Login.js
16
src/Login.js
|
@ -59,8 +59,8 @@ export default class Login {
|
|||
}
|
||||
|
||||
getFlows() {
|
||||
var self = this;
|
||||
var client = this._createTemporaryClient();
|
||||
const self = this;
|
||||
const client = this._createTemporaryClient();
|
||||
return client.loginFlows().then(function(result) {
|
||||
self._flows = result.flows;
|
||||
self._currentFlowIndex = 0;
|
||||
|
@ -77,12 +77,12 @@ export default class Login {
|
|||
getCurrentFlowStep() {
|
||||
// technically the flow can have multiple steps, but no one does this
|
||||
// for login so we can ignore it.
|
||||
var flowStep = this._flows[this._currentFlowIndex];
|
||||
const flowStep = this._flows[this._currentFlowIndex];
|
||||
return flowStep ? flowStep.type : null;
|
||||
}
|
||||
|
||||
loginAsGuest() {
|
||||
var client = this._createTemporaryClient();
|
||||
const client = this._createTemporaryClient();
|
||||
return client.registerGuest({
|
||||
body: {
|
||||
initial_device_display_name: this._defaultDeviceDisplayName,
|
||||
|
@ -94,7 +94,7 @@ export default class Login {
|
|||
accessToken: creds.access_token,
|
||||
homeserverUrl: this._hsUrl,
|
||||
identityServerUrl: this._isUrl,
|
||||
guest: true
|
||||
guest: true,
|
||||
};
|
||||
}, (error) => {
|
||||
throw error;
|
||||
|
@ -149,12 +149,12 @@ export default class Login {
|
|||
identityServerUrl: self._isUrl,
|
||||
userId: data.user_id,
|
||||
deviceId: data.device_id,
|
||||
accessToken: data.access_token
|
||||
accessToken: data.access_token,
|
||||
});
|
||||
}, function(error) {
|
||||
if (error.httpStatus === 403) {
|
||||
if (self._fallbackHsUrl) {
|
||||
var fbClient = Matrix.createClient({
|
||||
const fbClient = Matrix.createClient({
|
||||
baseUrl: self._fallbackHsUrl,
|
||||
idBaseUrl: this._isUrl,
|
||||
});
|
||||
|
@ -165,7 +165,7 @@ export default class Login {
|
|||
identityServerUrl: self._isUrl,
|
||||
userId: data.user_id,
|
||||
deviceId: data.device_id,
|
||||
accessToken: data.access_token
|
||||
accessToken: data.access_token,
|
||||
});
|
||||
}, function(fallback_error) {
|
||||
// throw the original error
|
||||
|
|
|
@ -48,7 +48,7 @@ function html_if_tag_allowed(node) {
|
|||
* or false if it is only a single line.
|
||||
*/
|
||||
function is_multi_line(node) {
|
||||
var par = node;
|
||||
let par = node;
|
||||
while (par.parent) {
|
||||
par = par.parent;
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ export default class Markdown {
|
|||
if (isMultiLine) this.cr();
|
||||
html_if_tag_allowed.call(this, node);
|
||||
if (isMultiLine) this.cr();
|
||||
}
|
||||
};
|
||||
|
||||
return renderer.render(this.parsed);
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ export default class Markdown {
|
|||
renderer.html_block = function(node) {
|
||||
this.lit(node.literal);
|
||||
if (is_multi_line(node) && node.next) this.lit('\n\n');
|
||||
}
|
||||
};
|
||||
|
||||
return renderer.render(this.parsed);
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ class MatrixClientPeg {
|
|||
opts.pendingEventOrdering = "detached";
|
||||
|
||||
try {
|
||||
let promise = this.matrixClient.store.startup();
|
||||
const promise = this.matrixClient.store.startup();
|
||||
console.log(`MatrixClientPeg: waiting for MatrixClient store to initialise`);
|
||||
await promise;
|
||||
} catch(err) {
|
||||
|
@ -136,7 +136,7 @@ class MatrixClientPeg {
|
|||
}
|
||||
|
||||
_createClient(creds: MatrixClientCreds) {
|
||||
var opts = {
|
||||
const opts = {
|
||||
baseUrl: creds.homeserverUrl,
|
||||
idBaseUrl: creds.identityServerUrl,
|
||||
accessToken: creds.accessToken,
|
||||
|
@ -153,8 +153,8 @@ class MatrixClientPeg {
|
|||
|
||||
this.matrixClient.setGuest(Boolean(creds.guest));
|
||||
|
||||
var notifTimelineSet = new EventTimelineSet(null, {
|
||||
timelineSupport: true
|
||||
const notifTimelineSet = new EventTimelineSet(null, {
|
||||
timelineSupport: true,
|
||||
});
|
||||
// XXX: what is our initial pagination token?! it somehow needs to be synchronised with /sync.
|
||||
notifTimelineSet.getLiveTimeline().setPaginationToken("", EventTimeline.BACKWARDS);
|
||||
|
|
22
src/Modal.js
22
src/Modal.js
|
@ -17,8 +17,8 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactDOM = require('react-dom');
|
||||
const React = require('react');
|
||||
const ReactDOM = require('react-dom');
|
||||
import Analytics from './Analytics';
|
||||
import sdk from './index';
|
||||
|
||||
|
@ -137,15 +137,15 @@ class ModalManager {
|
|||
* @param {String} className CSS class to apply to the modal wrapper
|
||||
*/
|
||||
createDialogAsync(loader, props, className) {
|
||||
var self = this;
|
||||
const self = this;
|
||||
const modal = {};
|
||||
|
||||
// never call this from onFinished() otherwise it will loop
|
||||
//
|
||||
// nb explicit function() rather than arrow function, to get `arguments`
|
||||
var closeDialog = function() {
|
||||
const closeDialog = function() {
|
||||
if (props && props.onFinished) props.onFinished.apply(null, arguments);
|
||||
var i = self._modals.indexOf(modal);
|
||||
const i = self._modals.indexOf(modal);
|
||||
if (i >= 0) {
|
||||
self._modals.splice(i, 1);
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ class ModalManager {
|
|||
// property set here so you can't close the dialog from a button click!
|
||||
modal.elem = (
|
||||
<AsyncWrapper key={modalCount} loader={loader} {...props}
|
||||
onFinished={closeDialog}/>
|
||||
onFinished={closeDialog} />
|
||||
);
|
||||
modal.onFinished = props ? props.onFinished : null;
|
||||
modal.className = className;
|
||||
|
@ -191,13 +191,13 @@ class ModalManager {
|
|||
return;
|
||||
}
|
||||
|
||||
var modal = this._modals[0];
|
||||
var dialog = (
|
||||
<div className={"mx_Dialog_wrapper " + (modal.className ? modal.className : '') }>
|
||||
const modal = this._modals[0];
|
||||
const dialog = (
|
||||
<div className={"mx_Dialog_wrapper " + (modal.className ? modal.className : '')}>
|
||||
<div className="mx_Dialog">
|
||||
{modal.elem}
|
||||
{ modal.elem }
|
||||
</div>
|
||||
<div className="mx_Dialog_background" onClick={ this.closeAll }></div>
|
||||
<div className="mx_Dialog_background" onClick={this.closeAll}></div>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ const Notifier = {
|
|||
}
|
||||
|
||||
const avatarUrl = ev.sender ? Avatar.avatarUrlForMember(
|
||||
ev.sender, 40, 40, 'crop'
|
||||
ev.sender, 40, 40, 'crop',
|
||||
) : null;
|
||||
|
||||
const notif = plaf.displayNotification(title, msg, avatarUrl, room);
|
||||
|
@ -303,7 +303,7 @@ const Notifier = {
|
|||
this._playAudioNotification(ev, room);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (!global.mxNotifier) {
|
||||
|
|
|
@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
var MatrixClientPeg = require("./MatrixClientPeg");
|
||||
var dis = require("./dispatcher");
|
||||
const MatrixClientPeg = require("./MatrixClientPeg");
|
||||
const dis = require("./dispatcher");
|
||||
|
||||
// Time in ms after that a user is considered as unavailable/away
|
||||
var UNAVAILABLE_TIME_MS = 3 * 60 * 1000; // 3 mins
|
||||
var PRESENCE_STATES = ["online", "offline", "unavailable"];
|
||||
const UNAVAILABLE_TIME_MS = 3 * 60 * 1000; // 3 mins
|
||||
const PRESENCE_STATES = ["online", "offline", "unavailable"];
|
||||
|
||||
class Presence {
|
||||
|
||||
|
@ -71,14 +71,14 @@ class Presence {
|
|||
if (!this.running) {
|
||||
return;
|
||||
}
|
||||
var old_state = this.state;
|
||||
const old_state = this.state;
|
||||
this.state = newState;
|
||||
|
||||
if (MatrixClientPeg.get().isGuest()) {
|
||||
return; // don't try to set presence when a guest; it won't work.
|
||||
}
|
||||
|
||||
var self = this;
|
||||
const self = this;
|
||||
MatrixClientPeg.get().setPresence(this.state).done(function() {
|
||||
console.log("Presence: %s", newState);
|
||||
}, function(err) {
|
||||
|
@ -104,7 +104,7 @@ class Presence {
|
|||
* @private
|
||||
*/
|
||||
_resetTimer() {
|
||||
var self = this;
|
||||
const self = this;
|
||||
this.setState("online");
|
||||
// Re-arm the timer
|
||||
clearTimeout(this.timer);
|
||||
|
|
|
@ -44,9 +44,9 @@ export const contentStateToHTML = (contentState: ContentState) => {
|
|||
return stateToHTML(contentState, {
|
||||
inlineStyles: {
|
||||
UNDERLINE: {
|
||||
element: 'u'
|
||||
}
|
||||
}
|
||||
element: 'u',
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -59,7 +59,7 @@ function unicodeToEmojiUri(str) {
|
|||
let replaceWith, unicode, alt;
|
||||
if ((!emojione.unicodeAlt) || (emojione.sprites)) {
|
||||
// if we are using the shortname as the alt tag then we need a reversed array to map unicode code point to shortnames
|
||||
let mappedUnicode = emojione.mapUnicodeToShort();
|
||||
const mappedUnicode = emojione.mapUnicodeToShort();
|
||||
}
|
||||
|
||||
str = str.replace(emojione.regUnicode, function(unicodeChar) {
|
||||
|
@ -90,14 +90,14 @@ function findWithRegex(regex, contentBlock: ContentBlock, callback: (start: numb
|
|||
}
|
||||
|
||||
// Workaround for https://github.com/facebook/draft-js/issues/414
|
||||
let emojiDecorator = {
|
||||
const emojiDecorator = {
|
||||
strategy: (contentState, contentBlock, callback) => {
|
||||
findWithRegex(EMOJI_REGEX, contentBlock, callback);
|
||||
},
|
||||
component: (props) => {
|
||||
let uri = unicodeToEmojiUri(props.children[0].props.text);
|
||||
let shortname = emojione.toShort(props.children[0].props.text);
|
||||
let style = {
|
||||
const uri = unicodeToEmojiUri(props.children[0].props.text);
|
||||
const shortname = emojione.toShort(props.children[0].props.text);
|
||||
const style = {
|
||||
display: 'inline-block',
|
||||
width: '1em',
|
||||
maxHeight: '1em',
|
||||
|
@ -106,7 +106,7 @@ let emojiDecorator = {
|
|||
backgroundPosition: 'center center',
|
||||
overflow: 'hidden',
|
||||
};
|
||||
return (<span title={shortname} style={style}><span style={{opacity: 0}}>{props.children}</span></span>);
|
||||
return (<span title={shortname} style={style}><span style={{opacity: 0}}>{ props.children }</span></span>);
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -118,16 +118,16 @@ export function getScopedRTDecorators(scope: any): CompositeDecorator {
|
|||
}
|
||||
|
||||
export function getScopedMDDecorators(scope: any): CompositeDecorator {
|
||||
let markdownDecorators = ['HR', 'BOLD', 'ITALIC', 'CODE', 'STRIKETHROUGH'].map(
|
||||
const markdownDecorators = ['HR', 'BOLD', 'ITALIC', 'CODE', 'STRIKETHROUGH'].map(
|
||||
(style) => ({
|
||||
strategy: (contentState, contentBlock, callback) => {
|
||||
return findWithRegex(MARKDOWN_REGEX[style], contentBlock, callback);
|
||||
},
|
||||
component: (props) => (
|
||||
<span className={"mx_MarkdownElement mx_Markdown_" + style}>
|
||||
{props.children}
|
||||
{ props.children }
|
||||
</span>
|
||||
)
|
||||
),
|
||||
}));
|
||||
|
||||
markdownDecorators.push({
|
||||
|
@ -136,9 +136,9 @@ export function getScopedMDDecorators(scope: any): CompositeDecorator {
|
|||
},
|
||||
component: (props) => (
|
||||
<a href="#" className="mx_MarkdownElement mx_Markdown_LINK">
|
||||
{props.children}
|
||||
{ props.children }
|
||||
</a>
|
||||
)
|
||||
),
|
||||
});
|
||||
// markdownDecorators.push(emojiDecorator);
|
||||
// TODO Consider renabling "syntax highlighting" when we can do it properly
|
||||
|
@ -161,7 +161,7 @@ export function modifyText(contentState: ContentState, rangeToReplace: Selection
|
|||
for (let currentKey = startKey;
|
||||
currentKey && currentKey !== endKey;
|
||||
currentKey = contentState.getKeyAfter(currentKey)) {
|
||||
let blockText = getText(currentKey);
|
||||
const blockText = getText(currentKey);
|
||||
text += blockText.substring(startOffset, blockText.length);
|
||||
|
||||
// from now on, we'll take whole blocks
|
||||
|
@ -182,7 +182,7 @@ export function modifyText(contentState: ContentState, rangeToReplace: Selection
|
|||
export function selectionStateToTextOffsets(selectionState: SelectionState,
|
||||
contentBlocks: Array<ContentBlock>): {start: number, end: number} {
|
||||
let offset = 0, start = 0, end = 0;
|
||||
for (let block of contentBlocks) {
|
||||
for (const block of contentBlocks) {
|
||||
if (selectionState.getStartKey() === block.getKey()) {
|
||||
start = offset + selectionState.getStartOffset();
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ export function attachImmutableEntitiesToEmoji(editorState: EditorState): Editor
|
|||
.set('focusOffset', end);
|
||||
const emojiText = plainText.substring(start, end);
|
||||
newContentState = newContentState.createEntity(
|
||||
'emoji', 'IMMUTABLE', { emojiUnicode: emojiText }
|
||||
'emoji', 'IMMUTABLE', { emojiUnicode: emojiText },
|
||||
);
|
||||
const entityKey = newContentState.getLastCreatedEntityKey();
|
||||
newContentState = Modifier.replaceText(
|
||||
|
|
|
@ -62,8 +62,7 @@ export function isConfCallRoom(room, me, conferenceHandler) {
|
|||
|
||||
export function looksLikeDirectMessageRoom(room, me) {
|
||||
if (me.membership == "join" || me.membership === "ban" ||
|
||||
(me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey()))
|
||||
{
|
||||
(me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey())) {
|
||||
// Used to split rooms via tags
|
||||
const tagNames = Object.keys(room.tags);
|
||||
// Used for 1:1 direct chats
|
||||
|
|
|
@ -15,10 +15,10 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import Promise from 'bluebird';
|
||||
var request = require('browser-request');
|
||||
const request = require('browser-request');
|
||||
|
||||
var SdkConfig = require('./SdkConfig');
|
||||
var MatrixClientPeg = require('./MatrixClientPeg');
|
||||
const SdkConfig = require('./SdkConfig');
|
||||
const MatrixClientPeg = require('./MatrixClientPeg');
|
||||
|
||||
class ScalarAuthClient {
|
||||
|
||||
|
@ -38,7 +38,7 @@ class ScalarAuthClient {
|
|||
|
||||
// Returns a scalar_token string
|
||||
getScalarToken() {
|
||||
var tok = window.localStorage.getItem("mx_scalar_token");
|
||||
const tok = window.localStorage.getItem("mx_scalar_token");
|
||||
if (tok) return Promise.resolve(tok);
|
||||
|
||||
// No saved token, so do the dance to get one. First, we
|
||||
|
@ -53,9 +53,9 @@ class ScalarAuthClient {
|
|||
}
|
||||
|
||||
exchangeForScalarToken(openid_token_object) {
|
||||
var defer = Promise.defer();
|
||||
const defer = Promise.defer();
|
||||
|
||||
var scalar_rest_url = SdkConfig.get().integrations_rest_url;
|
||||
const scalar_rest_url = SdkConfig.get().integrations_rest_url;
|
||||
request({
|
||||
method: 'POST',
|
||||
uri: scalar_rest_url+'/register',
|
||||
|
@ -77,7 +77,7 @@ class ScalarAuthClient {
|
|||
}
|
||||
|
||||
getScalarInterfaceUrlForRoom(roomId, screen, id) {
|
||||
var url = SdkConfig.get().integrations_ui_url;
|
||||
let url = SdkConfig.get().integrations_ui_url;
|
||||
url += "?scalar_token=" + encodeURIComponent(this.scalarToken);
|
||||
url += "&room_id=" + encodeURIComponent(roomId);
|
||||
if (id) {
|
||||
|
|
|
@ -356,12 +356,12 @@ function getWidgets(event, roomId) {
|
|||
}
|
||||
const stateEvents = room.currentState.getStateEvents("im.vector.modular.widgets");
|
||||
// Only return widgets which have required fields
|
||||
let widgetStateEvents = [];
|
||||
const widgetStateEvents = [];
|
||||
stateEvents.forEach((ev) => {
|
||||
if (ev.getContent().type && ev.getContent().url) {
|
||||
widgetStateEvents.push(ev.event); // return the raw event
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
sendResponse(event, widgetStateEvents);
|
||||
}
|
||||
|
@ -376,7 +376,7 @@ function setPlumbingState(event, roomId, status) {
|
|||
sendError(event, _t('You need to be logged in.'));
|
||||
return;
|
||||
}
|
||||
client.sendStateEvent(roomId, "m.room.plumbing", { status : status }).done(() => {
|
||||
client.sendStateEvent(roomId, "m.room.plumbing", { status: status }).done(() => {
|
||||
sendResponse(event, {
|
||||
success: true,
|
||||
});
|
||||
|
@ -415,11 +415,11 @@ function setBotPower(event, roomId, userId, level) {
|
|||
}
|
||||
|
||||
client.getStateEvent(roomId, "m.room.power_levels", "").then((powerLevels) => {
|
||||
let powerEvent = new MatrixEvent(
|
||||
const powerEvent = new MatrixEvent(
|
||||
{
|
||||
type: "m.room.power_levels",
|
||||
content: powerLevels,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
client.setPowerLevel(roomId, userId, level, powerEvent).done(() => {
|
||||
|
@ -485,8 +485,7 @@ function canSendEvent(event, roomId) {
|
|||
let canSend = false;
|
||||
if (isState) {
|
||||
canSend = room.currentState.maySendStateEvent(evType, me);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
canSend = room.currentState.maySendEvent(evType, me);
|
||||
}
|
||||
|
||||
|
@ -517,8 +516,8 @@ function returnStateEvent(event, roomId, eventType, stateKey) {
|
|||
sendResponse(event, stateEvent.getContent());
|
||||
}
|
||||
|
||||
var currentRoomId = null;
|
||||
var currentRoomAlias = null;
|
||||
let currentRoomId = null;
|
||||
let currentRoomAlias = null;
|
||||
|
||||
// Listen for when a room is viewed
|
||||
dis.register(onAction);
|
||||
|
@ -542,7 +541,7 @@ const onMessage = function(event) {
|
|||
//
|
||||
// All strings start with the empty string, so for sanity return if the length
|
||||
// of the event origin is 0.
|
||||
let url = SdkConfig.get().integrations_ui_url;
|
||||
const url = SdkConfig.get().integrations_ui_url;
|
||||
if (event.origin.length === 0 || !url.startsWith(event.origin) || !event.data.action) {
|
||||
return; // don't log this - debugging APIs like to spam postMessage which floods the log otherwise
|
||||
}
|
||||
|
@ -647,7 +646,7 @@ module.exports = {
|
|||
// Make an error so we get a stack trace
|
||||
const e = new Error(
|
||||
"ScalarMessaging: mismatched startListening / stopListening detected." +
|
||||
" Negative count"
|
||||
" Negative count",
|
||||
);
|
||||
console.error(e);
|
||||
}
|
||||
|
|
|
@ -18,10 +18,10 @@ limitations under the License.
|
|||
// module.exports otherwise this will break when included by both
|
||||
// react-sdk and apps layered on top.
|
||||
|
||||
var DEBUG = 0;
|
||||
const DEBUG = 0;
|
||||
|
||||
// The colour keys to be replaced as referred to in CSS
|
||||
var keyRgb = [
|
||||
const keyRgb = [
|
||||
"rgb(118, 207, 166)", // Vector Green
|
||||
"rgb(234, 245, 240)", // Vector Light Green
|
||||
"rgb(211, 239, 225)", // BottomLeftMenu overlay (20% Vector Green)
|
||||
|
@ -35,7 +35,7 @@ var keyRgb = [
|
|||
// x = (255 - 234) / (255 - 118) = 0.16
|
||||
|
||||
// The colour keys to be replaced as referred to in SVGs
|
||||
var keyHex = [
|
||||
const keyHex = [
|
||||
"#76CFA6", // Vector Green
|
||||
"#EAF5F0", // Vector Light Green
|
||||
"#D3EFE1", // BottomLeftMenu overlay (20% Vector Green overlaid on Vector Light Green)
|
||||
|
@ -44,14 +44,14 @@ var keyHex = [
|
|||
|
||||
// cache of our replacement colours
|
||||
// defaults to our keys.
|
||||
var colors = [
|
||||
const colors = [
|
||||
keyHex[0],
|
||||
keyHex[1],
|
||||
keyHex[2],
|
||||
keyHex[3],
|
||||
];
|
||||
|
||||
var cssFixups = [
|
||||
const cssFixups = [
|
||||
// {
|
||||
// style: a style object that should be fixed up taken from a stylesheet
|
||||
// attr: name of the attribute to be clobbered, e.g. 'color'
|
||||
|
@ -60,7 +60,7 @@ var cssFixups = [
|
|||
];
|
||||
|
||||
// CSS attributes to be fixed up
|
||||
var cssAttrs = [
|
||||
const cssAttrs = [
|
||||
"color",
|
||||
"backgroundColor",
|
||||
"borderColor",
|
||||
|
@ -69,17 +69,17 @@ var cssAttrs = [
|
|||
"borderLeftColor",
|
||||
];
|
||||
|
||||
var svgAttrs = [
|
||||
const svgAttrs = [
|
||||
"fill",
|
||||
"stroke",
|
||||
];
|
||||
|
||||
var cached = false;
|
||||
let cached = false;
|
||||
|
||||
function calcCssFixups() {
|
||||
if (DEBUG) console.log("calcSvgFixups start");
|
||||
for (var i = 0; i < document.styleSheets.length; i++) {
|
||||
var ss = document.styleSheets[i];
|
||||
for (let i = 0; i < document.styleSheets.length; i++) {
|
||||
const ss = document.styleSheets[i];
|
||||
if (!ss) continue; // well done safari >:(
|
||||
// Chromium apparently sometimes returns null here; unsure why.
|
||||
// see $14534907369972FRXBx:matrix.org in HQ
|
||||
|
@ -104,12 +104,12 @@ function calcCssFixups() {
|
|||
if (ss.href && !ss.href.match(/\/bundle.*\.css$/)) continue;
|
||||
|
||||
if (!ss.cssRules) continue;
|
||||
for (var j = 0; j < ss.cssRules.length; j++) {
|
||||
var rule = ss.cssRules[j];
|
||||
for (let j = 0; j < ss.cssRules.length; j++) {
|
||||
const rule = ss.cssRules[j];
|
||||
if (!rule.style) continue;
|
||||
for (var k = 0; k < cssAttrs.length; k++) {
|
||||
var attr = cssAttrs[k];
|
||||
for (var l = 0; l < keyRgb.length; l++) {
|
||||
for (let k = 0; k < cssAttrs.length; k++) {
|
||||
const attr = cssAttrs[k];
|
||||
for (let l = 0; l < keyRgb.length; l++) {
|
||||
if (rule.style[attr] === keyRgb[l]) {
|
||||
cssFixups.push({
|
||||
style: rule.style,
|
||||
|
@ -126,8 +126,8 @@ function calcCssFixups() {
|
|||
|
||||
function applyCssFixups() {
|
||||
if (DEBUG) console.log("applyCssFixups start");
|
||||
for (var i = 0; i < cssFixups.length; i++) {
|
||||
var cssFixup = cssFixups[i];
|
||||
for (let i = 0; i < cssFixups.length; i++) {
|
||||
const cssFixup = cssFixups[i];
|
||||
cssFixup.style[cssFixup.attr] = colors[cssFixup.index];
|
||||
}
|
||||
if (DEBUG) console.log("applyCssFixups end");
|
||||
|
@ -140,15 +140,15 @@ function hexToRgb(color) {
|
|||
color[1] + color[1] +
|
||||
color[2] + color[2];
|
||||
}
|
||||
var val = parseInt(color, 16);
|
||||
var r = (val >> 16) & 255;
|
||||
var g = (val >> 8) & 255;
|
||||
var b = val & 255;
|
||||
const val = parseInt(color, 16);
|
||||
const r = (val >> 16) & 255;
|
||||
const g = (val >> 8) & 255;
|
||||
const b = val & 255;
|
||||
return [r, g, b];
|
||||
}
|
||||
|
||||
function rgbToHex(rgb) {
|
||||
var val = (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
|
||||
const val = (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
|
||||
return '#' + (0x1000000 + val).toString(16).slice(1);
|
||||
}
|
||||
|
||||
|
@ -167,12 +167,11 @@ module.exports = {
|
|||
*
|
||||
* @param {Function} tintable Function to call when the tint changes.
|
||||
*/
|
||||
registerTintable : function(tintable) {
|
||||
registerTintable: function(tintable) {
|
||||
tintables.push(tintable);
|
||||
},
|
||||
|
||||
tint: function(primaryColor, secondaryColor, tertiaryColor) {
|
||||
|
||||
if (!cached) {
|
||||
calcCssFixups();
|
||||
cached = true;
|
||||
|
@ -185,7 +184,7 @@ module.exports = {
|
|||
|
||||
if (!secondaryColor) {
|
||||
const x = 0.16; // average weighting factor calculated from vector green & light green
|
||||
var rgb = hexToRgb(primaryColor);
|
||||
const rgb = hexToRgb(primaryColor);
|
||||
rgb[0] = x * rgb[0] + (1 - x) * 255;
|
||||
rgb[1] = x * rgb[1] + (1 - x) * 255;
|
||||
rgb[2] = x * rgb[2] + (1 - x) * 255;
|
||||
|
@ -194,8 +193,8 @@ module.exports = {
|
|||
|
||||
if (!tertiaryColor) {
|
||||
const x = 0.19;
|
||||
var rgb1 = hexToRgb(primaryColor);
|
||||
var rgb2 = hexToRgb(secondaryColor);
|
||||
const rgb1 = hexToRgb(primaryColor);
|
||||
const rgb2 = hexToRgb(secondaryColor);
|
||||
rgb1[0] = x * rgb1[0] + (1 - x) * rgb2[0];
|
||||
rgb1[1] = x * rgb1[1] + (1 - x) * rgb2[1];
|
||||
rgb1[2] = x * rgb1[2] + (1 - x) * rgb2[2];
|
||||
|
@ -204,8 +203,7 @@ module.exports = {
|
|||
|
||||
if (colors[0] === primaryColor &&
|
||||
colors[1] === secondaryColor &&
|
||||
colors[2] === tertiaryColor)
|
||||
{
|
||||
colors[2] === tertiaryColor) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -248,14 +246,13 @@ module.exports = {
|
|||
// key colour; cache the element and apply.
|
||||
|
||||
if (DEBUG) console.log("calcSvgFixups start for " + svgs);
|
||||
var fixups = [];
|
||||
for (var i = 0; i < svgs.length; i++) {
|
||||
const fixups = [];
|
||||
for (let i = 0; i < svgs.length; i++) {
|
||||
var svgDoc;
|
||||
try {
|
||||
svgDoc = svgs[i].contentDocument;
|
||||
}
|
||||
catch(e) {
|
||||
var msg = 'Failed to get svg.contentDocument of ' + svgs[i].toString();
|
||||
} catch(e) {
|
||||
let msg = 'Failed to get svg.contentDocument of ' + svgs[i].toString();
|
||||
if (e.message) {
|
||||
msg += e.message;
|
||||
}
|
||||
|
@ -265,12 +262,12 @@ module.exports = {
|
|||
console.error(e);
|
||||
}
|
||||
if (!svgDoc) continue;
|
||||
var tags = svgDoc.getElementsByTagName("*");
|
||||
for (var j = 0; j < tags.length; j++) {
|
||||
var tag = tags[j];
|
||||
for (var k = 0; k < svgAttrs.length; k++) {
|
||||
var attr = svgAttrs[k];
|
||||
for (var l = 0; l < keyHex.length; l++) {
|
||||
const tags = svgDoc.getElementsByTagName("*");
|
||||
for (let j = 0; j < tags.length; j++) {
|
||||
const tag = tags[j];
|
||||
for (let k = 0; k < svgAttrs.length; k++) {
|
||||
const attr = svgAttrs[k];
|
||||
for (let l = 0; l < keyHex.length; l++) {
|
||||
if (tag.getAttribute(attr) && tag.getAttribute(attr).toUpperCase() === keyHex[l]) {
|
||||
fixups.push({
|
||||
node: tag,
|
||||
|
@ -289,10 +286,10 @@ module.exports = {
|
|||
|
||||
applySvgFixups: function(fixups) {
|
||||
if (DEBUG) console.log("applySvgFixups start for " + fixups);
|
||||
for (var i = 0; i < fixups.length; i++) {
|
||||
var svgFixup = fixups[i];
|
||||
for (let i = 0; i < fixups.length; i++) {
|
||||
const svgFixup = fixups[i];
|
||||
svgFixup.node.setAttribute(svgFixup.attr, colors[svgFixup.index]);
|
||||
}
|
||||
if (DEBUG) console.log("applySvgFixups end");
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -14,10 +14,10 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
var MatrixClientPeg = require('./MatrixClientPeg');
|
||||
const MatrixClientPeg = require('./MatrixClientPeg');
|
||||
import UserSettingsStore from './UserSettingsStore';
|
||||
import shouldHideEvent from './shouldHideEvent';
|
||||
var sdk = require('./index');
|
||||
const sdk = require('./index');
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
|
@ -34,17 +34,17 @@ module.exports = {
|
|||
} else if (ev.getType == 'm.room.message' && ev.getContent().msgtype == 'm.notify') {
|
||||
return false;
|
||||
}
|
||||
var EventTile = sdk.getComponent('rooms.EventTile');
|
||||
const EventTile = sdk.getComponent('rooms.EventTile');
|
||||
return EventTile.haveTileForEvent(ev);
|
||||
},
|
||||
|
||||
doesRoomHaveUnreadMessages: function(room) {
|
||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
|
||||
// get the most recent read receipt sent by our account.
|
||||
// N.B. this is NOT a read marker (RM, aka "read up to marker"),
|
||||
// despite the name of the method :((
|
||||
var readUpToId = room.getEventReadUpTo(myUserId);
|
||||
const readUpToId = room.getEventReadUpTo(myUserId);
|
||||
|
||||
// as we don't send RRs for our own messages, make sure we special case that
|
||||
// if *we* sent the last message into the room, we consider it not unread!
|
||||
|
@ -54,8 +54,7 @@ module.exports = {
|
|||
// https://github.com/vector-im/riot-web/issues/3363
|
||||
if (room.timeline.length &&
|
||||
room.timeline[room.timeline.length - 1].sender &&
|
||||
room.timeline[room.timeline.length - 1].sender.userId === myUserId)
|
||||
{
|
||||
room.timeline[room.timeline.length - 1].sender.userId === myUserId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -67,8 +66,8 @@ module.exports = {
|
|||
|
||||
const syncedSettings = UserSettingsStore.getSyncedSettings();
|
||||
// Loop through messages, starting with the most recent...
|
||||
for (var i = room.timeline.length - 1; i >= 0; --i) {
|
||||
var ev = room.timeline[i];
|
||||
for (let i = room.timeline.length - 1; i >= 0; --i) {
|
||||
const ev = room.timeline[i];
|
||||
|
||||
if (ev.getId() == readUpToId) {
|
||||
// If we've read up to this event, there's nothing more recents
|
||||
|
@ -86,5 +85,5 @@ module.exports = {
|
|||
// is unread on the theory that false positives are better than
|
||||
// false negatives here.
|
||||
return true;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var React = require('react');
|
||||
var ReactDom = require('react-dom');
|
||||
var Velocity = require('velocity-vector');
|
||||
const React = require('react');
|
||||
const ReactDom = require('react-dom');
|
||||
const Velocity = require('velocity-vector');
|
||||
|
||||
/**
|
||||
* The Velociraptor contains components and animates transitions with velocity.
|
||||
|
@ -46,13 +46,13 @@ module.exports = React.createClass({
|
|||
* update `this.children` according to the new list of children given
|
||||
*/
|
||||
_updateChildren: function(newChildren) {
|
||||
var self = this;
|
||||
var oldChildren = this.children || {};
|
||||
const self = this;
|
||||
const oldChildren = this.children || {};
|
||||
this.children = {};
|
||||
React.Children.toArray(newChildren).forEach(function(c) {
|
||||
if (oldChildren[c.key]) {
|
||||
var old = oldChildren[c.key];
|
||||
var oldNode = ReactDom.findDOMNode(self.nodes[old.key]);
|
||||
const old = oldChildren[c.key];
|
||||
const oldNode = ReactDom.findDOMNode(self.nodes[old.key]);
|
||||
|
||||
if (oldNode && oldNode.style.left != c.props.style.left) {
|
||||
Velocity(oldNode, { left: c.props.style.left }, self.props.transition).then(function() {
|
||||
|
@ -71,18 +71,18 @@ module.exports = React.createClass({
|
|||
} else {
|
||||
// new element. If we have a startStyle, use that as the style and go through
|
||||
// the enter animations
|
||||
var newProps = {};
|
||||
var restingStyle = c.props.style;
|
||||
const newProps = {};
|
||||
const restingStyle = c.props.style;
|
||||
|
||||
var startStyles = self.props.startStyles;
|
||||
const startStyles = self.props.startStyles;
|
||||
if (startStyles.length > 0) {
|
||||
var startStyle = startStyles[0];
|
||||
const startStyle = startStyles[0];
|
||||
newProps.style = startStyle;
|
||||
// console.log("mounted@startstyle0: "+JSON.stringify(startStyle));
|
||||
}
|
||||
|
||||
newProps.ref = (n => self._collectNode(
|
||||
c.key, n, restingStyle
|
||||
newProps.ref = ((n) => self._collectNode(
|
||||
c.key, n, restingStyle,
|
||||
));
|
||||
|
||||
self.children[c.key] = React.cloneElement(c, newProps);
|
||||
|
@ -103,8 +103,8 @@ module.exports = React.createClass({
|
|||
this.nodes[k] === undefined &&
|
||||
this.props.startStyles.length > 0
|
||||
) {
|
||||
var startStyles = this.props.startStyles;
|
||||
var transitionOpts = this.props.enterTransitionOpts;
|
||||
const startStyles = this.props.startStyles;
|
||||
const transitionOpts = this.props.enterTransitionOpts;
|
||||
const domNode = ReactDom.findDOMNode(node);
|
||||
// start from startStyle 1: 0 is the one we gave it
|
||||
// to start with, so now we animate 1 etc.
|
||||
|
@ -154,7 +154,7 @@ module.exports = React.createClass({
|
|||
render: function() {
|
||||
return (
|
||||
<span>
|
||||
{Object.values(this.children)}
|
||||
{ Object.values(this.children) }
|
||||
</span>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
var Velocity = require('velocity-vector');
|
||||
const Velocity = require('velocity-vector');
|
||||
|
||||
// courtesy of https://github.com/julianshapiro/velocity/issues/283
|
||||
// We only use easeOutBounce (easeInBounce is just sort of nonsensical)
|
||||
function bounce( p ) {
|
||||
var pow2,
|
||||
let pow2,
|
||||
bounce = 4;
|
||||
|
||||
while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {
|
||||
|
|
|
@ -14,19 +14,19 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
var MatrixClientPeg = require("./MatrixClientPeg");
|
||||
const MatrixClientPeg = require("./MatrixClientPeg");
|
||||
import { _t } from './languageHandler';
|
||||
|
||||
module.exports = {
|
||||
usersTypingApartFromMeAndIgnored: function(room) {
|
||||
return this.usersTyping(
|
||||
room, [MatrixClientPeg.get().credentials.userId].concat(MatrixClientPeg.get().getIgnoredUsers())
|
||||
room, [MatrixClientPeg.get().credentials.userId].concat(MatrixClientPeg.get().getIgnoredUsers()),
|
||||
);
|
||||
},
|
||||
|
||||
usersTypingApartFromMe: function(room) {
|
||||
return this.usersTyping(
|
||||
room, [MatrixClientPeg.get().credentials.userId]
|
||||
room, [MatrixClientPeg.get().credentials.userId],
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -35,15 +35,15 @@ module.exports = {
|
|||
* to exclude, return a list of user objects who are typing.
|
||||
*/
|
||||
usersTyping: function(room, exclude) {
|
||||
var whoIsTyping = [];
|
||||
const whoIsTyping = [];
|
||||
|
||||
if (exclude === undefined) {
|
||||
exclude = [];
|
||||
}
|
||||
|
||||
var memberKeys = Object.keys(room.currentState.members);
|
||||
for (var i = 0; i < memberKeys.length; ++i) {
|
||||
var userId = memberKeys[i];
|
||||
const memberKeys = Object.keys(room.currentState.members);
|
||||
for (let i = 0; i < memberKeys.length; ++i) {
|
||||
const userId = memberKeys[i];
|
||||
|
||||
if (room.currentState.members[userId].typing) {
|
||||
if (exclude.indexOf(userId) == -1) {
|
||||
|
@ -76,5 +76,5 @@ module.exports = {
|
|||
const lastPerson = names.pop();
|
||||
return _t('%(names)s and %(lastPerson)s are typing', {names: names.join(', '), lastPerson: lastPerson});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -14,10 +14,10 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
var React = require("react");
|
||||
const React = require("react");
|
||||
import { _t } from '../../../languageHandler';
|
||||
var sdk = require('../../../index');
|
||||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||
const sdk = require('../../../index');
|
||||
const MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'EncryptedEventDialog',
|
||||
|
@ -33,7 +33,7 @@ module.exports = React.createClass({
|
|||
|
||||
componentWillMount: function() {
|
||||
this._unmounted = false;
|
||||
var client = MatrixClientPeg.get();
|
||||
const client = MatrixClientPeg.get();
|
||||
|
||||
// first try to load the device from our store.
|
||||
//
|
||||
|
@ -60,7 +60,7 @@ module.exports = React.createClass({
|
|||
|
||||
componentWillUnmount: function() {
|
||||
this._unmounted = true;
|
||||
var client = MatrixClientPeg.get();
|
||||
const client = MatrixClientPeg.get();
|
||||
if (client) {
|
||||
client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
|
||||
}
|
||||
|
@ -89,12 +89,12 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_renderDeviceInfo: function() {
|
||||
var device = this.state.device;
|
||||
const device = this.state.device;
|
||||
if (!device) {
|
||||
return (<i>{ _t('unknown device') }</i>);
|
||||
}
|
||||
|
||||
var verificationStatus = (<b>{ _t('NOT verified') }</b>);
|
||||
let verificationStatus = (<b>{ _t('NOT verified') }</b>);
|
||||
if (device.isBlocked()) {
|
||||
verificationStatus = (<b>{ _t('Blacklisted') }</b>);
|
||||
} else if (device.isVerified()) {
|
||||
|
@ -118,7 +118,7 @@ module.exports = React.createClass({
|
|||
</tr>
|
||||
<tr>
|
||||
<td>{ _t('Ed25519 fingerprint') }</td>
|
||||
<td><code>{device.getFingerprint()}</code></td>
|
||||
<td><code>{ device.getFingerprint() }</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -126,7 +126,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_renderEventInfo: function() {
|
||||
var event = this.props.event;
|
||||
const event = this.props.event;
|
||||
|
||||
return (
|
||||
<table>
|
||||
|
@ -165,36 +165,36 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var DeviceVerifyButtons = sdk.getComponent('elements.DeviceVerifyButtons');
|
||||
const DeviceVerifyButtons = sdk.getComponent('elements.DeviceVerifyButtons');
|
||||
|
||||
var buttons = null;
|
||||
let buttons = null;
|
||||
if (this.state.device) {
|
||||
buttons = (
|
||||
<DeviceVerifyButtons device={ this.state.device }
|
||||
userId={ this.props.event.getSender() }
|
||||
<DeviceVerifyButtons device={this.state.device}
|
||||
userId={this.props.event.getSender()}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_EncryptedEventDialog" onKeyDown={ this.onKeyDown }>
|
||||
<div className="mx_EncryptedEventDialog" onKeyDown={this.onKeyDown}>
|
||||
<div className="mx_Dialog_title">
|
||||
{ _t('End-to-end encryption information') }
|
||||
</div>
|
||||
<div className="mx_Dialog_content">
|
||||
<h4>{ _t('Event information') }</h4>
|
||||
{this._renderEventInfo()}
|
||||
{ this._renderEventInfo() }
|
||||
|
||||
<h4>{ _t('Sender device information') }</h4>
|
||||
{this._renderDeviceInfo()}
|
||||
{ this._renderDeviceInfo() }
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button className="mx_Dialog_primary" onClick={ this.props.onFinished } autoFocus={ true }>
|
||||
<button className="mx_Dialog_primary" onClick={this.props.onFinished} autoFocus={true}>
|
||||
{ _t('OK') }
|
||||
</button>
|
||||
{buttons}
|
||||
{ buttons }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -45,7 +45,7 @@ const PROVIDERS = [
|
|||
EmojiProvider,
|
||||
CommandProvider,
|
||||
DuckDuckGoProvider,
|
||||
].map(completer => completer.getInstance());
|
||||
].map((completer) => completer.getInstance());
|
||||
|
||||
// Providers will get rejected if they take longer than this.
|
||||
const PROVIDER_COMPLETION_TIMEOUT = 3000;
|
||||
|
|
|
@ -30,13 +30,13 @@ export class TextualCompletion extends React.Component {
|
|||
subtitle,
|
||||
description,
|
||||
className,
|
||||
...restProps,
|
||||
...restProps
|
||||
} = this.props;
|
||||
return (
|
||||
<div className={classNames('mx_Autocomplete_Completion_block', className)} {...restProps}>
|
||||
<span className="mx_Autocomplete_Completion_title">{title}</span>
|
||||
<span className="mx_Autocomplete_Completion_subtitle">{subtitle}</span>
|
||||
<span className="mx_Autocomplete_Completion_description">{description}</span>
|
||||
<span className="mx_Autocomplete_Completion_title">{ title }</span>
|
||||
<span className="mx_Autocomplete_Completion_subtitle">{ subtitle }</span>
|
||||
<span className="mx_Autocomplete_Completion_description">{ description }</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -56,14 +56,14 @@ export class PillCompletion extends React.Component {
|
|||
description,
|
||||
initialComponent,
|
||||
className,
|
||||
...restProps,
|
||||
...restProps
|
||||
} = this.props;
|
||||
return (
|
||||
<div className={classNames('mx_Autocomplete_Completion_pill', className)} {...restProps}>
|
||||
{initialComponent}
|
||||
<span className="mx_Autocomplete_Completion_title">{title}</span>
|
||||
<span className="mx_Autocomplete_Completion_subtitle">{subtitle}</span>
|
||||
<span className="mx_Autocomplete_Completion_description">{description}</span>
|
||||
{ initialComponent }
|
||||
<span className="mx_Autocomplete_Completion_title">{ title }</span>
|
||||
<span className="mx_Autocomplete_Completion_subtitle">{ subtitle }</span>
|
||||
<span className="mx_Autocomplete_Completion_description">{ description }</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ export default class DuckDuckGoProvider extends AutocompleteProvider {
|
|||
}
|
||||
|
||||
async getCompletions(query: string, selection: {start: number, end: number}) {
|
||||
let {command, range} = this.getCurrentCommand(query, selection);
|
||||
const {command, range} = this.getCurrentCommand(query, selection);
|
||||
if (!query || !command) {
|
||||
return [];
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ export default class DuckDuckGoProvider extends AutocompleteProvider {
|
|||
method: 'GET',
|
||||
});
|
||||
const json = await response.json();
|
||||
let results = json.Results.map(result => {
|
||||
const results = json.Results.map((result) => {
|
||||
return {
|
||||
completion: result.Text,
|
||||
component: (
|
||||
|
@ -105,7 +105,7 @@ export default class DuckDuckGoProvider extends AutocompleteProvider {
|
|||
|
||||
renderCompletions(completions: [React.Component]): ?React.Component {
|
||||
return <div className="mx_Autocomplete_Completion_container_block">
|
||||
{completions}
|
||||
{ completions }
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ export default class EmojiProvider extends AutocompleteProvider {
|
|||
return {
|
||||
completion: unicode,
|
||||
component: (
|
||||
<PillCompletion title={shortname} initialComponent={<EmojiText style={{maxWidth: '1em'}}>{unicode}</EmojiText>} />
|
||||
<PillCompletion title={shortname} initialComponent={<EmojiText style={{maxWidth: '1em'}}>{ unicode }</EmojiText>} />
|
||||
),
|
||||
range,
|
||||
};
|
||||
|
@ -152,14 +152,13 @@ export default class EmojiProvider extends AutocompleteProvider {
|
|||
}
|
||||
|
||||
static getInstance() {
|
||||
if (instance == null)
|
||||
{instance = new EmojiProvider();}
|
||||
if (instance == null) {instance = new EmojiProvider();}
|
||||
return instance;
|
||||
}
|
||||
|
||||
renderCompletions(completions: [React.Component]): ?React.Component {
|
||||
return <div className="mx_Autocomplete_Completion_container_pill">
|
||||
{completions}
|
||||
{ completions }
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ export default class UserProvider extends AutocompleteProvider {
|
|||
if (this.users === null) this._makeUsers();
|
||||
|
||||
let completions = [];
|
||||
let {command, range} = this.getCurrentCommand(query, selection, force);
|
||||
const {command, range} = this.getCurrentCommand(query, selection, force);
|
||||
if (command) {
|
||||
completions = this.matcher.match(command[0]).map((user) => {
|
||||
const displayName = (user.name || user.userId || '').replace(' (IRC)', ''); // FIXME when groups are done
|
||||
|
@ -71,7 +71,7 @@ export default class UserProvider extends AutocompleteProvider {
|
|||
href: 'https://matrix.to/#/' + user.userId,
|
||||
component: (
|
||||
<PillCompletion
|
||||
initialComponent={<MemberAvatar member={user} width={24} height={24}/>}
|
||||
initialComponent={<MemberAvatar member={user} width={24} height={24} />}
|
||||
title={displayName}
|
||||
description={user.userId} />
|
||||
),
|
||||
|
@ -132,7 +132,7 @@ export default class UserProvider extends AutocompleteProvider {
|
|||
|
||||
renderCompletions(completions: [React.Component]): ?React.Component {
|
||||
return <div className="mx_Autocomplete_Completion_container_pill mx_Autocomplete_Completion_container_truncate">
|
||||
{completions}
|
||||
{ completions }
|
||||
</div>;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,9 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var classNames = require('classnames');
|
||||
var React = require('react');
|
||||
var ReactDOM = require('react-dom');
|
||||
const classNames = require('classnames');
|
||||
const React = require('react');
|
||||
const ReactDOM = require('react-dom');
|
||||
|
||||
// Shamelessly ripped off Modal.js. There's probably a better way
|
||||
// of doing reusable widgets like dialog boxes & menus where we go and
|
||||
|
@ -36,7 +36,7 @@ module.exports = {
|
|||
},
|
||||
|
||||
getOrCreateContainer: function() {
|
||||
var container = document.getElementById(this.ContextualMenuContainerId);
|
||||
let container = document.getElementById(this.ContextualMenuContainerId);
|
||||
|
||||
if (!container) {
|
||||
container = document.createElement("div");
|
||||
|
@ -48,9 +48,9 @@ module.exports = {
|
|||
},
|
||||
|
||||
createMenu: function(Element, props) {
|
||||
var self = this;
|
||||
const self = this;
|
||||
|
||||
var closeMenu = function() {
|
||||
const closeMenu = function() {
|
||||
ReactDOM.unmountComponentAtNode(self.getOrCreateContainer());
|
||||
|
||||
if (props && props.onFinished) {
|
||||
|
@ -58,17 +58,17 @@ module.exports = {
|
|||
}
|
||||
};
|
||||
|
||||
var position = {
|
||||
const position = {
|
||||
top: props.top,
|
||||
};
|
||||
|
||||
var chevronOffset = {};
|
||||
const chevronOffset = {};
|
||||
if (props.chevronOffset) {
|
||||
chevronOffset.top = props.chevronOffset;
|
||||
}
|
||||
|
||||
// To override the default chevron colour, if it's been set
|
||||
var chevronCSS = "";
|
||||
let chevronCSS = "";
|
||||
if (props.menuColour) {
|
||||
chevronCSS = `
|
||||
.mx_ContextualMenu_chevron_left:after {
|
||||
|
@ -81,7 +81,7 @@ module.exports = {
|
|||
`;
|
||||
}
|
||||
|
||||
var chevron = null;
|
||||
let chevron = null;
|
||||
if (props.left) {
|
||||
chevron = <div style={chevronOffset} className="mx_ContextualMenu_chevron_left"></div>;
|
||||
position.left = props.left;
|
||||
|
@ -90,15 +90,15 @@ module.exports = {
|
|||
position.right = props.right;
|
||||
}
|
||||
|
||||
var className = 'mx_ContextualMenu_wrapper';
|
||||
const className = 'mx_ContextualMenu_wrapper';
|
||||
|
||||
var menuClasses = classNames({
|
||||
const menuClasses = classNames({
|
||||
'mx_ContextualMenu': true,
|
||||
'mx_ContextualMenu_left': props.left,
|
||||
'mx_ContextualMenu_right': !props.left,
|
||||
});
|
||||
|
||||
var menuStyle = {};
|
||||
const menuStyle = {};
|
||||
if (props.menuWidth) {
|
||||
menuStyle.width = props.menuWidth;
|
||||
}
|
||||
|
@ -113,14 +113,14 @@ module.exports = {
|
|||
|
||||
// FIXME: If a menu uses getDefaultProps it clobbers the onFinished
|
||||
// property set here so you can't close the menu from a button click!
|
||||
var menu = (
|
||||
const menu = (
|
||||
<div className={className} style={position}>
|
||||
<div className={menuClasses} style={menuStyle}>
|
||||
{chevron}
|
||||
<Element {...props} onFinished={closeMenu}/>
|
||||
{ chevron }
|
||||
<Element {...props} onFinished={closeMenu} />
|
||||
</div>
|
||||
<div className="mx_ContextualMenu_background" onClick={closeMenu}></div>
|
||||
<style>{chevronCSS}</style>
|
||||
<style>{ chevronCSS }</style>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onCreateRoom: function() {
|
||||
var options = {};
|
||||
const options = {};
|
||||
|
||||
if (this.state.room_name) {
|
||||
options.name = this.state.room_name;
|
||||
|
@ -79,14 +79,14 @@ module.exports = React.createClass({
|
|||
{
|
||||
type: "m.room.join_rules",
|
||||
content: {
|
||||
"join_rule": this.state.is_private ? "invite" : "public"
|
||||
}
|
||||
"join_rule": this.state.is_private ? "invite" : "public",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "m.room.history_visibility",
|
||||
content: {
|
||||
"history_visibility": this.state.share_history ? "shared" : "invited"
|
||||
}
|
||||
"history_visibility": this.state.share_history ? "shared" : "invited",
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -94,19 +94,19 @@ module.exports = React.createClass({
|
|||
|
||||
options.invite = this.state.invited_users;
|
||||
|
||||
var alias = this.getAliasLocalpart();
|
||||
const alias = this.getAliasLocalpart();
|
||||
if (alias) {
|
||||
options.room_alias_name = alias;
|
||||
}
|
||||
|
||||
var cli = MatrixClientPeg.get();
|
||||
const cli = MatrixClientPeg.get();
|
||||
if (!cli) {
|
||||
// TODO: Error.
|
||||
console.error("Cannot create room: No matrix client.");
|
||||
return;
|
||||
}
|
||||
|
||||
var deferred = cli.createRoom(options);
|
||||
const deferred = cli.createRoom(options);
|
||||
|
||||
if (this.state.encrypt) {
|
||||
// TODO
|
||||
|
@ -116,7 +116,7 @@ module.exports = React.createClass({
|
|||
phase: this.phases.CREATING,
|
||||
});
|
||||
|
||||
var self = this;
|
||||
const self = this;
|
||||
|
||||
deferred.then(function(resp) {
|
||||
self.setState({
|
||||
|
@ -209,7 +209,7 @@ module.exports = React.createClass({
|
|||
|
||||
onAliasChanged: function(alias) {
|
||||
this.setState({
|
||||
alias: alias
|
||||
alias: alias,
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -220,64 +220,64 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var curr_phase = this.state.phase;
|
||||
const curr_phase = this.state.phase;
|
||||
if (curr_phase == this.phases.CREATING) {
|
||||
var Loader = sdk.getComponent("elements.Spinner");
|
||||
const Loader = sdk.getComponent("elements.Spinner");
|
||||
return (
|
||||
<Loader/>
|
||||
<Loader />
|
||||
);
|
||||
} else {
|
||||
var error_box = "";
|
||||
let error_box = "";
|
||||
if (curr_phase == this.phases.ERROR) {
|
||||
error_box = (
|
||||
<div className="mx_Error">
|
||||
{_t('An error occurred: %(error_string)s', {error_string: this.state.error_string})}
|
||||
{ _t('An error occurred: %(error_string)s', {error_string: this.state.error_string}) }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
var CreateRoomButton = sdk.getComponent("create_room.CreateRoomButton");
|
||||
var RoomAlias = sdk.getComponent("create_room.RoomAlias");
|
||||
var Presets = sdk.getComponent("create_room.Presets");
|
||||
var UserSelector = sdk.getComponent("elements.UserSelector");
|
||||
var SimpleRoomHeader = sdk.getComponent("rooms.SimpleRoomHeader");
|
||||
const CreateRoomButton = sdk.getComponent("create_room.CreateRoomButton");
|
||||
const RoomAlias = sdk.getComponent("create_room.RoomAlias");
|
||||
const Presets = sdk.getComponent("create_room.Presets");
|
||||
const UserSelector = sdk.getComponent("elements.UserSelector");
|
||||
const SimpleRoomHeader = sdk.getComponent("rooms.SimpleRoomHeader");
|
||||
|
||||
var domain = MatrixClientPeg.get().getDomain();
|
||||
const domain = MatrixClientPeg.get().getDomain();
|
||||
|
||||
return (
|
||||
<div className="mx_CreateRoom">
|
||||
<SimpleRoomHeader title={_t("Create Room")} collapsedRhs={ this.props.collapsedRhs }/>
|
||||
<SimpleRoomHeader title={_t("Create Room")} collapsedRhs={this.props.collapsedRhs} />
|
||||
<div className="mx_CreateRoom_body">
|
||||
<input type="text" ref="room_name" value={this.state.room_name} onChange={this.onNameChange} placeholder={_t('Name')}/> <br />
|
||||
<textarea className="mx_CreateRoom_description" ref="topic" value={this.state.topic} onChange={this.onTopicChange} placeholder={_t('Topic')}/> <br />
|
||||
<RoomAlias ref="alias" alias={this.state.alias} homeserver={ domain } onChange={this.onAliasChanged}/> <br />
|
||||
<UserSelector ref="user_selector" selected_users={this.state.invited_users} onChange={this.onInviteChanged}/> <br />
|
||||
<Presets ref="presets" onChange={this.onPresetChanged} preset={this.state.preset}/> <br />
|
||||
<input type="text" ref="room_name" value={this.state.room_name} onChange={this.onNameChange} placeholder={_t('Name')} /> <br />
|
||||
<textarea className="mx_CreateRoom_description" ref="topic" value={this.state.topic} onChange={this.onTopicChange} placeholder={_t('Topic')} /> <br />
|
||||
<RoomAlias ref="alias" alias={this.state.alias} homeserver={domain} onChange={this.onAliasChanged} /> <br />
|
||||
<UserSelector ref="user_selector" selected_users={this.state.invited_users} onChange={this.onInviteChanged} /> <br />
|
||||
<Presets ref="presets" onChange={this.onPresetChanged} preset={this.state.preset} /> <br />
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" ref="is_private" checked={this.state.is_private} onChange={this.onPrivateChanged}/>
|
||||
{_t('Make this room private')}
|
||||
<input type="checkbox" ref="is_private" checked={this.state.is_private} onChange={this.onPrivateChanged} />
|
||||
{ _t('Make this room private') }
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" ref="share_history" checked={this.state.share_history} onChange={this.onShareHistoryChanged}/>
|
||||
{_t('Share message history with new users')}
|
||||
<input type="checkbox" ref="share_history" checked={this.state.share_history} onChange={this.onShareHistoryChanged} />
|
||||
{ _t('Share message history with new users') }
|
||||
</label>
|
||||
</div>
|
||||
<div className="mx_CreateRoom_encrypt">
|
||||
<label>
|
||||
<input type="checkbox" ref="encrypt" checked={this.state.encrypt} onChange={this.onEncryptChanged}/>
|
||||
{_t('Encrypt room')}
|
||||
<input type="checkbox" ref="encrypt" checked={this.state.encrypt} onChange={this.onEncryptChanged} />
|
||||
{ _t('Encrypt room') }
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<CreateRoomButton onCreateRoom={this.onCreateRoom} /> <br />
|
||||
</div>
|
||||
{error_box}
|
||||
{ error_box }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -24,7 +24,7 @@ import { _t, _tJsx } from '../../languageHandler';
|
|||
/*
|
||||
* Component which shows the filtered file using a TimelinePanel
|
||||
*/
|
||||
var FilePanel = React.createClass({
|
||||
const FilePanel = React.createClass({
|
||||
displayName: 'FilePanel',
|
||||
|
||||
propTypes: {
|
||||
|
@ -55,33 +55,33 @@ var FilePanel = React.createClass({
|
|||
},
|
||||
|
||||
updateTimelineSet: function(roomId) {
|
||||
var client = MatrixClientPeg.get();
|
||||
var room = client.getRoom(roomId);
|
||||
const client = MatrixClientPeg.get();
|
||||
const room = client.getRoom(roomId);
|
||||
|
||||
this.noRoom = !room;
|
||||
|
||||
if (room) {
|
||||
var filter = new Matrix.Filter(client.credentials.userId);
|
||||
const filter = new Matrix.Filter(client.credentials.userId);
|
||||
filter.setDefinition(
|
||||
{
|
||||
"room": {
|
||||
"timeline": {
|
||||
"contains_url": true
|
||||
"contains_url": true,
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// FIXME: we shouldn't be doing this every time we change room - see comment above.
|
||||
client.getOrCreateFilter("FILTER_FILES_" + client.credentials.userId, filter).then(
|
||||
(filterId)=>{
|
||||
filter.filterId = filterId;
|
||||
var timelineSet = room.getOrCreateFilteredTimelineSet(filter);
|
||||
const timelineSet = room.getOrCreateFilteredTimelineSet(filter);
|
||||
this.setState({ timelineSet: timelineSet });
|
||||
},
|
||||
(error)=>{
|
||||
console.error("Failed to get or create file panel filter", error);
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
console.error("Failed to add filtered timelineSet for FilePanel as no room!");
|
||||
|
@ -92,18 +92,18 @@ var FilePanel = React.createClass({
|
|||
if (MatrixClientPeg.get().isGuest()) {
|
||||
return <div className="mx_FilePanel mx_RoomView_messageListWrapper">
|
||||
<div className="mx_RoomView_empty">
|
||||
{_tJsx("You must <a>register</a> to use this functionality", /<a>(.*?)<\/a>/, (sub) => <a href="#/register" key="sub">{sub}</a>)}
|
||||
{ _tJsx("You must <a>register</a> to use this functionality", /<a>(.*?)<\/a>/, (sub) => <a href="#/register" key="sub">{ sub }</a>) }
|
||||
</div>
|
||||
</div>;
|
||||
} else if (this.noRoom) {
|
||||
return <div className="mx_FilePanel mx_RoomView_messageListWrapper">
|
||||
<div className="mx_RoomView_empty">{_t("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>;
|
||||
}
|
||||
|
||||
// wrap a TimelinePanel with the jump-to-event bits turned off.
|
||||
var TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
||||
var Loader = sdk.getComponent("elements.Spinner");
|
||||
const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
||||
const Loader = sdk.getComponent("elements.Spinner");
|
||||
|
||||
if (this.state.timelineSet) {
|
||||
// console.log("rendering TimelinePanel for timelineSet " + this.state.timelineSet.room.roomId + " " +
|
||||
|
@ -114,17 +114,16 @@ var FilePanel = React.createClass({
|
|||
manageReadReceipts={false}
|
||||
manageReadMarkers={false}
|
||||
timelineSet={this.state.timelineSet}
|
||||
showUrlPreview = { false }
|
||||
showUrlPreview = {false}
|
||||
tileShape="file_grid"
|
||||
opacity={ this.props.opacity }
|
||||
opacity={this.props.opacity}
|
||||
empty={_t('There are no visible files in this room')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return (
|
||||
<div className="mx_FilePanel">
|
||||
<Loader/>
|
||||
<Loader />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ export default React.createClass({
|
|||
|
||||
const msg = error.message || error.toString();
|
||||
this.setState({
|
||||
errorText: msg
|
||||
errorText: msg,
|
||||
});
|
||||
}).done();
|
||||
|
||||
|
@ -207,7 +207,7 @@ export default React.createClass({
|
|||
if (this.state.errorText) {
|
||||
error = (
|
||||
<div className="error">
|
||||
{this.state.errorText}
|
||||
{ this.state.errorText }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -215,8 +215,8 @@ export default React.createClass({
|
|||
return (
|
||||
<div>
|
||||
<div>
|
||||
{this._renderCurrentStage()}
|
||||
{error}
|
||||
{ this._renderCurrentStage() }
|
||||
{ error }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -164,7 +164,7 @@ export default React.createClass({
|
|||
case KeyCode.UP:
|
||||
case KeyCode.DOWN:
|
||||
if (ev.altKey && !ev.shiftKey && !ev.ctrlKey && !ev.metaKey) {
|
||||
let action = ev.keyCode == KeyCode.UP ?
|
||||
const action = ev.keyCode == KeyCode.UP ?
|
||||
'view_prev_room' : 'view_next_room';
|
||||
dis.dispatch({action: action});
|
||||
handled = true;
|
||||
|
@ -206,8 +206,7 @@ export default React.createClass({
|
|||
_onScrollKeyPressed: function(ev) {
|
||||
if (this.refs.roomView) {
|
||||
this.refs.roomView.handleScrollKey(ev);
|
||||
}
|
||||
else if (this.refs.roomDirectory) {
|
||||
} else if (this.refs.roomDirectory) {
|
||||
this.refs.roomDirectory.handleScrollKey(ev);
|
||||
}
|
||||
},
|
||||
|
@ -255,7 +254,7 @@ export default React.createClass({
|
|||
referralBaseUrl={this.props.config.referralBaseUrl}
|
||||
teamToken={this.props.teamToken}
|
||||
/>;
|
||||
if (!this.props.collapseRhs) right_panel = <RightPanel opacity={this.props.rightOpacity}/>;
|
||||
if (!this.props.collapseRhs) right_panel = <RightPanel opacity={this.props.rightOpacity} />;
|
||||
break;
|
||||
|
||||
case PageTypes.MyGroups:
|
||||
|
@ -267,7 +266,7 @@ export default React.createClass({
|
|||
onRoomCreated={this.props.onRoomCreated}
|
||||
collapsedRhs={this.props.collapseRhs}
|
||||
/>;
|
||||
if (!this.props.collapseRhs) right_panel = <RightPanel opacity={this.props.rightOpacity}/>;
|
||||
if (!this.props.collapseRhs) right_panel = <RightPanel opacity={this.props.rightOpacity} />;
|
||||
break;
|
||||
|
||||
case PageTypes.RoomDirectory:
|
||||
|
@ -320,7 +319,7 @@ export default React.createClass({
|
|||
topBar = <MatrixToolbar />;
|
||||
}
|
||||
|
||||
var bodyClasses = 'mx_MatrixChat';
|
||||
let bodyClasses = 'mx_MatrixChat';
|
||||
if (topBar) {
|
||||
bodyClasses += ' mx_MatrixChat_toolbarShowing';
|
||||
}
|
||||
|
@ -330,7 +329,7 @@ export default React.createClass({
|
|||
|
||||
return (
|
||||
<div className='mx_MatrixChat_wrapper'>
|
||||
{topBar}
|
||||
{ topBar }
|
||||
<div className={bodyClasses}>
|
||||
<LeftPanel
|
||||
selectedRoom={this.props.currentRoomId}
|
||||
|
@ -338,9 +337,9 @@ export default React.createClass({
|
|||
opacity={this.props.leftOpacity}
|
||||
/>
|
||||
<main className='mx_MatrixChat_middlePanel'>
|
||||
{page_element}
|
||||
{ page_element }
|
||||
</main>
|
||||
{right_panel}
|
||||
{ right_panel }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -154,15 +154,15 @@ module.exports = React.createClass({
|
|||
// 0: read marker is within the window
|
||||
// +1: read marker is below the window
|
||||
getReadMarkerPosition: function() {
|
||||
var readMarker = this.refs.readMarkerNode;
|
||||
var messageWrapper = this.refs.scrollPanel;
|
||||
const readMarker = this.refs.readMarkerNode;
|
||||
const messageWrapper = this.refs.scrollPanel;
|
||||
|
||||
if (!readMarker || !messageWrapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var wrapperRect = ReactDOM.findDOMNode(messageWrapper).getBoundingClientRect();
|
||||
var readMarkerRect = readMarker.getBoundingClientRect();
|
||||
const wrapperRect = ReactDOM.findDOMNode(messageWrapper).getBoundingClientRect();
|
||||
const readMarkerRect = readMarker.getBoundingClientRect();
|
||||
|
||||
// the read-marker pretends to have zero height when it is actually
|
||||
// two pixels high; +2 here to account for that.
|
||||
|
@ -262,7 +262,7 @@ module.exports = React.createClass({
|
|||
|
||||
this.eventNodes = {};
|
||||
|
||||
var i;
|
||||
let i;
|
||||
|
||||
// first figure out which is the last event in the list which we're
|
||||
// actually going to show; this allows us to behave slightly
|
||||
|
@ -272,9 +272,9 @@ module.exports = React.createClass({
|
|||
// a local echo, to manage the read-marker.
|
||||
let lastShownEvent;
|
||||
|
||||
var lastShownNonLocalEchoIndex = -1;
|
||||
let lastShownNonLocalEchoIndex = -1;
|
||||
for (i = this.props.events.length-1; i >= 0; i--) {
|
||||
var mxEv = this.props.events[i];
|
||||
const mxEv = this.props.events[i];
|
||||
if (!this._shouldShowEvent(mxEv)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -292,12 +292,12 @@ module.exports = React.createClass({
|
|||
break;
|
||||
}
|
||||
|
||||
var ret = [];
|
||||
const ret = [];
|
||||
|
||||
var prevEvent = null; // the last event we showed
|
||||
let prevEvent = null; // the last event we showed
|
||||
|
||||
// assume there is no read marker until proven otherwise
|
||||
var readMarkerVisible = false;
|
||||
let readMarkerVisible = false;
|
||||
|
||||
// if the readmarker has moved, cancel any active ghost.
|
||||
if (this.currentReadMarkerEventId && this.props.readMarkerEventId &&
|
||||
|
@ -309,16 +309,16 @@ module.exports = React.createClass({
|
|||
const isMembershipChange = (e) => e.getType() === 'm.room.member';
|
||||
|
||||
for (i = 0; i < this.props.events.length; i++) {
|
||||
let mxEv = this.props.events[i];
|
||||
let eventId = mxEv.getId();
|
||||
let last = (mxEv === lastShownEvent);
|
||||
const mxEv = this.props.events[i];
|
||||
const eventId = mxEv.getId();
|
||||
const last = (mxEv === lastShownEvent);
|
||||
|
||||
const wantTile = this._shouldShowEvent(mxEv);
|
||||
|
||||
// Wrap consecutive member events in a ListSummary, ignore if redacted
|
||||
if (isMembershipChange(mxEv) && wantTile) {
|
||||
let readMarkerInMels = false;
|
||||
let ts1 = mxEv.getTs();
|
||||
const ts1 = mxEv.getTs();
|
||||
// Ensure that the key of the MemberEventListSummary does not change with new
|
||||
// member events. This will prevent it from being re-created unnecessarily, and
|
||||
// instead will allow new props to be provided. In turn, the shouldComponentUpdate
|
||||
|
@ -330,7 +330,7 @@ module.exports = React.createClass({
|
|||
const key = "membereventlistsummary-" + (prevEvent ? mxEv.getId() : "initial");
|
||||
|
||||
if (this._wantsDateSeparator(prevEvent, mxEv.getDate())) {
|
||||
let dateSeparator = <li key={ts1+'~'}><DateSeparator key={ts1+'~'} ts={ts1} showTwelveHour={this.props.isTwelveHour}/></li>;
|
||||
const dateSeparator = <li key={ts1+'~'}><DateSeparator key={ts1+'~'} ts={ts1} showTwelveHour={this.props.isTwelveHour} /></li>;
|
||||
ret.push(dateSeparator);
|
||||
}
|
||||
|
||||
|
@ -339,7 +339,7 @@ module.exports = React.createClass({
|
|||
readMarkerInMels = true;
|
||||
}
|
||||
|
||||
let summarisedEvents = [mxEv];
|
||||
const summarisedEvents = [mxEv];
|
||||
for (;i + 1 < this.props.events.length; i++) {
|
||||
const collapsedMxEv = this.props.events[i + 1];
|
||||
|
||||
|
@ -390,7 +390,7 @@ module.exports = React.createClass({
|
|||
onToggle={this._onWidgetLoad} // Update scroll state
|
||||
startExpanded={highlightInMels}
|
||||
>
|
||||
{eventTiles}
|
||||
{ eventTiles }
|
||||
</MemberEventListSummary>);
|
||||
|
||||
if (readMarkerInMels) {
|
||||
|
@ -408,7 +408,7 @@ module.exports = React.createClass({
|
|||
prevEvent = mxEv;
|
||||
}
|
||||
|
||||
var isVisibleReadMarker = false;
|
||||
let isVisibleReadMarker = false;
|
||||
|
||||
if (eventId == this.props.readMarkerEventId) {
|
||||
var visible = this.props.readMarkerVisible;
|
||||
|
@ -448,10 +448,10 @@ module.exports = React.createClass({
|
|||
_getTilesForEvent: function(prevEvent, mxEv, last) {
|
||||
const EventTile = sdk.getComponent('rooms.EventTile');
|
||||
const DateSeparator = sdk.getComponent('messages.DateSeparator');
|
||||
var ret = [];
|
||||
const ret = [];
|
||||
|
||||
// is this a continuation of the previous message?
|
||||
var continuation = false;
|
||||
let continuation = false;
|
||||
|
||||
if (prevEvent !== null
|
||||
&& prevEvent.sender && mxEv.sender
|
||||
|
@ -476,8 +476,8 @@ module.exports = React.createClass({
|
|||
|
||||
// local echoes have a fake date, which could even be yesterday. Treat them
|
||||
// as 'today' for the date separators.
|
||||
var ts1 = mxEv.getTs();
|
||||
var eventDate = mxEv.getDate();
|
||||
let ts1 = mxEv.getTs();
|
||||
let eventDate = mxEv.getDate();
|
||||
if (mxEv.status) {
|
||||
eventDate = new Date();
|
||||
ts1 = eventDate.getTime();
|
||||
|
@ -485,19 +485,19 @@ module.exports = React.createClass({
|
|||
|
||||
// do we need a date separator since the last event?
|
||||
if (this._wantsDateSeparator(prevEvent, eventDate)) {
|
||||
var dateSeparator = <li key={ts1}><DateSeparator key={ts1} ts={ts1} showTwelveHour={this.props.isTwelveHour}/></li>;
|
||||
const dateSeparator = <li key={ts1}><DateSeparator key={ts1} ts={ts1} showTwelveHour={this.props.isTwelveHour} /></li>;
|
||||
ret.push(dateSeparator);
|
||||
continuation = false;
|
||||
}
|
||||
|
||||
var eventId = mxEv.getId();
|
||||
var highlight = (eventId == this.props.highlightedEventId);
|
||||
const eventId = mxEv.getId();
|
||||
const highlight = (eventId == this.props.highlightedEventId);
|
||||
|
||||
// we can't use local echoes as scroll tokens, because their event IDs change.
|
||||
// Local echos have a send "status".
|
||||
var scrollToken = mxEv.status ? undefined : eventId;
|
||||
const scrollToken = mxEv.status ? undefined : eventId;
|
||||
|
||||
var readReceipts;
|
||||
let readReceipts;
|
||||
if (this.props.showReadReceipts) {
|
||||
readReceipts = this._getReadReceiptsForEvent(mxEv);
|
||||
}
|
||||
|
@ -515,8 +515,8 @@ module.exports = React.createClass({
|
|||
eventSendStatus={mxEv.status}
|
||||
tileShape={this.props.tileShape}
|
||||
isTwelveHour={this.props.isTwelveHour}
|
||||
last={last} isSelectedEvent={highlight}/>
|
||||
</li>
|
||||
last={last} isSelectedEvent={highlight} />
|
||||
</li>,
|
||||
);
|
||||
|
||||
return ret;
|
||||
|
@ -551,7 +551,7 @@ module.exports = React.createClass({
|
|||
if (!room) {
|
||||
return null;
|
||||
}
|
||||
let receipts = [];
|
||||
const receipts = [];
|
||||
room.getReceiptsForEvent(event).forEach((r) => {
|
||||
if (!r.userId || r.type !== "m.read" || r.userId === myUserId) {
|
||||
return; // ignore non-read receipts and receipts from self.
|
||||
|
@ -559,7 +559,7 @@ module.exports = React.createClass({
|
|||
if (MatrixClientPeg.get().isUserIgnored(r.userId)) {
|
||||
return; // ignore ignored users
|
||||
}
|
||||
let member = room.getMember(r.userId);
|
||||
const member = room.getMember(r.userId);
|
||||
if (!member) {
|
||||
return; // ignore unknown user IDs
|
||||
}
|
||||
|
@ -575,7 +575,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_getReadMarkerTile: function(visible) {
|
||||
var hr;
|
||||
let hr;
|
||||
if (visible) {
|
||||
hr = <hr className="mx_RoomView_myReadMarker"
|
||||
style={{opacity: 1, width: '99%'}}
|
||||
|
@ -585,7 +585,7 @@ module.exports = React.createClass({
|
|||
return (
|
||||
<li key="_readupto" ref="readMarkerNode"
|
||||
className="mx_RoomView_myReadMarker_container">
|
||||
{hr}
|
||||
{ hr }
|
||||
</li>
|
||||
);
|
||||
},
|
||||
|
@ -604,7 +604,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_getReadMarkerGhostTile: function() {
|
||||
var hr = <hr className="mx_RoomView_myReadMarker"
|
||||
const hr = <hr className="mx_RoomView_myReadMarker"
|
||||
style={{opacity: 1, width: '99%'}}
|
||||
ref={this._startAnimation}
|
||||
/>;
|
||||
|
@ -615,7 +615,7 @@ module.exports = React.createClass({
|
|||
return (
|
||||
<li key={"_readuptoghost_"+this.currentGhostEventId}
|
||||
className="mx_RoomView_myReadMarker_container">
|
||||
{hr}
|
||||
{ hr }
|
||||
</li>
|
||||
);
|
||||
},
|
||||
|
@ -627,7 +627,7 @@ module.exports = React.createClass({
|
|||
// once dynamic content in the events load, make the scrollPanel check the
|
||||
// scroll offsets.
|
||||
_onWidgetLoad: function() {
|
||||
var scrollPanel = this.refs.scrollPanel;
|
||||
const scrollPanel = this.refs.scrollPanel;
|
||||
if (scrollPanel) {
|
||||
scrollPanel.forceUpdate();
|
||||
}
|
||||
|
@ -638,9 +638,9 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var ScrollPanel = sdk.getComponent("structures.ScrollPanel");
|
||||
var Spinner = sdk.getComponent("elements.Spinner");
|
||||
var topSpinner, bottomSpinner;
|
||||
const ScrollPanel = sdk.getComponent("structures.ScrollPanel");
|
||||
const Spinner = sdk.getComponent("elements.Spinner");
|
||||
let topSpinner, bottomSpinner;
|
||||
if (this.props.backPaginating) {
|
||||
topSpinner = <li key="_topSpinner"><Spinner /></li>;
|
||||
}
|
||||
|
@ -648,25 +648,25 @@ module.exports = React.createClass({
|
|||
bottomSpinner = <li key="_bottomSpinner"><Spinner /></li>;
|
||||
}
|
||||
|
||||
var style = this.props.hidden ? { display: 'none' } : {};
|
||||
const style = this.props.hidden ? { display: 'none' } : {};
|
||||
style.opacity = this.props.opacity;
|
||||
|
||||
var className = this.props.className + " mx_fadable";
|
||||
let className = this.props.className + " mx_fadable";
|
||||
if (this.props.alwaysShowTimestamps) {
|
||||
className += " mx_MessagePanel_alwaysShowTimestamps";
|
||||
}
|
||||
|
||||
return (
|
||||
<ScrollPanel ref="scrollPanel" className={ className }
|
||||
onScroll={ this.props.onScroll }
|
||||
onResize={ this.onResize }
|
||||
onFillRequest={ this.props.onFillRequest }
|
||||
onUnfillRequest={ this.props.onUnfillRequest }
|
||||
style={ style }
|
||||
stickyBottom={ this.props.stickyBottom }>
|
||||
{topSpinner}
|
||||
{this._getEventTiles()}
|
||||
{bottomSpinner}
|
||||
<ScrollPanel ref="scrollPanel" className={className}
|
||||
onScroll={this.props.onScroll}
|
||||
onResize={this.onResize}
|
||||
onFillRequest={this.props.onFillRequest}
|
||||
onUnfillRequest={this.props.onUnfillRequest}
|
||||
style={style}
|
||||
stickyBottom={this.props.stickyBottom}>
|
||||
{ topSpinner }
|
||||
{ this._getEventTiles() }
|
||||
{ bottomSpinner }
|
||||
</ScrollPanel>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -14,18 +14,18 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
var React = require('react');
|
||||
var ReactDOM = require("react-dom");
|
||||
const React = require('react');
|
||||
const ReactDOM = require("react-dom");
|
||||
import { _t } from '../../languageHandler';
|
||||
var Matrix = require("matrix-js-sdk");
|
||||
var sdk = require('../../index');
|
||||
var MatrixClientPeg = require("../../MatrixClientPeg");
|
||||
var dis = require("../../dispatcher");
|
||||
const Matrix = require("matrix-js-sdk");
|
||||
const sdk = require('../../index');
|
||||
const MatrixClientPeg = require("../../MatrixClientPeg");
|
||||
const dis = require("../../dispatcher");
|
||||
|
||||
/*
|
||||
* Component which shows the global notification list using a TimelinePanel
|
||||
*/
|
||||
var NotificationPanel = React.createClass({
|
||||
const NotificationPanel = React.createClass({
|
||||
displayName: 'NotificationPanel',
|
||||
|
||||
propTypes: {
|
||||
|
@ -33,10 +33,10 @@ var NotificationPanel = React.createClass({
|
|||
|
||||
render: function() {
|
||||
// wrap a TimelinePanel with the jump-to-event bits turned off.
|
||||
var TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
||||
var Loader = sdk.getComponent("elements.Spinner");
|
||||
const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
||||
const Loader = sdk.getComponent("elements.Spinner");
|
||||
|
||||
var timelineSet = MatrixClientPeg.get().getNotifTimelineSet();
|
||||
const timelineSet = MatrixClientPeg.get().getNotifTimelineSet();
|
||||
if (timelineSet) {
|
||||
return (
|
||||
<TimelinePanel key={"NotificationPanel_" + this.props.roomId}
|
||||
|
@ -44,18 +44,17 @@ var NotificationPanel = React.createClass({
|
|||
manageReadReceipts={false}
|
||||
manageReadMarkers={false}
|
||||
timelineSet={timelineSet}
|
||||
showUrlPreview = { false }
|
||||
opacity={ this.props.opacity }
|
||||
showUrlPreview = {false}
|
||||
opacity={this.props.opacity}
|
||||
tileShape="notif"
|
||||
empty={ _t('You have no visible notifications') }
|
||||
empty={_t('You have no visible notifications')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
console.error("No notifTimelineSet available!");
|
||||
return (
|
||||
<div className="mx_NotificationPanel">
|
||||
<Loader/>
|
||||
<Loader />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ module.exports = React.createClass({
|
|||
|
||||
componentWillUnmount: function() {
|
||||
// we may have entirely lost our client as we're logging out before clicking login on the guest bar...
|
||||
var client = MatrixClientPeg.get();
|
||||
const client = MatrixClientPeg.get();
|
||||
if (client) {
|
||||
client.removeListener("sync", this.onSyncStateChange);
|
||||
client.removeListener("RoomMember.typing", this.onRoomMemberTyping);
|
||||
|
@ -115,7 +115,7 @@ module.exports = React.createClass({
|
|||
return;
|
||||
}
|
||||
this.setState({
|
||||
syncState: state
|
||||
syncState: state,
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -126,7 +126,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
// Check whether current size is greater than 0, if yes call props.onVisible
|
||||
_checkSize: function () {
|
||||
_checkSize: function() {
|
||||
if (this.props.onVisible && this._getSize()) {
|
||||
this.props.onVisible();
|
||||
}
|
||||
|
@ -157,9 +157,9 @@ module.exports = React.createClass({
|
|||
if (this.props.numUnreadMessages) {
|
||||
return (
|
||||
<div className="mx_RoomStatusBar_scrollDownIndicator"
|
||||
onClick={ this.props.onScrollToBottomClick }>
|
||||
onClick={this.props.onScrollToBottomClick}>
|
||||
<img src="img/newmessages.svg" width="24" height="24"
|
||||
alt=""/>
|
||||
alt="" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -167,18 +167,18 @@ module.exports = React.createClass({
|
|||
if (!this.props.atEndOfLiveTimeline) {
|
||||
return (
|
||||
<div className="mx_RoomStatusBar_scrollDownIndicator"
|
||||
onClick={ this.props.onScrollToBottomClick }>
|
||||
onClick={this.props.onScrollToBottomClick}>
|
||||
<img src="img/scrolldown.svg" width="24" height="24"
|
||||
alt={ _t("Scroll to bottom of page") }
|
||||
title={ _t("Scroll to bottom of page") }/>
|
||||
alt={_t("Scroll to bottom of page")}
|
||||
title={_t("Scroll to bottom of page")} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.hasActiveCall) {
|
||||
var TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||
return (
|
||||
<TintableSvg src="img/sound-indicator.svg" width="23" height="20"/>
|
||||
<TintableSvg src="img/sound-indicator.svg" width="23" height="20" />
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ module.exports = React.createClass({
|
|||
if (wantPlaceholder) {
|
||||
return (
|
||||
<div className="mx_RoomStatusBar_typingIndicatorAvatars">
|
||||
{this._renderTypingIndicatorAvatars(this.props.whoIsTypingLimit)}
|
||||
{ this._renderTypingIndicatorAvatars(this.props.whoIsTypingLimit) }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -221,8 +221,8 @@ module.exports = React.createClass({
|
|||
if (othersCount > 0) {
|
||||
avatars.push(
|
||||
<span className="mx_RoomStatusBar_typingIndicatorRemaining" key="others">
|
||||
+{othersCount}
|
||||
</span>
|
||||
+{ othersCount }
|
||||
</span>,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -240,12 +240,12 @@ module.exports = React.createClass({
|
|||
if (this.state.syncState === "ERROR") {
|
||||
return (
|
||||
<div className="mx_RoomStatusBar_connectionLostBar">
|
||||
<img src="img/warning.svg" width="24" height="23" title="/!\ " alt="/!\ "/>
|
||||
<img src="img/warning.svg" width="24" height="23" title="/!\ " alt="/!\ " />
|
||||
<div className="mx_RoomStatusBar_connectionLostBar_title">
|
||||
{_t('Connectivity to the server has been lost.')}
|
||||
{ _t('Connectivity to the server has been lost.') }
|
||||
</div>
|
||||
<div className="mx_RoomStatusBar_connectionLostBar_desc">
|
||||
{_t('Sent messages will be stored until your connection has returned.')}
|
||||
{ _t('Sent messages will be stored until your connection has returned.') }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -254,18 +254,18 @@ module.exports = React.createClass({
|
|||
if (this.props.unsentMessageError) {
|
||||
return (
|
||||
<div className="mx_RoomStatusBar_connectionLostBar">
|
||||
<img src="img/warning.svg" width="24" height="23" title="/!\ " alt="/!\ "/>
|
||||
<img src="img/warning.svg" width="24" height="23" title="/!\ " alt="/!\ " />
|
||||
<div className="mx_RoomStatusBar_connectionLostBar_title">
|
||||
{ this.props.unsentMessageError }
|
||||
</div>
|
||||
<div className="mx_RoomStatusBar_connectionLostBar_desc">
|
||||
{_tJsx("<a>Resend all</a> or <a>cancel all</a> now. You can also select individual messages to resend or cancel.",
|
||||
{ _tJsx("<a>Resend all</a> or <a>cancel all</a> now. You can also select individual messages to resend or cancel.",
|
||||
[/<a>(.*?)<\/a>/, /<a>(.*?)<\/a>/],
|
||||
[
|
||||
(sub) => <a className="mx_RoomStatusBar_resend_link" key="resend" onClick={ this.props.onResendAllClick }>{sub}</a>,
|
||||
(sub) => <a className="mx_RoomStatusBar_resend_link" key="cancel" onClick={ this.props.onCancelAllClick }>{sub}</a>,
|
||||
]
|
||||
)}
|
||||
(sub) => <a className="mx_RoomStatusBar_resend_link" key="resend" onClick={this.props.onResendAllClick}>{ sub }</a>,
|
||||
(sub) => <a className="mx_RoomStatusBar_resend_link" key="cancel" onClick={this.props.onCancelAllClick}>{ sub }</a>,
|
||||
],
|
||||
) }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -275,24 +275,24 @@ module.exports = React.createClass({
|
|||
// set when you've scrolled up
|
||||
if (this.props.numUnreadMessages) {
|
||||
// MUST use var name "count" for pluralization to kick in
|
||||
var unreadMsgs = _t("%(count)s new messages", {count: this.props.numUnreadMessages});
|
||||
const unreadMsgs = _t("%(count)s new messages", {count: this.props.numUnreadMessages});
|
||||
|
||||
return (
|
||||
<div className="mx_RoomStatusBar_unreadMessagesBar"
|
||||
onClick={ this.props.onScrollToBottomClick }>
|
||||
{unreadMsgs}
|
||||
onClick={this.props.onScrollToBottomClick}>
|
||||
{ unreadMsgs }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const typingString = WhoIsTyping.whoIsTypingString(
|
||||
this.state.usersTyping,
|
||||
this.props.whoIsTypingLimit
|
||||
this.props.whoIsTypingLimit,
|
||||
);
|
||||
if (typingString) {
|
||||
return (
|
||||
<div className="mx_RoomStatusBar_typingBar">
|
||||
<EmojiText>{typingString}</EmojiText>
|
||||
<EmojiText>{ typingString }</EmojiText>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ module.exports = React.createClass({
|
|||
if (this.props.hasActiveCall) {
|
||||
return (
|
||||
<div className="mx_RoomStatusBar_callBar">
|
||||
<b>{_t('Active call')}</b>
|
||||
<b>{ _t('Active call') }</b>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -310,15 +310,15 @@ module.exports = React.createClass({
|
|||
|
||||
|
||||
render: function() {
|
||||
var content = this._getContent();
|
||||
var indicator = this._getIndicator(this.state.usersTyping.length > 0);
|
||||
const content = this._getContent();
|
||||
const indicator = this._getIndicator(this.state.usersTyping.length > 0);
|
||||
|
||||
return (
|
||||
<div className="mx_RoomStatusBar">
|
||||
<div className="mx_RoomStatusBar_indicator">
|
||||
{indicator}
|
||||
{ indicator }
|
||||
</div>
|
||||
{content}
|
||||
{ content }
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -22,25 +22,25 @@ limitations under the License.
|
|||
|
||||
import shouldHideEvent from "../../shouldHideEvent";
|
||||
|
||||
var React = require("react");
|
||||
var ReactDOM = require("react-dom");
|
||||
const React = require("react");
|
||||
const ReactDOM = require("react-dom");
|
||||
import Promise from 'bluebird';
|
||||
var classNames = require("classnames");
|
||||
var Matrix = require("matrix-js-sdk");
|
||||
const classNames = require("classnames");
|
||||
const Matrix = require("matrix-js-sdk");
|
||||
import { _t } from '../../languageHandler';
|
||||
|
||||
var UserSettingsStore = require('../../UserSettingsStore');
|
||||
var MatrixClientPeg = require("../../MatrixClientPeg");
|
||||
var ContentMessages = require("../../ContentMessages");
|
||||
var Modal = require("../../Modal");
|
||||
var sdk = require('../../index');
|
||||
var CallHandler = require('../../CallHandler');
|
||||
var Resend = require("../../Resend");
|
||||
var dis = require("../../dispatcher");
|
||||
var Tinter = require("../../Tinter");
|
||||
var rate_limited_func = require('../../ratelimitedfunc');
|
||||
var ObjectUtils = require('../../ObjectUtils');
|
||||
var Rooms = require('../../Rooms');
|
||||
const UserSettingsStore = require('../../UserSettingsStore');
|
||||
const MatrixClientPeg = require("../../MatrixClientPeg");
|
||||
const ContentMessages = require("../../ContentMessages");
|
||||
const Modal = require("../../Modal");
|
||||
const sdk = require('../../index');
|
||||
const CallHandler = require('../../CallHandler');
|
||||
const Resend = require("../../Resend");
|
||||
const dis = require("../../dispatcher");
|
||||
const Tinter = require("../../Tinter");
|
||||
const rate_limited_func = require('../../ratelimitedfunc');
|
||||
const ObjectUtils = require('../../ObjectUtils');
|
||||
const Rooms = require('../../Rooms');
|
||||
|
||||
import KeyCode from '../../KeyCode';
|
||||
|
||||
|
@ -49,7 +49,7 @@ import UserProvider from '../../autocomplete/UserProvider';
|
|||
import RoomViewStore from '../../stores/RoomViewStore';
|
||||
import RoomScrollStateStore from '../../stores/RoomScrollStateStore';
|
||||
|
||||
let DEBUG = false;
|
||||
const DEBUG = false;
|
||||
let debuglog = function() {};
|
||||
|
||||
const BROWSER_SUPPORTS_SANDBOX = 'sandbox' in document.createElement('iframe');
|
||||
|
@ -307,10 +307,10 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
var call = this._getCallForRoom();
|
||||
var callState = call ? call.call_state : "ended";
|
||||
const call = this._getCallForRoom();
|
||||
const callState = call ? call.call_state : "ended";
|
||||
this.setState({
|
||||
callState: callState
|
||||
callState: callState,
|
||||
});
|
||||
|
||||
this._updateConfCallNotification();
|
||||
|
@ -327,9 +327,8 @@ module.exports = React.createClass({
|
|||
this.state.room.getJoinedMembers().length == 1 &&
|
||||
this.state.room.getLiveTimeline() &&
|
||||
this.state.room.getLiveTimeline().getEvents() &&
|
||||
this.state.room.getLiveTimeline().getEvents().length <= 6)
|
||||
{
|
||||
var inviteBox = document.getElementById("mx_SearchableEntityList_query");
|
||||
this.state.room.getLiveTimeline().getEvents().length <= 6) {
|
||||
const inviteBox = document.getElementById("mx_SearchableEntityList_query");
|
||||
setTimeout(function() {
|
||||
if (inviteBox) {
|
||||
inviteBox.focus();
|
||||
|
@ -345,7 +344,7 @@ module.exports = React.createClass({
|
|||
|
||||
componentDidUpdate: function() {
|
||||
if (this.refs.roomView) {
|
||||
var roomView = ReactDOM.findDOMNode(this.refs.roomView);
|
||||
const roomView = ReactDOM.findDOMNode(this.refs.roomView);
|
||||
if (!roomView.ondrop) {
|
||||
roomView.addEventListener('drop', this.onDrop);
|
||||
roomView.addEventListener('dragover', this.onDragOver);
|
||||
|
@ -372,7 +371,7 @@ module.exports = React.createClass({
|
|||
// is really just for hygiene - we're going to be
|
||||
// deleted anyway, so it doesn't matter if the event listeners
|
||||
// don't get cleaned up.
|
||||
var roomView = ReactDOM.findDOMNode(this.refs.roomView);
|
||||
const roomView = ReactDOM.findDOMNode(this.refs.roomView);
|
||||
roomView.removeEventListener('drop', this.onDrop);
|
||||
roomView.removeEventListener('dragover', this.onDragOver);
|
||||
roomView.removeEventListener('dragleave', this.onDragLeaveOrEnd);
|
||||
|
@ -478,8 +477,7 @@ module.exports = React.createClass({
|
|||
|
||||
if (call) {
|
||||
callState = call.call_state;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
callState = "ended";
|
||||
}
|
||||
|
||||
|
@ -591,17 +589,17 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_calculatePeekRules: function(room) {
|
||||
var guestAccessEvent = room.currentState.getStateEvents("m.room.guest_access", "");
|
||||
const guestAccessEvent = room.currentState.getStateEvents("m.room.guest_access", "");
|
||||
if (guestAccessEvent && guestAccessEvent.getContent().guest_access === "can_join") {
|
||||
this.setState({
|
||||
guestsCanJoin: true
|
||||
guestsCanJoin: true,
|
||||
});
|
||||
}
|
||||
|
||||
var historyVisibility = room.currentState.getStateEvents("m.room.history_visibility", "");
|
||||
const historyVisibility = room.currentState.getStateEvents("m.room.history_visibility", "");
|
||||
if (historyVisibility && historyVisibility.getContent().history_visibility === "world_readable") {
|
||||
this.setState({
|
||||
canPeek: true
|
||||
canPeek: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -610,35 +608,35 @@ module.exports = React.createClass({
|
|||
// console.log("_updatePreviewUrlVisibility");
|
||||
|
||||
// check our per-room overrides
|
||||
var roomPreviewUrls = room.getAccountData("org.matrix.room.preview_urls");
|
||||
const roomPreviewUrls = room.getAccountData("org.matrix.room.preview_urls");
|
||||
if (roomPreviewUrls && roomPreviewUrls.getContent().disable !== undefined) {
|
||||
this.setState({
|
||||
showUrlPreview: !roomPreviewUrls.getContent().disable
|
||||
showUrlPreview: !roomPreviewUrls.getContent().disable,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// check our global disable override
|
||||
var userRoomPreviewUrls = MatrixClientPeg.get().getAccountData("org.matrix.preview_urls");
|
||||
const userRoomPreviewUrls = MatrixClientPeg.get().getAccountData("org.matrix.preview_urls");
|
||||
if (userRoomPreviewUrls && userRoomPreviewUrls.getContent().disable) {
|
||||
this.setState({
|
||||
showUrlPreview: false
|
||||
showUrlPreview: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// check the room state event
|
||||
var roomStatePreviewUrls = room.currentState.getStateEvents('org.matrix.room.preview_urls', '');
|
||||
const roomStatePreviewUrls = room.currentState.getStateEvents('org.matrix.room.preview_urls', '');
|
||||
if (roomStatePreviewUrls && roomStatePreviewUrls.getContent().disable) {
|
||||
this.setState({
|
||||
showUrlPreview: false
|
||||
showUrlPreview: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise, we assume they're on.
|
||||
this.setState({
|
||||
showUrlPreview: true
|
||||
showUrlPreview: true,
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -654,11 +652,11 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
updateTint: function() {
|
||||
var room = this.state.room;
|
||||
const room = this.state.room;
|
||||
if (!room) return;
|
||||
|
||||
var color_scheme_event = room.getAccountData("org.matrix.room.color_scheme");
|
||||
var color_scheme = {};
|
||||
const color_scheme_event = room.getAccountData("org.matrix.room.color_scheme");
|
||||
let color_scheme = {};
|
||||
if (color_scheme_event) {
|
||||
color_scheme = color_scheme_event.getContent();
|
||||
// XXX: we should validate the event
|
||||
|
@ -676,12 +674,11 @@ module.exports = React.createClass({
|
|||
onRoomAccountData: function(event, room) {
|
||||
if (room.roomId == this.state.roomId) {
|
||||
if (event.getType() === "org.matrix.room.color_scheme") {
|
||||
var color_scheme = event.getContent();
|
||||
const color_scheme = event.getContent();
|
||||
// XXX: we should validate the event
|
||||
console.log("Tinter.tint from onRoomAccountData");
|
||||
Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
|
||||
}
|
||||
else if (event.getType() === "org.matrix.room.preview_urls") {
|
||||
} else if (event.getType() === "org.matrix.room.preview_urls") {
|
||||
this._updatePreviewUrlVisibility(room);
|
||||
}
|
||||
}
|
||||
|
@ -720,7 +717,7 @@ module.exports = React.createClass({
|
|||
// if we are now a member of the room, where we were not before, that
|
||||
// means we have finished joining a room we were previously peeking
|
||||
// into.
|
||||
var me = MatrixClientPeg.get().credentials.userId;
|
||||
const me = MatrixClientPeg.get().credentials.userId;
|
||||
if (this.state.joining && this.state.room.hasMembershipState(me, "join")) {
|
||||
// Having just joined a room, check to see if it looks like a DM room, and if so,
|
||||
// mark it as one. This is to work around the fact that some clients don't support
|
||||
|
@ -754,18 +751,18 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_updateConfCallNotification: function() {
|
||||
var room = this.state.room;
|
||||
const room = this.state.room;
|
||||
if (!room || !this.props.ConferenceHandler) {
|
||||
return;
|
||||
}
|
||||
var confMember = room.getMember(
|
||||
this.props.ConferenceHandler.getConferenceUserIdForRoom(room.roomId)
|
||||
const confMember = room.getMember(
|
||||
this.props.ConferenceHandler.getConferenceUserIdForRoom(room.roomId),
|
||||
);
|
||||
|
||||
if (!confMember) {
|
||||
return;
|
||||
}
|
||||
var confCall = this.props.ConferenceHandler.getConferenceCallForRoom(confMember.roomId);
|
||||
const confCall = this.props.ConferenceHandler.getConferenceCallForRoom(confMember.roomId);
|
||||
|
||||
// A conf call notification should be displayed if there is an ongoing
|
||||
// conf call but this cilent isn't a part of it.
|
||||
|
@ -773,7 +770,7 @@ module.exports = React.createClass({
|
|||
displayConfCallNotification: (
|
||||
(!confCall || confCall.call_state === "ended") &&
|
||||
confMember.membership === "join"
|
||||
)
|
||||
),
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -788,7 +785,7 @@ module.exports = React.createClass({
|
|||
|
||||
if (this.state.searchResults.next_batch) {
|
||||
debuglog("requesting more search results");
|
||||
var searchPromise = MatrixClientPeg.get().backPaginateRoomEventsSearch(
|
||||
const searchPromise = MatrixClientPeg.get().backPaginateRoomEventsSearch(
|
||||
this.state.searchResults);
|
||||
return this._handleSearchResult(searchPromise);
|
||||
} else {
|
||||
|
@ -883,8 +880,7 @@ module.exports = React.createClass({
|
|||
numUnreadMessages: 0,
|
||||
atEndOfLiveTimeline: true,
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.setState({
|
||||
atEndOfLiveTimeline: false,
|
||||
});
|
||||
|
@ -898,10 +894,10 @@ module.exports = React.createClass({
|
|||
|
||||
ev.dataTransfer.dropEffect = 'none';
|
||||
|
||||
var items = ev.dataTransfer.items;
|
||||
const items = ev.dataTransfer.items;
|
||||
if (items.length == 1) {
|
||||
if (items[0].kind == 'file') {
|
||||
this.setState({ draggingFile : true });
|
||||
this.setState({ draggingFile: true });
|
||||
ev.dataTransfer.dropEffect = 'copy';
|
||||
}
|
||||
}
|
||||
|
@ -910,8 +906,8 @@ module.exports = React.createClass({
|
|||
onDrop: function(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.setState({ draggingFile : false });
|
||||
var files = ev.dataTransfer.files;
|
||||
this.setState({ draggingFile: false });
|
||||
const files = ev.dataTransfer.files;
|
||||
if (files.length == 1) {
|
||||
this.uploadFile(files[0]);
|
||||
}
|
||||
|
@ -920,7 +916,7 @@ module.exports = React.createClass({
|
|||
onDragLeaveOrEnd: function(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.setState({ draggingFile : false });
|
||||
this.setState({ draggingFile: false });
|
||||
},
|
||||
|
||||
uploadFile: function(file) {
|
||||
|
@ -930,7 +926,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
|
||||
ContentMessages.sendContentToRoom(
|
||||
file, this.state.room.roomId, MatrixClientPeg.get()
|
||||
file, this.state.room.roomId, MatrixClientPeg.get(),
|
||||
).done(undefined, (error) => {
|
||||
if (error.name === "UnknownDeviceError") {
|
||||
dis.dispatch({
|
||||
|
@ -969,19 +965,19 @@ module.exports = React.createClass({
|
|||
// todo: should cancel any previous search requests.
|
||||
this.searchId = new Date().getTime();
|
||||
|
||||
var filter;
|
||||
let filter;
|
||||
if (scope === "Room") {
|
||||
filter = {
|
||||
// XXX: it's unintuitive that the filter for searching doesn't have the same shape as the v2 filter API :(
|
||||
rooms: [
|
||||
this.state.room.roomId
|
||||
]
|
||||
this.state.room.roomId,
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
debuglog("sending search request");
|
||||
|
||||
var searchPromise = MatrixClientPeg.get().searchRoomEvents({
|
||||
const searchPromise = MatrixClientPeg.get().searchRoomEvents({
|
||||
filter: filter,
|
||||
term: term,
|
||||
});
|
||||
|
@ -989,11 +985,11 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_handleSearchResult: function(searchPromise) {
|
||||
var self = this;
|
||||
const self = this;
|
||||
|
||||
// keep a record of the current search id, so that if the search terms
|
||||
// change before we get a response, we can ignore the results.
|
||||
var localSearchId = this.searchId;
|
||||
const localSearchId = this.searchId;
|
||||
|
||||
this.setState({
|
||||
searchInProgress: true,
|
||||
|
@ -1012,7 +1008,7 @@ module.exports = React.createClass({
|
|||
// In either case, we want to highlight the literal search term
|
||||
// whether it was used by the search engine or not.
|
||||
|
||||
var highlights = results.highlights;
|
||||
let highlights = results.highlights;
|
||||
if (highlights.indexOf(self.state.searchTerm) < 0) {
|
||||
highlights = highlights.concat(self.state.searchTerm);
|
||||
}
|
||||
|
@ -1020,14 +1016,15 @@ module.exports = React.createClass({
|
|||
// For overlapping highlights,
|
||||
// favour longer (more specific) terms first
|
||||
highlights = highlights.sort(function(a, b) {
|
||||
return b.length - a.length; });
|
||||
return b.length - a.length;
|
||||
});
|
||||
|
||||
self.setState({
|
||||
searchHighlights: highlights,
|
||||
searchResults: results,
|
||||
});
|
||||
}, function(error) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
console.error("Search failed: " + error);
|
||||
Modal.createTrackedDialog('Search failed', '', ErrorDialog, {
|
||||
title: _t("Search failed"),
|
||||
|
@ -1035,17 +1032,17 @@ module.exports = React.createClass({
|
|||
});
|
||||
}).finally(function() {
|
||||
self.setState({
|
||||
searchInProgress: false
|
||||
searchInProgress: false,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getSearchResultTiles: function() {
|
||||
var EventTile = sdk.getComponent('rooms.EventTile');
|
||||
var SearchResultTile = sdk.getComponent('rooms.SearchResultTile');
|
||||
var Spinner = sdk.getComponent("elements.Spinner");
|
||||
const EventTile = sdk.getComponent('rooms.EventTile');
|
||||
const SearchResultTile = sdk.getComponent('rooms.SearchResultTile');
|
||||
const Spinner = sdk.getComponent("elements.Spinner");
|
||||
|
||||
var cli = MatrixClientPeg.get();
|
||||
const cli = MatrixClientPeg.get();
|
||||
|
||||
// XXX: todo: merge overlapping results somehow?
|
||||
// XXX: why doesn't searching on name work?
|
||||
|
@ -1055,7 +1052,7 @@ module.exports = React.createClass({
|
|||
return [];
|
||||
}
|
||||
|
||||
var ret = [];
|
||||
const ret = [];
|
||||
|
||||
if (this.state.searchInProgress) {
|
||||
ret.push(<li key="search-spinner">
|
||||
|
@ -1067,32 +1064,32 @@ module.exports = React.createClass({
|
|||
if (this.state.searchResults.results.length == 0) {
|
||||
ret.push(<li key="search-top-marker">
|
||||
<h2 className="mx_RoomView_topMarker">{ _t("No results") }</h2>
|
||||
</li>
|
||||
</li>,
|
||||
);
|
||||
} else {
|
||||
ret.push(<li key="search-top-marker">
|
||||
<h2 className="mx_RoomView_topMarker">{ _t("No more results") }</h2>
|
||||
</li>
|
||||
</li>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// once dynamic content in the search results load, make the scrollPanel check
|
||||
// the scroll offsets.
|
||||
var onWidgetLoad = () => {
|
||||
var scrollPanel = this.refs.searchResultsPanel;
|
||||
const onWidgetLoad = () => {
|
||||
const scrollPanel = this.refs.searchResultsPanel;
|
||||
if (scrollPanel) {
|
||||
scrollPanel.checkScroll();
|
||||
}
|
||||
};
|
||||
|
||||
var lastRoomId;
|
||||
let lastRoomId;
|
||||
|
||||
for (var i = this.state.searchResults.results.length - 1; i >= 0; i--) {
|
||||
var result = this.state.searchResults.results[i];
|
||||
for (let i = this.state.searchResults.results.length - 1; i >= 0; i--) {
|
||||
const result = this.state.searchResults.results[i];
|
||||
|
||||
var mxEv = result.context.getEvent();
|
||||
var roomId = mxEv.getRoomId();
|
||||
const mxEv = result.context.getEvent();
|
||||
const roomId = mxEv.getRoomId();
|
||||
|
||||
if (!EventTile.haveTileForEvent(mxEv)) {
|
||||
// XXX: can this ever happen? It will make the result count
|
||||
|
@ -1102,13 +1099,13 @@ module.exports = React.createClass({
|
|||
|
||||
if (this.state.searchScope === 'All') {
|
||||
if(roomId != lastRoomId) {
|
||||
var room = cli.getRoom(roomId);
|
||||
const room = cli.getRoom(roomId);
|
||||
|
||||
// XXX: if we've left the room, we might not know about
|
||||
// it. We should tell the js sdk to go and find out about
|
||||
// it. But that's not an issue currently, as synapse only
|
||||
// returns results for rooms we're joined to.
|
||||
var roomName = room ? room.name : _t("Unknown room %(roomId)s", { roomId: roomId });
|
||||
const roomName = room ? room.name : _t("Unknown room %(roomId)s", { roomId: roomId });
|
||||
|
||||
ret.push(<li key={mxEv.getId() + "-room"}>
|
||||
<h1>{ _t("Room") }: { roomName }</h1>
|
||||
|
@ -1117,13 +1114,13 @@ module.exports = React.createClass({
|
|||
}
|
||||
}
|
||||
|
||||
var resultLink = "#/room/"+roomId+"/"+mxEv.getId();
|
||||
const resultLink = "#/room/"+roomId+"/"+mxEv.getId();
|
||||
|
||||
ret.push(<SearchResultTile key={mxEv.getId()}
|
||||
searchResult={result}
|
||||
searchHighlights={this.state.searchHighlights}
|
||||
resultLink={resultLink}
|
||||
onWidgetLoad={onWidgetLoad}/>);
|
||||
onWidgetLoad={onWidgetLoad} />);
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
@ -1139,38 +1136,37 @@ module.exports = React.createClass({
|
|||
uploadingRoomSettings: true,
|
||||
});
|
||||
|
||||
var newName = this.refs.header.getEditedName();
|
||||
const newName = this.refs.header.getEditedName();
|
||||
if (newName !== undefined) {
|
||||
this.refs.room_settings.setName(newName);
|
||||
}
|
||||
var newTopic = this.refs.header.getEditedTopic();
|
||||
const newTopic = this.refs.header.getEditedTopic();
|
||||
if (newTopic !== undefined) {
|
||||
this.refs.room_settings.setTopic(newTopic);
|
||||
}
|
||||
|
||||
this.refs.room_settings.save().then((results) => {
|
||||
var fails = results.filter(function(result) { return result.state !== "fulfilled"; });
|
||||
const fails = results.filter(function(result) { return result.state !== "fulfilled"; });
|
||||
console.log("Settings saved with %s errors", fails.length);
|
||||
if (fails.length) {
|
||||
fails.forEach(function(result) {
|
||||
console.error(result.reason);
|
||||
});
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createTrackedDialog('Failed to save room settings', '', ErrorDialog, {
|
||||
title: _t("Failed to save settings"),
|
||||
description: fails.map(function(result) { return result.reason; }).join("\n"),
|
||||
});
|
||||
// still editing room settings
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.setState({
|
||||
editingRoomSettings: false
|
||||
editingRoomSettings: false,
|
||||
});
|
||||
}
|
||||
}).finally(() => {
|
||||
this.setState({
|
||||
uploadingRoomSettings: false,
|
||||
editingRoomSettings: false
|
||||
editingRoomSettings: false,
|
||||
});
|
||||
}).done();
|
||||
},
|
||||
|
@ -1201,8 +1197,8 @@ module.exports = React.createClass({
|
|||
MatrixClientPeg.get().forget(this.state.room.roomId).done(function() {
|
||||
dis.dispatch({ action: 'view_next_room' });
|
||||
}, function(err) {
|
||||
var errCode = err.errcode || _t("unknown error code");
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
const errCode = err.errcode || _t("unknown error code");
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createTrackedDialog('Failed to forget room', '', ErrorDialog, {
|
||||
title: _t("Error"),
|
||||
description: _t("Failed to forget room %(errCode)s", { errCode: errCode }),
|
||||
|
@ -1211,20 +1207,20 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onRejectButtonClicked: function(ev) {
|
||||
var self = this;
|
||||
const self = this;
|
||||
this.setState({
|
||||
rejecting: true
|
||||
rejecting: true,
|
||||
});
|
||||
MatrixClientPeg.get().leave(this.state.roomId).done(function() {
|
||||
dis.dispatch({ action: 'view_next_room' });
|
||||
self.setState({
|
||||
rejecting: false
|
||||
rejecting: false,
|
||||
});
|
||||
}, function(error) {
|
||||
console.error("Failed to reject invite: %s", error);
|
||||
|
||||
var msg = error.message ? error.message : JSON.stringify(error);
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
const msg = error.message ? error.message : JSON.stringify(error);
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createTrackedDialog('Failed to reject invite', '', ErrorDialog, {
|
||||
title: _t("Failed to reject invite"),
|
||||
description: msg,
|
||||
|
@ -1232,7 +1228,7 @@ module.exports = React.createClass({
|
|||
|
||||
self.setState({
|
||||
rejecting: false,
|
||||
rejectError: error
|
||||
rejectError: error,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -1292,7 +1288,7 @@ module.exports = React.createClass({
|
|||
// restored when we switch back to it.
|
||||
//
|
||||
_getScrollState: function() {
|
||||
var messagePanel = this.refs.messagePanel;
|
||||
const messagePanel = this.refs.messagePanel;
|
||||
if (!messagePanel) return null;
|
||||
|
||||
// if we're following the live timeline, we want to return null; that
|
||||
|
@ -1307,7 +1303,7 @@ module.exports = React.createClass({
|
|||
return null;
|
||||
}
|
||||
|
||||
var scrollState = messagePanel.getScrollState();
|
||||
const scrollState = messagePanel.getScrollState();
|
||||
|
||||
if (scrollState.stuckAtBottom) {
|
||||
// we don't really expect to be in this state, but it will
|
||||
|
@ -1334,7 +1330,7 @@ module.exports = React.createClass({
|
|||
// a maxHeight on the underlying remote video tag.
|
||||
|
||||
// header + footer + status + give us at least 120px of scrollback at all times.
|
||||
var auxPanelMaxHeight = window.innerHeight -
|
||||
let auxPanelMaxHeight = window.innerHeight -
|
||||
(83 + // height of RoomHeader
|
||||
36 + // height of the status area
|
||||
72 + // minimum height of the message compmoser
|
||||
|
@ -1353,26 +1349,26 @@ module.exports = React.createClass({
|
|||
onFullscreenClick: function() {
|
||||
dis.dispatch({
|
||||
action: 'video_fullscreen',
|
||||
fullscreen: true
|
||||
fullscreen: true,
|
||||
}, true);
|
||||
},
|
||||
|
||||
onMuteAudioClick: function() {
|
||||
var call = this._getCallForRoom();
|
||||
const call = this._getCallForRoom();
|
||||
if (!call) {
|
||||
return;
|
||||
}
|
||||
var newState = !call.isMicrophoneMuted();
|
||||
const newState = !call.isMicrophoneMuted();
|
||||
call.setMicrophoneMuted(newState);
|
||||
this.forceUpdate(); // TODO: just update the voip buttons
|
||||
},
|
||||
|
||||
onMuteVideoClick: function() {
|
||||
var call = this._getCallForRoom();
|
||||
const call = this._getCallForRoom();
|
||||
if (!call) {
|
||||
return;
|
||||
}
|
||||
var newState = !call.isLocalVideoMuted();
|
||||
const newState = !call.isLocalVideoMuted();
|
||||
call.setLocalVideoMuted(newState);
|
||||
this.forceUpdate(); // TODO: just update the voip buttons
|
||||
},
|
||||
|
@ -1408,7 +1404,7 @@ module.exports = React.createClass({
|
|||
* We pass it down to the scroll panel.
|
||||
*/
|
||||
handleScrollKey: function(ev) {
|
||||
var panel;
|
||||
let panel;
|
||||
if(this.refs.searchResultsPanel) {
|
||||
panel = this.refs.searchResultsPanel;
|
||||
} else if(this.refs.messagePanel) {
|
||||
|
@ -1478,13 +1474,13 @@ module.exports = React.createClass({
|
|||
<RoomHeader ref="header"
|
||||
room={this.state.room}
|
||||
oobData={this.props.oobData}
|
||||
collapsedRhs={ this.props.collapsedRhs }
|
||||
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 }
|
||||
<RoomPreviewBar onJoinClick={this.onJoinButtonClicked}
|
||||
onForgetClick={this.onForgetClick}
|
||||
onRejectClick={this.onRejectThreepidInviteButtonClicked}
|
||||
canPreview={false} error={this.state.roomLoadError}
|
||||
roomAlias={roomAlias}
|
||||
spinner={this.state.joining}
|
||||
inviterName={inviterName}
|
||||
|
@ -1498,8 +1494,8 @@ module.exports = React.createClass({
|
|||
}
|
||||
}
|
||||
|
||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
var myMember = this.state.room.getMember(myUserId);
|
||||
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
const myMember = this.state.room.getMember(myUserId);
|
||||
if (myMember && myMember.membership == 'invite') {
|
||||
if (this.state.joining || this.state.rejecting) {
|
||||
return (
|
||||
|
@ -1508,7 +1504,7 @@ module.exports = React.createClass({
|
|||
</div>
|
||||
);
|
||||
} else {
|
||||
var inviteEvent = myMember.events.member;
|
||||
const inviteEvent = myMember.events.member;
|
||||
var inviterName = inviteEvent.sender ? inviteEvent.sender.name : inviteEvent.getSender();
|
||||
|
||||
// We deliberately don't try to peek into invites, even if we have permission to peek
|
||||
|
@ -1521,14 +1517,14 @@ module.exports = React.createClass({
|
|||
<RoomHeader
|
||||
ref="header"
|
||||
room={this.state.room}
|
||||
collapsedRhs={ this.props.collapsedRhs }
|
||||
collapsedRhs={this.props.collapsedRhs}
|
||||
/>
|
||||
<div className="mx_RoomView_auxPanel">
|
||||
<RoomPreviewBar onJoinClick={ this.onJoinButtonClicked }
|
||||
onForgetClick={ this.onForgetClick }
|
||||
onRejectClick={ this.onRejectButtonClicked }
|
||||
inviterName={ inviterName }
|
||||
canPreview={ false }
|
||||
<RoomPreviewBar onJoinClick={this.onJoinButtonClicked}
|
||||
onForgetClick={this.onForgetClick}
|
||||
onRejectClick={this.onRejectButtonClicked}
|
||||
inviterName={inviterName}
|
||||
canPreview={false}
|
||||
spinner={this.state.joining}
|
||||
room={this.state.room}
|
||||
/>
|
||||
|
@ -1542,24 +1538,24 @@ module.exports = React.createClass({
|
|||
// We have successfully loaded this room, and are not previewing.
|
||||
// Display the "normal" room view.
|
||||
|
||||
var call = this._getCallForRoom();
|
||||
var inCall = false;
|
||||
const call = this._getCallForRoom();
|
||||
let inCall = false;
|
||||
if (call && (this.state.callState !== 'ended' && this.state.callState !== 'ringing')) {
|
||||
inCall = true;
|
||||
}
|
||||
|
||||
var scrollheader_classes = classNames({
|
||||
const scrollheader_classes = classNames({
|
||||
mx_RoomView_scrollheader: true,
|
||||
});
|
||||
|
||||
var statusBar;
|
||||
let statusBar;
|
||||
let isStatusAreaExpanded = true;
|
||||
|
||||
if (ContentMessages.getCurrentUploads().length > 0) {
|
||||
var UploadBar = sdk.getComponent('structures.UploadBar');
|
||||
const UploadBar = sdk.getComponent('structures.UploadBar');
|
||||
statusBar = <UploadBar room={this.state.room} />;
|
||||
} else if (!this.state.searchResults) {
|
||||
var RoomStatusBar = sdk.getComponent('structures.RoomStatusBar');
|
||||
const RoomStatusBar = sdk.getComponent('structures.RoomStatusBar');
|
||||
isStatusAreaExpanded = this.state.statusBarVisible;
|
||||
statusBar = <RoomStatusBar
|
||||
room={this.state.room}
|
||||
|
@ -1582,12 +1578,12 @@ module.exports = React.createClass({
|
|||
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/>;
|
||||
aux = <Loader />;
|
||||
} else if (this.state.forwardingEvent !== null) {
|
||||
aux = <ForwardMessage onCancelClick={this.onCancelClick} />;
|
||||
} 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}/>;
|
||||
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.
|
||||
// We may have a 3rd party invite to it.
|
||||
|
@ -1602,7 +1598,7 @@ module.exports = React.createClass({
|
|||
hideCancel = true;
|
||||
aux = (
|
||||
<RoomPreviewBar onJoinClick={this.onJoinButtonClicked}
|
||||
onForgetClick={ this.onForgetClick }
|
||||
onForgetClick={this.onForgetClick}
|
||||
onRejectClick={this.onRejectThreepidInviteButtonClicked}
|
||||
spinner={this.state.joining}
|
||||
inviterName={inviterName}
|
||||
|
@ -1613,7 +1609,7 @@ module.exports = React.createClass({
|
|||
);
|
||||
}
|
||||
|
||||
var auxPanel = (
|
||||
const auxPanel = (
|
||||
<AuxPanel ref="auxPanel" room={this.state.room}
|
||||
userId={MatrixClientPeg.get().credentials.userId}
|
||||
conferenceHandler={this.props.ConferenceHandler}
|
||||
|
@ -1626,8 +1622,8 @@ module.exports = React.createClass({
|
|||
</AuxPanel>
|
||||
);
|
||||
|
||||
var messageComposer, searchInfo;
|
||||
var canSpeak = (
|
||||
let messageComposer, searchInfo;
|
||||
const canSpeak = (
|
||||
// joined and not showing search results
|
||||
myMember && (myMember.membership == 'join') && !this.state.searchResults
|
||||
);
|
||||
|
@ -1638,8 +1634,8 @@ module.exports = React.createClass({
|
|||
onResize={this.onChildResize}
|
||||
uploadFile={this.uploadFile}
|
||||
callState={this.state.callState}
|
||||
opacity={ this.props.opacity }
|
||||
showApps={ this.state.showApps }
|
||||
opacity={this.props.opacity}
|
||||
showApps={this.state.showApps}
|
||||
/>;
|
||||
}
|
||||
|
||||
|
@ -1647,19 +1643,19 @@ module.exports = React.createClass({
|
|||
// in this.state if this is what RoomHeader desires?
|
||||
if (this.state.searchResults) {
|
||||
searchInfo = {
|
||||
searchTerm : this.state.searchTerm,
|
||||
searchScope : this.state.searchScope,
|
||||
searchCount : this.state.searchResults.count,
|
||||
searchTerm: this.state.searchTerm,
|
||||
searchScope: this.state.searchScope,
|
||||
searchCount: this.state.searchResults.count,
|
||||
};
|
||||
}
|
||||
|
||||
if (inCall) {
|
||||
var zoomButton, voiceMuteButton, videoMuteButton;
|
||||
let zoomButton, voiceMuteButton, videoMuteButton;
|
||||
|
||||
if (call.type === "video") {
|
||||
zoomButton = (
|
||||
<div className="mx_RoomView_voipButton" onClick={this.onFullscreenClick} title={ _t("Fill screen") }>
|
||||
<TintableSvg src="img/fullscreen.svg" width="29" height="22" style={{ marginTop: 1, marginRight: 4 }}/>
|
||||
<div className="mx_RoomView_voipButton" onClick={this.onFullscreenClick} title={_t("Fill screen")}>
|
||||
<TintableSvg src="img/fullscreen.svg" width="29" height="22" style={{ marginTop: 1, marginRight: 4 }} />
|
||||
</div>
|
||||
);
|
||||
|
||||
|
@ -1667,14 +1663,14 @@ module.exports = React.createClass({
|
|||
<div className="mx_RoomView_voipButton" onClick={this.onMuteVideoClick}>
|
||||
<TintableSvg src={call.isLocalVideoMuted() ? "img/video-unmute.svg" : "img/video-mute.svg"}
|
||||
alt={call.isLocalVideoMuted() ? _t("Click to unmute video") : _t("Click to mute video")}
|
||||
width="31" height="27"/>
|
||||
width="31" height="27" />
|
||||
</div>;
|
||||
}
|
||||
voiceMuteButton =
|
||||
<div className="mx_RoomView_voipButton" onClick={this.onMuteAudioClick}>
|
||||
<TintableSvg src={call.isMicrophoneMuted() ? "img/voice-unmute.svg" : "img/voice-mute.svg"}
|
||||
alt={call.isMicrophoneMuted() ? _t("Click to unmute audio") : _t("Click to mute audio")}
|
||||
width="21" height="26"/>
|
||||
width="21" height="26" />
|
||||
</div>;
|
||||
|
||||
// wrap the existing status bar into a 'callStatusBar' which adds more knobs.
|
||||
|
@ -1684,25 +1680,25 @@ module.exports = React.createClass({
|
|||
{ videoMuteButton }
|
||||
{ zoomButton }
|
||||
{ statusBar }
|
||||
<TintableSvg className="mx_RoomView_voipChevron" src="img/voip-chevron.svg" width="22" height="17"/>
|
||||
<TintableSvg className="mx_RoomView_voipChevron" src="img/voip-chevron.svg" width="22" height="17" />
|
||||
</div>;
|
||||
}
|
||||
|
||||
// if we have search results, we keep the messagepanel (so that it preserves its
|
||||
// scroll state), but hide it.
|
||||
var searchResultsPanel;
|
||||
var hideMessagePanel = false;
|
||||
let searchResultsPanel;
|
||||
let hideMessagePanel = false;
|
||||
|
||||
if (this.state.searchResults) {
|
||||
searchResultsPanel = (
|
||||
<ScrollPanel ref="searchResultsPanel"
|
||||
className="mx_RoomView_messagePanel mx_RoomView_searchResultsPanel"
|
||||
onFillRequest={ this.onSearchResultsFillRequest }
|
||||
onResize={ this.onSearchResultsResize }
|
||||
onFillRequest={this.onSearchResultsFillRequest}
|
||||
onResize={this.onSearchResultsResize}
|
||||
style={{ opacity: this.props.opacity }}
|
||||
>
|
||||
<li className={scrollheader_classes}></li>
|
||||
{this.getSearchResultTiles()}
|
||||
{ this.getSearchResultTiles() }
|
||||
</ScrollPanel>
|
||||
);
|
||||
hideMessagePanel = true;
|
||||
|
@ -1717,7 +1713,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
|
||||
// console.log("ShowUrlPreview for %s is %s", this.state.room.roomId, this.state.showUrlPreview);
|
||||
var messagePanel = (
|
||||
const messagePanel = (
|
||||
<TimelinePanel ref={this._gatherTimelinePanelRef}
|
||||
timelineSet={this.state.room.getUnfilteredTimelineSet()}
|
||||
showReadReceipts={!UserSettingsStore.getSyncedSetting('hideReadReceipts', false)}
|
||||
|
@ -1727,16 +1723,16 @@ module.exports = React.createClass({
|
|||
highlightedEventId={highlightedEventId}
|
||||
eventId={this.state.initialEventId}
|
||||
eventPixelOffset={this.state.initialEventPixelOffset}
|
||||
onScroll={ this.onMessageListScroll }
|
||||
onReadMarkerUpdated={ this._updateTopUnreadMessagesBar }
|
||||
showUrlPreview = { this.state.showUrlPreview }
|
||||
opacity={ this.props.opacity }
|
||||
onScroll={this.onMessageListScroll}
|
||||
onReadMarkerUpdated={this._updateTopUnreadMessagesBar}
|
||||
showUrlPreview = {this.state.showUrlPreview}
|
||||
opacity={this.props.opacity}
|
||||
className="mx_RoomView_messagePanel"
|
||||
/>);
|
||||
|
||||
var topUnreadMessagesBar = null;
|
||||
let topUnreadMessagesBar = null;
|
||||
if (this.state.showTopUnreadMessagesBar) {
|
||||
var TopUnreadMessagesBar = sdk.getComponent('rooms.TopUnreadMessagesBar');
|
||||
const TopUnreadMessagesBar = sdk.getComponent('rooms.TopUnreadMessagesBar');
|
||||
topUnreadMessagesBar = (
|
||||
<div className="mx_RoomView_topUnreadMessagesBar mx_fadable" style={{ opacity: this.props.opacity }}>
|
||||
<TopUnreadMessagesBar
|
||||
|
@ -1752,13 +1748,13 @@ module.exports = React.createClass({
|
|||
}
|
||||
|
||||
return (
|
||||
<div className={ "mx_RoomView" + (inCall ? " mx_RoomView_inCall" : "") } ref="roomView">
|
||||
<div className={"mx_RoomView" + (inCall ? " mx_RoomView_inCall" : "")} ref="roomView">
|
||||
<RoomHeader ref="header" room={this.state.room} searchInfo={searchInfo}
|
||||
oobData={this.props.oobData}
|
||||
editing={this.state.editingRoomSettings}
|
||||
saving={this.state.uploadingRoomSettings}
|
||||
inRoom={myMember && myMember.membership === 'join'}
|
||||
collapsedRhs={ this.props.collapsedRhs }
|
||||
collapsedRhs={this.props.collapsedRhs}
|
||||
onSearchClick={this.onSearchClick}
|
||||
onSettingsClick={this.onSettingsClick}
|
||||
onSaveClick={this.onSettingsSaveClick}
|
||||
|
|
|
@ -14,13 +14,13 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
var React = require("react");
|
||||
var ReactDOM = require("react-dom");
|
||||
var GeminiScrollbar = require('react-gemini-scrollbar');
|
||||
const React = require("react");
|
||||
const ReactDOM = require("react-dom");
|
||||
const GeminiScrollbar = require('react-gemini-scrollbar');
|
||||
import Promise from 'bluebird';
|
||||
var KeyCode = require('../../KeyCode');
|
||||
const KeyCode = require('../../KeyCode');
|
||||
|
||||
var DEBUG_SCROLL = false;
|
||||
const DEBUG_SCROLL = false;
|
||||
// var DEBUG_SCROLL = true;
|
||||
|
||||
// The amount of extra scroll distance to allow prior to unfilling.
|
||||
|
@ -178,7 +178,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onScroll: function(ev) {
|
||||
var sn = this._getScrollNode();
|
||||
const sn = this._getScrollNode();
|
||||
debuglog("Scroll event: offset now:", sn.scrollTop,
|
||||
"_lastSetScroll:", this._lastSetScroll);
|
||||
|
||||
|
@ -238,7 +238,7 @@ module.exports = React.createClass({
|
|||
// about whether the the content is scrolled down right now, irrespective of
|
||||
// whether it will stay that way when the children update.
|
||||
isAtBottom: function() {
|
||||
var sn = this._getScrollNode();
|
||||
const sn = this._getScrollNode();
|
||||
|
||||
// there seems to be some bug with flexbox/gemini/chrome/richvdh's
|
||||
// understanding of the box model, wherein the scrollNode ends up 2
|
||||
|
@ -281,7 +281,7 @@ module.exports = React.createClass({
|
|||
// |#########| |
|
||||
// `---------' -
|
||||
_getExcessHeight: function(backwards) {
|
||||
var sn = this._getScrollNode();
|
||||
const sn = this._getScrollNode();
|
||||
if (backwards) {
|
||||
return sn.scrollTop - sn.clientHeight - UNPAGINATION_PADDING;
|
||||
} else {
|
||||
|
@ -295,7 +295,7 @@ module.exports = React.createClass({
|
|||
return;
|
||||
}
|
||||
|
||||
var sn = this._getScrollNode();
|
||||
const sn = this._getScrollNode();
|
||||
|
||||
// if there is less than a screenful of messages above or below the
|
||||
// viewport, try to get some more messages.
|
||||
|
@ -377,7 +377,7 @@ module.exports = React.createClass({
|
|||
|
||||
// check if there is already a pending fill request. If not, set one off.
|
||||
_maybeFill: function(backwards) {
|
||||
var dir = backwards ? 'b' : 'f';
|
||||
const dir = backwards ? 'b' : 'f';
|
||||
if (this._pendingFillRequests[dir]) {
|
||||
debuglog("ScrollPanel: Already a "+dir+" fill in progress - not starting another");
|
||||
return;
|
||||
|
@ -470,8 +470,8 @@ module.exports = React.createClass({
|
|||
* mult: -1 to page up, +1 to page down
|
||||
*/
|
||||
scrollRelative: function(mult) {
|
||||
var scrollNode = this._getScrollNode();
|
||||
var delta = mult * scrollNode.clientHeight * 0.5;
|
||||
const scrollNode = this._getScrollNode();
|
||||
const delta = mult * scrollNode.clientHeight * 0.5;
|
||||
this._setScrollTop(scrollNode.scrollTop + delta);
|
||||
this._saveScrollState();
|
||||
},
|
||||
|
@ -535,7 +535,7 @@ module.exports = React.createClass({
|
|||
this.scrollState = {
|
||||
stuckAtBottom: false,
|
||||
trackedScrollToken: scrollToken,
|
||||
pixelOffset: pixelOffset
|
||||
pixelOffset: pixelOffset,
|
||||
};
|
||||
|
||||
// ... then make it so.
|
||||
|
@ -546,10 +546,10 @@ module.exports = React.createClass({
|
|||
// given offset in the window. A helper for _restoreSavedScrollState.
|
||||
_scrollToToken: function(scrollToken, pixelOffset) {
|
||||
/* find the dom node with the right scrolltoken */
|
||||
var node;
|
||||
var messages = this.refs.itemlist.children;
|
||||
for (var i = messages.length-1; i >= 0; --i) {
|
||||
var m = messages[i];
|
||||
let node;
|
||||
const messages = this.refs.itemlist.children;
|
||||
for (let i = messages.length-1; i >= 0; --i) {
|
||||
const m = messages[i];
|
||||
// 'data-scroll-tokens' is a DOMString of comma-separated scroll tokens
|
||||
// There might only be one scroll token
|
||||
if (m.dataset.scrollTokens &&
|
||||
|
@ -564,10 +564,10 @@ module.exports = React.createClass({
|
|||
return;
|
||||
}
|
||||
|
||||
var scrollNode = this._getScrollNode();
|
||||
var wrapperRect = ReactDOM.findDOMNode(this).getBoundingClientRect();
|
||||
var boundingRect = node.getBoundingClientRect();
|
||||
var scrollDelta = boundingRect.bottom + pixelOffset - wrapperRect.bottom;
|
||||
const scrollNode = this._getScrollNode();
|
||||
const wrapperRect = ReactDOM.findDOMNode(this).getBoundingClientRect();
|
||||
const boundingRect = node.getBoundingClientRect();
|
||||
const scrollDelta = boundingRect.bottom + pixelOffset - wrapperRect.bottom;
|
||||
|
||||
debuglog("ScrollPanel: scrolling to token '" + scrollToken + "'+" +
|
||||
pixelOffset + " (delta: "+scrollDelta+")");
|
||||
|
@ -575,7 +575,6 @@ module.exports = React.createClass({
|
|||
if(scrollDelta != 0) {
|
||||
this._setScrollTop(scrollNode.scrollTop + scrollDelta);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
_saveScrollState: function() {
|
||||
|
@ -585,16 +584,16 @@ module.exports = React.createClass({
|
|||
return;
|
||||
}
|
||||
|
||||
var itemlist = this.refs.itemlist;
|
||||
var wrapperRect = ReactDOM.findDOMNode(this).getBoundingClientRect();
|
||||
var messages = itemlist.children;
|
||||
const itemlist = this.refs.itemlist;
|
||||
const wrapperRect = ReactDOM.findDOMNode(this).getBoundingClientRect();
|
||||
const messages = itemlist.children;
|
||||
let newScrollState = null;
|
||||
|
||||
for (var i = messages.length-1; i >= 0; --i) {
|
||||
var node = messages[i];
|
||||
for (let i = messages.length-1; i >= 0; --i) {
|
||||
const node = messages[i];
|
||||
if (!node.dataset.scrollTokens) continue;
|
||||
|
||||
var boundingRect = node.getBoundingClientRect();
|
||||
const boundingRect = node.getBoundingClientRect();
|
||||
newScrollState = {
|
||||
stuckAtBottom: false,
|
||||
trackedScrollToken: node.dataset.scrollTokens.split(',')[0],
|
||||
|
@ -619,8 +618,8 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_restoreSavedScrollState: function() {
|
||||
var scrollState = this.scrollState;
|
||||
var scrollNode = this._getScrollNode();
|
||||
const scrollState = this.scrollState;
|
||||
const scrollNode = this._getScrollNode();
|
||||
|
||||
if (scrollState.stuckAtBottom) {
|
||||
this._setScrollTop(Number.MAX_VALUE);
|
||||
|
@ -631,9 +630,9 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_setScrollTop: function(scrollTop) {
|
||||
var scrollNode = this._getScrollNode();
|
||||
const scrollNode = this._getScrollNode();
|
||||
|
||||
var prevScroll = scrollNode.scrollTop;
|
||||
const prevScroll = scrollNode.scrollTop;
|
||||
|
||||
// FF ignores attempts to set scrollTop to very large numbers
|
||||
scrollNode.scrollTop = Math.min(scrollTop, scrollNode.scrollHeight);
|
||||
|
@ -676,7 +675,7 @@ module.exports = React.createClass({
|
|||
className={this.props.className} style={this.props.style}>
|
||||
<div className="mx_RoomView_messageListWrapper">
|
||||
<ol ref="itemlist" className="mx_RoomView_MessageList" aria-live="polite">
|
||||
{this.props.children}
|
||||
{ this.props.children }
|
||||
</ol>
|
||||
</div>
|
||||
</GeminiScrollbar>
|
||||
|
|
|
@ -15,27 +15,27 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
var React = require('react');
|
||||
var ReactDOM = require("react-dom");
|
||||
const React = require('react');
|
||||
const ReactDOM = require("react-dom");
|
||||
import Promise from 'bluebird';
|
||||
|
||||
var Matrix = require("matrix-js-sdk");
|
||||
var EventTimeline = Matrix.EventTimeline;
|
||||
const Matrix = require("matrix-js-sdk");
|
||||
const EventTimeline = Matrix.EventTimeline;
|
||||
|
||||
var sdk = require('../../index');
|
||||
const sdk = require('../../index');
|
||||
import { _t } from '../../languageHandler';
|
||||
var MatrixClientPeg = require("../../MatrixClientPeg");
|
||||
var dis = require("../../dispatcher");
|
||||
var ObjectUtils = require('../../ObjectUtils');
|
||||
var Modal = require("../../Modal");
|
||||
var UserActivity = require("../../UserActivity");
|
||||
var KeyCode = require('../../KeyCode');
|
||||
const MatrixClientPeg = require("../../MatrixClientPeg");
|
||||
const dis = require("../../dispatcher");
|
||||
const ObjectUtils = require('../../ObjectUtils');
|
||||
const Modal = require("../../Modal");
|
||||
const UserActivity = require("../../UserActivity");
|
||||
const KeyCode = require('../../KeyCode');
|
||||
import UserSettingsStore from '../../UserSettingsStore';
|
||||
|
||||
var PAGINATE_SIZE = 20;
|
||||
var INITIAL_SIZE = 20;
|
||||
const PAGINATE_SIZE = 20;
|
||||
const INITIAL_SIZE = 20;
|
||||
|
||||
var DEBUG = false;
|
||||
const DEBUG = false;
|
||||
|
||||
if (DEBUG) {
|
||||
// using bind means that we get to keep useful line numbers in the console
|
||||
|
@ -260,7 +260,7 @@ var TimelinePanel = React.createClass({
|
|||
|
||||
dis.unregister(this.dispatcherRef);
|
||||
|
||||
var client = MatrixClientPeg.get();
|
||||
const client = MatrixClientPeg.get();
|
||||
if (client) {
|
||||
client.removeListener("Room.timeline", this.onRoomTimeline);
|
||||
client.removeListener("Room.timelineReset", this.onRoomTimelineReset);
|
||||
|
@ -275,20 +275,20 @@ var TimelinePanel = React.createClass({
|
|||
|
||||
onMessageListUnfillRequest: function(backwards, scrollToken) {
|
||||
// If backwards, unpaginate from the back (i.e. the start of the timeline)
|
||||
let dir = backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS;
|
||||
const dir = backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS;
|
||||
debuglog("TimelinePanel: unpaginating events in direction", dir);
|
||||
|
||||
// All tiles are inserted by MessagePanel to have a scrollToken === eventId, and
|
||||
// this particular event should be the first or last to be unpaginated.
|
||||
let eventId = scrollToken;
|
||||
const eventId = scrollToken;
|
||||
|
||||
let marker = this.state.events.findIndex(
|
||||
const marker = this.state.events.findIndex(
|
||||
(ev) => {
|
||||
return ev.getId() === eventId;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
let count = backwards ? marker + 1 : this.state.events.length - marker;
|
||||
const count = backwards ? marker + 1 : this.state.events.length - marker;
|
||||
|
||||
if (count > 0) {
|
||||
debuglog("TimelinePanel: Unpaginating", count, "in direction", dir);
|
||||
|
@ -305,9 +305,9 @@ var TimelinePanel = React.createClass({
|
|||
|
||||
// set off a pagination request.
|
||||
onMessageListFillRequest: function(backwards) {
|
||||
var dir = backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS;
|
||||
var canPaginateKey = backwards ? 'canBackPaginate' : 'canForwardPaginate';
|
||||
var paginatingKey = backwards ? 'backPaginating' : 'forwardPaginating';
|
||||
const dir = backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS;
|
||||
const canPaginateKey = backwards ? 'canBackPaginate' : 'canForwardPaginate';
|
||||
const paginatingKey = backwards ? 'backPaginating' : 'forwardPaginating';
|
||||
|
||||
if (!this.state[canPaginateKey]) {
|
||||
debuglog("TimelinePanel: have given up", dir, "paginating this timeline");
|
||||
|
@ -328,7 +328,7 @@ var TimelinePanel = React.createClass({
|
|||
|
||||
debuglog("TimelinePanel: paginate complete backwards:"+backwards+"; success:"+r);
|
||||
|
||||
var newState = {
|
||||
const newState = {
|
||||
[paginatingKey]: false,
|
||||
[canPaginateKey]: r,
|
||||
events: this._getEvents(),
|
||||
|
@ -336,8 +336,8 @@ var TimelinePanel = React.createClass({
|
|||
|
||||
// moving the window in this direction may mean that we can now
|
||||
// paginate in the other where we previously could not.
|
||||
var otherDirection = backwards ? EventTimeline.FORWARDS : EventTimeline.BACKWARDS;
|
||||
var canPaginateOtherWayKey = backwards ? 'canForwardPaginate' : 'canBackPaginate';
|
||||
const otherDirection = backwards ? EventTimeline.FORWARDS : EventTimeline.BACKWARDS;
|
||||
const canPaginateOtherWayKey = backwards ? 'canForwardPaginate' : 'canBackPaginate';
|
||||
if (!this.state[canPaginateOtherWayKey] &&
|
||||
this._timelineWindow.canPaginate(otherDirection)) {
|
||||
debuglog('TimelinePanel: can now', otherDirection, 'paginate again');
|
||||
|
@ -420,15 +420,15 @@ var TimelinePanel = React.createClass({
|
|||
this._timelineWindow.paginate(EventTimeline.FORWARDS, 1, false).done(() => {
|
||||
if (this.unmounted) { return; }
|
||||
|
||||
var events = this._timelineWindow.getEvents();
|
||||
var lastEv = events[events.length-1];
|
||||
const events = this._timelineWindow.getEvents();
|
||||
const lastEv = events[events.length-1];
|
||||
|
||||
// if we're at the end of the live timeline, append the pending events
|
||||
if (this.props.timelineSet.room && !this._timelineWindow.canPaginate(EventTimeline.FORWARDS)) {
|
||||
events.push(...this.props.timelineSet.room.getPendingEvents());
|
||||
}
|
||||
|
||||
var updatedState = {events: events};
|
||||
const updatedState = {events: events};
|
||||
|
||||
if (this.props.manageReadMarkers) {
|
||||
// when a new event arrives when the user is not watching the
|
||||
|
@ -439,8 +439,8 @@ var TimelinePanel = React.createClass({
|
|||
// read-marker when a remote echo of an event we have just sent takes
|
||||
// more than the timeout on userCurrentlyActive.
|
||||
//
|
||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
var sender = ev.sender ? ev.sender.userId : null;
|
||||
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
const sender = ev.sender ? ev.sender.userId : null;
|
||||
var callback = null;
|
||||
if (sender != myUserId && !UserActivity.userCurrentlyActive()) {
|
||||
updatedState.readMarkerVisible = true;
|
||||
|
@ -646,7 +646,7 @@ var TimelinePanel = React.createClass({
|
|||
// and we'll get confused when their ID changes and we can't figure out
|
||||
// where the RM is pointing to. The read marker will be invisible for
|
||||
// now anyway, so this doesn't really matter.
|
||||
var lastDisplayedIndex = this._getLastDisplayedEventIndex({
|
||||
const lastDisplayedIndex = this._getLastDisplayedEventIndex({
|
||||
allowPartial: true,
|
||||
ignoreEchoes: true,
|
||||
});
|
||||
|
@ -655,7 +655,7 @@ var TimelinePanel = React.createClass({
|
|||
return;
|
||||
}
|
||||
|
||||
var lastDisplayedEvent = this.state.events[lastDisplayedIndex];
|
||||
const lastDisplayedEvent = this.state.events[lastDisplayedIndex];
|
||||
this._setReadMarker(lastDisplayedEvent.getId(),
|
||||
lastDisplayedEvent.getTs());
|
||||
|
||||
|
@ -676,7 +676,7 @@ var TimelinePanel = React.createClass({
|
|||
// we call _timelineWindow.getEvents() rather than using
|
||||
// this.state.events, because react batches the update to the latter, so it
|
||||
// may not have been updated yet.
|
||||
var events = this._timelineWindow.getEvents();
|
||||
const events = this._timelineWindow.getEvents();
|
||||
|
||||
// first find where the current RM is
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
|
@ -689,7 +689,7 @@ var TimelinePanel = React.createClass({
|
|||
}
|
||||
|
||||
// now think about advancing it
|
||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
for (i++; i < events.length; i++) {
|
||||
var ev = events[i];
|
||||
if (!ev.sender || ev.sender.userId != myUserId) {
|
||||
|
@ -734,7 +734,7 @@ var TimelinePanel = React.createClass({
|
|||
//
|
||||
// a quick way to figure out if we've loaded the relevant event is
|
||||
// simply to check if the messagepanel knows where the read-marker is.
|
||||
var ret = this.refs.messagePanel.getReadMarkerPosition();
|
||||
const ret = this.refs.messagePanel.getReadMarkerPosition();
|
||||
if (ret !== null) {
|
||||
// The messagepanel knows where the RM is, so we must have loaded
|
||||
// the relevant event.
|
||||
|
@ -755,13 +755,13 @@ var TimelinePanel = React.createClass({
|
|||
forgetReadMarker: function() {
|
||||
if (!this.props.manageReadMarkers) return;
|
||||
|
||||
var rmId = this._getCurrentReadReceipt();
|
||||
const rmId = this._getCurrentReadReceipt();
|
||||
|
||||
// see if we know the timestamp for the rr event
|
||||
var tl = this.props.timelineSet.getTimelineForEvent(rmId);
|
||||
var rmTs;
|
||||
const tl = this.props.timelineSet.getTimelineForEvent(rmId);
|
||||
let rmTs;
|
||||
if (tl) {
|
||||
var event = tl.getEvents().find((e) => { return e.getId() == rmId; });
|
||||
const event = tl.getEvents().find((e) => { return e.getId() == rmId; });
|
||||
if (event) {
|
||||
rmTs = event.getTs();
|
||||
}
|
||||
|
@ -801,7 +801,7 @@ var TimelinePanel = React.createClass({
|
|||
if (!this.props.manageReadMarkers) return null;
|
||||
if (!this.refs.messagePanel) return null;
|
||||
|
||||
var ret = this.refs.messagePanel.getReadMarkerPosition();
|
||||
const ret = this.refs.messagePanel.getReadMarkerPosition();
|
||||
if (ret !== null) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -844,8 +844,7 @@ var TimelinePanel = React.createClass({
|
|||
// jump to the live timeline on ctrl-end, rather than the end of the
|
||||
// timeline window.
|
||||
if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey &&
|
||||
ev.keyCode == KeyCode.END)
|
||||
{
|
||||
ev.keyCode == KeyCode.END) {
|
||||
this.jumpToLiveTimeline();
|
||||
} else {
|
||||
this.refs.messagePanel.handleScrollKey(ev);
|
||||
|
@ -853,12 +852,12 @@ var TimelinePanel = React.createClass({
|
|||
},
|
||||
|
||||
_initTimeline: function(props) {
|
||||
var initialEvent = props.eventId;
|
||||
var pixelOffset = props.eventPixelOffset;
|
||||
const initialEvent = props.eventId;
|
||||
const pixelOffset = props.eventPixelOffset;
|
||||
|
||||
// if a pixelOffset is given, it is relative to the bottom of the
|
||||
// container. If not, put the event in the middle of the container.
|
||||
var offsetBase = 1;
|
||||
let offsetBase = 1;
|
||||
if (pixelOffset == null) {
|
||||
offsetBase = 0.5;
|
||||
}
|
||||
|
@ -887,7 +886,7 @@ var TimelinePanel = React.createClass({
|
|||
MatrixClientPeg.get(), this.props.timelineSet,
|
||||
{windowLimit: this.props.timelineCap});
|
||||
|
||||
var onLoaded = () => {
|
||||
const onLoaded = () => {
|
||||
this._reloadEvents();
|
||||
|
||||
// If we switched away from the room while there were pending
|
||||
|
@ -922,15 +921,15 @@ var TimelinePanel = React.createClass({
|
|||
});
|
||||
};
|
||||
|
||||
var onError = (error) => {
|
||||
const onError = (error) => {
|
||||
this.setState({timelineLoading: false});
|
||||
console.error(
|
||||
`Error loading timeline panel at ${eventId}: ${error}`,
|
||||
);
|
||||
var msg = error.message ? error.message : JSON.stringify(error);
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
const msg = error.message ? error.message : JSON.stringify(error);
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
|
||||
var onFinished;
|
||||
let onFinished;
|
||||
|
||||
// if we were given an event ID, then when the user closes the
|
||||
// dialog, let's jump to the end of the timeline. If we weren't,
|
||||
|
@ -945,7 +944,7 @@ var TimelinePanel = React.createClass({
|
|||
});
|
||||
};
|
||||
}
|
||||
var message = (error.errcode == 'M_FORBIDDEN')
|
||||
const 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.createTrackedDialog('Failed to load timeline position', '', ErrorDialog, {
|
||||
|
@ -955,7 +954,7 @@ var TimelinePanel = React.createClass({
|
|||
});
|
||||
};
|
||||
|
||||
var prom = this._timelineWindow.load(eventId, INITIAL_SIZE);
|
||||
let prom = this._timelineWindow.load(eventId, INITIAL_SIZE);
|
||||
|
||||
// if we already have the event in question, TimelineWindow.load
|
||||
// returns a resolved promise.
|
||||
|
@ -996,7 +995,7 @@ var TimelinePanel = React.createClass({
|
|||
|
||||
// get the list of events from the timeline window and the pending event list
|
||||
_getEvents: function() {
|
||||
var events = this._timelineWindow.getEvents();
|
||||
const events = this._timelineWindow.getEvents();
|
||||
|
||||
// if we're at the end of the live timeline, append the pending events
|
||||
if (!this._timelineWindow.canPaginate(EventTimeline.FORWARDS)) {
|
||||
|
@ -1007,7 +1006,7 @@ var TimelinePanel = React.createClass({
|
|||
},
|
||||
|
||||
_indexForEventId: function(evId) {
|
||||
for (var i = 0; i < this.state.events.length; ++i) {
|
||||
for (let i = 0; i < this.state.events.length; ++i) {
|
||||
if (evId == this.state.events[i].getId()) {
|
||||
return i;
|
||||
}
|
||||
|
@ -1017,18 +1016,18 @@ var TimelinePanel = React.createClass({
|
|||
|
||||
_getLastDisplayedEventIndex: function(opts) {
|
||||
opts = opts || {};
|
||||
var ignoreOwn = opts.ignoreOwn || false;
|
||||
var ignoreEchoes = opts.ignoreEchoes || false;
|
||||
var allowPartial = opts.allowPartial || false;
|
||||
const ignoreOwn = opts.ignoreOwn || false;
|
||||
const ignoreEchoes = opts.ignoreEchoes || false;
|
||||
const allowPartial = opts.allowPartial || false;
|
||||
|
||||
var messagePanel = this.refs.messagePanel;
|
||||
const messagePanel = this.refs.messagePanel;
|
||||
if (messagePanel === undefined) return null;
|
||||
|
||||
var wrapperRect = ReactDOM.findDOMNode(messagePanel).getBoundingClientRect();
|
||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
const wrapperRect = ReactDOM.findDOMNode(messagePanel).getBoundingClientRect();
|
||||
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
|
||||
for (var i = this.state.events.length-1; i >= 0; --i) {
|
||||
var ev = this.state.events[i];
|
||||
for (let i = this.state.events.length-1; i >= 0; --i) {
|
||||
const ev = this.state.events[i];
|
||||
|
||||
if (ignoreOwn && ev.sender && ev.sender.userId == myUserId) {
|
||||
continue;
|
||||
|
@ -1039,10 +1038,10 @@ var TimelinePanel = React.createClass({
|
|||
continue;
|
||||
}
|
||||
|
||||
var node = messagePanel.getNodeForEventId(ev.getId());
|
||||
const node = messagePanel.getNodeForEventId(ev.getId());
|
||||
if (!node) continue;
|
||||
|
||||
var boundingRect = node.getBoundingClientRect();
|
||||
const boundingRect = node.getBoundingClientRect();
|
||||
if ((allowPartial && boundingRect.top < wrapperRect.bottom) ||
|
||||
(!allowPartial && boundingRect.bottom < wrapperRect.bottom)) {
|
||||
return i;
|
||||
|
@ -1060,18 +1059,18 @@ var TimelinePanel = React.createClass({
|
|||
* SDK.
|
||||
*/
|
||||
_getCurrentReadReceipt: function(ignoreSynthesized) {
|
||||
var client = MatrixClientPeg.get();
|
||||
const client = MatrixClientPeg.get();
|
||||
// the client can be null on logout
|
||||
if (client == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var myUserId = client.credentials.userId;
|
||||
const myUserId = client.credentials.userId;
|
||||
return this.props.timelineSet.room.getEventReadUpTo(myUserId, ignoreSynthesized);
|
||||
},
|
||||
|
||||
_setReadMarker: function(eventId, eventTs, inhibitSetState) {
|
||||
var roomId = this.props.timelineSet.room.roomId;
|
||||
const roomId = this.props.timelineSet.room.roomId;
|
||||
|
||||
// don't update the state (and cause a re-render) if there is
|
||||
// no change to the RM.
|
||||
|
@ -1096,8 +1095,8 @@ var TimelinePanel = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var MessagePanel = sdk.getComponent("structures.MessagePanel");
|
||||
var Loader = sdk.getComponent("elements.Spinner");
|
||||
const MessagePanel = sdk.getComponent("structures.MessagePanel");
|
||||
const Loader = sdk.getComponent("elements.Spinner");
|
||||
|
||||
// just show a spinner while the timeline loads.
|
||||
//
|
||||
|
@ -1112,7 +1111,7 @@ var TimelinePanel = React.createClass({
|
|||
// exist.
|
||||
if (this.state.timelineLoading) {
|
||||
return (
|
||||
<div className={ this.props.className + " mx_RoomView_messageListWrapper" }>
|
||||
<div className={this.props.className + " mx_RoomView_messageListWrapper"}>
|
||||
<Loader />
|
||||
</div>
|
||||
);
|
||||
|
@ -1120,7 +1119,7 @@ var TimelinePanel = React.createClass({
|
|||
|
||||
if (this.state.events.length == 0 && !this.state.canBackPaginate && this.props.empty) {
|
||||
return (
|
||||
<div className={ this.props.className + " mx_RoomView_messageListWrapper" }>
|
||||
<div className={this.props.className + " mx_RoomView_messageListWrapper"}>
|
||||
<div className="mx_RoomView_empty">{ this.props.empty }</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1134,7 +1133,7 @@ var TimelinePanel = React.createClass({
|
|||
// forwards, otherwise if somebody hits the bottom of the loaded
|
||||
// events when viewing historical messages, we get stuck in a loop
|
||||
// of paginating our way through the entire history of the room.
|
||||
var stickyBottom = !this._timelineWindow.canPaginate(EventTimeline.FORWARDS);
|
||||
const stickyBottom = !this._timelineWindow.canPaginate(EventTimeline.FORWARDS);
|
||||
|
||||
// If the state is PREPARED, we're still waiting for the js-sdk to sync with
|
||||
// the HS and fetch the latest events, so we are effectively forward paginating.
|
||||
|
@ -1143,26 +1142,26 @@ 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 }
|
||||
showReadReceipts={ this.props.showReadReceipts }
|
||||
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}
|
||||
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}
|
||||
showReadReceipts={this.props.showReadReceipts}
|
||||
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}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -14,15 +14,15 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
var React = require('react');
|
||||
var ContentMessages = require('../../ContentMessages');
|
||||
var dis = require('../../dispatcher');
|
||||
var filesize = require('filesize');
|
||||
const React = require('react');
|
||||
const ContentMessages = require('../../ContentMessages');
|
||||
const dis = require('../../dispatcher');
|
||||
const filesize = require('filesize');
|
||||
import { _t } from '../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({displayName: 'UploadBar',
|
||||
propTypes: {
|
||||
room: React.PropTypes.object
|
||||
room: React.PropTypes.object,
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
|
@ -46,7 +46,7 @@ module.exports = React.createClass({displayName: 'UploadBar',
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var uploads = ContentMessages.getCurrentUploads();
|
||||
const uploads = ContentMessages.getCurrentUploads();
|
||||
|
||||
// for testing UI... - also fix up the ContentMessages.getCurrentUploads().length
|
||||
// check in RoomView
|
||||
|
@ -62,8 +62,8 @@ module.exports = React.createClass({displayName: 'UploadBar',
|
|||
return <div />;
|
||||
}
|
||||
|
||||
var upload;
|
||||
for (var i = 0; i < uploads.length; ++i) {
|
||||
let upload;
|
||||
for (let i = 0; i < uploads.length; ++i) {
|
||||
if (uploads[i].roomId == this.props.room.roomId) {
|
||||
upload = uploads[i];
|
||||
break;
|
||||
|
@ -73,32 +73,32 @@ module.exports = React.createClass({displayName: 'UploadBar',
|
|||
return <div />;
|
||||
}
|
||||
|
||||
var innerProgressStyle = {
|
||||
width: ((upload.loaded / (upload.total || 1)) * 100) + '%'
|
||||
const innerProgressStyle = {
|
||||
width: ((upload.loaded / (upload.total || 1)) * 100) + '%',
|
||||
};
|
||||
var uploadedSize = filesize(upload.loaded);
|
||||
var totalSize = filesize(upload.total);
|
||||
let uploadedSize = filesize(upload.loaded);
|
||||
const totalSize = filesize(upload.total);
|
||||
if (uploadedSize.replace(/^.* /, '') === totalSize.replace(/^.* /, '')) {
|
||||
uploadedSize = uploadedSize.replace(/ .*/, '');
|
||||
}
|
||||
|
||||
// MUST use var name 'count' for pluralization to kick in
|
||||
var uploadText = _t("Uploading %(filename)s and %(count)s others", {filename: upload.fileName, count: (uploads.length - 1)});
|
||||
const uploadText = _t("Uploading %(filename)s and %(count)s others", {filename: upload.fileName, count: (uploads.length - 1)});
|
||||
|
||||
return (
|
||||
<div className="mx_UploadBar">
|
||||
<div className="mx_UploadBar_uploadProgressOuter">
|
||||
<div className="mx_UploadBar_uploadProgressInner" style={innerProgressStyle}></div>
|
||||
</div>
|
||||
<img className="mx_UploadBar_uploadIcon mx_filterFlipColor" src="img/fileicon.png" width="17" height="22"/>
|
||||
<img className="mx_UploadBar_uploadIcon mx_filterFlipColor" src="img/fileicon.png" width="17" height="22" />
|
||||
<img className="mx_UploadBar_uploadCancel mx_filterFlipColor" src="img/cancel.svg" width="18" height="18"
|
||||
onClick={function() { ContentMessages.cancelUpload(upload.promise); }}
|
||||
/>
|
||||
<div className="mx_UploadBar_uploadBytes">
|
||||
{ uploadedSize } / { totalSize }
|
||||
</div>
|
||||
<div className="mx_UploadBar_uploadFilename">{uploadText}</div>
|
||||
<div className="mx_UploadBar_uploadFilename">{ uploadText }</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -17,13 +17,13 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
const React = require('react');
|
||||
import { _t } from '../../../languageHandler';
|
||||
var sdk = require('../../../index');
|
||||
var Modal = require("../../../Modal");
|
||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
const sdk = require('../../../index');
|
||||
const Modal = require("../../../Modal");
|
||||
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
|
||||
var PasswordReset = require("../../../PasswordReset");
|
||||
const PasswordReset = require("../../../PasswordReset");
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'ForgotPassword',
|
||||
|
@ -35,30 +35,30 @@ module.exports = React.createClass({
|
|||
customIsUrl: React.PropTypes.string,
|
||||
onLoginClick: React.PropTypes.func,
|
||||
onRegisterClick: React.PropTypes.func,
|
||||
onComplete: React.PropTypes.func.isRequired
|
||||
onComplete: React.PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
enteredHomeserverUrl: this.props.customHsUrl || this.props.defaultHsUrl,
|
||||
enteredIdentityServerUrl: this.props.customIsUrl || this.props.defaultIsUrl,
|
||||
progress: null
|
||||
progress: null,
|
||||
};
|
||||
},
|
||||
|
||||
submitPasswordReset: function(hsUrl, identityUrl, email, password) {
|
||||
this.setState({
|
||||
progress: "sending_email"
|
||||
progress: "sending_email",
|
||||
});
|
||||
this.reset = new PasswordReset(hsUrl, identityUrl);
|
||||
this.reset.resetPassword(email, password).done(() => {
|
||||
this.setState({
|
||||
progress: "sent_email"
|
||||
progress: "sent_email",
|
||||
});
|
||||
}, (err) => {
|
||||
this.showErrorDialog(_t('Failed to send email') + ": " + err.message);
|
||||
this.setState({
|
||||
progress: null
|
||||
progress: null,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
@ -81,15 +81,12 @@ module.exports = React.createClass({
|
|||
|
||||
if (!this.state.email) {
|
||||
this.showErrorDialog(_t('The email address linked to your account must be entered.'));
|
||||
}
|
||||
else if (!this.state.password || !this.state.password2) {
|
||||
} else if (!this.state.password || !this.state.password2) {
|
||||
this.showErrorDialog(_t('A new password must be entered.'));
|
||||
}
|
||||
else if (this.state.password !== this.state.password2) {
|
||||
} else if (this.state.password !== this.state.password2) {
|
||||
this.showErrorDialog(_t('New passwords must match each other.'));
|
||||
}
|
||||
else {
|
||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
} else {
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
Modal.createTrackedDialog('Forgot Password Warning', '', QuestionDialog, {
|
||||
title: _t('Warning!'),
|
||||
description:
|
||||
|
@ -99,7 +96,7 @@ module.exports = React.createClass({
|
|||
'end-to-end encryption keys on all devices, ' +
|
||||
'making encrypted chat history unreadable, ' +
|
||||
'unless you first export your room keys and re-import ' +
|
||||
'them afterwards. In future this will be improved.'
|
||||
'them afterwards. In future this will be improved.',
|
||||
) }
|
||||
</div>,
|
||||
button: _t('Continue'),
|
||||
|
@ -107,13 +104,13 @@ module.exports = React.createClass({
|
|||
<button className="mx_Dialog_primary"
|
||||
onClick={this._onExportE2eKeysClicked}>
|
||||
{ _t('Export E2E room keys') }
|
||||
</button>
|
||||
</button>,
|
||||
],
|
||||
onFinished: (confirmed) => {
|
||||
if (confirmed) {
|
||||
this.submitPasswordReset(
|
||||
this.state.enteredHomeserverUrl, this.state.enteredIdentityServerUrl,
|
||||
this.state.email, this.state.password
|
||||
this.state.email, this.state.password,
|
||||
);
|
||||
}
|
||||
},
|
||||
|
@ -133,7 +130,7 @@ module.exports = React.createClass({
|
|||
|
||||
onInputChanged: function(stateKey, ev) {
|
||||
this.setState({
|
||||
[stateKey]: ev.target.value
|
||||
[stateKey]: ev.target.value,
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -149,7 +146,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
showErrorDialog: function(body, title) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
Modal.createTrackedDialog('Forgot Password Error', '', ErrorDialog, {
|
||||
title: title,
|
||||
description: body,
|
||||
|
@ -157,37 +154,34 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var LoginHeader = sdk.getComponent("login.LoginHeader");
|
||||
var LoginFooter = sdk.getComponent("login.LoginFooter");
|
||||
var ServerConfig = sdk.getComponent("login.ServerConfig");
|
||||
var Spinner = sdk.getComponent("elements.Spinner");
|
||||
const LoginHeader = sdk.getComponent("login.LoginHeader");
|
||||
const LoginFooter = sdk.getComponent("login.LoginFooter");
|
||||
const ServerConfig = sdk.getComponent("login.ServerConfig");
|
||||
const Spinner = sdk.getComponent("elements.Spinner");
|
||||
|
||||
var resetPasswordJsx;
|
||||
let resetPasswordJsx;
|
||||
|
||||
if (this.state.progress === "sending_email") {
|
||||
resetPasswordJsx = <Spinner />;
|
||||
}
|
||||
else if (this.state.progress === "sent_email") {
|
||||
} else if (this.state.progress === "sent_email") {
|
||||
resetPasswordJsx = (
|
||||
<div>
|
||||
{ _t('An email has been sent to') } {this.state.email}. { _t("Once you've followed the link it contains, click below") }.
|
||||
{ _t('An email has been sent to') } { this.state.email }. { _t("Once you've followed the link it contains, click below") }.
|
||||
<br />
|
||||
<input className="mx_Login_submit" type="button" onClick={this.onVerify}
|
||||
value={ _t('I have verified my email address') } />
|
||||
value={_t('I have verified my email address')} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
else if (this.state.progress === "complete") {
|
||||
} else if (this.state.progress === "complete") {
|
||||
resetPasswordJsx = (
|
||||
<div>
|
||||
<p>{ _t('Your password has been reset') }.</p>
|
||||
<p>{ _t('You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device') }.</p>
|
||||
<input className="mx_Login_submit" type="button" onClick={this.props.onComplete}
|
||||
value={ _t('Return to login screen') } />
|
||||
value={_t('Return to login screen')} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
resetPasswordJsx = (
|
||||
<div>
|
||||
<div className="mx_Login_prompt">
|
||||
|
@ -199,21 +193,21 @@ module.exports = React.createClass({
|
|||
name="reset_email" // define a name so browser's password autofill gets less confused
|
||||
value={this.state.email}
|
||||
onChange={this.onInputChanged.bind(this, "email")}
|
||||
placeholder={ _t('Email address') } autoFocus />
|
||||
placeholder={_t('Email address')} autoFocus />
|
||||
<br />
|
||||
<input className="mx_Login_field" ref="pass" type="password"
|
||||
name="reset_password"
|
||||
value={this.state.password}
|
||||
onChange={this.onInputChanged.bind(this, "password")}
|
||||
placeholder={ _t('New password') } />
|
||||
placeholder={_t('New password')} />
|
||||
<br />
|
||||
<input className="mx_Login_field" ref="pass" type="password"
|
||||
name="reset_password_confirm"
|
||||
value={this.state.password2}
|
||||
onChange={this.onInputChanged.bind(this, "password2")}
|
||||
placeholder={ _t('Confirm your new password') } />
|
||||
placeholder={_t('Confirm your new password')} />
|
||||
<br />
|
||||
<input className="mx_Login_submit" type="submit" value={ _t('Send Reset Email') } />
|
||||
<input className="mx_Login_submit" type="submit" value={_t('Send Reset Email')} />
|
||||
</form>
|
||||
<ServerConfig ref="serverConfig"
|
||||
withToggleButton={true}
|
||||
|
@ -222,11 +216,11 @@ module.exports = React.createClass({
|
|||
customHsUrl={this.props.customHsUrl}
|
||||
customIsUrl={this.props.customIsUrl}
|
||||
onServerConfigChange={this.onServerConfigChange}
|
||||
delayTimeMs={0}/>
|
||||
delayTimeMs={0} />
|
||||
<div className="mx_Login_error">
|
||||
</div>
|
||||
<a className="mx_Login_create" onClick={this.props.onLoginClick} href="#">
|
||||
{_t('Return to login screen')}
|
||||
{ _t('Return to login screen') }
|
||||
</a>
|
||||
<a className="mx_Login_create" onClick={this.props.onRegisterClick} href="#">
|
||||
{ _t('Create an account') }
|
||||
|
@ -242,9 +236,9 @@ module.exports = React.createClass({
|
|||
<div className="mx_Login">
|
||||
<div className="mx_Login_box">
|
||||
<LoginHeader />
|
||||
{resetPasswordJsx}
|
||||
{ resetPasswordJsx }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -134,7 +134,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_onLoginAsGuestClick: function() {
|
||||
var self = this;
|
||||
const self = this;
|
||||
self.setState({
|
||||
busy: true,
|
||||
errorText: null,
|
||||
|
@ -156,7 +156,7 @@ module.exports = React.createClass({
|
|||
});
|
||||
}).finally(function() {
|
||||
self.setState({
|
||||
busy: false
|
||||
busy: false,
|
||||
});
|
||||
}).done();
|
||||
},
|
||||
|
@ -183,8 +183,8 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onServerConfigChange: function(config) {
|
||||
var self = this;
|
||||
let newState = {
|
||||
const self = this;
|
||||
const newState = {
|
||||
errorText: null, // reset err messages
|
||||
};
|
||||
if (config.hsUrl !== undefined) {
|
||||
|
@ -199,13 +199,13 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_initLoginLogic: function(hsUrl, isUrl) {
|
||||
var self = this;
|
||||
const self = this;
|
||||
hsUrl = hsUrl || this.state.enteredHomeserverUrl;
|
||||
isUrl = isUrl || this.state.enteredIdentityServerUrl;
|
||||
|
||||
var fallbackHsUrl = hsUrl == this.props.defaultHsUrl ? this.props.fallbackHsUrl : null;
|
||||
const fallbackHsUrl = hsUrl == this.props.defaultHsUrl ? this.props.fallbackHsUrl : null;
|
||||
|
||||
var loginLogic = new Login(hsUrl, isUrl, fallbackHsUrl, {
|
||||
const loginLogic = new Login(hsUrl, isUrl, fallbackHsUrl, {
|
||||
defaultDeviceDisplayName: this.props.defaultDeviceDisplayName,
|
||||
});
|
||||
this._loginLogic = loginLogic;
|
||||
|
@ -259,15 +259,15 @@ module.exports = React.createClass({
|
|||
{ _tJsx("Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. " +
|
||||
"Either use HTTPS or <a>enable unsafe scripts</a>.",
|
||||
/<a>(.*?)<\/a>/,
|
||||
(sub) => { return <a href="https://www.google.com/search?&q=enable%20unsafe%20scripts">{ sub }</a>; }
|
||||
)}
|
||||
(sub) => { return <a href="https://www.google.com/search?&q=enable%20unsafe%20scripts">{ sub }</a>; },
|
||||
) }
|
||||
</span>;
|
||||
} else {
|
||||
errorText = <span>
|
||||
{ _tJsx("Can't connect to homeserver - please check your connectivity, ensure your <a>homeserver's SSL certificate</a> is trusted, and that a browser extension is not blocking requests.",
|
||||
/<a>(.*?)<\/a>/,
|
||||
(sub) => { return <a href={this.state.enteredHomeserverUrl}>{ sub }</a>; }
|
||||
)}
|
||||
(sub) => { return <a href={this.state.enteredHomeserverUrl}>{ sub }</a>; },
|
||||
) }
|
||||
</span>;
|
||||
}
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
return (
|
||||
<div>
|
||||
{ _t('Sorry, this homeserver is using a login which is not recognised ')}({step})
|
||||
{ _t('Sorry, this homeserver is using a login which is not recognised ') }({ step })
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -334,19 +334,19 @@ module.exports = React.createClass({
|
|||
const ServerConfig = sdk.getComponent("login.ServerConfig");
|
||||
const loader = this.state.busy ? <div className="mx_Login_loader"><Loader /></div> : null;
|
||||
|
||||
var loginAsGuestJsx;
|
||||
let loginAsGuestJsx;
|
||||
if (this.props.enableGuest) {
|
||||
loginAsGuestJsx =
|
||||
<a className="mx_Login_create" onClick={this._onLoginAsGuestClick} href="#">
|
||||
{ _t('Login as guest')}
|
||||
{ _t('Login as guest') }
|
||||
</a>;
|
||||
}
|
||||
|
||||
var returnToAppJsx;
|
||||
let returnToAppJsx;
|
||||
if (this.props.onCancelClick) {
|
||||
returnToAppJsx =
|
||||
<a className="mx_Login_create" onClick={this.props.onCancelClick} href="#">
|
||||
{ _t('Return to app')}
|
||||
{ _t('Return to app') }
|
||||
</a>;
|
||||
}
|
||||
|
||||
|
@ -355,7 +355,7 @@ module.exports = React.createClass({
|
|||
<div className="mx_Login_box">
|
||||
<LoginHeader />
|
||||
<div>
|
||||
<h2>{ _t('Sign in')}
|
||||
<h2>{ _t('Sign in') }
|
||||
{ loader }
|
||||
</h2>
|
||||
{ this.componentForStep(this.state.currentFlow) }
|
||||
|
@ -366,12 +366,12 @@ module.exports = React.createClass({
|
|||
defaultHsUrl={this.props.defaultHsUrl}
|
||||
defaultIsUrl={this.props.defaultIsUrl}
|
||||
onServerConfigChange={this.onServerConfigChange}
|
||||
delayTimeMs={1000}/>
|
||||
delayTimeMs={1000} />
|
||||
<div className="mx_Login_error">
|
||||
{ this.state.errorText }
|
||||
</div>
|
||||
<a className="mx_Login_create" onClick={this.props.onRegisterClick} href="#">
|
||||
{ _t('Create an account')}
|
||||
{ _t('Create an account') }
|
||||
</a>
|
||||
{ loginAsGuestJsx }
|
||||
{ returnToAppJsx }
|
||||
|
@ -381,5 +381,5 @@ module.exports = React.createClass({
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -25,14 +25,14 @@ module.exports = React.createClass({
|
|||
displayName: 'PostRegistration',
|
||||
|
||||
propTypes: {
|
||||
onComplete: React.PropTypes.func.isRequired
|
||||
onComplete: React.PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
avatarUrl: null,
|
||||
errorString: null,
|
||||
busy: false
|
||||
busy: false,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -40,26 +40,26 @@ module.exports = React.createClass({
|
|||
// There is some assymetry between ChangeDisplayName and ChangeAvatar,
|
||||
// as ChangeDisplayName will auto-get the name but ChangeAvatar expects
|
||||
// the URL to be passed to you (because it's also used for room avatars).
|
||||
var cli = MatrixClientPeg.get();
|
||||
const cli = MatrixClientPeg.get();
|
||||
this.setState({busy: true});
|
||||
var self = this;
|
||||
const self = this;
|
||||
cli.getProfileInfo(cli.credentials.userId).done(function(result) {
|
||||
self.setState({
|
||||
avatarUrl: MatrixClientPeg.get().mxcUrlToHttp(result.avatar_url),
|
||||
busy: false
|
||||
busy: false,
|
||||
});
|
||||
}, function(error) {
|
||||
self.setState({
|
||||
errorString: _t("Failed to fetch avatar URL"),
|
||||
busy: false
|
||||
busy: false,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var ChangeDisplayName = sdk.getComponent('settings.ChangeDisplayName');
|
||||
var ChangeAvatar = sdk.getComponent('settings.ChangeAvatar');
|
||||
var LoginHeader = sdk.getComponent('login.LoginHeader');
|
||||
const ChangeDisplayName = sdk.getComponent('settings.ChangeDisplayName');
|
||||
const ChangeAvatar = sdk.getComponent('settings.ChangeAvatar');
|
||||
const LoginHeader = sdk.getComponent('login.LoginHeader');
|
||||
return (
|
||||
<div className="mx_Login">
|
||||
<div className="mx_Login_box">
|
||||
|
@ -71,10 +71,10 @@ module.exports = React.createClass({
|
|||
<ChangeAvatar
|
||||
initialAvatarUrl={this.state.avatarUrl} />
|
||||
<button onClick={this.props.onComplete}>{ _t('Continue') }</button>
|
||||
{this.state.errorString}
|
||||
{ this.state.errorString }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -57,7 +57,7 @@ module.exports = React.createClass({
|
|||
|
||||
// registration shouldn't know or care how login is done.
|
||||
onLoginClick: React.PropTypes.func.isRequired,
|
||||
onCancelClick: React.PropTypes.func
|
||||
onCancelClick: React.PropTypes.func,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
|
@ -121,7 +121,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onServerConfigChange: function(config) {
|
||||
let newState = {};
|
||||
const newState = {};
|
||||
if (config.hsUrl !== undefined) {
|
||||
newState.hsUrl = config.hsUrl;
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ module.exports = React.createClass({
|
|||
|
||||
this._rtsClient.getTeam(teamToken).then((team) => {
|
||||
console.log(
|
||||
`User successfully registered with team ${team.name}`
|
||||
`User successfully registered with team ${team.name}`,
|
||||
);
|
||||
if (!team.rooms) {
|
||||
return;
|
||||
|
@ -223,7 +223,7 @@ module.exports = React.createClass({
|
|||
deviceId: response.device_id,
|
||||
homeserverUrl: this._matrixClient.getHomeserverUrl(),
|
||||
identityServerUrl: this._matrixClient.getIdentityServerUrl(),
|
||||
accessToken: response.access_token
|
||||
accessToken: response.access_token,
|
||||
}, teamToken);
|
||||
}).then((cli) => {
|
||||
return this._setupPushers(cli);
|
||||
|
@ -253,7 +253,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onFormValidationFailed: function(errCode) {
|
||||
var errMsg;
|
||||
let errMsg;
|
||||
switch (errCode) {
|
||||
case "RegistrationForm.ERR_PASSWORD_MISSING":
|
||||
errMsg = _t('Missing password.');
|
||||
|
@ -282,7 +282,7 @@ module.exports = React.createClass({
|
|||
break;
|
||||
}
|
||||
this.setState({
|
||||
errorText: errMsg
|
||||
errorText: errMsg,
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -316,7 +316,7 @@ module.exports = React.createClass({
|
|||
emailAddress: this.state.formVals.email,
|
||||
phoneCountry: this.state.formVals.phoneCountry,
|
||||
phoneNumber: this.state.formVals.phoneNumber,
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
|
@ -346,7 +346,7 @@ module.exports = React.createClass({
|
|||
} else {
|
||||
let errorSection;
|
||||
if (this.state.errorText) {
|
||||
errorSection = <div className="mx_Login_error">{this.state.errorText}</div>;
|
||||
errorSection = <div className="mx_Login_error">{ this.state.errorText }</div>;
|
||||
}
|
||||
registerBody = (
|
||||
<div>
|
||||
|
@ -362,7 +362,7 @@ module.exports = React.createClass({
|
|||
onRegisterClick={this.onFormSubmit}
|
||||
onTeamSelected={this.onTeamSelected}
|
||||
/>
|
||||
{errorSection}
|
||||
{ errorSection }
|
||||
<ServerConfig ref="serverConfig"
|
||||
withToggleButton={true}
|
||||
customHsUrl={this.props.customHsUrl}
|
||||
|
@ -380,7 +380,7 @@ module.exports = React.createClass({
|
|||
if (this.props.onCancelClick) {
|
||||
returnToAppJsx = (
|
||||
<a className="mx_Login_create" onClick={this.props.onCancelClick} href="#">
|
||||
{_t('Return to app')}
|
||||
{ _t('Return to app') }
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
@ -393,15 +393,15 @@ module.exports = React.createClass({
|
|||
this.state.teamSelected.domain + "/icon.png" :
|
||||
null}
|
||||
/>
|
||||
<h2>{_t('Create an account')}</h2>
|
||||
{registerBody}
|
||||
<h2>{ _t('Create an account') }</h2>
|
||||
{ registerBody }
|
||||
<a className="mx_Login_create" onClick={this.props.onLoginClick} href="#">
|
||||
{_t('I already have an account')}
|
||||
{ _t('I already have an account') }
|
||||
</a>
|
||||
{returnToAppJsx}
|
||||
{ returnToAppJsx }
|
||||
<LoginFooter />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -32,7 +32,7 @@ module.exports = React.createClass({
|
|||
height: React.PropTypes.number,
|
||||
// XXX resizeMethod not actually used.
|
||||
resizeMethod: React.PropTypes.string,
|
||||
defaultToInitialLetter: React.PropTypes.bool // true to add default url
|
||||
defaultToInitialLetter: React.PropTypes.bool, // true to add default url
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
|
@ -40,7 +40,7 @@ module.exports = React.createClass({
|
|||
width: 40,
|
||||
height: 40,
|
||||
resizeMethod: 'crop',
|
||||
defaultToInitialLetter: true
|
||||
defaultToInitialLetter: true,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -50,15 +50,14 @@ module.exports = React.createClass({
|
|||
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
// work out if we need to call setState (if the image URLs array has changed)
|
||||
var newState = this._getState(nextProps);
|
||||
var newImageUrls = newState.imageUrls;
|
||||
var oldImageUrls = this.state.imageUrls;
|
||||
const newState = this._getState(nextProps);
|
||||
const newImageUrls = newState.imageUrls;
|
||||
const oldImageUrls = this.state.imageUrls;
|
||||
if (newImageUrls.length !== oldImageUrls.length) {
|
||||
this.setState(newState); // detected a new entry
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// check each one to see if they are the same
|
||||
for (var i = 0; i < newImageUrls.length; i++) {
|
||||
for (let i = 0; i < newImageUrls.length; i++) {
|
||||
if (oldImageUrls[i] !== newImageUrls[i]) {
|
||||
this.setState(newState); // detected a diff
|
||||
break;
|
||||
|
@ -71,31 +70,31 @@ module.exports = React.createClass({
|
|||
// work out the full set of urls to try to load. This is formed like so:
|
||||
// imageUrls: [ props.url, props.urls, default image ]
|
||||
|
||||
var urls = props.urls || [];
|
||||
const urls = props.urls || [];
|
||||
if (props.url) {
|
||||
urls.unshift(props.url); // put in urls[0]
|
||||
}
|
||||
|
||||
var defaultImageUrl = null;
|
||||
let defaultImageUrl = null;
|
||||
if (props.defaultToInitialLetter) {
|
||||
defaultImageUrl = AvatarLogic.defaultAvatarUrlForString(
|
||||
props.idName || props.name
|
||||
props.idName || props.name,
|
||||
);
|
||||
urls.push(defaultImageUrl); // lowest priority
|
||||
}
|
||||
return {
|
||||
imageUrls: urls,
|
||||
defaultImageUrl: defaultImageUrl,
|
||||
urlsIndex: 0
|
||||
urlsIndex: 0,
|
||||
};
|
||||
},
|
||||
|
||||
onError: function(ev) {
|
||||
var nextIndex = this.state.urlsIndex + 1;
|
||||
const nextIndex = this.state.urlsIndex + 1;
|
||||
if (nextIndex < this.state.imageUrls.length) {
|
||||
// try the next one
|
||||
this.setState({
|
||||
urlsIndex: nextIndex
|
||||
urlsIndex: nextIndex,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -109,32 +108,32 @@ module.exports = React.createClass({
|
|||
return undefined;
|
||||
}
|
||||
|
||||
var idx = 0;
|
||||
var initial = name[0];
|
||||
let idx = 0;
|
||||
const initial = name[0];
|
||||
if ((initial === '@' || initial === '#') && name[1]) {
|
||||
idx++;
|
||||
}
|
||||
|
||||
// string.codePointAt(0) would do this, but that isn't supported by
|
||||
// some browsers (notably PhantomJS).
|
||||
var chars = 1;
|
||||
var first = name.charCodeAt(idx);
|
||||
let chars = 1;
|
||||
const first = name.charCodeAt(idx);
|
||||
|
||||
// check if it’s the start of a surrogate pair
|
||||
if (first >= 0xD800 && first <= 0xDBFF && name[idx+1]) {
|
||||
var second = name.charCodeAt(idx+1);
|
||||
const second = name.charCodeAt(idx+1);
|
||||
if (second >= 0xDC00 && second <= 0xDFFF) {
|
||||
chars++;
|
||||
}
|
||||
}
|
||||
|
||||
var firstChar = name.substring(idx, idx+chars);
|
||||
const firstChar = name.substring(idx, idx+chars);
|
||||
return firstChar.toUpperCase();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||
var imageUrl = this.state.imageUrls[this.state.urlsIndex];
|
||||
const imageUrl = this.state.imageUrls[this.state.urlsIndex];
|
||||
|
||||
const {
|
||||
name, idName, title, url, urls, width, height, resizeMethod,
|
||||
|
@ -150,7 +149,7 @@ module.exports = React.createClass({
|
|||
width: width + "px",
|
||||
lineHeight: height + "px" }}
|
||||
>
|
||||
{initialLetter}
|
||||
{ initialLetter }
|
||||
</EmojiText>
|
||||
);
|
||||
const imgNode = (
|
||||
|
@ -163,15 +162,15 @@ module.exports = React.createClass({
|
|||
<AccessibleButton element='span' className="mx_BaseAvatar"
|
||||
onClick={onClick} {...otherProps}
|
||||
>
|
||||
{textNode}
|
||||
{imgNode}
|
||||
{ textNode }
|
||||
{ imgNode }
|
||||
</AccessibleButton>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<span className="mx_BaseAvatar" {...otherProps}>
|
||||
{textNode}
|
||||
{imgNode}
|
||||
{ textNode }
|
||||
{ imgNode }
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
@ -196,5 +195,5 @@ module.exports = React.createClass({
|
|||
{...otherProps} />
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -16,9 +16,9 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var Avatar = require('../../../Avatar');
|
||||
var sdk = require("../../../index");
|
||||
const React = require('react');
|
||||
const Avatar = require('../../../Avatar');
|
||||
const sdk = require("../../../index");
|
||||
const dispatcher = require("../../../dispatcher");
|
||||
|
||||
module.exports = React.createClass({
|
||||
|
@ -63,14 +63,14 @@ module.exports = React.createClass({
|
|||
imageUrl: Avatar.avatarUrlForMember(props.member,
|
||||
props.width,
|
||||
props.height,
|
||||
props.resizeMethod)
|
||||
props.resizeMethod),
|
||||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
||||
const BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
||||
|
||||
var {member, onClick, viewUserOnClick, ...otherProps} = this.props;
|
||||
let {member, onClick, viewUserOnClick, ...otherProps} = this.props;
|
||||
|
||||
if (viewUserOnClick) {
|
||||
onClick = () => {
|
||||
|
@ -83,7 +83,7 @@ module.exports = React.createClass({
|
|||
|
||||
return (
|
||||
<BaseAvatar {...otherProps} name={this.state.name} title={this.state.title}
|
||||
idName={member.userId} url={this.state.imageUrl} onClick={onClick}/>
|
||||
idName={member.userId} url={this.state.imageUrl} onClick={onClick} />
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -36,7 +36,7 @@ module.exports = React.createClass({
|
|||
|
||||
render: function() {
|
||||
return (
|
||||
<button className="mx_CreateRoomButton" onClick={this.onClick}>{_t("Create Room")}</button>
|
||||
<button className="mx_CreateRoomButton" onClick={this.onClick}>{ _t("Create Room") }</button>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -16,10 +16,10 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
const React = require('react');
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
var Presets = {
|
||||
const Presets = {
|
||||
PrivateChat: "private_chat",
|
||||
PublicChat: "public_chat",
|
||||
Custom: "custom",
|
||||
|
@ -29,7 +29,7 @@ module.exports = React.createClass({
|
|||
displayName: 'CreateRoomPresets',
|
||||
propTypes: {
|
||||
onChange: React.PropTypes.func,
|
||||
preset: React.PropTypes.string
|
||||
preset: React.PropTypes.string,
|
||||
},
|
||||
|
||||
Presets: Presets,
|
||||
|
@ -47,10 +47,10 @@ module.exports = React.createClass({
|
|||
render: function() {
|
||||
return (
|
||||
<select className="mx_Presets" onChange={this.onValueChanged} value={this.props.preset}>
|
||||
<option value={this.Presets.PrivateChat}>{_t("Private Chat")}</option>
|
||||
<option value={this.Presets.PublicChat}>{_t("Public Chat")}</option>
|
||||
<option value={this.Presets.Custom}>{_t("Custom")}</option>
|
||||
<option value={this.Presets.PrivateChat}>{ _t("Private Chat") }</option>
|
||||
<option value={this.Presets.PublicChat}>{ _t("Public Chat") }</option>
|
||||
<option value={this.Presets.Custom}>{ _t("Custom") }</option>
|
||||
</select>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
var React = require('react');
|
||||
const React = require('react');
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
|
@ -35,10 +35,10 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
getAliasLocalpart: function() {
|
||||
var room_alias = this.props.alias;
|
||||
let room_alias = this.props.alias;
|
||||
|
||||
if (room_alias && this.props.homeserver) {
|
||||
var suffix = ":" + this.props.homeserver;
|
||||
const suffix = ":" + this.props.homeserver;
|
||||
if (room_alias.startsWith("#") && room_alias.endsWith(suffix)) {
|
||||
room_alias = room_alias.slice(1, -suffix.length);
|
||||
}
|
||||
|
@ -52,22 +52,22 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onFocus: function(ev) {
|
||||
var target = ev.target;
|
||||
var curr_val = ev.target.value;
|
||||
const target = ev.target;
|
||||
const curr_val = ev.target.value;
|
||||
|
||||
if (this.props.homeserver) {
|
||||
if (curr_val == "") {
|
||||
var self = this;
|
||||
const self = this;
|
||||
setTimeout(function() {
|
||||
target.value = "#:" + self.props.homeserver;
|
||||
target.setSelectionRange(1, 1);
|
||||
}, 0);
|
||||
} else {
|
||||
var suffix = ":" + this.props.homeserver;
|
||||
const suffix = ":" + this.props.homeserver;
|
||||
setTimeout(function() {
|
||||
target.setSelectionRange(
|
||||
curr_val.startsWith("#") ? 1 : 0,
|
||||
curr_val.endsWith(suffix) ? (target.value.length - suffix.length) : target.value.length
|
||||
curr_val.endsWith(suffix) ? (target.value.length - suffix.length) : target.value.length,
|
||||
);
|
||||
}, 0);
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onBlur: function(ev) {
|
||||
var curr_val = ev.target.value;
|
||||
const curr_val = ev.target.value;
|
||||
|
||||
if (this.props.homeserver) {
|
||||
if (curr_val == "#:" + this.props.homeserver) {
|
||||
|
@ -84,8 +84,8 @@ module.exports = React.createClass({
|
|||
}
|
||||
|
||||
if (curr_val != "") {
|
||||
var new_val = ev.target.value;
|
||||
var suffix = ":" + this.props.homeserver;
|
||||
let new_val = ev.target.value;
|
||||
const suffix = ":" + this.props.homeserver;
|
||||
if (!curr_val.startsWith("#")) new_val = "#" + new_val;
|
||||
if (!curr_val.endsWith(suffix)) new_val = new_val + suffix;
|
||||
ev.target.value = new_val;
|
||||
|
@ -97,7 +97,7 @@ module.exports = React.createClass({
|
|||
return (
|
||||
<input type="text" className="mx_RoomAlias" placeholder={_t("Alias (optional)")}
|
||||
onChange={this.onValueChanged} onFocus={this.onFocus} onBlur={this.onBlur}
|
||||
value={this.props.alias}/>
|
||||
value={this.props.alias} />
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -155,7 +155,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
|
|||
width={48} height={48}
|
||||
/>
|
||||
<div className="mx_ChatCreateOrReuseDialog_profile_name">
|
||||
{this.state.profile.displayName || this.props.userId}
|
||||
{ this.state.profile.displayName || this.props.userId }
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
|
|||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||
return (
|
||||
<BaseDialog className='mx_ChatCreateOrReuseDialog'
|
||||
onFinished={ this.props.onFinished.bind(false) }
|
||||
onFinished={this.props.onFinished.bind(false)}
|
||||
title={title}
|
||||
>
|
||||
{ content }
|
||||
|
|
|
@ -83,7 +83,7 @@ export default class DeactivateAccountDialog extends React.Component {
|
|||
let error = null;
|
||||
if (this.state.errStr) {
|
||||
error = <div className="error">
|
||||
{this.state.errStr}
|
||||
{ this.state.errStr }
|
||||
</div>;
|
||||
passwordBoxClass = 'error';
|
||||
}
|
||||
|
@ -94,30 +94,30 @@ export default class DeactivateAccountDialog extends React.Component {
|
|||
let cancelButton = null;
|
||||
if (!this.state.busy) {
|
||||
cancelButton = <button onClick={this._onCancel} autoFocus={true}>
|
||||
{_t("Cancel")}
|
||||
{ _t("Cancel") }
|
||||
</button>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_DeactivateAccountDialog">
|
||||
<div className="mx_Dialog_title danger">
|
||||
{_t("Deactivate Account")}
|
||||
{ _t("Deactivate Account") }
|
||||
</div>
|
||||
<div className="mx_Dialog_content">
|
||||
<p>{_t("This will make your account permanently unusable. You will not be able to re-register the same user ID.")}</p>
|
||||
<p>{ _t("This will make your account permanently unusable. You will not be able to re-register the same user ID.") }</p>
|
||||
|
||||
<p>{_t("This action is irreversible.")}</p>
|
||||
<p>{ _t("This action is irreversible.") }</p>
|
||||
|
||||
<p>{_t("To continue, please enter your password.")}</p>
|
||||
<p>{ _t("To continue, please enter your password.") }</p>
|
||||
|
||||
<p>{_t("Password")}:</p>
|
||||
<p>{ _t("Password") }:</p>
|
||||
<input
|
||||
type="password"
|
||||
onChange={this._onPasswordFieldChange}
|
||||
ref={(e) => {this._passwordField = e;}}
|
||||
className={passwordBoxClass}
|
||||
/>
|
||||
{error}
|
||||
{ error }
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button
|
||||
|
@ -125,10 +125,10 @@ export default class DeactivateAccountDialog extends React.Component {
|
|||
onClick={this._onOk}
|
||||
disabled={!okEnabled}
|
||||
>
|
||||
{okLabel}
|
||||
{ okLabel }
|
||||
</button>
|
||||
|
||||
{cancelButton}
|
||||
{ cancelButton }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -48,7 +48,7 @@ export default React.createClass({
|
|||
getInitialState: function() {
|
||||
return {
|
||||
authError: null,
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
_onAuthFinished: function(success, result) {
|
||||
|
@ -73,12 +73,12 @@ export default React.createClass({
|
|||
if (this.state.authError) {
|
||||
content = (
|
||||
<div>
|
||||
<div>{this.state.authError.message || this.state.authError.toString()}</div>
|
||||
<div>{ this.state.authError.message || this.state.authError.toString() }</div>
|
||||
<br />
|
||||
<AccessibleButton onClick={this._onDismissClick}
|
||||
className="mx_UserSettings_button"
|
||||
>
|
||||
{_t("Dismiss")}
|
||||
{ _t("Dismiss") }
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
);
|
||||
|
@ -100,7 +100,7 @@ export default React.createClass({
|
|||
onFinished={this.props.onFinished}
|
||||
title={this.state.authError ? 'Error' : (this.props.title || _t('Authentication'))}
|
||||
>
|
||||
{content}
|
||||
{ content }
|
||||
</BaseDialog>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -28,9 +28,9 @@ function DeviceListEntry(props) {
|
|||
|
||||
return (
|
||||
<li>
|
||||
<DeviceVerifyButtons device={ device } userId={ userId } />
|
||||
<DeviceVerifyButtons device={device} userId={userId} />
|
||||
{ device.deviceId }
|
||||
<br/>
|
||||
<br />
|
||||
{ device.getDisplayName() }
|
||||
</li>
|
||||
);
|
||||
|
@ -48,13 +48,13 @@ function UserUnknownDeviceList(props) {
|
|||
const {userId, userDevices} = props;
|
||||
|
||||
const deviceListEntries = Object.keys(userDevices).map((deviceId) =>
|
||||
<DeviceListEntry key={ deviceId } userId={ userId }
|
||||
device={ userDevices[deviceId] } />,
|
||||
<DeviceListEntry key={deviceId} userId={userId}
|
||||
device={userDevices[deviceId]} />,
|
||||
);
|
||||
|
||||
return (
|
||||
<ul className="mx_UnknownDeviceDialog_deviceList">
|
||||
{deviceListEntries}
|
||||
{ deviceListEntries }
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
@ -71,13 +71,13 @@ function UnknownDeviceList(props) {
|
|||
const {devices} = props;
|
||||
|
||||
const userListEntries = Object.keys(devices).map((userId) =>
|
||||
<li key={ userId }>
|
||||
<li key={userId}>
|
||||
<p>{ userId }:</p>
|
||||
<UserUnknownDeviceList userId={ userId } userDevices={ devices[userId] } />
|
||||
<UserUnknownDeviceList userId={userId} userDevices={devices[userId]} />
|
||||
</li>,
|
||||
);
|
||||
|
||||
return <ul>{userListEntries}</ul>;
|
||||
return <ul>{ userListEntries }</ul>;
|
||||
}
|
||||
|
||||
UnknownDeviceList.propTypes = {
|
||||
|
@ -120,17 +120,17 @@ export default React.createClass({
|
|||
if (blacklistUnverified) {
|
||||
warning = (
|
||||
<h4>
|
||||
{_t("You are currently blacklisting unverified devices; to send " +
|
||||
"messages to these devices you must verify them.")}
|
||||
{ _t("You are currently blacklisting unverified devices; to send " +
|
||||
"messages to these devices you must verify them.") }
|
||||
</h4>
|
||||
);
|
||||
} else {
|
||||
warning = (
|
||||
<div>
|
||||
<p>
|
||||
{_t("We recommend you go through the verification process " +
|
||||
{ _t("We recommend you go through the verification process " +
|
||||
"for each device to confirm they belong to their legitimate owner, " +
|
||||
"but you can resend the message without verifying if you prefer.")}
|
||||
"but you can resend the message without verifying if you prefer.") }
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
@ -149,22 +149,22 @@ export default React.createClass({
|
|||
>
|
||||
<GeminiScrollbar autoshow={false} className="mx_Dialog_content">
|
||||
<h4>
|
||||
{_t('"%(RoomName)s" contains devices that you haven\'t seen before.', {RoomName: this.props.room.name})}
|
||||
{ _t('"%(RoomName)s" contains devices that you haven\'t seen before.', {RoomName: this.props.room.name}) }
|
||||
</h4>
|
||||
{ warning }
|
||||
{_t("Unknown devices")}:
|
||||
{ _t("Unknown devices") }:
|
||||
|
||||
<UnknownDeviceList devices={this.props.devices} />
|
||||
</GeminiScrollbar>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button className="mx_Dialog_primary" autoFocus={ true }
|
||||
<button className="mx_Dialog_primary" autoFocus={true}
|
||||
onClick={() => {
|
||||
this.props.onFinished();
|
||||
Resend.resendUnsentEvents(this.props.room);
|
||||
}}>
|
||||
{_t("Send anyway")}
|
||||
{ _t("Send anyway") }
|
||||
</button>
|
||||
<button className="mx_Dialog_primary" autoFocus={ true }
|
||||
<button className="mx_Dialog_primary" autoFocus={true}
|
||||
onClick={() => {
|
||||
// XXX: temporary logging to try to diagnose
|
||||
// https://github.com/vector-im/riot-web/issues/3148
|
||||
|
|
|
@ -79,8 +79,8 @@ export default React.createClass({
|
|||
onMouseLeave={this._onMouseLeave}
|
||||
>
|
||||
<TintableSvg src={this.props.iconPath} width={this.props.size} height={this.props.size} />
|
||||
{tooltip}
|
||||
{ tooltip }
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -46,8 +46,8 @@ export default React.createClass({
|
|||
|
||||
componentWillReceiveProps: function(props) {
|
||||
// Make sure the selected item isn't outside the list bounds
|
||||
var selected = this.state.selected;
|
||||
var maxSelected = this._maxSelected(props.addressList);
|
||||
const selected = this.state.selected;
|
||||
const maxSelected = this._maxSelected(props.addressList);
|
||||
if (selected > maxSelected) {
|
||||
this.setState({ selected: maxSelected });
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ export default React.createClass({
|
|||
// As the user scrolls with the arrow keys keep the selected item
|
||||
// at the top of the window.
|
||||
if (this.scrollElement && this.props.addressList.length > 0 && !this.state.hover) {
|
||||
var elementHeight = this.addressListElement.getBoundingClientRect().height;
|
||||
const elementHeight = this.addressListElement.getBoundingClientRect().height;
|
||||
this.scrollElement.scrollTop = (this.state.selected * elementHeight) - elementHeight;
|
||||
}
|
||||
},
|
||||
|
@ -75,7 +75,7 @@ export default React.createClass({
|
|||
if (this.state.selected > 0) {
|
||||
this.setState({
|
||||
selected: this.state.selected - 1,
|
||||
hover : false,
|
||||
hover: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -84,7 +84,7 @@ export default React.createClass({
|
|||
if (this.state.selected < this._maxSelected(this.props.addressList)) {
|
||||
this.setState({
|
||||
selected: this.state.selected + 1,
|
||||
hover : false,
|
||||
hover: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -105,7 +105,7 @@ export default React.createClass({
|
|||
},
|
||||
|
||||
onMouseLeave: function() {
|
||||
this.setState({ hover : false });
|
||||
this.setState({ hover: false });
|
||||
},
|
||||
|
||||
selectAddress: function(index) {
|
||||
|
@ -117,15 +117,15 @@ export default React.createClass({
|
|||
},
|
||||
|
||||
createAddressListTiles: function() {
|
||||
var self = this;
|
||||
var AddressTile = sdk.getComponent("elements.AddressTile");
|
||||
var maxSelected = this._maxSelected(this.props.addressList);
|
||||
var addressList = [];
|
||||
const self = this;
|
||||
const AddressTile = sdk.getComponent("elements.AddressTile");
|
||||
const maxSelected = this._maxSelected(this.props.addressList);
|
||||
const addressList = [];
|
||||
|
||||
// Only create the address elements if there are address
|
||||
if (this.props.addressList.length > 0) {
|
||||
for (var i = 0; i <= maxSelected; i++) {
|
||||
var classes = classNames({
|
||||
for (let i = 0; i <= maxSelected; i++) {
|
||||
const classes = classNames({
|
||||
"mx_AddressSelector_addressListElement": true,
|
||||
"mx_AddressSelector_selected": this.state.selected === i,
|
||||
});
|
||||
|
@ -143,7 +143,7 @@ export default React.createClass({
|
|||
ref={(ref) => { this.addressListElement = ref; }}
|
||||
>
|
||||
<AddressTile address={this.props.addressList[i]} justified={true} networkName="vector" networkUrl="img/search-icon-vector.svg" />
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -151,13 +151,13 @@ export default React.createClass({
|
|||
},
|
||||
|
||||
_maxSelected: function(list) {
|
||||
var listSize = list.length === 0 ? 0 : list.length - 1;
|
||||
var maxSelected = listSize > (this.props.truncateAt - 1) ? (this.props.truncateAt - 1) : listSize;
|
||||
const listSize = list.length === 0 ? 0 : list.length - 1;
|
||||
const maxSelected = listSize > (this.props.truncateAt - 1) ? (this.props.truncateAt - 1) : listSize;
|
||||
return maxSelected;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var classes = classNames({
|
||||
const classes = classNames({
|
||||
"mx_AddressSelector": true,
|
||||
"mx_AddressSelector_empty": this.props.addressList.length === 0,
|
||||
});
|
||||
|
@ -168,5 +168,5 @@ export default React.createClass({
|
|||
{ this.createAddressListTiles() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -107,24 +107,24 @@ export default React.createClass({
|
|||
|
||||
let nameNode = null;
|
||||
if (address.displayName) {
|
||||
nameNode = <div className={nameClasses}>{ address.displayName }</div>
|
||||
nameNode = <div className={nameClasses}>{ address.displayName }</div>;
|
||||
}
|
||||
|
||||
info = (
|
||||
<div className="mx_AddressTile_mx">
|
||||
<div className={emailClasses}>{ address.address }</div>
|
||||
{nameNode}
|
||||
{ nameNode }
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
error = true;
|
||||
var unknownClasses = classNames({
|
||||
const unknownClasses = classNames({
|
||||
"mx_AddressTile_unknown": true,
|
||||
"mx_AddressTile_justified": this.props.justified,
|
||||
});
|
||||
|
||||
info = (
|
||||
<div className={unknownClasses}>{_t("Unknown Address")}</div>
|
||||
<div className={unknownClasses}>{ _t("Unknown Address") }</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -151,5 +151,5 @@ export default React.createClass({
|
|||
{ dismiss }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -24,7 +24,7 @@ const CreateRoomButton = function(props) {
|
|||
return (
|
||||
<ActionButton action="view_create_room"
|
||||
mouseOverAction={props.callout ? "callout_create_room" : null}
|
||||
label={ _t("Create new room") }
|
||||
label={_t("Create new room")}
|
||||
iconPath="img/icons-create-room.svg"
|
||||
size={props.size}
|
||||
tooltip={props.tooltip}
|
||||
|
|
|
@ -30,7 +30,7 @@ export default React.createClass({
|
|||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
device: this.props.device
|
||||
device: this.props.device,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -60,37 +60,37 @@ export default React.createClass({
|
|||
|
||||
onUnverifyClick: function() {
|
||||
MatrixClientPeg.get().setDeviceVerified(
|
||||
this.props.userId, this.state.device.deviceId, false
|
||||
this.props.userId, this.state.device.deviceId, false,
|
||||
);
|
||||
},
|
||||
|
||||
onBlacklistClick: function() {
|
||||
MatrixClientPeg.get().setDeviceBlocked(
|
||||
this.props.userId, this.state.device.deviceId, true
|
||||
this.props.userId, this.state.device.deviceId, true,
|
||||
);
|
||||
},
|
||||
|
||||
onUnblacklistClick: function() {
|
||||
MatrixClientPeg.get().setDeviceBlocked(
|
||||
this.props.userId, this.state.device.deviceId, false
|
||||
this.props.userId, this.state.device.deviceId, false,
|
||||
);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var blacklistButton = null, verifyButton = null;
|
||||
let blacklistButton = null, verifyButton = null;
|
||||
|
||||
if (this.state.device.isBlocked()) {
|
||||
blacklistButton = (
|
||||
<button className="mx_MemberDeviceInfo_textButton mx_MemberDeviceInfo_unblacklist"
|
||||
onClick={this.onUnblacklistClick}>
|
||||
{_t("Unblacklist")}
|
||||
{ _t("Unblacklist") }
|
||||
</button>
|
||||
);
|
||||
} else {
|
||||
blacklistButton = (
|
||||
<button className="mx_MemberDeviceInfo_textButton mx_MemberDeviceInfo_blacklist"
|
||||
onClick={this.onBlacklistClick}>
|
||||
{_t("Blacklist")}
|
||||
{ _t("Blacklist") }
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
@ -99,14 +99,14 @@ export default React.createClass({
|
|||
verifyButton = (
|
||||
<button className="mx_MemberDeviceInfo_textButton mx_MemberDeviceInfo_unverify"
|
||||
onClick={this.onUnverifyClick}>
|
||||
{_t("Unverify")}
|
||||
{ _t("Unverify") }
|
||||
</button>
|
||||
);
|
||||
} else {
|
||||
verifyButton = (
|
||||
<button className="mx_MemberDeviceInfo_textButton mx_MemberDeviceInfo_verify"
|
||||
onClick={this.onVerifyClick}>
|
||||
{_t("Verify...")}
|
||||
{ _t("Verify...") }
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ export default class DirectorySearchBox extends React.Component {
|
|||
onChange={this._onChange} onKeyUp={this._onKeyUp}
|
||||
placeholder={this.props.placeholder} autoFocus
|
||||
/>
|
||||
{join_button}
|
||||
{ join_button }
|
||||
<span className="mx_DirectorySearchBox_clear_wrapper">
|
||||
<span className="mx_DirectorySearchBox_clear" onClick={this._onClearClick} />
|
||||
</span>
|
||||
|
|
|
@ -29,7 +29,7 @@ class MenuOption extends React.Component {
|
|||
getDefaultProps() {
|
||||
return {
|
||||
disabled: false,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
_onMouseEnter() {
|
||||
|
@ -52,15 +52,15 @@ class MenuOption extends React.Component {
|
|||
onClick={this._onClick} onKeyPress={this._onKeyPress}
|
||||
onMouseEnter={this._onMouseEnter}
|
||||
>
|
||||
{this.props.children}
|
||||
</div>
|
||||
{ this.props.children }
|
||||
</div>;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
MenuOption.propTypes = {
|
||||
children: React.PropTypes.oneOfType([
|
||||
React.PropTypes.arrayOf(React.PropTypes.node),
|
||||
React.PropTypes.node
|
||||
React.PropTypes.node,
|
||||
]),
|
||||
highlighted: React.PropTypes.bool,
|
||||
dropdownKey: React.PropTypes.string,
|
||||
|
@ -258,13 +258,13 @@ export default class Dropdown extends React.Component {
|
|||
onMouseEnter={this._setHighlightedOption}
|
||||
onClick={this._onMenuOptionClick}
|
||||
>
|
||||
{child}
|
||||
{ child }
|
||||
</MenuOption>
|
||||
);
|
||||
});
|
||||
if (options.length === 0) {
|
||||
return [<div key="0" className="mx_Dropdown_option">
|
||||
{_t("No results")}
|
||||
{ _t("No results") }
|
||||
</div>];
|
||||
}
|
||||
return options;
|
||||
|
@ -287,7 +287,7 @@ export default class Dropdown extends React.Component {
|
|||
/>;
|
||||
}
|
||||
menu = <div className="mx_Dropdown_menu" style={menuStyle}>
|
||||
{this._getMenuOptions()}
|
||||
{ this._getMenuOptions() }
|
||||
</div>;
|
||||
}
|
||||
|
||||
|
@ -296,8 +296,8 @@ export default class Dropdown extends React.Component {
|
|||
this.props.getShortOption(this.props.value) :
|
||||
this.childrenByKey[this.props.value];
|
||||
currentValue = <div className="mx_Dropdown_option">
|
||||
{selectedChild}
|
||||
</div>
|
||||
{ selectedChild }
|
||||
</div>;
|
||||
}
|
||||
|
||||
const dropdownClasses = {
|
||||
|
@ -312,9 +312,9 @@ export default class Dropdown extends React.Component {
|
|||
// to the input, but overflows below it. The root contains both.
|
||||
return <div className={classnames(dropdownClasses)} ref={this._collectRoot}>
|
||||
<AccessibleButton className="mx_Dropdown_input" onClick={this._onInputClick}>
|
||||
{currentValue}
|
||||
{ currentValue }
|
||||
<span className="mx_Dropdown_arrow"></span>
|
||||
{menu}
|
||||
{ menu }
|
||||
</AccessibleButton>
|
||||
</div>;
|
||||
}
|
||||
|
@ -340,4 +340,4 @@ Dropdown.propTypes = {
|
|||
value: React.PropTypes.string,
|
||||
// negative for consistency with HTML
|
||||
disabled: React.PropTypes.bool,
|
||||
}
|
||||
};
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
const React = require('react');
|
||||
|
||||
const KEY_TAB = 9;
|
||||
const KEY_SHIFT = 16;
|
||||
|
@ -95,8 +95,7 @@ module.exports = React.createClass({
|
|||
this.refs.editable_div.setAttribute("class", this.props.className + " " + this.props.placeholderClassName);
|
||||
this.placeholder = true;
|
||||
this.value = '';
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.refs.editable_div.textContent = this.value;
|
||||
this.refs.editable_div.setAttribute("class", this.props.className);
|
||||
this.placeholder = false;
|
||||
|
@ -152,8 +151,7 @@ module.exports = React.createClass({
|
|||
|
||||
if (!ev.target.textContent) {
|
||||
this.showPlaceholder(true);
|
||||
}
|
||||
else if (!this.placeholder) {
|
||||
} else if (!this.placeholder) {
|
||||
this.value = ev.target.textContent;
|
||||
}
|
||||
|
||||
|
@ -177,21 +175,21 @@ module.exports = React.createClass({
|
|||
onFocus: function(ev) {
|
||||
//ev.target.setSelectionRange(0, ev.target.textContent.length);
|
||||
|
||||
var node = ev.target.childNodes[0];
|
||||
const node = ev.target.childNodes[0];
|
||||
if (node) {
|
||||
var range = document.createRange();
|
||||
const range = document.createRange();
|
||||
range.setStart(node, 0);
|
||||
range.setEnd(node, node.length);
|
||||
|
||||
var sel = window.getSelection();
|
||||
const sel = window.getSelection();
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
}
|
||||
},
|
||||
|
||||
onFinish: function(ev, shouldSubmit) {
|
||||
var self = this;
|
||||
var submit = (ev.key === "Enter") || shouldSubmit;
|
||||
const self = this;
|
||||
const submit = (ev.key === "Enter") || shouldSubmit;
|
||||
this.setState({
|
||||
phase: this.Phases.Display,
|
||||
}, function() {
|
||||
|
@ -202,19 +200,16 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onBlur: function(ev) {
|
||||
var sel = window.getSelection();
|
||||
const sel = window.getSelection();
|
||||
sel.removeAllRanges();
|
||||
|
||||
if (this.props.blurToCancel)
|
||||
{this.cancelEdit();}
|
||||
else
|
||||
{this.onFinish(ev, this.props.blurToSubmit);}
|
||||
if (this.props.blurToCancel) {this.cancelEdit();} else {this.onFinish(ev, this.props.blurToSubmit);}
|
||||
|
||||
this.showPlaceholder(!this.value);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var editable_el;
|
||||
let editable_el;
|
||||
|
||||
if (!this.props.editable || (this.state.phase == this.Phases.Display && (this.props.label || this.props.labelClassName) && !this.value)) {
|
||||
// show the label
|
||||
|
@ -226,5 +221,5 @@ module.exports = React.createClass({
|
|||
}
|
||||
|
||||
return editable_el;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -64,7 +64,7 @@ export default class EditableTextContainer extends React.Component {
|
|||
errorString: error.toString(),
|
||||
busy: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -96,22 +96,22 @@ export default class EditableTextContainer extends React.Component {
|
|||
errorString: error.toString(),
|
||||
busy: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.busy) {
|
||||
var Loader = sdk.getComponent("elements.Spinner");
|
||||
const Loader = sdk.getComponent("elements.Spinner");
|
||||
return (
|
||||
<Loader />
|
||||
);
|
||||
} else if (this.state.errorString) {
|
||||
return (
|
||||
<div className="error">{this.state.errorString}</div>
|
||||
<div className="error">{ this.state.errorString }</div>
|
||||
);
|
||||
} else {
|
||||
var EditableText = sdk.getComponent('elements.EditableText');
|
||||
const EditableText = sdk.getComponent('elements.EditableText');
|
||||
return (
|
||||
<EditableText initialValue={this.state.value}
|
||||
placeholder={this.props.placeholder}
|
||||
|
|
|
@ -23,7 +23,7 @@ const HomeButton = function(props) {
|
|||
const ActionButton = sdk.getComponent('elements.ActionButton');
|
||||
return (
|
||||
<ActionButton action="view_home_page"
|
||||
label={ _t("Home") }
|
||||
label={_t("Home")}
|
||||
iconPath="img/icons-home.svg"
|
||||
size={props.size}
|
||||
tooltip={props.tooltip}
|
||||
|
|
|
@ -35,12 +35,12 @@ export default class LanguageDropdown extends React.Component {
|
|||
this.state = {
|
||||
searchQuery: '',
|
||||
langs: null,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
languageHandler.getAllLanguagesFromJson().then((langs) => {
|
||||
langs.sort(function(a, b){
|
||||
langs.sort(function(a, b) {
|
||||
if(a.label < b.label) return -1;
|
||||
if(a.label > b.label) return 1;
|
||||
return 0;
|
||||
|
@ -89,7 +89,7 @@ export default class LanguageDropdown extends React.Component {
|
|||
|
||||
const options = displayedLanguages.map((language) => {
|
||||
return <div key={language.value}>
|
||||
{language.label}
|
||||
{ language.label }
|
||||
</div>;
|
||||
});
|
||||
|
||||
|
@ -108,8 +108,8 @@ export default class LanguageDropdown extends React.Component {
|
|||
onOptionChange={this.props.onOptionChange} onSearchChange={this._onSearchChange}
|
||||
searchEnabled={true} value={value}
|
||||
>
|
||||
{options}
|
||||
</Dropdown>
|
||||
{ options }
|
||||
</Dropdown>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -96,12 +96,12 @@ module.exports = React.createClass({
|
|||
// Transform into consecutive repetitions of the same transition (like 5
|
||||
// consecutive 'joined_and_left's)
|
||||
const coalescedTransitions = this._coalesceRepeatedTransitions(
|
||||
canonicalTransitions
|
||||
canonicalTransitions,
|
||||
);
|
||||
|
||||
const descs = coalescedTransitions.map((t) => {
|
||||
return this._getDescriptionForTransition(
|
||||
t.transitionType, plural, t.repeats
|
||||
t.transitionType, plural, t.repeats,
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -119,7 +119,7 @@ module.exports = React.createClass({
|
|||
return (
|
||||
<span className="mx_TextualEvent mx_MemberEventListSummary_summary">
|
||||
<EmojiText>
|
||||
{summaries.join(", ")}
|
||||
{ summaries.join(", ") }
|
||||
</EmojiText>
|
||||
</span>
|
||||
);
|
||||
|
@ -370,7 +370,7 @@ module.exports = React.createClass({
|
|||
*/
|
||||
_renderCommaSeparatedList(items, itemLimit) {
|
||||
const remaining = itemLimit === undefined ? 0 : Math.max(
|
||||
items.length - itemLimit, 0
|
||||
items.length - itemLimit, 0,
|
||||
);
|
||||
if (items.length === 0) {
|
||||
return "";
|
||||
|
@ -394,8 +394,8 @@ module.exports = React.createClass({
|
|||
);
|
||||
});
|
||||
return (
|
||||
<span className="mx_MemberEventListSummary_avatars" onClick={ this._toggleSummary }>
|
||||
{avatars}
|
||||
<span className="mx_MemberEventListSummary_avatars" onClick={this._toggleSummary}>
|
||||
{ avatars }
|
||||
</span>
|
||||
);
|
||||
},
|
||||
|
@ -419,19 +419,15 @@ module.exports = React.createClass({
|
|||
case 'join':
|
||||
if (e.mxEvent.getPrevContent().membership === 'join') {
|
||||
if (e.mxEvent.getContent().displayname !==
|
||||
e.mxEvent.getPrevContent().displayname)
|
||||
{
|
||||
e.mxEvent.getPrevContent().displayname) {
|
||||
return 'changed_name';
|
||||
}
|
||||
else if (e.mxEvent.getContent().avatar_url !==
|
||||
e.mxEvent.getPrevContent().avatar_url)
|
||||
{
|
||||
} else if (e.mxEvent.getContent().avatar_url !==
|
||||
e.mxEvent.getPrevContent().avatar_url) {
|
||||
return 'changed_avatar';
|
||||
}
|
||||
// console.log("MELS ignoring duplicate membership join event");
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return 'joined';
|
||||
}
|
||||
case 'leave':
|
||||
|
@ -483,7 +479,7 @@ module.exports = React.createClass({
|
|||
firstEvent.index < aggregateIndices[seq]) {
|
||||
aggregateIndices[seq] = firstEvent.index;
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
|
@ -494,7 +490,7 @@ module.exports = React.createClass({
|
|||
|
||||
render: function() {
|
||||
const eventsToRender = this.props.events;
|
||||
const eventIds = eventsToRender.map(e => e.getId()).join(',');
|
||||
const eventIds = eventsToRender.map((e) => e.getId()).join(',');
|
||||
const fewEvents = eventsToRender.length < this.props.threshold;
|
||||
const expanded = this.state.expanded || fewEvents;
|
||||
|
||||
|
@ -506,7 +502,7 @@ module.exports = React.createClass({
|
|||
if (fewEvents) {
|
||||
return (
|
||||
<div className="mx_MemberEventListSummary" data-scroll-tokens={eventIds}>
|
||||
{expandedEvents}
|
||||
{ expandedEvents }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -542,7 +538,7 @@ module.exports = React.createClass({
|
|||
|
||||
// Sort types by order of lowest event index within sequence
|
||||
const orderedTransitionSequences = Object.keys(aggregate.names).sort(
|
||||
(seq1, seq2) => aggregate.indices[seq1] > aggregate.indices[seq2]
|
||||
(seq1, seq2) => aggregate.indices[seq1] > aggregate.indices[seq2],
|
||||
);
|
||||
|
||||
let summaryContainer = null;
|
||||
|
@ -550,24 +546,24 @@ module.exports = React.createClass({
|
|||
summaryContainer = (
|
||||
<div className="mx_EventTile_line">
|
||||
<div className="mx_EventTile_info">
|
||||
{this._renderAvatars(avatarMembers)}
|
||||
{this._renderSummary(aggregate.names, orderedTransitionSequences)}
|
||||
{ this._renderAvatars(avatarMembers) }
|
||||
{ this._renderSummary(aggregate.names, orderedTransitionSequences) }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const toggleButton = (
|
||||
<div className={"mx_MemberEventListSummary_toggle"} onClick={this._toggleSummary}>
|
||||
{expanded ? 'collapse' : 'expand'}
|
||||
{ expanded ? 'collapse' : 'expand' }
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="mx_MemberEventListSummary" data-scroll-tokens={eventIds}>
|
||||
{toggleButton}
|
||||
{summaryContainer}
|
||||
{expanded ? <div className="mx_MemberEventListSummary_line"> </div> : null}
|
||||
{expandedEvents}
|
||||
{ toggleButton }
|
||||
{ summaryContainer }
|
||||
{ expanded ? <div className="mx_MemberEventListSummary_line"> </div> : null }
|
||||
{ expandedEvents }
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -20,8 +20,8 @@ import React from 'react';
|
|||
import * as Roles from '../../../Roles';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
var LEVEL_ROLE_MAP = {};
|
||||
var reverseRoles = {};
|
||||
let LEVEL_ROLE_MAP = {};
|
||||
const reverseRoles = {};
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'PowerSelector',
|
||||
|
@ -72,7 +72,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
getValue: function() {
|
||||
var value;
|
||||
let value;
|
||||
if (this.refs.select) {
|
||||
value = reverseRoles[this.refs.select.value];
|
||||
if (this.refs.custom) {
|
||||
|
@ -83,30 +83,27 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var customPicker;
|
||||
let customPicker;
|
||||
if (this.state.custom) {
|
||||
var input;
|
||||
let input;
|
||||
if (this.props.disabled) {
|
||||
input = <span>{ this.props.value }</span>;
|
||||
}
|
||||
else {
|
||||
input = <input ref="custom" type="text" size="3" defaultValue={ this.props.value } onBlur={ this.onCustomBlur } onKeyDown={ this.onCustomKeyDown }/>;
|
||||
} else {
|
||||
input = <input ref="custom" type="text" size="3" defaultValue={this.props.value} onBlur={this.onCustomBlur} onKeyDown={this.onCustomKeyDown} />;
|
||||
}
|
||||
customPicker = <span> of { input }</span>;
|
||||
}
|
||||
|
||||
var selectValue;
|
||||
let selectValue;
|
||||
if (this.state.custom) {
|
||||
selectValue = "Custom";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
selectValue = LEVEL_ROLE_MAP[this.props.value] || "Custom";
|
||||
}
|
||||
var select;
|
||||
let select;
|
||||
if (this.props.disabled) {
|
||||
select = <span>{ selectValue }</span>;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Each level must have a definition in LEVEL_ROLE_MAP
|
||||
const levels = [0, 50, 100];
|
||||
let options = levels.map((level) => {
|
||||
|
@ -115,18 +112,18 @@ module.exports = React.createClass({
|
|||
// Give a userDefault (users_default in the power event) of 0 but
|
||||
// because level !== undefined, this should never be used.
|
||||
text: Roles.textualPowerLevel(level, 0),
|
||||
}
|
||||
};
|
||||
});
|
||||
options.push({ value: "Custom", text: _t("Custom level") });
|
||||
options = options.map((op) => {
|
||||
return <option value={op.value} key={op.value}>{op.text}</option>;
|
||||
return <option value={op.value} key={op.value}>{ op.text }</option>;
|
||||
});
|
||||
|
||||
select =
|
||||
<select ref="select"
|
||||
value={ this.props.controlled ? selectValue : undefined }
|
||||
defaultValue={ !this.props.controlled ? selectValue : undefined }
|
||||
onChange={ this.onSelectChange }>
|
||||
value={this.props.controlled ? selectValue : undefined}
|
||||
defaultValue={!this.props.controlled ? selectValue : undefined}
|
||||
onChange={this.onSelectChange}>
|
||||
{ options }
|
||||
</select>;
|
||||
}
|
||||
|
@ -137,5 +134,5 @@ module.exports = React.createClass({
|
|||
{ customPicker }
|
||||
</span>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -16,23 +16,23 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
const React = require('react');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'ProgressBar',
|
||||
propTypes: {
|
||||
value: React.PropTypes.number,
|
||||
max: React.PropTypes.number
|
||||
max: React.PropTypes.number,
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// Would use an HTML5 progress tag but if that doesn't animate if you
|
||||
// use the HTML attributes rather than styles
|
||||
var progressStyle = {
|
||||
width: ((this.props.value / this.props.max) * 100)+"%"
|
||||
const progressStyle = {
|
||||
width: ((this.props.value / this.props.max) * 100)+"%",
|
||||
};
|
||||
return (
|
||||
<div className="mx_ProgressBar"><div className="mx_ProgressBar_fill" style={progressStyle}></div></div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -24,7 +24,7 @@ const RoomDirectoryButton = function(props) {
|
|||
return (
|
||||
<ActionButton action="view_room_directory"
|
||||
mouseOverAction={props.callout ? "callout_room_directory" : null}
|
||||
label={ _t("Room directory") }
|
||||
label={_t("Room directory")}
|
||||
iconPath="img/icons-directory.svg"
|
||||
size={props.size}
|
||||
tooltip={props.tooltip}
|
||||
|
|
|
@ -23,7 +23,7 @@ const SettingsButton = function(props) {
|
|||
const ActionButton = sdk.getComponent('elements.ActionButton');
|
||||
return (
|
||||
<ActionButton action="view_user_settings"
|
||||
label={ _t("Settings") }
|
||||
label={_t("Settings")}
|
||||
iconPath="img/icons-settings.svg"
|
||||
size={props.size}
|
||||
tooltip={props.tooltip}
|
||||
|
|
|
@ -24,7 +24,7 @@ const StartChatButton = function(props) {
|
|||
return (
|
||||
<ActionButton action="view_create_chat"
|
||||
mouseOverAction={props.callout ? "callout_start_chat" : null}
|
||||
label={ _t("Start chat") }
|
||||
label={_t("Start chat")}
|
||||
iconPath="img/icons-people.svg"
|
||||
size={props.size}
|
||||
tooltip={props.tooltip}
|
||||
|
|
|
@ -16,9 +16,9 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactDOM = require("react-dom");
|
||||
var Tinter = require("../../../Tinter");
|
||||
const React = require('react');
|
||||
const ReactDOM = require("react-dom");
|
||||
const Tinter = require("../../../Tinter");
|
||||
|
||||
var TintableSvg = React.createClass({
|
||||
displayName: 'TintableSvg',
|
||||
|
@ -63,16 +63,16 @@ var TintableSvg = React.createClass({
|
|||
|
||||
render: function() {
|
||||
return (
|
||||
<object className={ "mx_TintableSvg " + (this.props.className ? this.props.className : "") }
|
||||
<object className={"mx_TintableSvg " + (this.props.className ? this.props.className : "")}
|
||||
type="image/svg+xml"
|
||||
data={ this.props.src }
|
||||
width={ this.props.width }
|
||||
height={ this.props.height }
|
||||
onLoad={ this.onLoad }
|
||||
data={this.props.src}
|
||||
width={this.props.width}
|
||||
height={this.props.height}
|
||||
onLoad={this.onLoad}
|
||||
tabIndex="-1"
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Register with the Tinter so that we will be told if the tint changes
|
||||
|
|
|
@ -52,19 +52,19 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var self = this;
|
||||
const self = this;
|
||||
return (
|
||||
<div>
|
||||
<ul className="mx_UserSelector_UserIdList" ref="list">
|
||||
{this.props.selected_users.map(function(user_id, i) {
|
||||
return <li key={user_id}>{user_id} - <span onClick={function() {self.removeUser(user_id);}}>X</span></li>;
|
||||
})}
|
||||
{ this.props.selected_users.map(function(user_id, i) {
|
||||
return <li key={user_id}>{ user_id } - <span onClick={function() {self.removeUser(user_id);}}>X</span></li>;
|
||||
}) }
|
||||
</ul>
|
||||
<input type="text" ref="user_id_input" defaultValue="" className="mx_UserSelector_userIdInput" placeholder={_t("ex. @bob:example.com")}/>
|
||||
<input type="text" ref="user_id_input" defaultValue="" className="mx_UserSelector_userIdInput" placeholder={_t("ex. @bob:example.com")} />
|
||||
<button onClick={this.onAddUserId} className="mx_UserSelector_AddUserId">
|
||||
{_t("Add User")}
|
||||
{ _t("Add User") }
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -20,7 +20,7 @@ import React from 'react';
|
|||
import ReactDOM from 'react-dom';
|
||||
import { _t, _tJsx } from '../../../languageHandler';
|
||||
|
||||
var DIV_ID = 'mx_recaptcha';
|
||||
const DIV_ID = 'mx_recaptcha';
|
||||
|
||||
/**
|
||||
* A pure UI component which displays a captcha form.
|
||||
|
@ -60,9 +60,9 @@ module.exports = React.createClass({
|
|||
} else {
|
||||
console.log("Loading recaptcha script...");
|
||||
window.mx_on_recaptcha_loaded = () => {this._onCaptchaLoaded();};
|
||||
var protocol = global.location.protocol;
|
||||
const protocol = global.location.protocol;
|
||||
if (protocol === "file:") {
|
||||
var warning = document.createElement('div');
|
||||
const warning = document.createElement('div');
|
||||
// XXX: fix hardcoded app URL. Better solutions include:
|
||||
// * jumping straight to a hosted captcha page (but we don't support that yet)
|
||||
// * embedding the captcha in an iframe (if that works)
|
||||
|
@ -72,11 +72,10 @@ module.exports = React.createClass({
|
|||
/<a>(.*?)<\/a>/,
|
||||
(sub) => { return <a href='https://riot.im/app'>{ sub }</a>; }), warning);
|
||||
this.refs.recaptchaContainer.appendChild(warning);
|
||||
}
|
||||
else {
|
||||
var scriptTag = document.createElement('script');
|
||||
} else {
|
||||
const scriptTag = document.createElement('script');
|
||||
scriptTag.setAttribute(
|
||||
'src', protocol+"//www.google.com/recaptcha/api.js?onload=mx_on_recaptcha_loaded&render=explicit"
|
||||
'src', protocol+"//www.google.com/recaptcha/api.js?onload=mx_on_recaptcha_loaded&render=explicit",
|
||||
);
|
||||
this.refs.recaptchaContainer.appendChild(scriptTag);
|
||||
}
|
||||
|
@ -93,7 +92,7 @@ module.exports = React.createClass({
|
|||
throw new Error("Recaptcha did not load successfully");
|
||||
}
|
||||
|
||||
var publicKey = this.props.sitePublicKey;
|
||||
const publicKey = this.props.sitePublicKey;
|
||||
if (!publicKey) {
|
||||
console.error("No public key for recaptcha!");
|
||||
throw new Error(
|
||||
|
@ -130,18 +129,18 @@ module.exports = React.createClass({
|
|||
if (this.state.errorText) {
|
||||
error = (
|
||||
<div className="error">
|
||||
{this.state.errorText}
|
||||
{ this.state.errorText }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div ref="recaptchaContainer">
|
||||
{_t("This Home Server would like to make sure you are not a robot")}
|
||||
<br/>
|
||||
{ _t("This Home Server would like to make sure you are not a robot") }
|
||||
<br />
|
||||
<div id={DIV_ID}></div>
|
||||
{error}
|
||||
{ error }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -29,9 +29,9 @@ module.exports = React.createClass({
|
|||
render: function() {
|
||||
return (
|
||||
<div>
|
||||
<button onClick={this.props.onSubmit}>{_t("Sign in with CAS")}</button>
|
||||
<button onClick={this.props.onSubmit}>{ _t("Sign in with CAS") }</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
|
|
@ -69,7 +69,7 @@ export default class CountryDropdown extends React.Component {
|
|||
}
|
||||
|
||||
_flagImgForIso2(iso2) {
|
||||
return <img src={`flags/${iso2}.png`}/>;
|
||||
return <img src={`flags/${iso2}.png`} />;
|
||||
}
|
||||
|
||||
_getShortOption(iso2) {
|
||||
|
@ -111,8 +111,8 @@ export default class CountryDropdown extends React.Component {
|
|||
|
||||
const options = displayedCountries.map((country) => {
|
||||
return <div key={country.iso2}>
|
||||
{this._flagImgForIso2(country.iso2)}
|
||||
{country.name} <span>(+{country.prefix})</span>
|
||||
{ this._flagImgForIso2(country.iso2) }
|
||||
{ country.name } <span>(+{ country.prefix })</span>
|
||||
</div>;
|
||||
});
|
||||
|
||||
|
@ -125,7 +125,7 @@ export default class CountryDropdown extends React.Component {
|
|||
menuWidth={298} getShortOption={this._getShortOption}
|
||||
value={value} searchEnabled={true} disabled={this.props.disabled}
|
||||
>
|
||||
{options}
|
||||
{ options }
|
||||
</Dropdown>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,27 +24,27 @@ module.exports = React.createClass({
|
|||
return (
|
||||
<div className="mx_ErrorDialog">
|
||||
<div className="mx_Dialog_title">
|
||||
{_t("Custom Server Options")}
|
||||
{ _t("Custom Server Options") }
|
||||
</div>
|
||||
<div className="mx_Dialog_content">
|
||||
<span>
|
||||
{_t("You can use the custom server options to sign into other Matrix " +
|
||||
"servers by specifying a different Home server URL.")}
|
||||
<br/>
|
||||
{_t("This allows you to use this app with an existing Matrix account on " +
|
||||
"a different home server.")}
|
||||
<br/>
|
||||
<br/>
|
||||
{_t("You can also set a custom identity server but this will typically prevent " +
|
||||
"interaction with users based on email address.")}
|
||||
{ _t("You can use the custom server options to sign into other Matrix " +
|
||||
"servers by specifying a different Home server URL.") }
|
||||
<br />
|
||||
{ _t("This allows you to use this app with an existing Matrix account on " +
|
||||
"a different home server.") }
|
||||
<br />
|
||||
<br />
|
||||
{ _t("You can also set a custom identity server but this will typically prevent " +
|
||||
"interaction with users based on email address.") }
|
||||
</span>
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button onClick={this.props.onFinished} autoFocus={true}>
|
||||
{_t("Dismiss")}
|
||||
{ _t("Dismiss") }
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -129,8 +129,8 @@ export const PasswordAuthEntry = React.createClass({
|
|||
|
||||
return (
|
||||
<div>
|
||||
<p>{_t("To continue, please enter your password.")}</p>
|
||||
<p>{_t("Password:")}</p>
|
||||
<p>{ _t("To continue, please enter your password.") }</p>
|
||||
<p>{ _t("Password:") }</p>
|
||||
<form onSubmit={this._onSubmit}>
|
||||
<input
|
||||
ref="passwordField"
|
||||
|
@ -139,11 +139,11 @@ export const PasswordAuthEntry = React.createClass({
|
|||
type="password"
|
||||
/>
|
||||
<div className="mx_button_row">
|
||||
{submitButtonOrSpinner}
|
||||
{ submitButtonOrSpinner }
|
||||
</div>
|
||||
</form>
|
||||
<div className="error">
|
||||
{this.props.errorText}
|
||||
{ this.props.errorText }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -178,14 +178,14 @@ export const RecaptchaAuthEntry = React.createClass({
|
|||
}
|
||||
|
||||
const CaptchaForm = sdk.getComponent("views.login.CaptchaForm");
|
||||
var sitePublicKey = this.props.stageParams.public_key;
|
||||
const sitePublicKey = this.props.stageParams.public_key;
|
||||
return (
|
||||
<div>
|
||||
<CaptchaForm sitePublicKey={sitePublicKey}
|
||||
onCaptchaResponse={this._onCaptchaResponse}
|
||||
/>
|
||||
<div className="error">
|
||||
{this.props.errorText}
|
||||
{ this.props.errorText }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -256,8 +256,8 @@ export const EmailIdentityAuthEntry = React.createClass({
|
|||
} else {
|
||||
return (
|
||||
<div>
|
||||
<p>{_t("An email has been sent to")} <i>{this.props.inputs.emailAddress}</i></p>
|
||||
<p>{_t("Please check your email to continue registration.")}</p>
|
||||
<p>{ _t("An email has been sent to") } <i>{ this.props.inputs.emailAddress }</i></p>
|
||||
<p>{ _t("Please check your email to continue registration.") }</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -333,12 +333,12 @@ export const MsisdnAuthEntry = React.createClass({
|
|||
});
|
||||
|
||||
this.props.matrixClient.submitMsisdnToken(
|
||||
this._sid, this.props.clientSecret, this.state.token
|
||||
this._sid, this.props.clientSecret, this.state.token,
|
||||
).then((result) => {
|
||||
if (result.success) {
|
||||
const idServerParsedUrl = url.parse(
|
||||
this.props.matrixClient.getIdentityServerUrl(),
|
||||
)
|
||||
);
|
||||
this.props.submitAuthDict({
|
||||
type: MsisdnAuthEntry.LOGIN_TYPE,
|
||||
threepid_creds: {
|
||||
|
@ -370,8 +370,8 @@ export const MsisdnAuthEntry = React.createClass({
|
|||
});
|
||||
return (
|
||||
<div>
|
||||
<p>{_t("A text message has been sent to")} +<i>{this._msisdn}</i></p>
|
||||
<p>{_t("Please enter the code it contains:")}</p>
|
||||
<p>{ _t("A text message has been sent to") } +<i>{ this._msisdn }</i></p>
|
||||
<p>{ _t("Please enter the code it contains:") }</p>
|
||||
<div className="mx_InteractiveAuthEntryComponents_msisdnWrapper">
|
||||
<form onSubmit={this._onFormSubmit}>
|
||||
<input type="text"
|
||||
|
@ -386,7 +386,7 @@ export const MsisdnAuthEntry = React.createClass({
|
|||
/>
|
||||
</form>
|
||||
<div className="error">
|
||||
{this.state.errorText}
|
||||
{ this.state.errorText }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -421,9 +421,9 @@ export const FallbackAuthEntry = React.createClass({
|
|||
},
|
||||
|
||||
_onShowFallbackClick: function() {
|
||||
var url = this.props.matrixClient.getFallbackAuthUrl(
|
||||
const url = this.props.matrixClient.getFallbackAuthUrl(
|
||||
this.props.loginType,
|
||||
this.props.authSessionId
|
||||
this.props.authSessionId,
|
||||
);
|
||||
this._popupWindow = window.open(url);
|
||||
},
|
||||
|
@ -440,9 +440,9 @@ export const FallbackAuthEntry = React.createClass({
|
|||
render: function() {
|
||||
return (
|
||||
<div>
|
||||
<a onClick={this._onShowFallbackClick}>{_t("Start authentication")}</a>
|
||||
<a onClick={this._onShowFallbackClick}>{ _t("Start authentication") }</a>
|
||||
<div className="error">
|
||||
{this.props.errorText}
|
||||
{ this.props.errorText }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -457,7 +457,7 @@ const AuthEntryComponents = [
|
|||
];
|
||||
|
||||
export function getEntryComponentForLoginType(loginType) {
|
||||
for (var c of AuthEntryComponents) {
|
||||
for (const c of AuthEntryComponents) {
|
||||
if (c.LOGIN_TYPE == loginType) {
|
||||
return c;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
const React = require('react');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'LoginHeader',
|
||||
|
@ -27,5 +27,5 @@ module.exports = React.createClass({
|
|||
Matrix
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -94,7 +94,7 @@ class PasswordLogin extends React.Component {
|
|||
onLoginTypeChange(loginType) {
|
||||
this.setState({
|
||||
loginType: loginType,
|
||||
username: "" // Reset because email and username use the same state
|
||||
username: "", // Reset because email and username use the same state
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ class PasswordLogin extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
var forgotPasswordJsx;
|
||||
let forgotPasswordJsx;
|
||||
|
||||
if (this.props.onForgotPasswordClick) {
|
||||
forgotPasswordJsx = (
|
||||
|
@ -220,21 +220,21 @@ class PasswordLogin extends React.Component {
|
|||
value={this.state.loginType}
|
||||
disabled={matrixIdText === ''}
|
||||
onOptionChange={this.onLoginTypeChange}>
|
||||
<span key={PasswordLogin.LOGIN_FIELD_MXID}>{matrixIdText}</span>
|
||||
<span key={PasswordLogin.LOGIN_FIELD_MXID}>{ matrixIdText }</span>
|
||||
<span key={PasswordLogin.LOGIN_FIELD_EMAIL}>{ _t('Email address') }</span>
|
||||
<span key={PasswordLogin.LOGIN_FIELD_PHONE}>{ _t('Phone') }</span>
|
||||
</Dropdown>
|
||||
</div>
|
||||
{loginField}
|
||||
{ loginField }
|
||||
<input className={pwFieldClass} ref={(e) => {this._passwordField = e;}} type="password"
|
||||
name="password"
|
||||
value={this.state.password} onChange={this.onPasswordChanged}
|
||||
placeholder={ _t('Password') }
|
||||
placeholder={_t('Password')}
|
||||
disabled={matrixIdText === ''}
|
||||
/>
|
||||
<br />
|
||||
{forgotPasswordJsx}
|
||||
<input className="mx_Login_submit" type="submit" value={ _t('Sign in') } disabled={matrixIdText === ''} />
|
||||
{ forgotPasswordJsx }
|
||||
<input className="mx_Login_submit" type="submit" value={_t('Sign in')} disabled={matrixIdText === ''} />
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -64,7 +64,7 @@ module.exports = React.createClass({
|
|||
minPasswordLength: 6,
|
||||
onError: function(e) {
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -91,16 +91,16 @@ module.exports = React.createClass({
|
|||
this.validateField(FIELD_PHONE_NUMBER);
|
||||
this.validateField(FIELD_EMAIL);
|
||||
|
||||
var self = this;
|
||||
const self = this;
|
||||
if (this.allFieldsValid()) {
|
||||
if (this.refs.email.value == '') {
|
||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, {
|
||||
title: _t("Warning!"),
|
||||
description:
|
||||
<div>
|
||||
{_t("If you don't specify an email address, you won't be able to reset your password. " +
|
||||
"Are you sure?")}
|
||||
{ _t("If you don't specify an email address, you won't be able to reset your password. " +
|
||||
"Are you sure?") }
|
||||
</div>,
|
||||
button: _t("Continue"),
|
||||
onFinished: function(confirmed) {
|
||||
|
@ -116,8 +116,8 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
_doSubmit: function(ev) {
|
||||
let email = this.refs.email.value.trim();
|
||||
var promise = this.props.onRegisterClick({
|
||||
const email = this.refs.email.value.trim();
|
||||
const promise = this.props.onRegisterClick({
|
||||
username: this.refs.username.value.trim(),
|
||||
password: this.refs.password.value.trim(),
|
||||
email: email,
|
||||
|
@ -138,8 +138,8 @@ module.exports = React.createClass({
|
|||
* they were validated.
|
||||
*/
|
||||
allFieldsValid: function() {
|
||||
var keys = Object.keys(this.state.fieldValid);
|
||||
for (var i = 0; i < keys.length; ++i) {
|
||||
const keys = Object.keys(this.state.fieldValid);
|
||||
for (let i = 0; i < keys.length; ++i) {
|
||||
if (this.state.fieldValid[keys[i]] == false) {
|
||||
return false;
|
||||
}
|
||||
|
@ -152,8 +152,8 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
validateField: function(field_id) {
|
||||
var pwd1 = this.refs.password.value.trim();
|
||||
var pwd2 = this.refs.passwordConfirm.value.trim();
|
||||
const pwd1 = this.refs.password.value.trim();
|
||||
const pwd2 = this.refs.passwordConfirm.value.trim();
|
||||
|
||||
switch (field_id) {
|
||||
case FIELD_EMAIL:
|
||||
|
@ -162,7 +162,7 @@ module.exports = React.createClass({
|
|||
const matchingTeam = this.props.teamsConfig.teams.find(
|
||||
(team) => {
|
||||
return email.split('@').pop() === team.domain;
|
||||
}
|
||||
},
|
||||
) || null;
|
||||
this.setState({
|
||||
selectedTeam: matchingTeam,
|
||||
|
@ -191,13 +191,13 @@ module.exports = React.createClass({
|
|||
this.markFieldValid(
|
||||
field_id,
|
||||
false,
|
||||
"RegistrationForm.ERR_USERNAME_INVALID"
|
||||
"RegistrationForm.ERR_USERNAME_INVALID",
|
||||
);
|
||||
} else if (username == '') {
|
||||
this.markFieldValid(
|
||||
field_id,
|
||||
false,
|
||||
"RegistrationForm.ERR_USERNAME_BLANK"
|
||||
"RegistrationForm.ERR_USERNAME_BLANK",
|
||||
);
|
||||
} else {
|
||||
this.markFieldValid(field_id, true);
|
||||
|
@ -208,13 +208,13 @@ module.exports = React.createClass({
|
|||
this.markFieldValid(
|
||||
field_id,
|
||||
false,
|
||||
"RegistrationForm.ERR_PASSWORD_MISSING"
|
||||
"RegistrationForm.ERR_PASSWORD_MISSING",
|
||||
);
|
||||
} else if (pwd1.length < this.props.minPasswordLength) {
|
||||
this.markFieldValid(
|
||||
field_id,
|
||||
false,
|
||||
"RegistrationForm.ERR_PASSWORD_LENGTH"
|
||||
"RegistrationForm.ERR_PASSWORD_LENGTH",
|
||||
);
|
||||
} else {
|
||||
this.markFieldValid(field_id, true);
|
||||
|
@ -223,14 +223,14 @@ module.exports = React.createClass({
|
|||
case FIELD_PASSWORD_CONFIRM:
|
||||
this.markFieldValid(
|
||||
field_id, pwd1 == pwd2,
|
||||
"RegistrationForm.ERR_PASSWORD_MISMATCH"
|
||||
"RegistrationForm.ERR_PASSWORD_MISMATCH",
|
||||
);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
markFieldValid: function(field_id, val, error_code) {
|
||||
var fieldValid = this.state.fieldValid;
|
||||
const fieldValid = this.state.fieldValid;
|
||||
fieldValid[field_id] = val;
|
||||
this.setState({fieldValid: fieldValid});
|
||||
if (!val) {
|
||||
|
@ -271,7 +271,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var self = this;
|
||||
const self = this;
|
||||
|
||||
const emailSection = (
|
||||
<div>
|
||||
|
@ -280,7 +280,7 @@ module.exports = React.createClass({
|
|||
defaultValue={this.props.defaultEmail}
|
||||
className={this._classForField(FIELD_EMAIL, 'mx_Login_field')}
|
||||
onBlur={function() {self.validateField(FIELD_EMAIL);}}
|
||||
value={self.state.email}/>
|
||||
value={self.state.email} />
|
||||
</div>
|
||||
);
|
||||
let belowEmailSection;
|
||||
|
@ -291,7 +291,7 @@ module.exports = React.createClass({
|
|||
Sorry, but your university is not registered with us just yet.
|
||||
Email us on
|
||||
<a href={"mailto:" + this.props.teamsConfig.supportEmail}>
|
||||
{this.props.teamsConfig.supportEmail}
|
||||
{ this.props.teamsConfig.supportEmail }
|
||||
</a>
|
||||
to get your university signed up. Or continue to register with Riot to enjoy our open source platform.
|
||||
</p>
|
||||
|
@ -299,7 +299,7 @@ module.exports = React.createClass({
|
|||
} else if (this.state.selectedTeam) {
|
||||
belowEmailSection = (
|
||||
<p className="mx_Login_support">
|
||||
{_t("You are registering with %(SelectedTeamName)s", {SelectedTeamName: this.state.selectedTeam.name})}
|
||||
{ _t("You are registering with %(SelectedTeamName)s", {SelectedTeamName: this.state.selectedTeam.name}) }
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ module.exports = React.createClass({
|
|||
FIELD_PHONE_NUMBER,
|
||||
'mx_Login_phoneNumberField',
|
||||
'mx_Login_field',
|
||||
'mx_Login_field_has_prefix'
|
||||
'mx_Login_field_has_prefix',
|
||||
)}
|
||||
onBlur={function() {self.validateField(FIELD_PHONE_NUMBER);}}
|
||||
value={self.state.phoneNumber}
|
||||
|
@ -333,16 +333,16 @@ module.exports = React.createClass({
|
|||
<input className="mx_Login_submit" type="submit" value={_t("Register")} />
|
||||
);
|
||||
|
||||
let placeholderUserName = _t("User name");
|
||||
const placeholderUserName = _t("User name");
|
||||
|
||||
return (
|
||||
<div>
|
||||
<form onSubmit={this.onSubmit}>
|
||||
{emailSection}
|
||||
{belowEmailSection}
|
||||
{phoneSection}
|
||||
{ emailSection }
|
||||
{ belowEmailSection }
|
||||
{ phoneSection }
|
||||
<input type="text" ref="username"
|
||||
placeholder={ placeholderUserName } defaultValue={this.props.defaultUsername}
|
||||
placeholder={placeholderUserName} defaultValue={this.props.defaultUsername}
|
||||
className={this._classForField(FIELD_USERNAME, 'mx_Login_field')}
|
||||
onBlur={function() {self.validateField(FIELD_USERNAME);}} />
|
||||
<br />
|
||||
|
@ -357,9 +357,9 @@ module.exports = React.createClass({
|
|||
onBlur={function() {self.validateField(FIELD_PASSWORD_CONFIRM);}}
|
||||
defaultValue={this.props.defaultPassword} />
|
||||
<br />
|
||||
{registerButton}
|
||||
{ registerButton }
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -16,9 +16,9 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var Modal = require('../../../Modal');
|
||||
var sdk = require('../../../index');
|
||||
const React = require('react');
|
||||
const Modal = require('../../../Modal');
|
||||
const sdk = require('../../../index');
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
/**
|
||||
|
@ -45,7 +45,7 @@ module.exports = React.createClass({
|
|||
customIsUrl: React.PropTypes.string,
|
||||
|
||||
withToggleButton: React.PropTypes.bool,
|
||||
delayTimeMs: React.PropTypes.number // time to wait before invoking onChanged
|
||||
delayTimeMs: React.PropTypes.number, // time to wait before invoking onChanged
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
|
@ -54,7 +54,7 @@ module.exports = React.createClass({
|
|||
customHsUrl: "",
|
||||
customIsUrl: "",
|
||||
withToggleButton: false,
|
||||
delayTimeMs: 0
|
||||
delayTimeMs: 0,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -65,18 +65,18 @@ module.exports = React.createClass({
|
|||
// if withToggleButton is false, then show the config all the time given we have no way otherwise of making it visible
|
||||
configVisible: !this.props.withToggleButton ||
|
||||
(this.props.customHsUrl !== this.props.defaultHsUrl) ||
|
||||
(this.props.customIsUrl !== this.props.defaultIsUrl)
|
||||
(this.props.customIsUrl !== this.props.defaultIsUrl),
|
||||
};
|
||||
},
|
||||
|
||||
onHomeserverChanged: function(ev) {
|
||||
this.setState({hs_url: ev.target.value}, function() {
|
||||
this._hsTimeoutId = this._waitThenInvoke(this._hsTimeoutId, function() {
|
||||
var hsUrl = this.state.hs_url.trim().replace(/\/$/, "");
|
||||
let hsUrl = this.state.hs_url.trim().replace(/\/$/, "");
|
||||
if (hsUrl === "") hsUrl = this.props.defaultHsUrl;
|
||||
this.props.onServerConfigChange({
|
||||
hsUrl : this.state.hs_url,
|
||||
isUrl : this.state.is_url,
|
||||
hsUrl: this.state.hs_url,
|
||||
isUrl: this.state.is_url,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -85,11 +85,11 @@ module.exports = React.createClass({
|
|||
onIdentityServerChanged: function(ev) {
|
||||
this.setState({is_url: ev.target.value}, function() {
|
||||
this._isTimeoutId = this._waitThenInvoke(this._isTimeoutId, function() {
|
||||
var isUrl = this.state.is_url.trim().replace(/\/$/, "");
|
||||
let isUrl = this.state.is_url.trim().replace(/\/$/, "");
|
||||
if (isUrl === "") isUrl = this.props.defaultIsUrl;
|
||||
this.props.onServerConfigChange({
|
||||
hsUrl : this.state.hs_url,
|
||||
isUrl : this.state.is_url,
|
||||
hsUrl: this.state.hs_url,
|
||||
isUrl: this.state.is_url,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -104,32 +104,31 @@ module.exports = React.createClass({
|
|||
|
||||
onServerConfigVisibleChange: function(visible, ev) {
|
||||
this.setState({
|
||||
configVisible: visible
|
||||
configVisible: visible,
|
||||
});
|
||||
if (!visible) {
|
||||
this.props.onServerConfigChange({
|
||||
hsUrl : this.props.defaultHsUrl,
|
||||
isUrl : this.props.defaultIsUrl,
|
||||
hsUrl: this.props.defaultHsUrl,
|
||||
isUrl: this.props.defaultIsUrl,
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.props.onServerConfigChange({
|
||||
hsUrl : this.state.hs_url,
|
||||
isUrl : this.state.is_url,
|
||||
hsUrl: this.state.hs_url,
|
||||
isUrl: this.state.is_url,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
showHelpPopup: function() {
|
||||
var CustomServerDialog = sdk.getComponent('login.CustomServerDialog');
|
||||
const CustomServerDialog = sdk.getComponent('login.CustomServerDialog');
|
||||
Modal.createTrackedDialog('Custom Server Dialog', '', CustomServerDialog);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var serverConfigStyle = {};
|
||||
const serverConfigStyle = {};
|
||||
serverConfigStyle.display = this.state.configVisible ? 'block' : 'none';
|
||||
|
||||
var toggleButton;
|
||||
let toggleButton;
|
||||
if (this.props.withToggleButton) {
|
||||
toggleButton = (
|
||||
<div className="mx_ServerConfig_selector">
|
||||
|
@ -137,14 +136,14 @@ module.exports = React.createClass({
|
|||
checked={!this.state.configVisible}
|
||||
onChange={this.onServerConfigVisibleChange.bind(this, false)} />
|
||||
<label className="mx_Login_label" htmlFor="basic">
|
||||
{_t("Default server")}
|
||||
{ _t("Default server") }
|
||||
</label>
|
||||
|
||||
<input className="mx_Login_radio" id="advanced" name="configVisible" type="radio"
|
||||
checked={this.state.configVisible}
|
||||
onChange={this.onServerConfigVisibleChange.bind(this, true)} />
|
||||
<label className="mx_Login_label" htmlFor="advanced">
|
||||
{_t("Custom server")}
|
||||
{ _t("Custom server") }
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
|
@ -152,11 +151,11 @@ module.exports = React.createClass({
|
|||
|
||||
return (
|
||||
<div>
|
||||
{toggleButton}
|
||||
{ toggleButton }
|
||||
<div style={serverConfigStyle}>
|
||||
<div className="mx_ServerConfig">
|
||||
<label className="mx_Login_label mx_ServerConfig_hslabel" htmlFor="hsurl">
|
||||
{_t("Home server URL")}
|
||||
{ _t("Home server URL") }
|
||||
</label>
|
||||
<input className="mx_Login_field" id="hsurl" type="text"
|
||||
placeholder={this.props.defaultHsUrl}
|
||||
|
@ -164,7 +163,7 @@ module.exports = React.createClass({
|
|||
value={this.state.hs_url}
|
||||
onChange={this.onHomeserverChanged} />
|
||||
<label className="mx_Login_label mx_ServerConfig_islabel" htmlFor="isurl">
|
||||
{_t("Identity server URL")}
|
||||
{ _t("Identity server URL") }
|
||||
</label>
|
||||
<input className="mx_Login_field" id="isurl" type="text"
|
||||
placeholder={this.props.defaultIsUrl}
|
||||
|
@ -172,11 +171,11 @@ module.exports = React.createClass({
|
|||
value={this.state.is_url}
|
||||
onChange={this.onIdentityServerChanged} />
|
||||
<a className="mx_ServerConfig_help" href="#" onClick={this.showHelpPopup}>
|
||||
{_t("What does this mean?")}
|
||||
{ _t("What does this mean?") }
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -35,7 +35,7 @@ export default class MAudioBody extends React.Component {
|
|||
}
|
||||
onPlayToggle() {
|
||||
this.setState({
|
||||
playing: !this.state.playing
|
||||
playing: !this.state.playing,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -49,9 +49,9 @@ export default class MAudioBody extends React.Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
var content = this.props.mxEvent.getContent();
|
||||
const content = this.props.mxEvent.getContent();
|
||||
if (content.file !== undefined && this.state.decryptedUrl === null) {
|
||||
var decryptedBlob;
|
||||
let decryptedBlob;
|
||||
decryptFile(content.file).then(function(blob) {
|
||||
decryptedBlob = blob;
|
||||
return readBlobAsDataUri(decryptedBlob);
|
||||
|
@ -70,14 +70,13 @@ export default class MAudioBody extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
|
||||
const content = this.props.mxEvent.getContent();
|
||||
|
||||
if (this.state.error !== null) {
|
||||
return (
|
||||
<span className="mx_MAudioBody" ref="body">
|
||||
<img src="img/warning.svg" width="16" height="16"/>
|
||||
{_t("Error decrypting audio")}
|
||||
<img src="img/warning.svg" width="16" height="16" />
|
||||
{ _t("Error decrypting audio") }
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
@ -89,7 +88,7 @@ export default class MAudioBody extends React.Component {
|
|||
// Not sure how tall the audio player is so not sure how tall it should actually be.
|
||||
return (
|
||||
<span className="mx_MAudioBody">
|
||||
<img src="img/spinner.gif" alt={content.body} width="16" height="16"/>
|
||||
<img src="img/spinner.gif" alt={content.body} width="16" height="16" />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -28,10 +28,10 @@ import Modal from '../../../Modal';
|
|||
|
||||
|
||||
// A cached tinted copy of "img/download.svg"
|
||||
var tintedDownloadImageURL;
|
||||
let tintedDownloadImageURL;
|
||||
// Track a list of mounted MFileBody instances so that we can update
|
||||
// the "img/download.svg" when the tint changes.
|
||||
var nextMountId = 0;
|
||||
let nextMountId = 0;
|
||||
const mounts = {};
|
||||
|
||||
/**
|
||||
|
@ -169,11 +169,11 @@ function computedStyle(element) {
|
|||
return "";
|
||||
}
|
||||
const style = window.getComputedStyle(element, null);
|
||||
var cssText = style.cssText;
|
||||
let cssText = style.cssText;
|
||||
if (cssText == "") {
|
||||
// Firefox doesn't implement ".cssText" for computed styles.
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=137687
|
||||
for (var i = 0; i < style.length; i++) {
|
||||
for (let i = 0; i < style.length; i++) {
|
||||
cssText += style[i] + ":";
|
||||
cssText += style.getPropertyValue(style[i]) + ";";
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ module.exports = React.createClass({
|
|||
* @return {string} the human readable link text for the attachment.
|
||||
*/
|
||||
presentableTextForFile: function(content) {
|
||||
var linkText = _t("Attachment");
|
||||
let linkText = _t("Attachment");
|
||||
if (content.body && content.body.length > 0) {
|
||||
// The content body should be the name of the file including a
|
||||
// file extension.
|
||||
|
@ -270,7 +270,7 @@ module.exports = React.createClass({
|
|||
// Need to decrypt the attachment
|
||||
// Wait for the user to click on the link before downloading
|
||||
// and decrypting the attachment.
|
||||
var decrypting = false;
|
||||
let decrypting = false;
|
||||
const decrypt = () => {
|
||||
if (decrypting) {
|
||||
return false;
|
||||
|
@ -328,14 +328,14 @@ module.exports = React.createClass({
|
|||
<span className="mx_MFileBody">
|
||||
<div className="mx_MImageBody_download">
|
||||
<div style={{display: "none"}}>
|
||||
{/*
|
||||
{ /*
|
||||
* Add dummy copy of the "a" tag
|
||||
* We'll use it to learn how the download link
|
||||
* would have been styled if it was rendered inline.
|
||||
*/}
|
||||
<a ref="dummyLink"/>
|
||||
*/ }
|
||||
<a ref="dummyLink" />
|
||||
</div>
|
||||
<iframe src={renderer_url} onLoad={onIframeLoad} ref="iframe"/>
|
||||
<iframe src={renderer_url} onLoad={onIframeLoad} ref="iframe" />
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
|
@ -356,13 +356,12 @@ module.exports = React.createClass({
|
|||
</div>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return (
|
||||
<span className="mx_MFileBody">
|
||||
<div className="mx_MImageBody_download">
|
||||
<a href={contentUrl} download={fileName} target="_blank" rel="noopener">
|
||||
<img src={tintedDownloadImageURL} width="12" height="14" ref="downloadImage"/>
|
||||
<img src={tintedDownloadImageURL} width="12" height="14" ref="downloadImage" />
|
||||
{ _t("Download %(text)s", { text: text }) }
|
||||
</a>
|
||||
</div>
|
||||
|
@ -370,7 +369,7 @@ module.exports = React.createClass({
|
|||
);
|
||||
}
|
||||
} else {
|
||||
var extra = text ? (': ' + text) : '';
|
||||
const extra = text ? (': ' + text) : '';
|
||||
return <span className="mx_MFileBody">
|
||||
{ _t("Invalid file%(extra)s", { extra: extra }) }
|
||||
</span>;
|
||||
|
|
|
@ -191,8 +191,8 @@ module.exports = React.createClass({
|
|||
if (this.state.error !== null) {
|
||||
return (
|
||||
<span className="mx_MImageBody" ref="body">
|
||||
<img src="img/warning.svg" width="16" height="16"/>
|
||||
{_t("Error decrypting image")}
|
||||
<img src="img/warning.svg" width="16" height="16" />
|
||||
{ _t("Error decrypting image") }
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ module.exports = React.createClass({
|
|||
}}>
|
||||
<img src="img/spinner.gif" alt={content.body} width="32" height="32" style={{
|
||||
"margin": "auto",
|
||||
}}/>
|
||||
}} />
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
|
@ -227,7 +227,7 @@ module.exports = React.createClass({
|
|||
if (thumbUrl) {
|
||||
return (
|
||||
<span className="mx_MImageBody" ref="body">
|
||||
<a href={contentUrl} onClick={ this.onClick }>
|
||||
<a href={contentUrl} onClick={this.onClick}>
|
||||
<img className="mx_MImageBody_thumbnail" src={thumbUrl} ref="image"
|
||||
alt={content.body}
|
||||
onMouseEnter={this.onImageEnter}
|
||||
|
@ -239,13 +239,13 @@ module.exports = React.createClass({
|
|||
} else if (content.body) {
|
||||
return (
|
||||
<span className="mx_MImageBody">
|
||||
{_t("Image '%(Body)s' cannot be displayed.", {Body: content.body})}
|
||||
{ _t("Image '%(Body)s' cannot be displayed.", {Body: content.body}) }
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<span className="mx_MImageBody">
|
||||
{_t("This image cannot be displayed.")}
|
||||
{ _t("This image cannot be displayed.") }
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -54,13 +54,12 @@ module.exports = React.createClass({
|
|||
// no scaling needs to be applied
|
||||
return 1;
|
||||
}
|
||||
var widthMulti = thumbWidth / fullWidth;
|
||||
var heightMulti = thumbHeight / fullHeight;
|
||||
const widthMulti = thumbWidth / fullWidth;
|
||||
const heightMulti = thumbHeight / fullHeight;
|
||||
if (widthMulti < heightMulti) {
|
||||
// width is the dominant dimension so scaling will be fixed on that
|
||||
return widthMulti;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// height is the dominant dimension so scaling will be fixed on that
|
||||
return heightMulti;
|
||||
}
|
||||
|
@ -89,15 +88,15 @@ module.exports = React.createClass({
|
|||
componentDidMount: function() {
|
||||
const content = this.props.mxEvent.getContent();
|
||||
if (content.file !== undefined && this.state.decryptedUrl === null) {
|
||||
var thumbnailPromise = Promise.resolve(null);
|
||||
let thumbnailPromise = Promise.resolve(null);
|
||||
if (content.info.thumbnail_file) {
|
||||
thumbnailPromise = decryptFile(
|
||||
content.info.thumbnail_file
|
||||
content.info.thumbnail_file,
|
||||
).then(function(blob) {
|
||||
return readBlobAsDataUri(blob);
|
||||
});
|
||||
}
|
||||
var decryptedBlob;
|
||||
let decryptedBlob;
|
||||
thumbnailPromise.then((thumbnailUrl) => {
|
||||
return decryptFile(content.file).then(function(blob) {
|
||||
decryptedBlob = blob;
|
||||
|
@ -126,8 +125,8 @@ module.exports = React.createClass({
|
|||
if (this.state.error !== null) {
|
||||
return (
|
||||
<span className="mx_MVideoBody" ref="body">
|
||||
<img src="img/warning.svg" width="16" height="16"/>
|
||||
{_t("Error decrypting video")}
|
||||
<img src="img/warning.svg" width="16" height="16" />
|
||||
{ _t("Error decrypting video") }
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
@ -144,7 +143,7 @@ module.exports = React.createClass({
|
|||
"justify-items": "center",
|
||||
"width": "100%",
|
||||
}}>
|
||||
<img src="img/spinner.gif" alt={content.body} width="16" height="16"/>
|
||||
<img src="img/spinner.gif" alt={content.body} width="16" height="16" />
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
|
|
|
@ -16,8 +16,8 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var sdk = require('../../../index');
|
||||
const React = require('react');
|
||||
const sdk = require('../../../index');
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'MessageEvent',
|
||||
|
@ -47,21 +47,21 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var UnknownBody = sdk.getComponent('messages.UnknownBody');
|
||||
const UnknownBody = sdk.getComponent('messages.UnknownBody');
|
||||
|
||||
var bodyTypes = {
|
||||
const bodyTypes = {
|
||||
'm.text': sdk.getComponent('messages.TextualBody'),
|
||||
'm.notice': sdk.getComponent('messages.TextualBody'),
|
||||
'm.emote': sdk.getComponent('messages.TextualBody'),
|
||||
'm.image': sdk.getComponent('messages.MImageBody'),
|
||||
'm.file': sdk.getComponent('messages.MFileBody'),
|
||||
'm.audio': sdk.getComponent('messages.MAudioBody'),
|
||||
'm.video': sdk.getComponent('messages.MVideoBody')
|
||||
'm.video': sdk.getComponent('messages.MVideoBody'),
|
||||
};
|
||||
|
||||
var content = this.props.mxEvent.getContent();
|
||||
var msgtype = content.msgtype;
|
||||
var BodyType = UnknownBody;
|
||||
const content = this.props.mxEvent.getContent();
|
||||
const msgtype = content.msgtype;
|
||||
let BodyType = UnknownBody;
|
||||
if (msgtype && bodyTypes[msgtype]) {
|
||||
BodyType = bodyTypes[msgtype];
|
||||
} else if (content.url) {
|
||||
|
|
|
@ -31,9 +31,9 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onAvatarClick: function(name) {
|
||||
var httpUrl = MatrixClientPeg.get().mxcUrlToHttp(this.props.mxEvent.getContent().url);
|
||||
var ImageView = sdk.getComponent("elements.ImageView");
|
||||
var params = {
|
||||
const httpUrl = MatrixClientPeg.get().mxcUrlToHttp(this.props.mxEvent.getContent().url);
|
||||
const ImageView = sdk.getComponent("elements.ImageView");
|
||||
const params = {
|
||||
src: httpUrl,
|
||||
name: name,
|
||||
};
|
||||
|
@ -41,12 +41,12 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var ev = this.props.mxEvent;
|
||||
var senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||
var BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
||||
const ev = this.props.mxEvent;
|
||||
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||
const BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
||||
|
||||
var room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||
var name = _t('%(senderDisplayName)s changed the avatar for %(roomName)s', {
|
||||
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||
const name = _t('%(senderDisplayName)s changed the avatar for %(roomName)s', {
|
||||
senderDisplayName: senderDisplayName,
|
||||
roomName: room ? room.name : '',
|
||||
});
|
||||
|
@ -59,12 +59,12 @@ module.exports = React.createClass({
|
|||
);
|
||||
}
|
||||
|
||||
var url = ContentRepo.getHttpUriForMxc(
|
||||
const url = ContentRepo.getHttpUriForMxc(
|
||||
MatrixClientPeg.get().getHomeserverUrl(),
|
||||
ev.getContent().url,
|
||||
Math.ceil(14 * window.devicePixelRatio),
|
||||
Math.ceil(14 * window.devicePixelRatio),
|
||||
'crop'
|
||||
'crop',
|
||||
);
|
||||
|
||||
// it sucks that _tJsx doesn't support normal _t substitutions :((
|
||||
|
@ -79,11 +79,11 @@ module.exports = React.createClass({
|
|||
(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 } />
|
||||
onClick={this.onAvatarClick.bind(this, name)}>
|
||||
<BaseAvatar width={14} height={14} url={url}
|
||||
name={name} />
|
||||
</AccessibleButton>,
|
||||
]
|
||||
],
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -104,10 +104,10 @@ module.exports = React.createClass({
|
|||
if (this._unmounted) return;
|
||||
for (let i = 0; i < blocks.length; i++) {
|
||||
if (UserSettingsStore.getSyncedSetting("enableSyntaxHighlightLanguageDetection", false)) {
|
||||
highlight.highlightBlock(blocks[i])
|
||||
highlight.highlightBlock(blocks[i]);
|
||||
} else {
|
||||
// Only syntax highlight if there's a class starting with language-
|
||||
let classes = blocks[i].className.split(/\s+/).filter(function (cl) {
|
||||
const classes = blocks[i].className.split(/\s+/).filter(function(cl) {
|
||||
return cl.startsWith('language-');
|
||||
});
|
||||
|
||||
|
@ -146,7 +146,7 @@ module.exports = React.createClass({
|
|||
//console.log("calculateUrlPreview: ShowUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview);
|
||||
|
||||
if (this.props.showUrlPreview && !this.state.links.length) {
|
||||
var links = this.findLinks(this.refs.content.children);
|
||||
let links = this.findLinks(this.refs.content.children);
|
||||
if (links.length) {
|
||||
// de-dup the links (but preserve ordering)
|
||||
const seen = new Set();
|
||||
|
@ -160,7 +160,7 @@ module.exports = React.createClass({
|
|||
|
||||
// lazy-load the hidden state of the preview widget from localstorage
|
||||
if (global.localStorage) {
|
||||
var hidden = global.localStorage.getItem("hide_preview_" + this.props.mxEvent.getId());
|
||||
const hidden = global.localStorage.getItem("hide_preview_" + this.props.mxEvent.getId());
|
||||
this.setState({ widgetHidden: hidden });
|
||||
}
|
||||
}
|
||||
|
@ -197,21 +197,18 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
findLinks: function(nodes) {
|
||||
var links = [];
|
||||
let links = [];
|
||||
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
var node = nodes[i];
|
||||
if (node.tagName === "A" && node.getAttribute("href"))
|
||||
{
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
const node = nodes[i];
|
||||
if (node.tagName === "A" && node.getAttribute("href")) {
|
||||
if (this.isLinkPreviewable(node)) {
|
||||
links.push(node.getAttribute("href"));
|
||||
}
|
||||
}
|
||||
else if (node.tagName === "PRE" || node.tagName === "CODE" ||
|
||||
} else if (node.tagName === "PRE" || node.tagName === "CODE" ||
|
||||
node.tagName === "BLOCKQUOTE") {
|
||||
continue;
|
||||
}
|
||||
else if (node.children && node.children.length) {
|
||||
} else if (node.children && node.children.length) {
|
||||
links = links.concat(this.findLinks(node.children));
|
||||
}
|
||||
}
|
||||
|
@ -221,8 +218,7 @@ module.exports = React.createClass({
|
|||
isLinkPreviewable: function(node) {
|
||||
// don't try to preview relative links
|
||||
if (!node.getAttribute("href").startsWith("http://") &&
|
||||
!node.getAttribute("href").startsWith("https://"))
|
||||
{
|
||||
!node.getAttribute("href").startsWith("https://")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -231,13 +227,11 @@ module.exports = React.createClass({
|
|||
// or from a full foo.bar/baz style schemeless URL) - or be a markdown-style
|
||||
// link, in which case we check the target text differs from the link value.
|
||||
// TODO: make this configurable?
|
||||
if (node.textContent.indexOf("/") > -1)
|
||||
{
|
||||
if (node.textContent.indexOf("/") > -1) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
var url = node.getAttribute("href");
|
||||
var host = url.match(/^https?:\/\/(.*?)(\/|$)/)[1];
|
||||
} else {
|
||||
const url = node.getAttribute("href");
|
||||
const host = url.match(/^https?:\/\/(.*?)(\/|$)/)[1];
|
||||
|
||||
// never preview matrix.to links (if anything we should give a smart
|
||||
// preview of the room/user they point to: nobody needs to be reminded
|
||||
|
@ -247,8 +241,7 @@ module.exports = React.createClass({
|
|||
if (node.textContent.toLowerCase().trim().startsWith(host.toLowerCase())) {
|
||||
// it's a "foo.pl" style link
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// it's a [foo bar](http://foo.com) style link
|
||||
return true;
|
||||
}
|
||||
|
@ -314,7 +307,7 @@ module.exports = React.createClass({
|
|||
|
||||
getInnerText: () => {
|
||||
return this.refs.content.innerText;
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -328,28 +321,28 @@ module.exports = React.createClass({
|
|||
// the window.open command occurs in the same stack frame as the onClick callback.
|
||||
|
||||
// Go fetch a scalar token
|
||||
let scalarClient = new ScalarAuthClient();
|
||||
const scalarClient = new ScalarAuthClient();
|
||||
scalarClient.connect().then(() => {
|
||||
let completeUrl = scalarClient.getStarterLink(starterLink);
|
||||
let QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
let integrationsUrl = SdkConfig.get().integrations_ui_url;
|
||||
const completeUrl = scalarClient.getStarterLink(starterLink);
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
const integrationsUrl = SdkConfig.get().integrations_ui_url;
|
||||
Modal.createTrackedDialog('Add an integration', '', QuestionDialog, {
|
||||
title: _t("Add an Integration"),
|
||||
description:
|
||||
<div>
|
||||
{_t("You are about to be taken to a third-party site so you can " +
|
||||
{ _t("You are about to be taken to a third-party site so you can " +
|
||||
"authenticate your account for use with %(integrationsUrl)s. " +
|
||||
"Do you wish to continue?", { integrationsUrl: integrationsUrl })}
|
||||
"Do you wish to continue?", { integrationsUrl: integrationsUrl }) }
|
||||
</div>,
|
||||
button: _t("Continue"),
|
||||
onFinished: function(confirmed) {
|
||||
if (!confirmed) {
|
||||
return;
|
||||
}
|
||||
let width = window.screen.width > 1024 ? 1024 : window.screen.width;
|
||||
let height = window.screen.height > 800 ? 800 : window.screen.height;
|
||||
let left = (window.screen.width - width) / 2;
|
||||
let top = (window.screen.height - height) / 2;
|
||||
const width = window.screen.width > 1024 ? 1024 : window.screen.width;
|
||||
const height = window.screen.height > 800 ? 800 : window.screen.height;
|
||||
const left = (window.screen.width - width) / 2;
|
||||
const top = (window.screen.height - height) / 2;
|
||||
window.open(completeUrl, '_blank', `height=${height}, width=${width}, top=${top}, left=${left},`);
|
||||
},
|
||||
});
|
||||
|
@ -358,28 +351,27 @@ module.exports = React.createClass({
|
|||
|
||||
render: function() {
|
||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||
var mxEvent = this.props.mxEvent;
|
||||
var content = mxEvent.getContent();
|
||||
const mxEvent = this.props.mxEvent;
|
||||
const content = mxEvent.getContent();
|
||||
|
||||
var body = HtmlUtils.bodyToHtml(content, this.props.highlights, {});
|
||||
let body = HtmlUtils.bodyToHtml(content, this.props.highlights, {});
|
||||
|
||||
if (this.props.highlightLink) {
|
||||
body = <a href={ this.props.highlightLink }>{ body }</a>;
|
||||
}
|
||||
else if (content.data && typeof content.data["org.matrix.neb.starter_link"] === "string") {
|
||||
body = <a href="#" onClick={ this.onStarterLinkClick.bind(this, content.data["org.matrix.neb.starter_link"]) }>{ body }</a>;
|
||||
body = <a href={this.props.highlightLink}>{ body }</a>;
|
||||
} else if (content.data && typeof content.data["org.matrix.neb.starter_link"] === "string") {
|
||||
body = <a href="#" onClick={this.onStarterLinkClick.bind(this, content.data["org.matrix.neb.starter_link"])}>{ body }</a>;
|
||||
}
|
||||
|
||||
var widgets;
|
||||
let widgets;
|
||||
if (this.state.links.length && !this.state.widgetHidden && this.props.showUrlPreview) {
|
||||
var LinkPreviewWidget = sdk.getComponent('rooms.LinkPreviewWidget');
|
||||
const LinkPreviewWidget = sdk.getComponent('rooms.LinkPreviewWidget');
|
||||
widgets = this.state.links.map((link)=>{
|
||||
return <LinkPreviewWidget
|
||||
key={ link }
|
||||
link={ link }
|
||||
mxEvent={ this.props.mxEvent }
|
||||
onCancelClick={ this.onCancelClick }
|
||||
onWidgetLoad={ this.props.onWidgetLoad }/>;
|
||||
key={link}
|
||||
link={link}
|
||||
mxEvent={this.props.mxEvent}
|
||||
onCancelClick={this.onCancelClick}
|
||||
onWidgetLoad={this.props.onWidgetLoad} />;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -393,7 +385,7 @@ module.exports = React.createClass({
|
|||
className="mx_MEmoteBody_sender"
|
||||
onClick={this.onEmoteSenderClick}
|
||||
>
|
||||
{name}
|
||||
{ name }
|
||||
</EmojiText>
|
||||
|
||||
{ body }
|
||||
|
|
|
@ -16,9 +16,9 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
const React = require('react');
|
||||
|
||||
var TextForEvent = require('../../../TextForEvent');
|
||||
const TextForEvent = require('../../../TextForEvent');
|
||||
import sdk from '../../../index';
|
||||
|
||||
module.exports = React.createClass({
|
||||
|
@ -31,10 +31,10 @@ module.exports = React.createClass({
|
|||
|
||||
render: function() {
|
||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||
var text = TextForEvent.textForEvent(this.props.mxEvent);
|
||||
const text = TextForEvent.textForEvent(this.props.mxEvent);
|
||||
if (text == null || text.length === 0) return null;
|
||||
return (
|
||||
<EmojiText element="div" className="mx_TextualEvent">{text}</EmojiText>
|
||||
<EmojiText element="div" className="mx_TextualEvent">{ text }</EmojiText>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -15,12 +15,12 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import Promise from 'bluebird';
|
||||
var React = require('react');
|
||||
var ObjectUtils = require("../../../ObjectUtils");
|
||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
var sdk = require("../../../index");
|
||||
const React = require('react');
|
||||
const ObjectUtils = require("../../../ObjectUtils");
|
||||
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
const sdk = require("../../../index");
|
||||
import { _t } from '../../../languageHandler';
|
||||
var Modal = require("../../../Modal");
|
||||
const Modal = require("../../../Modal");
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'AliasSettings',
|
||||
|
@ -30,14 +30,14 @@ module.exports = React.createClass({
|
|||
canSetCanonicalAlias: React.PropTypes.bool.isRequired,
|
||||
canSetAliases: React.PropTypes.bool.isRequired,
|
||||
aliasEvents: React.PropTypes.array, // [MatrixEvent]
|
||||
canonicalAliasEvent: React.PropTypes.object // MatrixEvent
|
||||
canonicalAliasEvent: React.PropTypes.object, // MatrixEvent
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
canSetAliases: false,
|
||||
canSetCanonicalAlias: false,
|
||||
aliasEvents: []
|
||||
aliasEvents: [],
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -48,12 +48,12 @@ module.exports = React.createClass({
|
|||
recalculateState: function(aliasEvents, canonicalAliasEvent) {
|
||||
aliasEvents = aliasEvents || [];
|
||||
|
||||
var state = {
|
||||
const state = {
|
||||
domainToAliases: {}, // { domain.com => [#alias1:domain.com, #alias2:domain.com] }
|
||||
remoteDomains: [], // [ domain.com, foobar.com ]
|
||||
canonicalAlias: null // #canonical:domain.com
|
||||
canonicalAlias: null, // #canonical:domain.com
|
||||
};
|
||||
var localDomain = MatrixClientPeg.get().getDomain();
|
||||
const localDomain = MatrixClientPeg.get().getDomain();
|
||||
|
||||
state.domainToAliases = this.aliasEventsToDictionary(aliasEvents);
|
||||
|
||||
|
@ -69,26 +69,26 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
saveSettings: function() {
|
||||
var promises = [];
|
||||
let promises = [];
|
||||
|
||||
// save new aliases for m.room.aliases
|
||||
var aliasOperations = this.getAliasOperations();
|
||||
for (var i = 0; i < aliasOperations.length; i++) {
|
||||
var alias_operation = aliasOperations[i];
|
||||
const aliasOperations = this.getAliasOperations();
|
||||
for (let i = 0; i < aliasOperations.length; i++) {
|
||||
const alias_operation = aliasOperations[i];
|
||||
console.log("alias %s %s", alias_operation.place, alias_operation.val);
|
||||
switch (alias_operation.place) {
|
||||
case 'add':
|
||||
promises.push(
|
||||
MatrixClientPeg.get().createAlias(
|
||||
alias_operation.val, this.props.roomId
|
||||
)
|
||||
alias_operation.val, this.props.roomId,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case 'del':
|
||||
promises.push(
|
||||
MatrixClientPeg.get().deleteAlias(
|
||||
alias_operation.val
|
||||
)
|
||||
alias_operation.val,
|
||||
),
|
||||
);
|
||||
break;
|
||||
default:
|
||||
|
@ -98,7 +98,7 @@ module.exports = React.createClass({
|
|||
|
||||
|
||||
// save new canonical alias
|
||||
var oldCanonicalAlias = null;
|
||||
let oldCanonicalAlias = null;
|
||||
if (this.props.canonicalAliasEvent) {
|
||||
oldCanonicalAlias = this.props.canonicalAliasEvent.getContent().alias;
|
||||
}
|
||||
|
@ -107,9 +107,9 @@ module.exports = React.createClass({
|
|||
promises = [Promise.all(promises).then(
|
||||
MatrixClientPeg.get().sendStateEvent(
|
||||
this.props.roomId, "m.room.canonical_alias", {
|
||||
alias: this.state.canonicalAlias
|
||||
}, ""
|
||||
)
|
||||
alias: this.state.canonicalAlias,
|
||||
}, "",
|
||||
),
|
||||
)];
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
aliasEventsToDictionary: function(aliasEvents) { // m.room.alias events
|
||||
var dict = {};
|
||||
const dict = {};
|
||||
aliasEvents.forEach((event) => {
|
||||
dict[event.getStateKey()] = (
|
||||
(event.getContent().aliases || []).slice() // shallow-copy
|
||||
|
@ -132,7 +132,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
getAliasOperations: function() {
|
||||
var oldAliases = this.aliasEventsToDictionary(this.props.aliasEvents);
|
||||
const oldAliases = this.aliasEventsToDictionary(this.props.aliasEvents);
|
||||
return ObjectUtils.getKeyValueArrayDiffs(oldAliases, this.state.domainToAliases);
|
||||
},
|
||||
|
||||
|
@ -191,26 +191,26 @@ module.exports = React.createClass({
|
|||
|
||||
onCanonicalAliasChange: function(event) {
|
||||
this.setState({
|
||||
canonicalAlias: event.target.value
|
||||
canonicalAlias: event.target.value,
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var self = this;
|
||||
var EditableText = sdk.getComponent("elements.EditableText");
|
||||
var EditableItemList = sdk.getComponent("elements.EditableItemList");
|
||||
var localDomain = MatrixClientPeg.get().getDomain();
|
||||
const self = this;
|
||||
const EditableText = sdk.getComponent("elements.EditableText");
|
||||
const EditableItemList = sdk.getComponent("elements.EditableItemList");
|
||||
const localDomain = MatrixClientPeg.get().getDomain();
|
||||
|
||||
var canonical_alias_section;
|
||||
let canonical_alias_section;
|
||||
if (this.props.canSetCanonicalAlias) {
|
||||
canonical_alias_section = (
|
||||
<select onChange={this.onCanonicalAliasChange} defaultValue={ this.state.canonicalAlias }>
|
||||
<select onChange={this.onCanonicalAliasChange} defaultValue={this.state.canonicalAlias}>
|
||||
<option value="" key="unset">{ _t('not specified') }</option>
|
||||
{
|
||||
Object.keys(self.state.domainToAliases).map(function(domain, i) {
|
||||
return self.state.domainToAliases[domain].map(function(alias, j) {
|
||||
return (
|
||||
<option value={ alias } key={ i + "_" + j }>
|
||||
<option value={alias} key={i + "_" + j}>
|
||||
{ alias }
|
||||
</option>
|
||||
);
|
||||
|
@ -219,34 +219,33 @@ module.exports = React.createClass({
|
|||
}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
canonical_alias_section = (
|
||||
<b>{ this.state.canonicalAlias || _t('not set') }</b>
|
||||
);
|
||||
}
|
||||
|
||||
var remote_aliases_section;
|
||||
let remote_aliases_section;
|
||||
if (this.state.remoteDomains.length) {
|
||||
remote_aliases_section = (
|
||||
<div>
|
||||
<div className="mx_RoomSettings_aliasLabel">
|
||||
{_t("Remote addresses for this room:")}
|
||||
{ _t("Remote addresses for this room:") }
|
||||
</div>
|
||||
<div className="mx_RoomSettings_aliasesTable">
|
||||
{ this.state.remoteDomains.map((domain, i) => {
|
||||
return this.state.domainToAliases[domain].map(function(alias, j) {
|
||||
return (
|
||||
<div className="mx_RoomSettings_aliasesTableRow" key={ i + "_" + j }>
|
||||
<div className="mx_RoomSettings_aliasesTableRow" key={i + "_" + j}>
|
||||
<EditableText
|
||||
className="mx_RoomSettings_alias mx_RoomSettings_editable"
|
||||
blurToCancel={ false }
|
||||
editable={ false }
|
||||
initialValue={ alias } />
|
||||
blurToCancel={false}
|
||||
editable={false}
|
||||
initialValue={alias} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
})}
|
||||
}) }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -14,16 +14,16 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
import Promise from 'bluebird';
|
||||
var React = require('react');
|
||||
const React = require('react');
|
||||
|
||||
var sdk = require('../../../index');
|
||||
var Tinter = require('../../../Tinter');
|
||||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||
var Modal = require("../../../Modal");
|
||||
const sdk = require('../../../index');
|
||||
const Tinter = require('../../../Tinter');
|
||||
const MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||
const Modal = require("../../../Modal");
|
||||
|
||||
import dis from '../../../dispatcher';
|
||||
|
||||
var ROOM_COLORS = [
|
||||
const ROOM_COLORS = [
|
||||
// magic room default values courtesy of Ribot
|
||||
["#76cfa6", "#eaf5f0"],
|
||||
["#81bddb", "#eaf1f4"],
|
||||
|
@ -41,21 +41,21 @@ module.exports = React.createClass({
|
|||
displayName: 'ColorSettings',
|
||||
|
||||
propTypes: {
|
||||
room: React.PropTypes.object.isRequired
|
||||
room: React.PropTypes.object.isRequired,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
var data = {
|
||||
const data = {
|
||||
index: 0,
|
||||
primary_color: ROOM_COLORS[0].primary_color,
|
||||
secondary_color: ROOM_COLORS[0].secondary_color,
|
||||
hasChanged: false
|
||||
hasChanged: false,
|
||||
};
|
||||
var event = this.props.room.getAccountData("org.matrix.room.color_scheme");
|
||||
const event = this.props.room.getAccountData("org.matrix.room.color_scheme");
|
||||
if (!event) {
|
||||
return data;
|
||||
}
|
||||
var scheme = event.getContent();
|
||||
const scheme = event.getContent();
|
||||
data.primary_color = scheme.primary_color;
|
||||
data.secondary_color = scheme.secondary_color;
|
||||
data.index = this._getColorIndex(data);
|
||||
|
@ -64,7 +64,7 @@ module.exports = React.createClass({
|
|||
// append the unrecognised colours to our palette
|
||||
data.index = ROOM_COLORS.length;
|
||||
ROOM_COLORS.push([
|
||||
scheme.primary_color, scheme.secondary_color
|
||||
scheme.primary_color, scheme.secondary_color,
|
||||
]);
|
||||
}
|
||||
return data;
|
||||
|
@ -74,7 +74,7 @@ module.exports = React.createClass({
|
|||
if (!this.state.hasChanged) {
|
||||
return Promise.resolve(); // They didn't explicitly give a color to save.
|
||||
}
|
||||
var originalState = this.getInitialState();
|
||||
const originalState = this.getInitialState();
|
||||
if (originalState.primary_color !== this.state.primary_color ||
|
||||
originalState.secondary_color !== this.state.secondary_color) {
|
||||
console.log("ColorSettings: Saving new color");
|
||||
|
@ -84,8 +84,8 @@ module.exports = React.createClass({
|
|||
return MatrixClientPeg.get().setRoomAccountData(
|
||||
this.props.room.roomId, "org.matrix.room.color_scheme", {
|
||||
primary_color: this.state.primary_color,
|
||||
secondary_color: this.state.secondary_color
|
||||
}
|
||||
secondary_color: this.state.secondary_color,
|
||||
},
|
||||
).catch(function(err) {
|
||||
if (err.errcode == 'M_GUEST_ACCESS_FORBIDDEN') {
|
||||
dis.dispatch({action: 'view_set_mxid'});
|
||||
|
@ -100,8 +100,8 @@ module.exports = React.createClass({
|
|||
return -1;
|
||||
}
|
||||
// XXX: we should validate these values
|
||||
for (var i = 0; i < ROOM_COLORS.length; i++) {
|
||||
var room_color = ROOM_COLORS[i];
|
||||
for (let i = 0; i < ROOM_COLORS.length; i++) {
|
||||
const room_color = ROOM_COLORS[i];
|
||||
if (room_color[0] === String(scheme.primary_color).toLowerCase() &&
|
||||
room_color[1] === String(scheme.secondary_color).toLowerCase()) {
|
||||
return i;
|
||||
|
@ -117,34 +117,34 @@ module.exports = React.createClass({
|
|||
index: index,
|
||||
primary_color: ROOM_COLORS[index][0],
|
||||
secondary_color: ROOM_COLORS[index][1],
|
||||
hasChanged: true
|
||||
hasChanged: true,
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="mx_RoomSettings_roomColors">
|
||||
{ROOM_COLORS.map((room_color, i) => {
|
||||
var selected;
|
||||
{ ROOM_COLORS.map((room_color, i) => {
|
||||
let selected;
|
||||
if (i === this.state.index) {
|
||||
selected = (
|
||||
<div className="mx_RoomSettings_roomColor_selected">
|
||||
<img src="img/tick.svg" width="17" height="14" alt="./"/>
|
||||
<img src="img/tick.svg" width="17" height="14" alt="./" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
var boundClick = this._onColorSchemeChanged.bind(this, i);
|
||||
const boundClick = this._onColorSchemeChanged.bind(this, i);
|
||||
return (
|
||||
<div className="mx_RoomSettings_roomColor"
|
||||
key={ "room_color_" + i }
|
||||
key={"room_color_" + i}
|
||||
style={{ backgroundColor: room_color[1] }}
|
||||
onClick={ boundClick }>
|
||||
onClick={boundClick}>
|
||||
{ selected }
|
||||
<div className="mx_RoomSettings_roomColorPrimary" style={{ backgroundColor: room_color[0] }}></div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
}) }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -15,11 +15,11 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import Promise from 'bluebird';
|
||||
var React = require('react');
|
||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
var sdk = require("../../../index");
|
||||
var Modal = require("../../../Modal");
|
||||
var UserSettingsStore = require('../../../UserSettingsStore');
|
||||
const React = require('react');
|
||||
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
const sdk = require("../../../index");
|
||||
const Modal = require("../../../Modal");
|
||||
const UserSettingsStore = require('../../../UserSettingsStore');
|
||||
import { _t, _tJsx } from '../../../languageHandler';
|
||||
|
||||
|
||||
|
@ -31,11 +31,11 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
getInitialState: function() {
|
||||
var cli = MatrixClientPeg.get();
|
||||
var roomState = this.props.room.currentState;
|
||||
const cli = MatrixClientPeg.get();
|
||||
const roomState = this.props.room.currentState;
|
||||
|
||||
var roomPreviewUrls = this.props.room.currentState.getStateEvents('org.matrix.room.preview_urls', '');
|
||||
var userPreviewUrls = this.props.room.getAccountData("org.matrix.room.preview_urls");
|
||||
const roomPreviewUrls = this.props.room.currentState.getStateEvents('org.matrix.room.preview_urls', '');
|
||||
const userPreviewUrls = this.props.room.getAccountData("org.matrix.room.preview_urls");
|
||||
|
||||
return {
|
||||
globalDisableUrlPreview: (roomPreviewUrls && roomPreviewUrls.getContent().disable) || false,
|
||||
|
@ -49,37 +49,37 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
saveSettings: function() {
|
||||
var promises = [];
|
||||
const promises = [];
|
||||
|
||||
if (this.state.globalDisableUrlPreview !== this.originalState.globalDisableUrlPreview) {
|
||||
console.log("UrlPreviewSettings: Updating room's preview_urls state event");
|
||||
promises.push(
|
||||
MatrixClientPeg.get().sendStateEvent(
|
||||
this.props.room.roomId, "org.matrix.room.preview_urls", {
|
||||
disable: this.state.globalDisableUrlPreview
|
||||
}, ""
|
||||
)
|
||||
disable: this.state.globalDisableUrlPreview,
|
||||
}, "",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
var content = undefined;
|
||||
let content = undefined;
|
||||
if (this.state.userDisableUrlPreview !== this.originalState.userDisableUrlPreview) {
|
||||
console.log("UrlPreviewSettings: Disabling user's per-room preview_urls");
|
||||
content = this.state.userDisableUrlPreview ? { disable : true } : {};
|
||||
content = this.state.userDisableUrlPreview ? { disable: true } : {};
|
||||
}
|
||||
|
||||
if (this.state.userEnableUrlPreview !== this.originalState.userEnableUrlPreview) {
|
||||
console.log("UrlPreviewSettings: Enabling user's per-room preview_urls");
|
||||
if (!content || content.disable === undefined) {
|
||||
content = this.state.userEnableUrlPreview ? { disable : false } : {};
|
||||
content = this.state.userEnableUrlPreview ? { disable: false } : {};
|
||||
}
|
||||
}
|
||||
|
||||
if (content) {
|
||||
promises.push(
|
||||
MatrixClientPeg.get().setRoomAccountData(
|
||||
this.props.room.roomId, "org.matrix.room.preview_urls", content
|
||||
)
|
||||
this.props.room.roomId, "org.matrix.room.preview_urls", content,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -109,62 +109,59 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var self = this;
|
||||
var roomState = this.props.room.currentState;
|
||||
var cli = MatrixClientPeg.get();
|
||||
const self = this;
|
||||
const roomState = this.props.room.currentState;
|
||||
const cli = MatrixClientPeg.get();
|
||||
|
||||
var maySetRoomPreviewUrls = roomState.mayClientSendStateEvent('org.matrix.room.preview_urls', cli);
|
||||
var disableRoomPreviewUrls;
|
||||
const maySetRoomPreviewUrls = roomState.mayClientSendStateEvent('org.matrix.room.preview_urls', cli);
|
||||
let disableRoomPreviewUrls;
|
||||
if (maySetRoomPreviewUrls) {
|
||||
disableRoomPreviewUrls =
|
||||
<label>
|
||||
<input type="checkbox" ref="globalDisableUrlPreview"
|
||||
onChange={ this.onGlobalDisableUrlPreviewChange }
|
||||
checked={ this.state.globalDisableUrlPreview } />
|
||||
{_t("Disable URL previews by default for participants in this room")}
|
||||
onChange={this.onGlobalDisableUrlPreviewChange}
|
||||
checked={this.state.globalDisableUrlPreview} />
|
||||
{ _t("Disable URL previews by default for participants in this room") }
|
||||
</label>;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
disableRoomPreviewUrls =
|
||||
<label>
|
||||
{_t("URL previews are %(globalDisableUrlPreview)s by default for participants in this room.", {globalDisableUrlPreview: this.state.globalDisableUrlPreview ? _t("disabled") : _t("enabled")})}
|
||||
{ _t("URL previews are %(globalDisableUrlPreview)s by default for participants in this room.", {globalDisableUrlPreview: this.state.globalDisableUrlPreview ? _t("disabled") : _t("enabled")}) }
|
||||
</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>)
|
||||
_tJsx("You have <a>disabled</a> URL previews by default.", /<a>(.*?)<\/a>/, (sub)=><a href="#/settings">{ sub }</a>)
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
urlPreviewText = (
|
||||
_tJsx("You have <a>enabled</a> URL previews by default.", /<a>(.*?)<\/a>/, (sub)=><a href="#/settings">{sub}</a>)
|
||||
_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>
|
||||
<h3>{ _t("URL Previews") }</h3>
|
||||
|
||||
<label>
|
||||
{urlPreviewText}
|
||||
{ urlPreviewText }
|
||||
</label>
|
||||
{ disableRoomPreviewUrls }
|
||||
<label>
|
||||
<input type="checkbox" ref="userEnableUrlPreview"
|
||||
onChange={ this.onUserEnableUrlPreviewChange }
|
||||
checked={ this.state.userEnableUrlPreview } />
|
||||
{_t("Enable URL previews for this room (affects only you)")}
|
||||
onChange={this.onUserEnableUrlPreviewChange}
|
||||
checked={this.state.userEnableUrlPreview} />
|
||||
{ _t("Enable URL previews for this room (affects only you)") }
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" ref="userDisableUrlPreview"
|
||||
onChange={ this.onUserDisableUrlPreviewChange }
|
||||
checked={ this.state.userDisableUrlPreview } />
|
||||
{_t("Disable URL previews for this room (affects only you)")}
|
||||
onChange={this.onUserDisableUrlPreviewChange}
|
||||
checked={this.state.userDisableUrlPreview} />
|
||||
{ _t("Disable URL previews for this room (affects only you)") }
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -251,15 +251,15 @@ export default class Autocomplete extends React.Component {
|
|||
|
||||
return completions.length > 0 ? (
|
||||
<div key={i} className="mx_Autocomplete_ProviderSection">
|
||||
<EmojiText element="div" className="mx_Autocomplete_provider_name">{completionResult.provider.getName()}</EmojiText>
|
||||
{completionResult.provider.renderCompletions(completions)}
|
||||
<EmojiText element="div" className="mx_Autocomplete_provider_name">{ completionResult.provider.getName() }</EmojiText>
|
||||
{ completionResult.provider.renderCompletions(completions) }
|
||||
</div>
|
||||
) : null;
|
||||
}).filter((completion) => !!completion);
|
||||
|
||||
return !this.state.hide && renderedCompletions.length > 0 ? (
|
||||
<div className="mx_Autocomplete" ref={(e) => this.container = e}>
|
||||
{renderedCompletions}
|
||||
{ renderedCompletions }
|
||||
</div>
|
||||
) : null;
|
||||
}
|
||||
|
|
|
@ -83,9 +83,9 @@ module.exports = React.createClass({
|
|||
<div className="mx_RoomView_fileDropTarget">
|
||||
<div className="mx_RoomView_fileDropTargetLabel"
|
||||
title={_t("Drop File Here")}>
|
||||
<TintableSvg src="img/upload-big.svg" width="45" height="59"/>
|
||||
<br/>
|
||||
{_t("Drop file here to upload")}
|
||||
<TintableSvg src="img/upload-big.svg" width="45" height="59" />
|
||||
<br />
|
||||
{ _t("Drop file here to upload") }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -99,23 +99,23 @@ module.exports = React.createClass({
|
|||
supportedText = _t(" (unsupported)");
|
||||
} else {
|
||||
joinNode = (<span>
|
||||
{_tJsx(
|
||||
{ _tJsx(
|
||||
"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>,
|
||||
]
|
||||
)}
|
||||
(sub) => <a onClick={(event)=>{ this.onConferenceNotificationClick(event, 'voice');}} href="#">{ sub }</a>,
|
||||
(sub) => <a onClick={(event)=>{ this.onConferenceNotificationClick(event, 'video');}} href="#">{ sub }</a>,
|
||||
],
|
||||
) }
|
||||
</span>);
|
||||
}
|
||||
// XXX: the translation here isn't great: appending ' (unsupported)' is likely to not make sense in many languages,
|
||||
// but there are translations for this in the languages we do have so I'm leaving it for now.
|
||||
conferenceCallNotification = (
|
||||
<div className="mx_RoomView_ongoingConfCallNotification">
|
||||
{_t("Ongoing conference call%(supportedText)s.", {supportedText: supportedText})}
|
||||
{ _t("Ongoing conference call%(supportedText)s.", {supportedText: supportedText}) }
|
||||
|
||||
{joinNode}
|
||||
{ joinNode }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -16,18 +16,18 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
const React = require('react');
|
||||
|
||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
var sdk = require('../../../index');
|
||||
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
const sdk = require('../../../index');
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
|
||||
var PRESENCE_CLASS = {
|
||||
const PRESENCE_CLASS = {
|
||||
"offline": "mx_EntityTile_offline",
|
||||
"online": "mx_EntityTile_online",
|
||||
"unavailable": "mx_EntityTile_unavailable"
|
||||
"unavailable": "mx_EntityTile_unavailable",
|
||||
};
|
||||
|
||||
|
||||
|
@ -62,7 +62,7 @@ module.exports = React.createClass({
|
|||
showInviteButton: React.PropTypes.bool,
|
||||
shouldComponentUpdate: React.PropTypes.func,
|
||||
onClick: React.PropTypes.func,
|
||||
suppressOnHover: React.PropTypes.bool
|
||||
suppressOnHover: React.PropTypes.bool,
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
|
@ -73,13 +73,13 @@ module.exports = React.createClass({
|
|||
presenceLastActiveAgo: 0,
|
||||
presenceLastTs: 0,
|
||||
showInviteButton: false,
|
||||
suppressOnHover: false
|
||||
suppressOnHover: false,
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
hover: false
|
||||
hover: false,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -98,38 +98,37 @@ module.exports = React.createClass({
|
|||
|
||||
render: function() {
|
||||
const presenceClass = presenceClassForMember(
|
||||
this.props.presenceState, this.props.presenceLastActiveAgo
|
||||
this.props.presenceState, this.props.presenceLastActiveAgo,
|
||||
);
|
||||
|
||||
var mainClassName = "mx_EntityTile ";
|
||||
let mainClassName = "mx_EntityTile ";
|
||||
mainClassName += presenceClass + (this.props.className ? (" " + this.props.className) : "");
|
||||
var nameEl;
|
||||
let nameEl;
|
||||
const {name} = this.props;
|
||||
|
||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||
if (this.state.hover && !this.props.suppressOnHover) {
|
||||
var activeAgo = this.props.presenceLastActiveAgo ?
|
||||
const activeAgo = this.props.presenceLastActiveAgo ?
|
||||
(Date.now() - (this.props.presenceLastTs - this.props.presenceLastActiveAgo)) : -1;
|
||||
|
||||
mainClassName += " mx_EntityTile_hover";
|
||||
var PresenceLabel = sdk.getComponent("rooms.PresenceLabel");
|
||||
const PresenceLabel = sdk.getComponent("rooms.PresenceLabel");
|
||||
nameEl = (
|
||||
<div className="mx_EntityTile_details">
|
||||
<img className="mx_EntityTile_chevron" src="img/member_chevron.png" width="8" height="12"/>
|
||||
<EmojiText element="div" className="mx_EntityTile_name_hover" dir="auto">{name}</EmojiText>
|
||||
<PresenceLabel activeAgo={ activeAgo }
|
||||
<img className="mx_EntityTile_chevron" src="img/member_chevron.png" width="8" height="12" />
|
||||
<EmojiText element="div" className="mx_EntityTile_name_hover" dir="auto">{ name }</EmojiText>
|
||||
<PresenceLabel activeAgo={activeAgo}
|
||||
currentlyActive={this.props.presenceCurrentlyActive}
|
||||
presenceState={this.props.presenceState} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
nameEl = (
|
||||
<EmojiText element="div" className="mx_EntityTile_name" dir="auto">{name}</EmojiText>
|
||||
<EmojiText element="div" className="mx_EntityTile_name" dir="auto">{ name }</EmojiText>
|
||||
);
|
||||
}
|
||||
|
||||
var inviteButton;
|
||||
let inviteButton;
|
||||
if (this.props.showInviteButton) {
|
||||
inviteButton = (
|
||||
<div className="mx_EntityTile_invite">
|
||||
|
@ -138,25 +137,25 @@ module.exports = React.createClass({
|
|||
);
|
||||
}
|
||||
|
||||
var power;
|
||||
var powerLevel = this.props.powerLevel;
|
||||
let power;
|
||||
const powerLevel = this.props.powerLevel;
|
||||
if (powerLevel >= 50 && powerLevel < 99) {
|
||||
power = <img src="img/mod.svg" className="mx_EntityTile_power" width="16" height="17" alt={_t("Moderator")}/>;
|
||||
power = <img src="img/mod.svg" className="mx_EntityTile_power" width="16" height="17" alt={_t("Moderator")} />;
|
||||
}
|
||||
if (powerLevel >= 99) {
|
||||
power = <img src="img/admin.svg" className="mx_EntityTile_power" width="16" height="17" alt={_t("Admin")}/>;
|
||||
power = <img src="img/admin.svg" className="mx_EntityTile_power" width="16" height="17" alt={_t("Admin")} />;
|
||||
}
|
||||
|
||||
|
||||
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
|
||||
var av = this.props.avatarJsx || <BaseAvatar name={this.props.name} width={36} height={36} />;
|
||||
const av = this.props.avatarJsx || <BaseAvatar name={this.props.name} width={36} height={36} />;
|
||||
|
||||
return (
|
||||
<AccessibleButton className={mainClassName} title={ this.props.title }
|
||||
onClick={ this.props.onClick } onMouseEnter={ this.mouseEnter }
|
||||
onMouseLeave={ this.mouseLeave }>
|
||||
<AccessibleButton className={mainClassName} title={this.props.title}
|
||||
onClick={this.props.onClick} onMouseEnter={this.mouseEnter}
|
||||
onMouseLeave={this.mouseLeave}>
|
||||
<div className="mx_EntityTile_avatar">
|
||||
{ av }
|
||||
{ power }
|
||||
|
@ -165,5 +164,5 @@ module.exports = React.createClass({
|
|||
{ inviteButton }
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -17,38 +17,38 @@ limitations under the License.
|
|||
'use strict';
|
||||
|
||||
|
||||
var React = require('react');
|
||||
var classNames = require("classnames");
|
||||
const React = require('react');
|
||||
const classNames = require("classnames");
|
||||
import { _t } from '../../../languageHandler';
|
||||
var Modal = require('../../../Modal');
|
||||
const Modal = require('../../../Modal');
|
||||
|
||||
var sdk = require('../../../index');
|
||||
var TextForEvent = require('../../../TextForEvent');
|
||||
const sdk = require('../../../index');
|
||||
const TextForEvent = require('../../../TextForEvent');
|
||||
import withMatrixClient from '../../../wrappers/withMatrixClient';
|
||||
|
||||
var ContextualMenu = require('../../structures/ContextualMenu');
|
||||
const ContextualMenu = require('../../structures/ContextualMenu');
|
||||
import dis from '../../../dispatcher';
|
||||
|
||||
var ObjectUtils = require('../../../ObjectUtils');
|
||||
const ObjectUtils = require('../../../ObjectUtils');
|
||||
|
||||
var eventTileTypes = {
|
||||
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',
|
||||
'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.power_levels' : 'messages.TextualEvent',
|
||||
'm.room.member': 'messages.TextualEvent',
|
||||
'm.call.invite': 'messages.TextualEvent',
|
||||
'm.call.answer': 'messages.TextualEvent',
|
||||
'm.call.hangup': '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.power_levels': 'messages.TextualEvent',
|
||||
|
||||
'im.vector.modular.widgets': 'messages.TextualEvent',
|
||||
};
|
||||
|
||||
var MAX_READ_AVATARS = 5;
|
||||
const MAX_READ_AVATARS = 5;
|
||||
|
||||
// Our component structure for EventTiles on the timeline is:
|
||||
//
|
||||
|
@ -177,7 +177,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
var client = this.props.matrixClient;
|
||||
const client = this.props.matrixClient;
|
||||
client.removeListener("deviceVerificationChanged",
|
||||
this.onDeviceVerificationChanged);
|
||||
this.props.mxEvent.removeListener("Event.decrypted", this._onDecrypted);
|
||||
|
@ -204,20 +204,20 @@ module.exports = withMatrixClient(React.createClass({
|
|||
|
||||
const verified = await this.props.matrixClient.isEventSenderVerified(mxEvent);
|
||||
this.setState({
|
||||
verified: verified
|
||||
verified: verified,
|
||||
});
|
||||
},
|
||||
|
||||
_propsEqual: function(objA, objB) {
|
||||
var keysA = Object.keys(objA);
|
||||
var keysB = Object.keys(objB);
|
||||
const keysA = Object.keys(objA);
|
||||
const keysB = Object.keys(objB);
|
||||
|
||||
if (keysA.length !== keysB.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < keysA.length; i++) {
|
||||
var key = keysA[i];
|
||||
for (let i = 0; i < keysA.length; i++) {
|
||||
const key = keysA[i];
|
||||
|
||||
if (!objB.hasOwnProperty(key)) {
|
||||
return false;
|
||||
|
@ -225,8 +225,8 @@ module.exports = withMatrixClient(React.createClass({
|
|||
|
||||
// need to deep-compare readReceipts
|
||||
if (key == 'readReceipts') {
|
||||
var rA = objA[key];
|
||||
var rB = objB[key];
|
||||
const rA = objA[key];
|
||||
const rB = objB[key];
|
||||
if (rA === rB) {
|
||||
continue;
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
if (rA.length !== rB.length) {
|
||||
return false;
|
||||
}
|
||||
for (var j = 0; j < rA.length; j++) {
|
||||
for (let j = 0; j < rA.length; j++) {
|
||||
if (rA[j].roomMember.userId !== rB[j].roomMember.userId) {
|
||||
return false;
|
||||
}
|
||||
|
@ -253,12 +253,11 @@ module.exports = withMatrixClient(React.createClass({
|
|||
},
|
||||
|
||||
shouldHighlight: function() {
|
||||
var actions = this.props.matrixClient.getPushActionsForEvent(this.props.mxEvent);
|
||||
const actions = this.props.matrixClient.getPushActionsForEvent(this.props.mxEvent);
|
||||
if (!actions || !actions.tweaks) { return false; }
|
||||
|
||||
// don't show self-highlights from another of our clients
|
||||
if (this.props.mxEvent.getSender() === this.props.matrixClient.credentials.userId)
|
||||
{
|
||||
if (this.props.mxEvent.getSender() === this.props.matrixClient.credentials.userId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -266,13 +265,13 @@ module.exports = withMatrixClient(React.createClass({
|
|||
},
|
||||
|
||||
onEditClicked: function(e) {
|
||||
var MessageContextMenu = sdk.getComponent('context_menus.MessageContextMenu');
|
||||
var buttonRect = e.target.getBoundingClientRect();
|
||||
const MessageContextMenu = sdk.getComponent('context_menus.MessageContextMenu');
|
||||
const buttonRect = e.target.getBoundingClientRect();
|
||||
|
||||
// The window X and Y offsets are to adjust position when zoomed in to page
|
||||
var x = buttonRect.right + window.pageXOffset;
|
||||
var y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19;
|
||||
var self = this;
|
||||
const x = buttonRect.right + window.pageXOffset;
|
||||
const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19;
|
||||
const self = this;
|
||||
ContextualMenu.createMenu(MessageContextMenu, {
|
||||
chevronOffset: 10,
|
||||
mxEvent: this.props.mxEvent,
|
||||
|
@ -281,19 +280,18 @@ module.exports = withMatrixClient(React.createClass({
|
|||
eventTileOps: this.refs.tile && this.refs.tile.getEventTileOps ? this.refs.tile.getEventTileOps() : undefined,
|
||||
onFinished: function() {
|
||||
self.setState({menu: false});
|
||||
}
|
||||
},
|
||||
});
|
||||
this.setState({menu: true});
|
||||
},
|
||||
|
||||
toggleAllReadAvatars: function() {
|
||||
this.setState({
|
||||
allReadAvatars: !this.state.allReadAvatars
|
||||
allReadAvatars: !this.state.allReadAvatars,
|
||||
});
|
||||
},
|
||||
|
||||
getReadAvatars: function() {
|
||||
|
||||
// return early if there are no read receipts
|
||||
if (!this.props.readReceipts || this.props.readReceipts.length === 0) {
|
||||
return (<span className="mx_EventTile_readAvatars"></span>);
|
||||
|
@ -304,11 +302,11 @@ module.exports = withMatrixClient(React.createClass({
|
|||
const receiptOffset = 15;
|
||||
let left = 0;
|
||||
|
||||
var receipts = this.props.readReceipts || [];
|
||||
for (var i = 0; i < receipts.length; ++i) {
|
||||
var receipt = receipts[i];
|
||||
const receipts = this.props.readReceipts || [];
|
||||
for (let i = 0; i < receipts.length; ++i) {
|
||||
const receipt = receipts[i];
|
||||
|
||||
var hidden = true;
|
||||
let hidden = true;
|
||||
if ((i < MAX_READ_AVATARS) || this.state.allReadAvatars) {
|
||||
hidden = false;
|
||||
}
|
||||
|
@ -319,7 +317,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
// else set it proportional to index
|
||||
left = (hidden ? MAX_READ_AVATARS - 1 : i) * -receiptOffset;
|
||||
|
||||
var userId = receipt.roomMember.userId;
|
||||
const userId = receipt.roomMember.userId;
|
||||
var readReceiptInfo;
|
||||
|
||||
if (this.props.readReceiptMap) {
|
||||
|
@ -340,12 +338,12 @@ module.exports = withMatrixClient(React.createClass({
|
|||
onClick={this.toggleAllReadAvatars}
|
||||
timestamp={receipt.ts}
|
||||
showTwelveHour={this.props.isTwelveHour}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}
|
||||
var remText;
|
||||
let remText;
|
||||
if (!this.state.allReadAvatars) {
|
||||
var remainder = receipts.length - MAX_READ_AVATARS;
|
||||
const remainder = receipts.length - MAX_READ_AVATARS;
|
||||
if (remainder > 0) {
|
||||
remText = <span className="mx_EventTile_readAvatarRemainder"
|
||||
onClick={this.toggleAllReadAvatars}
|
||||
|
@ -369,7 +367,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
},
|
||||
|
||||
onCryptoClicked: function(e) {
|
||||
var event = this.props.mxEvent;
|
||||
const event = this.props.mxEvent;
|
||||
|
||||
Modal.createTrackedDialogAsync('Encrypted Event Dialog', '', (cb) => {
|
||||
require(['../../../async-components/views/dialogs/EncryptedEventDialog'], cb);
|
||||
|
@ -396,12 +394,12 @@ module.exports = withMatrixClient(React.createClass({
|
|||
|
||||
|
||||
if (ev.getContent().msgtype === 'm.bad.encrypted') {
|
||||
return <E2ePadlockUndecryptable {...props}/>;
|
||||
return <E2ePadlockUndecryptable {...props} />;
|
||||
} else if (ev.isEncrypted()) {
|
||||
if (this.state.verified) {
|
||||
return <E2ePadlockVerified {...props}/>;
|
||||
return <E2ePadlockVerified {...props} />;
|
||||
} else {
|
||||
return <E2ePadlockUnverified {...props}/>;
|
||||
return <E2ePadlockUnverified {...props} />;
|
||||
}
|
||||
} else {
|
||||
// XXX: if the event is being encrypted (ie eventSendStatus ===
|
||||
|
@ -412,7 +410,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
// open padlock
|
||||
const e2eEnabled = this.props.matrixClient.isRoomEncrypted(ev.getRoomId());
|
||||
if (e2eEnabled) {
|
||||
return <E2ePadlockUnencrypted {...props}/>;
|
||||
return <E2ePadlockUnencrypted {...props} />;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,27 +419,27 @@ module.exports = withMatrixClient(React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var MessageTimestamp = sdk.getComponent('messages.MessageTimestamp');
|
||||
var SenderProfile = sdk.getComponent('messages.SenderProfile');
|
||||
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||
const MessageTimestamp = sdk.getComponent('messages.MessageTimestamp');
|
||||
const SenderProfile = sdk.getComponent('messages.SenderProfile');
|
||||
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||
|
||||
//console.log("EventTile showUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview);
|
||||
|
||||
var content = this.props.mxEvent.getContent();
|
||||
var msgtype = content.msgtype;
|
||||
var eventType = this.props.mxEvent.getType();
|
||||
const content = this.props.mxEvent.getContent();
|
||||
const msgtype = content.msgtype;
|
||||
const eventType = this.props.mxEvent.getType();
|
||||
|
||||
// Info messages are basically information about commands processed on a room
|
||||
var isInfoMessage = (eventType !== 'm.room.message');
|
||||
const isInfoMessage = (eventType !== 'm.room.message');
|
||||
|
||||
var EventTileType = sdk.getComponent(eventTileTypes[eventType]);
|
||||
const EventTileType = sdk.getComponent(eventTileTypes[eventType]);
|
||||
// This shouldn't happen: the caller should check we support this type
|
||||
// before trying to instantiate us
|
||||
if (!EventTileType) {
|
||||
throw new Error("Event type not supported");
|
||||
}
|
||||
|
||||
var isSending = (['sending', 'queued', 'encrypting'].indexOf(this.props.eventSendStatus) !== -1);
|
||||
const isSending = (['sending', 'queued', 'encrypting'].indexOf(this.props.eventSendStatus) !== -1);
|
||||
const isRedacted = (eventType === 'm.room.message') && this.props.isRedacted;
|
||||
|
||||
const classes = classNames({
|
||||
|
@ -468,9 +466,9 @@ module.exports = withMatrixClient(React.createClass({
|
|||
this.props.mxEvent.getRoomId() + "/" +
|
||||
this.props.mxEvent.getId();
|
||||
|
||||
var readAvatars = this.getReadAvatars();
|
||||
const readAvatars = this.getReadAvatars();
|
||||
|
||||
var avatar, sender;
|
||||
let avatar, sender;
|
||||
let avatarSize;
|
||||
let needsSenderProfile;
|
||||
|
||||
|
@ -508,15 +506,14 @@ module.exports = withMatrixClient(React.createClass({
|
|||
if (msgtype === 'm.image') aux = _t('sent an image');
|
||||
else if (msgtype === 'm.video') aux = _t('sent a video');
|
||||
else if (msgtype === 'm.file') aux = _t('uploaded a file');
|
||||
sender = <SenderProfile onClick={ this.onSenderProfileClick } mxEvent={this.props.mxEvent} enableFlair={!aux} aux={aux} />;
|
||||
}
|
||||
else {
|
||||
sender = <SenderProfile onClick={this.onSenderProfileClick} mxEvent={this.props.mxEvent} enableFlair={!aux} aux={aux} />;
|
||||
} else {
|
||||
sender = <SenderProfile mxEvent={this.props.mxEvent} enableFlair={true} />;
|
||||
}
|
||||
}
|
||||
|
||||
const editButton = (
|
||||
<span className="mx_EventTile_editButton" title={ _t("Options") } onClick={this.onEditClicked} />
|
||||
<span className="mx_EventTile_editButton" title={_t("Options")} onClick={this.onEditClicked} />
|
||||
);
|
||||
|
||||
const timestamp = this.props.mxEvent.getTs() ?
|
||||
|
@ -527,13 +524,13 @@ module.exports = withMatrixClient(React.createClass({
|
|||
return (
|
||||
<div className={classes}>
|
||||
<div className="mx_EventTile_roomName">
|
||||
<a href={ permalink } onClick={this.onPermalinkClicked}>
|
||||
<a href={permalink} onClick={this.onPermalinkClicked}>
|
||||
{ room ? room.name : '' }
|
||||
</a>
|
||||
</div>
|
||||
<div className="mx_EventTile_senderDetails">
|
||||
{ avatar }
|
||||
<a href={ permalink } onClick={this.onPermalinkClicked}>
|
||||
<a href={permalink} onClick={this.onPermalinkClicked}>
|
||||
{ sender }
|
||||
{ timestamp }
|
||||
</a>
|
||||
|
@ -548,8 +545,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
else if (this.props.tileShape === "file_grid") {
|
||||
} else if (this.props.tileShape === "file_grid") {
|
||||
return (
|
||||
<div className={classes}>
|
||||
<div className="mx_EventTile_line" >
|
||||
|
@ -563,7 +559,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
</div>
|
||||
<a
|
||||
className="mx_EventTile_senderDetailsLink"
|
||||
href={ permalink }
|
||||
href={permalink}
|
||||
onClick={this.onPermalinkClicked}
|
||||
>
|
||||
<div className="mx_EventTile_senderDetails">
|
||||
|
@ -573,8 +569,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return (
|
||||
<div className={classes}>
|
||||
<div className="mx_EventTile_msgOption">
|
||||
|
@ -583,7 +578,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
{ avatar }
|
||||
{ sender }
|
||||
<div className="mx_EventTile_line">
|
||||
<a href={ permalink } onClick={this.onPermalinkClicked}>
|
||||
<a href={permalink} onClick={this.onPermalinkClicked}>
|
||||
{ timestamp }
|
||||
</a>
|
||||
{ this._renderE2EPadlock() }
|
||||
|
|
|
@ -16,16 +16,16 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
const React = require('react');
|
||||
|
||||
var sdk = require('../../../index');
|
||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
var ImageUtils = require('../../../ImageUtils');
|
||||
var Modal = require('../../../Modal');
|
||||
const sdk = require('../../../index');
|
||||
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
const ImageUtils = require('../../../ImageUtils');
|
||||
const Modal = require('../../../Modal');
|
||||
|
||||
var linkify = require('linkifyjs');
|
||||
var linkifyElement = require('linkifyjs/element');
|
||||
var linkifyMatrix = require('../../../linkify-matrix');
|
||||
const linkify = require('linkifyjs');
|
||||
const linkifyElement = require('linkifyjs/element');
|
||||
const linkifyMatrix = require('../../../linkify-matrix');
|
||||
linkifyMatrix(linkify);
|
||||
|
||||
module.exports = React.createClass({
|
||||
|
@ -40,7 +40,7 @@ module.exports = React.createClass({
|
|||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
preview: null
|
||||
preview: null,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -52,7 +52,7 @@ module.exports = React.createClass({
|
|||
}
|
||||
this.setState(
|
||||
{ preview: res },
|
||||
this.props.onWidgetLoad
|
||||
this.props.onWidgetLoad,
|
||||
);
|
||||
}, (error)=>{
|
||||
console.error("Failed to get preview for " + this.props.link + " " + error);
|
||||
|
@ -76,17 +76,17 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
onImageClick: function(ev) {
|
||||
var p = this.state.preview;
|
||||
const p = this.state.preview;
|
||||
if (ev.button != 0 || ev.metaKey) return;
|
||||
ev.preventDefault();
|
||||
var ImageView = sdk.getComponent("elements.ImageView");
|
||||
const ImageView = sdk.getComponent("elements.ImageView");
|
||||
|
||||
var src = p["og:image"];
|
||||
let src = p["og:image"];
|
||||
if (src && src.startsWith("mxc://")) {
|
||||
src = MatrixClientPeg.get().mxcUrlToHttp(src);
|
||||
}
|
||||
|
||||
var params = {
|
||||
const params = {
|
||||
src: src,
|
||||
width: p["og:image:width"],
|
||||
height: p["og:image:height"],
|
||||
|
@ -99,27 +99,27 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var p = this.state.preview;
|
||||
const p = this.state.preview;
|
||||
if (!p || Object.keys(p).length === 0) {
|
||||
return <div/>;
|
||||
return <div />;
|
||||
}
|
||||
|
||||
// FIXME: do we want to factor out all image displaying between this and MImageBody - especially for lightboxing?
|
||||
var image = p["og:image"];
|
||||
var imageMaxWidth = 100, imageMaxHeight = 100;
|
||||
let image = p["og:image"];
|
||||
let imageMaxWidth = 100, imageMaxHeight = 100;
|
||||
if (image && image.startsWith("mxc://")) {
|
||||
image = MatrixClientPeg.get().mxcUrlToHttp(image, imageMaxWidth, imageMaxHeight);
|
||||
}
|
||||
|
||||
var thumbHeight = imageMaxHeight;
|
||||
let thumbHeight = imageMaxHeight;
|
||||
if (p["og:image:width"] && p["og:image:height"]) {
|
||||
thumbHeight = ImageUtils.thumbHeight(p["og:image:width"], p["og:image:height"], imageMaxWidth, imageMaxHeight);
|
||||
}
|
||||
|
||||
var img;
|
||||
let img;
|
||||
if (image) {
|
||||
img = <div className="mx_LinkPreviewWidget_image" style={{ height: thumbHeight }}>
|
||||
<img style={{ maxWidth: imageMaxWidth, maxHeight: imageMaxHeight }} src={ image } onClick={ this.onImageClick }/>
|
||||
<img style={{ maxWidth: imageMaxWidth, maxHeight: imageMaxHeight }} src={image} onClick={this.onImageClick} />
|
||||
</div>;
|
||||
}
|
||||
|
||||
|
@ -127,15 +127,15 @@ module.exports = React.createClass({
|
|||
<div className="mx_LinkPreviewWidget" >
|
||||
{ img }
|
||||
<div className="mx_LinkPreviewWidget_caption">
|
||||
<div className="mx_LinkPreviewWidget_title"><a href={ this.props.link } target="_blank" rel="noopener">{ p["og:title"] }</a></div>
|
||||
<div className="mx_LinkPreviewWidget_title"><a href={this.props.link} target="_blank" rel="noopener">{ p["og:title"] }</a></div>
|
||||
<div className="mx_LinkPreviewWidget_siteName">{ p["og:site_name"] ? (" - " + p["og:site_name"]) : null }</div>
|
||||
<div className="mx_LinkPreviewWidget_description" ref="description">
|
||||
{ p["og:description"] }
|
||||
</div>
|
||||
</div>
|
||||
<img className="mx_LinkPreviewWidget_cancel" src="img/cancel.svg" width="18" height="18"
|
||||
onClick={ this.props.onCancelClick }/>
|
||||
onClick={this.props.onCancelClick} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -20,30 +20,30 @@ import { _t } from '../../../languageHandler';
|
|||
|
||||
export default class MemberDeviceInfo extends React.Component {
|
||||
render() {
|
||||
var indicator = null;
|
||||
var DeviceVerifyButtons = sdk.getComponent('elements.DeviceVerifyButtons');
|
||||
let indicator = null;
|
||||
const DeviceVerifyButtons = sdk.getComponent('elements.DeviceVerifyButtons');
|
||||
|
||||
if (this.props.device.isBlocked()) {
|
||||
indicator = (
|
||||
<div className="mx_MemberDeviceInfo_blacklisted">
|
||||
<img src="img/e2e-blocked.svg" width="12" height="12" style={{ marginLeft: "-1px" }} alt={_t("Blacklisted")}/>
|
||||
<img src="img/e2e-blocked.svg" width="12" height="12" style={{ marginLeft: "-1px" }} alt={_t("Blacklisted")} />
|
||||
</div>
|
||||
);
|
||||
} else if (this.props.device.isVerified()) {
|
||||
indicator = (
|
||||
<div className="mx_MemberDeviceInfo_verified">
|
||||
<img src="img/e2e-verified.svg" width="10" height="12" alt={_t("Verified")}/>
|
||||
<img src="img/e2e-verified.svg" width="10" height="12" alt={_t("Verified")} />
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
indicator = (
|
||||
<div className="mx_MemberDeviceInfo_unverified">
|
||||
<img src="img/e2e-warning.svg" width="15" height="12" style={{ marginLeft: "-2px" }} alt={_t("Unverified")}/>
|
||||
<img src="img/e2e-warning.svg" width="15" height="12" style={{ marginLeft: "-2px" }} alt={_t("Unverified")} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
var deviceName = this.props.device.ambiguous ?
|
||||
const deviceName = this.props.device.ambiguous ?
|
||||
(this.props.device.getDisplayName() ? this.props.device.getDisplayName() : "") + " (" + this.props.device.deviceId + ")" :
|
||||
this.props.device.getDisplayName();
|
||||
|
||||
|
@ -53,8 +53,8 @@ export default class MemberDeviceInfo extends React.Component {
|
|||
title={_t("device id: ") + this.props.device.deviceId} >
|
||||
<div className="mx_MemberDeviceInfo_deviceInfo">
|
||||
<div className="mx_MemberDeviceInfo_deviceId">
|
||||
{deviceName}
|
||||
{indicator}
|
||||
{ deviceName }
|
||||
{ indicator }
|
||||
</div>
|
||||
</div>
|
||||
<DeviceVerifyButtons userId={this.props.userId} device={this.props.device} />
|
||||
|
|
|
@ -55,7 +55,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
kick: false,
|
||||
ban: false,
|
||||
mute: false,
|
||||
modifyLevel: false
|
||||
modifyLevel: false,
|
||||
},
|
||||
muted: false,
|
||||
isTargetMod: false,
|
||||
|
@ -97,7 +97,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
var client = this.props.matrixClient;
|
||||
const client = this.props.matrixClient;
|
||||
if (client) {
|
||||
client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
|
||||
client.removeListener("Room", this.onRoom);
|
||||
|
@ -120,10 +120,10 @@ module.exports = withMatrixClient(React.createClass({
|
|||
},
|
||||
|
||||
_disambiguateDevices: function(devices) {
|
||||
var names = Object.create(null);
|
||||
for (var i = 0; i < devices.length; i++) {
|
||||
const names = Object.create(null);
|
||||
for (let i = 0; i < devices.length; i++) {
|
||||
var name = devices[i].getDisplayName();
|
||||
var indexList = names[name] || [];
|
||||
const indexList = names[name] || [];
|
||||
indexList.push(i);
|
||||
names[name] = indexList;
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
},
|
||||
|
||||
_updateStateForNewMember: function(member) {
|
||||
var newState = this._calculateOpsPermissions(member);
|
||||
const newState = this._calculateOpsPermissions(member);
|
||||
newState.devicesLoading = true;
|
||||
newState.devices = null;
|
||||
this.setState(newState);
|
||||
|
@ -211,11 +211,11 @@ module.exports = withMatrixClient(React.createClass({
|
|||
return;
|
||||
}
|
||||
|
||||
var cancelled = false;
|
||||
let cancelled = false;
|
||||
this._cancelDeviceList = function() { cancelled = true; };
|
||||
|
||||
var client = this.props.matrixClient;
|
||||
var self = this;
|
||||
const client = this.props.matrixClient;
|
||||
const self = this;
|
||||
client.downloadKeys([member.userId], true).then(() => {
|
||||
return client.getStoredDevicesForUser(member.userId);
|
||||
}).finally(function() {
|
||||
|
@ -260,7 +260,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
this.setState({ updating: this.state.updating + 1 });
|
||||
this.props.matrixClient.kick(
|
||||
this.props.member.roomId, this.props.member.userId,
|
||||
reason || undefined
|
||||
reason || undefined,
|
||||
).then(function() {
|
||||
// NO-OP; rely on the m.room.member event coming down else we could
|
||||
// get out of sync if we force setState here!
|
||||
|
@ -272,11 +272,11 @@ module.exports = withMatrixClient(React.createClass({
|
|||
title: _t("Failed to kick"),
|
||||
description: ((err && err.message) ? err.message : "Operation failed"),
|
||||
});
|
||||
}
|
||||
},
|
||||
).finally(()=>{
|
||||
this.setState({ updating: this.state.updating - 1 });
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -299,7 +299,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
} else {
|
||||
promise = this.props.matrixClient.ban(
|
||||
this.props.member.roomId, this.props.member.userId,
|
||||
reason || undefined
|
||||
reason || undefined,
|
||||
);
|
||||
}
|
||||
promise.then(
|
||||
|
@ -314,7 +314,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
title: _t("Error"),
|
||||
description: _t("Failed to ban user"),
|
||||
});
|
||||
}
|
||||
},
|
||||
).finally(()=>{
|
||||
this.setState({ updating: this.state.updating - 1 });
|
||||
});
|
||||
|
@ -323,30 +323,29 @@ module.exports = withMatrixClient(React.createClass({
|
|||
},
|
||||
|
||||
onMuteToggle: function() {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
var roomId = this.props.member.roomId;
|
||||
var target = this.props.member.userId;
|
||||
var room = this.props.matrixClient.getRoom(roomId);
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
const roomId = this.props.member.roomId;
|
||||
const target = this.props.member.userId;
|
||||
const room = this.props.matrixClient.getRoom(roomId);
|
||||
if (!room) {
|
||||
return;
|
||||
}
|
||||
var powerLevelEvent = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", ""
|
||||
const powerLevelEvent = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", "",
|
||||
);
|
||||
if (!powerLevelEvent) {
|
||||
return;
|
||||
}
|
||||
var isMuted = this.state.muted;
|
||||
var powerLevels = powerLevelEvent.getContent();
|
||||
var levelToSend = (
|
||||
const isMuted = this.state.muted;
|
||||
const powerLevels = powerLevelEvent.getContent();
|
||||
const levelToSend = (
|
||||
(powerLevels.events ? powerLevels.events["m.room.message"] : null) ||
|
||||
powerLevels.events_default
|
||||
);
|
||||
var level;
|
||||
let level;
|
||||
if (isMuted) { // unmute
|
||||
level = levelToSend;
|
||||
}
|
||||
else { // mute
|
||||
} else { // mute
|
||||
level = levelToSend - 1;
|
||||
}
|
||||
level = parseInt(level);
|
||||
|
@ -364,7 +363,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
title: _t("Error"),
|
||||
description: _t("Failed to mute user"),
|
||||
});
|
||||
}
|
||||
},
|
||||
).finally(()=>{
|
||||
this.setState({ updating: this.state.updating - 1 });
|
||||
});
|
||||
|
@ -372,28 +371,28 @@ module.exports = withMatrixClient(React.createClass({
|
|||
},
|
||||
|
||||
onModToggle: function() {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
var roomId = this.props.member.roomId;
|
||||
var target = this.props.member.userId;
|
||||
var room = this.props.matrixClient.getRoom(roomId);
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
const roomId = this.props.member.roomId;
|
||||
const target = this.props.member.userId;
|
||||
const room = this.props.matrixClient.getRoom(roomId);
|
||||
if (!room) {
|
||||
return;
|
||||
}
|
||||
var powerLevelEvent = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", ""
|
||||
const powerLevelEvent = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", "",
|
||||
);
|
||||
if (!powerLevelEvent) {
|
||||
return;
|
||||
}
|
||||
var me = room.getMember(this.props.matrixClient.credentials.userId);
|
||||
const me = room.getMember(this.props.matrixClient.credentials.userId);
|
||||
if (!me) {
|
||||
return;
|
||||
}
|
||||
var defaultLevel = powerLevelEvent.getContent().users_default;
|
||||
var modLevel = me.powerLevel - 1;
|
||||
const defaultLevel = powerLevelEvent.getContent().users_default;
|
||||
let modLevel = me.powerLevel - 1;
|
||||
if (modLevel > 50 && defaultLevel < 50) modLevel = 50; // try to stick with the vector level defaults
|
||||
// toggle the level
|
||||
var newLevel = this.state.isTargetMod ? defaultLevel : modLevel;
|
||||
const newLevel = this.state.isTargetMod ? defaultLevel : modLevel;
|
||||
this.setState({ updating: this.state.updating + 1 });
|
||||
this.props.matrixClient.setPowerLevel(roomId, target, parseInt(newLevel), powerLevelEvent).then(
|
||||
function() {
|
||||
|
@ -410,7 +409,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
description: _t("Failed to toggle moderator status"),
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
).finally(()=>{
|
||||
this.setState({ updating: this.state.updating - 1 });
|
||||
});
|
||||
|
@ -430,36 +429,36 @@ module.exports = withMatrixClient(React.createClass({
|
|||
title: _t("Error"),
|
||||
description: _t("Failed to change power level"),
|
||||
});
|
||||
}
|
||||
},
|
||||
).finally(()=>{
|
||||
this.setState({ updating: this.state.updating - 1 });
|
||||
}).done();
|
||||
},
|
||||
|
||||
onPowerChange: function(powerLevel) {
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
var roomId = this.props.member.roomId;
|
||||
var target = this.props.member.userId;
|
||||
var room = this.props.matrixClient.getRoom(roomId);
|
||||
var self = this;
|
||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
const roomId = this.props.member.roomId;
|
||||
const target = this.props.member.userId;
|
||||
const room = this.props.matrixClient.getRoom(roomId);
|
||||
const self = this;
|
||||
if (!room) {
|
||||
return;
|
||||
}
|
||||
var powerLevelEvent = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", ""
|
||||
const powerLevelEvent = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", "",
|
||||
);
|
||||
if (!powerLevelEvent) {
|
||||
return;
|
||||
}
|
||||
if (powerLevelEvent.getContent().users) {
|
||||
var myPower = powerLevelEvent.getContent().users[this.props.matrixClient.credentials.userId];
|
||||
const myPower = powerLevelEvent.getContent().users[this.props.matrixClient.credentials.userId];
|
||||
if (parseInt(myPower) === parseInt(powerLevel)) {
|
||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
Modal.createTrackedDialog('Promote to PL100 Warning', '', QuestionDialog, {
|
||||
title: _t("Warning!"),
|
||||
description:
|
||||
<div>
|
||||
{ _t("You will not be able to undo this change as you are promoting the user to have the same power level as yourself.") }<br/>
|
||||
{ _t("You will not be able to undo this change as you are promoting the user to have the same power level as yourself.") }<br />
|
||||
{ _t("Are you sure?") }
|
||||
</div>,
|
||||
button: _t("Continue"),
|
||||
|
@ -469,12 +468,10 @@ module.exports = withMatrixClient(React.createClass({
|
|||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this._applyPowerChange(roomId, target, powerLevel, powerLevelEvent);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this._applyPowerChange(roomId, target, powerLevel, powerLevelEvent);
|
||||
}
|
||||
},
|
||||
|
@ -497,14 +494,14 @@ module.exports = withMatrixClient(React.createClass({
|
|||
const defaultPerms = {
|
||||
can: {},
|
||||
muted: false,
|
||||
modifyLevel: false
|
||||
modifyLevel: false,
|
||||
};
|
||||
const room = this.props.matrixClient.getRoom(member.roomId);
|
||||
if (!room) {
|
||||
return defaultPerms;
|
||||
}
|
||||
const powerLevels = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", ""
|
||||
"m.room.power_levels", "",
|
||||
);
|
||||
if (!powerLevels) {
|
||||
return defaultPerms;
|
||||
|
@ -516,10 +513,10 @@ module.exports = withMatrixClient(React.createClass({
|
|||
const them = member;
|
||||
return {
|
||||
can: this._calculateCanPermissions(
|
||||
me, them, powerLevels.getContent()
|
||||
me, them, powerLevels.getContent(),
|
||||
),
|
||||
muted: this._isMuted(them, powerLevels.getContent()),
|
||||
isTargetMod: them.powerLevel > powerLevels.getContent().users_default
|
||||
isTargetMod: them.powerLevel > powerLevels.getContent().users_default,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -528,7 +525,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
kick: false,
|
||||
ban: false,
|
||||
mute: false,
|
||||
modifyLevel: false
|
||||
modifyLevel: false,
|
||||
};
|
||||
const canAffectUser = them.powerLevel < me.powerLevel;
|
||||
if (!canAffectUser) {
|
||||
|
@ -556,7 +553,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
if (!powerLevelContent || !member) {
|
||||
return false;
|
||||
}
|
||||
var levelToSend = (
|
||||
const levelToSend = (
|
||||
(powerLevelContent.events ? powerLevelContent.events["m.room.message"] : null) ||
|
||||
powerLevelContent.events_default
|
||||
);
|
||||
|
@ -566,19 +563,19 @@ module.exports = withMatrixClient(React.createClass({
|
|||
onCancel: function(e) {
|
||||
dis.dispatch({
|
||||
action: "view_user",
|
||||
member: null
|
||||
member: null,
|
||||
});
|
||||
},
|
||||
|
||||
onMemberAvatarClick: function() {
|
||||
var avatarUrl = this.props.member.user ? this.props.member.user.avatarUrl : this.props.member.events.member.getContent().avatar_url;
|
||||
const avatarUrl = this.props.member.user ? this.props.member.user.avatarUrl : this.props.member.events.member.getContent().avatar_url;
|
||||
if(!avatarUrl) return;
|
||||
|
||||
var httpUrl = this.props.matrixClient.mxcUrlToHttp(avatarUrl);
|
||||
var ImageView = sdk.getComponent("elements.ImageView");
|
||||
var params = {
|
||||
const httpUrl = this.props.matrixClient.mxcUrlToHttp(avatarUrl);
|
||||
const ImageView = sdk.getComponent("elements.ImageView");
|
||||
const params = {
|
||||
src: httpUrl,
|
||||
name: this.props.member.name
|
||||
name: this.props.member.name,
|
||||
};
|
||||
|
||||
Modal.createDialog(ImageView, params, "mx_Dialog_lightbox");
|
||||
|
@ -596,11 +593,11 @@ module.exports = withMatrixClient(React.createClass({
|
|||
return null;
|
||||
}
|
||||
|
||||
var devices = this.state.devices;
|
||||
var MemberDeviceInfo = sdk.getComponent('rooms.MemberDeviceInfo');
|
||||
var Spinner = sdk.getComponent("elements.Spinner");
|
||||
const devices = this.state.devices;
|
||||
const MemberDeviceInfo = sdk.getComponent('rooms.MemberDeviceInfo');
|
||||
const Spinner = sdk.getComponent("elements.Spinner");
|
||||
|
||||
var devComponents;
|
||||
let devComponents;
|
||||
if (this.state.devicesLoading) {
|
||||
// still loading
|
||||
devComponents = <Spinner />;
|
||||
|
@ -610,10 +607,10 @@ module.exports = withMatrixClient(React.createClass({
|
|||
devComponents = _t("No devices with registered encryption keys");
|
||||
} else {
|
||||
devComponents = [];
|
||||
for (var i = 0; i < devices.length; i++) {
|
||||
for (let i = 0; i < devices.length; i++) {
|
||||
devComponents.push(<MemberDeviceInfo key={i}
|
||||
userId={this.props.member.userId}
|
||||
device={devices[i]}/>);
|
||||
device={devices[i]} />);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -621,7 +618,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
<div>
|
||||
<h3>{ _t("Devices") }</h3>
|
||||
<div className="mx_MemberInfo_devices">
|
||||
{devComponents}
|
||||
{ devComponents }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -633,7 +630,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
if (this.props.member.userId !== this.props.matrixClient.getUserId()) {
|
||||
ignoreButton = (
|
||||
<AccessibleButton onClick={this.onIgnoreToggle} className="mx_MemberInfo_field">
|
||||
{this.state.isIgnoring ? _t("Unignore") : _t("Ignore")}
|
||||
{ this.state.isIgnoring ? _t("Unignore") : _t("Ignore") }
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
@ -644,14 +641,14 @@ module.exports = withMatrixClient(React.createClass({
|
|||
<div>
|
||||
<h3>{ _t("User Options") }</h3>
|
||||
<div className="mx_MemberInfo_buttons">
|
||||
{ignoreButton}
|
||||
{ ignoreButton }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var startChat, kickButton, banButton, muteButton, giveModButton, spinner;
|
||||
let startChat, kickButton, banButton, muteButton, giveModButton, spinner;
|
||||
if (this.props.member.userId !== this.props.matrixClient.credentials.userId) {
|
||||
const dmRoomMap = new DMRoomMap(this.props.matrixClient);
|
||||
const dmRooms = dmRoomMap.getDMRoomsForUserId(this.props.member.userId);
|
||||
|
@ -675,7 +672,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
highlight={highlight}
|
||||
isInvite={me.membership == "invite"}
|
||||
onClick={this.onRoomTileClick}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -696,14 +693,14 @@ module.exports = withMatrixClient(React.createClass({
|
|||
|
||||
startChat = <div>
|
||||
<h3>{ _t("Direct chats") }</h3>
|
||||
{tiles}
|
||||
{startNewChat}
|
||||
{ tiles }
|
||||
{ startNewChat }
|
||||
</div>;
|
||||
}
|
||||
|
||||
if (this.state.updating) {
|
||||
var Loader = sdk.getComponent("elements.Spinner");
|
||||
spinner = <Loader imgClassName="mx_ContextualMenu_spinner"/>;
|
||||
const Loader = sdk.getComponent("elements.Spinner");
|
||||
spinner = <Loader imgClassName="mx_ContextualMenu_spinner" />;
|
||||
}
|
||||
|
||||
if (this.state.can.kick) {
|
||||
|
@ -712,7 +709,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
kickButton = (
|
||||
<AccessibleButton className="mx_MemberInfo_field"
|
||||
onClick={this.onKick}>
|
||||
{kickLabel}
|
||||
{ kickLabel }
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
@ -724,7 +721,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
banButton = (
|
||||
<AccessibleButton className="mx_MemberInfo_field"
|
||||
onClick={this.onBanOrUnban}>
|
||||
{label}
|
||||
{ label }
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
@ -733,31 +730,31 @@ module.exports = withMatrixClient(React.createClass({
|
|||
muteButton = (
|
||||
<AccessibleButton className="mx_MemberInfo_field"
|
||||
onClick={this.onMuteToggle}>
|
||||
{muteLabel}
|
||||
{ muteLabel }
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
if (this.state.can.toggleMod) {
|
||||
var giveOpLabel = this.state.isTargetMod ? _t("Revoke Moderator") : _t("Make Moderator");
|
||||
const giveOpLabel = this.state.isTargetMod ? _t("Revoke Moderator") : _t("Make Moderator");
|
||||
giveModButton = <AccessibleButton className="mx_MemberInfo_field" onClick={this.onModToggle}>
|
||||
{giveOpLabel}
|
||||
{ giveOpLabel }
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
// TODO: we should have an invite button if this MemberInfo is showing a user who isn't actually in the current room yet
|
||||
// e.g. clicking on a linkified userid in a room
|
||||
|
||||
var adminTools;
|
||||
let adminTools;
|
||||
if (kickButton || banButton || muteButton || giveModButton) {
|
||||
adminTools =
|
||||
<div>
|
||||
<h3>{_t("Admin Tools")}</h3>
|
||||
<h3>{ _t("Admin Tools") }</h3>
|
||||
|
||||
<div className="mx_MemberInfo_buttons">
|
||||
{muteButton}
|
||||
{kickButton}
|
||||
{banButton}
|
||||
{giveModButton}
|
||||
{ muteButton }
|
||||
{ kickButton }
|
||||
{ banButton }
|
||||
{ giveModButton }
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
@ -767,35 +764,35 @@ module.exports = withMatrixClient(React.createClass({
|
|||
if (this.props.member.user) {
|
||||
var presenceState = this.props.member.user.presence;
|
||||
var presenceLastActiveAgo = this.props.member.user.lastActiveAgo;
|
||||
var presenceLastTs = this.props.member.user.lastPresenceTs;
|
||||
const presenceLastTs = this.props.member.user.lastPresenceTs;
|
||||
var presenceCurrentlyActive = this.props.member.user.currentlyActive;
|
||||
}
|
||||
|
||||
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||
var PowerSelector = sdk.getComponent('elements.PowerSelector');
|
||||
var PresenceLabel = sdk.getComponent('rooms.PresenceLabel');
|
||||
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||
const PowerSelector = sdk.getComponent('elements.PowerSelector');
|
||||
const PresenceLabel = sdk.getComponent('rooms.PresenceLabel');
|
||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||
return (
|
||||
<div className="mx_MemberInfo">
|
||||
<GeminiScrollbar autoshow={true}>
|
||||
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this.onCancel}> <img src="img/cancel.svg" width="18" height="18"/></AccessibleButton>
|
||||
<AccessibleButton className="mx_MemberInfo_cancel" onClick={this.onCancel}> <img src="img/cancel.svg" width="18" height="18" /></AccessibleButton>
|
||||
<div className="mx_MemberInfo_avatar">
|
||||
<MemberAvatar onClick={this.onMemberAvatarClick} member={this.props.member} width={48} height={48} />
|
||||
</div>
|
||||
|
||||
<EmojiText element="h2">{memberName}</EmojiText>
|
||||
<EmojiText element="h2">{ memberName }</EmojiText>
|
||||
|
||||
<div className="mx_MemberInfo_profile">
|
||||
<div className="mx_MemberInfo_profileField">
|
||||
{ this.props.member.userId }
|
||||
</div>
|
||||
<div className="mx_MemberInfo_profileField">
|
||||
{ _t("Level:") } <b><PowerSelector controlled={true} value={ parseInt(this.props.member.powerLevel) } disabled={ !this.state.can.modifyLevel } onChange={ this.onPowerChange }/></b>
|
||||
{ _t("Level:") } <b><PowerSelector controlled={true} value={parseInt(this.props.member.powerLevel)} disabled={!this.state.can.modifyLevel} onChange={this.onPowerChange} /></b>
|
||||
</div>
|
||||
<div className="mx_MemberInfo_profileField">
|
||||
<PresenceLabel activeAgo={ presenceLastActiveAgo }
|
||||
currentlyActive={ presenceCurrentlyActive }
|
||||
presenceState={ presenceState } />
|
||||
<PresenceLabel activeAgo={presenceLastActiveAgo}
|
||||
currentlyActive={presenceCurrentlyActive}
|
||||
presenceState={presenceState} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -811,5 +808,5 @@ module.exports = withMatrixClient(React.createClass({
|
|||
</GeminiScrollbar>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
|
|
@ -18,11 +18,11 @@ limitations under the License.
|
|||
|
||||
import React from 'react';
|
||||
import { _t } from '../../../languageHandler';
|
||||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||
var sdk = require('../../../index');
|
||||
var GeminiScrollbar = require('react-gemini-scrollbar');
|
||||
var rate_limited_func = require('../../../ratelimitedfunc');
|
||||
var CallHandler = require("../../../CallHandler");
|
||||
const MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||
const sdk = require('../../../index');
|
||||
const GeminiScrollbar = require('react-gemini-scrollbar');
|
||||
const rate_limited_func = require('../../../ratelimitedfunc');
|
||||
const CallHandler = require("../../../CallHandler");
|
||||
|
||||
const INITIAL_LOAD_NUM_MEMBERS = 30;
|
||||
const INITIAL_LOAD_NUM_INVITED = 5;
|
||||
|
@ -49,7 +49,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
var cli = MatrixClientPeg.get();
|
||||
const cli = MatrixClientPeg.get();
|
||||
cli.on("RoomState.members", this.onRoomStateMember);
|
||||
cli.on("RoomMember.name", this.onRoomMemberName);
|
||||
cli.on("RoomState.events", this.onRoomStateEvent);
|
||||
|
@ -62,7 +62,7 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
var cli = MatrixClientPeg.get();
|
||||
const cli = MatrixClientPeg.get();
|
||||
if (cli) {
|
||||
cli.removeListener("RoomState.members", this.onRoomStateMember);
|
||||
cli.removeListener("RoomMember.name", this.onRoomMemberName);
|
||||
|
@ -109,7 +109,7 @@ module.exports = React.createClass({
|
|||
// member tile and re-render it. This is more efficient than every tile
|
||||
// evar attaching their own listener.
|
||||
// console.log("explicit presence from " + user.userId);
|
||||
var tile = this.refs[user.userId];
|
||||
const tile = this.refs[user.userId];
|
||||
if (tile) {
|
||||
this._updateList(); // reorder the membership list
|
||||
}
|
||||
|
@ -153,11 +153,11 @@ module.exports = React.createClass({
|
|||
|
||||
getMemberDict: function() {
|
||||
if (!this.props.roomId) return {};
|
||||
var cli = MatrixClientPeg.get();
|
||||
var room = cli.getRoom(this.props.roomId);
|
||||
const cli = MatrixClientPeg.get();
|
||||
const room = cli.getRoom(this.props.roomId);
|
||||
if (!room) return {};
|
||||
|
||||
var all_members = room.currentState.members;
|
||||
const all_members = room.currentState.members;
|
||||
|
||||
Object.keys(all_members).map(function(userId) {
|
||||
// work around a race where you might have a room member object
|
||||
|
@ -175,17 +175,17 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
roomMembers: function() {
|
||||
var all_members = this.memberDict || {};
|
||||
var all_user_ids = Object.keys(all_members);
|
||||
var ConferenceHandler = CallHandler.getConferenceHandler();
|
||||
const all_members = this.memberDict || {};
|
||||
const all_user_ids = Object.keys(all_members);
|
||||
const ConferenceHandler = CallHandler.getConferenceHandler();
|
||||
|
||||
all_user_ids.sort(this.memberSort);
|
||||
|
||||
var to_display = [];
|
||||
var count = 0;
|
||||
for (var i = 0; i < all_user_ids.length; ++i) {
|
||||
var user_id = all_user_ids[i];
|
||||
var m = all_members[user_id];
|
||||
const to_display = [];
|
||||
let count = 0;
|
||||
for (let i = 0; i < all_user_ids.length; ++i) {
|
||||
const user_id = all_user_ids[i];
|
||||
const m = all_members[user_id];
|
||||
|
||||
if (m.membership == 'join' || m.membership == 'invite') {
|
||||
if ((ConferenceHandler && !ConferenceHandler.isConferenceUser(user_id)) || !ConferenceHandler) {
|
||||
|
@ -233,8 +233,7 @@ module.exports = React.createClass({
|
|||
memberString: function(member) {
|
||||
if (!member) {
|
||||
return "(null)";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return "(" + member.name + ", " + member.powerLevel + ", " + member.user.lastActiveAgo + ", " + member.user.currentlyActive + ")";
|
||||
}
|
||||
},
|
||||
|
@ -248,10 +247,10 @@ module.exports = React.createClass({
|
|||
// ...and then alphabetically.
|
||||
// We could tiebreak instead by "last recently spoken in this room" if we wanted to.
|
||||
|
||||
var memberA = this.memberDict[userIdA];
|
||||
var memberB = this.memberDict[userIdB];
|
||||
var userA = memberA.user;
|
||||
var userB = memberB.user;
|
||||
const memberA = this.memberDict[userIdA];
|
||||
const memberB = this.memberDict[userIdB];
|
||||
const userA = memberA.user;
|
||||
const userB = memberB.user;
|
||||
|
||||
// if (!userA || !userB) {
|
||||
// console.log("comparing " + memberA.name + " user=" + memberA.user + " with " + memberB.name + " user=" + memberB.user);
|
||||
|
@ -269,15 +268,13 @@ module.exports = React.createClass({
|
|||
// console.log(memberA + " and " + memberB + " have same power level");
|
||||
if (memberA.name && memberB.name) {
|
||||
// console.log("comparing names: " + memberA.name + " and " + memberB.name);
|
||||
var nameA = memberA.name[0] === '@' ? memberA.name.substr(1) : memberA.name;
|
||||
var nameB = memberB.name[0] === '@' ? memberB.name.substr(1) : memberB.name;
|
||||
const nameA = memberA.name[0] === '@' ? memberA.name.substr(1) : memberA.name;
|
||||
const nameB = memberB.name[0] === '@' ? memberB.name.substr(1) : memberB.name;
|
||||
return nameA.localeCompare(nameB);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// console.log("comparing power: " + memberA.powerLevel + " and " + memberB.powerLevel);
|
||||
return memberB.powerLevel - memberA.powerLevel;
|
||||
}
|
||||
|
@ -336,25 +333,25 @@ module.exports = React.createClass({
|
|||
// The HS may have already converted these into m.room.member invites so
|
||||
// we shouldn't add them if the 3pid invite state key (token) is in the
|
||||
// member invite (content.third_party_invite.signed.token)
|
||||
var room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
||||
var EntityTile = sdk.getComponent("rooms.EntityTile");
|
||||
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
||||
const EntityTile = sdk.getComponent("rooms.EntityTile");
|
||||
if (room) {
|
||||
room.currentState.getStateEvents("m.room.third_party_invite").forEach(
|
||||
function(e) {
|
||||
// any events without these keys are not valid 3pid invites, so we ignore them
|
||||
var required_keys = ['key_validity_url', 'public_key', 'display_name'];
|
||||
for (var i = 0; i < required_keys.length; ++i) {
|
||||
const required_keys = ['key_validity_url', 'public_key', 'display_name'];
|
||||
for (let i = 0; i < required_keys.length; ++i) {
|
||||
if (e.getContent()[required_keys[i]] === undefined) return;
|
||||
}
|
||||
|
||||
// discard all invites which have a m.room.member event since we've
|
||||
// already added them.
|
||||
var memberEvent = room.currentState.getInviteForThreePidToken(e.getStateKey());
|
||||
const memberEvent = room.currentState.getInviteForThreePidToken(e.getStateKey());
|
||||
if (memberEvent) {
|
||||
return;
|
||||
}
|
||||
memberList.push(
|
||||
<EntityTile key={e.getStateKey()} name={e.getContent().display_name} suppressOnHover={true} />
|
||||
<EntityTile key={e.getStateKey()} name={e.getContent().display_name} suppressOnHover={true} />,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -402,7 +399,7 @@ module.exports = React.createClass({
|
|||
<form autoComplete="off">
|
||||
<input className="mx_MemberList_query" id="mx_MemberList_query" type="text"
|
||||
onChange={this.onSearchQueryChanged} value={this.state.searchQuery}
|
||||
placeholder={ _t('Filter room members') } />
|
||||
placeholder={_t('Filter room members')} />
|
||||
</form>
|
||||
);
|
||||
|
||||
|
@ -415,9 +412,9 @@ module.exports = React.createClass({
|
|||
getChildren={this._getChildrenJoined}
|
||||
getChildCount={this._getChildCountJoined}
|
||||
/>
|
||||
{invitedSection}
|
||||
{ invitedSection }
|
||||
</GeminiScrollbar>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -16,12 +16,12 @@ limitations under the License.
|
|||
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
const React = require('react');
|
||||
|
||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
var sdk = require('../../../index');
|
||||
var dis = require('../../../dispatcher');
|
||||
var Modal = require("../../../Modal");
|
||||
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||
const sdk = require('../../../index');
|
||||
const dis = require('../../../dispatcher');
|
||||
const Modal = require("../../../Modal");
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
module.exports = React.createClass({
|
||||
|
@ -68,16 +68,16 @@ module.exports = React.createClass({
|
|||
},
|
||||
|
||||
render: function() {
|
||||
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
var EntityTile = sdk.getComponent('rooms.EntityTile');
|
||||
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||
const EntityTile = sdk.getComponent('rooms.EntityTile');
|
||||
|
||||
var member = this.props.member;
|
||||
var name = this._getDisplayName();
|
||||
var active = -1;
|
||||
var presenceState = member.user ? member.user.presence : null;
|
||||
const member = this.props.member;
|
||||
const name = this._getDisplayName();
|
||||
const active = -1;
|
||||
const presenceState = member.user ? member.user.presence : null;
|
||||
|
||||
var av = (
|
||||
const av = (
|
||||
<MemberAvatar member={member} width={36} height={36} />
|
||||
);
|
||||
|
||||
|
@ -88,11 +88,11 @@ module.exports = React.createClass({
|
|||
|
||||
return (
|
||||
<EntityTile {...this.props} presenceState={presenceState}
|
||||
presenceLastActiveAgo={ member.user ? member.user.lastActiveAgo : 0 }
|
||||
presenceLastTs={ member.user ? member.user.lastPresenceTs : 0 }
|
||||
presenceCurrentlyActive={ member.user ? member.user.currentlyActive : false }
|
||||
presenceLastActiveAgo={member.user ? member.user.lastActiveAgo : 0}
|
||||
presenceLastTs={member.user ? member.user.lastPresenceTs : 0}
|
||||
presenceCurrentlyActive={member.user ? member.user.currentlyActive : false}
|
||||
avatarJsx={av} title={this.getPowerLabel()} onClick={this.onClick}
|
||||
name={name} powerLevel={this.props.member.powerLevel} />
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -89,13 +89,13 @@ export default class MessageComposer extends React.Component {
|
|||
}
|
||||
|
||||
uploadFiles(files) {
|
||||
let QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
let TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||
|
||||
let fileList = [];
|
||||
const fileList = [];
|
||||
for (let i=0; i<files.length; i++) {
|
||||
fileList.push(<li key={i}>
|
||||
<TintableSvg key={i} src="img/files.svg" width="16" height="16" /> {files[i].name || _t('Attachment')}
|
||||
<TintableSvg key={i} src="img/files.svg" width="16" height="16" /> { files[i].name || _t('Attachment') }
|
||||
</li>);
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ export default class MessageComposer extends React.Component {
|
|||
<div>
|
||||
<p>{ _t('Are you sure you want to upload the following files?') }</p>
|
||||
<ul style={{listStyle: 'none', textAlign: 'left'}}>
|
||||
{fileList}
|
||||
{ fileList }
|
||||
</ul>
|
||||
</div>
|
||||
),
|
||||
|
@ -271,16 +271,16 @@ export default class MessageComposer extends React.Component {
|
|||
if (this.props.callState && this.props.callState !== 'ended') {
|
||||
hangupButton =
|
||||
<div key="controls_hangup" className="mx_MessageComposer_hangup" onClick={this.onHangupClick}>
|
||||
<img src="img/hangup.svg" alt={ _t('Hangup') } title={ _t('Hangup') } width="25" height="26"/>
|
||||
<img src="img/hangup.svg" alt={_t('Hangup')} title={_t('Hangup')} width="25" height="26" />
|
||||
</div>;
|
||||
} else {
|
||||
callButton =
|
||||
<div key="controls_call" className="mx_MessageComposer_voicecall" onClick={this.onVoiceCallClick} title={ _t('Voice call') }>
|
||||
<TintableSvg src="img/icon-call.svg" width="35" height="35"/>
|
||||
<div key="controls_call" className="mx_MessageComposer_voicecall" onClick={this.onVoiceCallClick} title={_t('Voice call')}>
|
||||
<TintableSvg src="img/icon-call.svg" width="35" height="35" />
|
||||
</div>;
|
||||
videoCallButton =
|
||||
<div key="controls_videocall" className="mx_MessageComposer_videocall" onClick={this.onCallClick} title={ _t('Video call') }>
|
||||
<TintableSvg src="img/icons-video.svg" width="35" height="35"/>
|
||||
<div key="controls_videocall" className="mx_MessageComposer_videocall" onClick={this.onCallClick} title={_t('Video call')}>
|
||||
<TintableSvg src="img/icons-video.svg" width="35" height="35" />
|
||||
</div>;
|
||||
}
|
||||
|
||||
|
@ -289,12 +289,12 @@ export default class MessageComposer extends React.Component {
|
|||
if (this.props.showApps) {
|
||||
hideAppsButton =
|
||||
<div key="controls_hide_apps" className="mx_MessageComposer_apps" onClick={this.onHideAppsClick} title={_t("Hide Apps")}>
|
||||
<TintableSvg src="img/icons-hide-apps.svg" width="35" height="35"/>
|
||||
<TintableSvg src="img/icons-hide-apps.svg" width="35" height="35" />
|
||||
</div>;
|
||||
} else {
|
||||
showAppsButton =
|
||||
<div key="show_apps" className="mx_MessageComposer_apps" onClick={this.onShowAppsClick} title={_t("Show Apps")}>
|
||||
<TintableSvg src="img/icons-show-apps.svg" width="35" height="35"/>
|
||||
<TintableSvg src="img/icons-show-apps.svg" width="35" height="35" />
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
@ -308,8 +308,8 @@ export default class MessageComposer extends React.Component {
|
|||
// complex because of conference calls.
|
||||
const uploadButton = (
|
||||
<div key="controls_upload" className="mx_MessageComposer_upload"
|
||||
onClick={this.onUploadClick} title={ _t('Upload file') }>
|
||||
<TintableSvg src="img/icons-upload.svg" width="35" height="35"/>
|
||||
onClick={this.onUploadClick} title={_t('Upload file')}>
|
||||
<TintableSvg src="img/icons-upload.svg" width="35" height="35" />
|
||||
<input ref="uploadInput" type="file"
|
||||
style={uploadInputStyle}
|
||||
multiple
|
||||
|
@ -363,7 +363,7 @@ export default class MessageComposer extends React.Component {
|
|||
const onFormatButtonClicked = this.onFormatButtonClicked.bind(this, name);
|
||||
const className = 'mx_MessageComposer_format_button mx_filterFlipColor';
|
||||
return <img className={className}
|
||||
title={ _t(name) }
|
||||
title={_t(name)}
|
||||
onMouseDown={onFormatButtonClicked}
|
||||
key={name}
|
||||
src={`img/button-text-${name}${suffix}.svg`}
|
||||
|
@ -375,18 +375,18 @@ export default class MessageComposer extends React.Component {
|
|||
<div className="mx_MessageComposer mx_fadable" style={{ opacity: this.props.opacity }}>
|
||||
<div className="mx_MessageComposer_wrapper">
|
||||
<div className="mx_MessageComposer_row">
|
||||
{controls}
|
||||
{ controls }
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx_MessageComposer_formatbar_wrapper">
|
||||
<div className="mx_MessageComposer_formatbar" style={this.state.showFormatting ? {} : {display: 'none'}}>
|
||||
{formatButtons}
|
||||
{ formatButtons }
|
||||
<div style={{flex: 1}}></div>
|
||||
<img title={ this.state.inputState.isRichtextEnabled ? _t("Turn Markdown on") : _t("Turn Markdown off") }
|
||||
<img title={this.state.inputState.isRichtextEnabled ? _t("Turn Markdown on") : _t("Turn Markdown off")}
|
||||
onMouseDown={this.onToggleMarkdownClicked}
|
||||
className="mx_MessageComposer_formatbar_markdown mx_filterFlipColor"
|
||||
src={`img/button-md-${!this.state.inputState.isRichtextEnabled}.png`} />
|
||||
<img title={ _t("Hide Text Formatting Toolbar") }
|
||||
<img title={_t("Hide Text Formatting Toolbar")}
|
||||
onClick={this.onToggleFormattingClicked}
|
||||
className="mx_MessageComposer_formatbar_cancel mx_filterFlipColor"
|
||||
src="img/icon-text-cancel.svg" />
|
||||
|
|
|
@ -224,7 +224,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
|
||||
return (
|
||||
<a href={url} data-offset-key={entityProps.offsetKey}>
|
||||
{entityProps.children}
|
||||
{ entityProps.children }
|
||||
</a>
|
||||
);
|
||||
},
|
||||
|
@ -286,7 +286,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
/// XXX: Not doing rich-text quoting from formatted-body because draft-js
|
||||
/// has regressed such that when links are quoted, errors are thrown. See
|
||||
/// https://github.com/vector-im/riot-web/issues/4756.
|
||||
let body = escape(payload.text);
|
||||
const body = escape(payload.text);
|
||||
if (body) {
|
||||
let content = RichText.htmlToContentState(`<blockquote>${body}</blockquote>`);
|
||||
if (!this.state.isRichtextEnabled) {
|
||||
|
@ -464,7 +464,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
// autocomplete will probably have different completions to show.
|
||||
if (
|
||||
!state.editorState.getSelection().equals(
|
||||
this.state.editorState.getSelection()
|
||||
this.state.editorState.getSelection(),
|
||||
)
|
||||
&& state.editorState.getCurrentContent().getPlainText() ===
|
||||
this.state.editorState.getCurrentContent().getPlainText()
|
||||
|
@ -974,7 +974,6 @@ export default class MessageComposerInput extends React.Component {
|
|||
editorState = EditorState.forceSelection(editorState,
|
||||
editorState.getSelection());
|
||||
this.setState({editorState});
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1134,12 +1133,12 @@ export default class MessageComposerInput extends React.Component {
|
|||
onConfirm={this.setDisplayedCompletion}
|
||||
onSelectionChange={this.setDisplayedCompletion}
|
||||
query={this.getAutocompleteQuery(content)}
|
||||
selection={selection}/>
|
||||
selection={selection} />
|
||||
</div>
|
||||
<div className={className}>
|
||||
<img className="mx_MessageComposer_input_markdownIndicator mx_filterFlipColor"
|
||||
onMouseDown={this.onMarkdownToggleClicked}
|
||||
title={ this.state.isRichtextEnabled ? _t("Markdown is disabled") : _t("Markdown is enabled")}
|
||||
title={this.state.isRichtextEnabled ? _t("Markdown is disabled") : _t("Markdown is enabled")}
|
||||
src={`img/button-md-${!this.state.isRichtextEnabled}.png`} />
|
||||
<Editor ref="editor"
|
||||
dir="auto"
|
||||
|
@ -1157,7 +1156,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
onUpArrow={this.onUpArrow}
|
||||
onDownArrow={this.onDownArrow}
|
||||
onEscape={this.onEscape}
|
||||
spellCheck={true}/>
|
||||
spellCheck={true} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue