Run eslint --fix
Fixing 1000s of lint issues. Some rules cannot be `--fix`ed but this goes some way to linting the entire codebase.
This commit is contained in:
parent
8958be9321
commit
d3f9a3aeb5
136 changed files with 2540 additions and 2657 deletions
|
@ -63,23 +63,22 @@ import dis from './dispatcher';
|
||||||
global.mxCalls = {
|
global.mxCalls = {
|
||||||
//room_id: MatrixCall
|
//room_id: MatrixCall
|
||||||
};
|
};
|
||||||
var calls = global.mxCalls;
|
const calls = global.mxCalls;
|
||||||
var ConferenceHandler = null;
|
let ConferenceHandler = null;
|
||||||
|
|
||||||
var audioPromises = {};
|
const audioPromises = {};
|
||||||
|
|
||||||
function play(audioId) {
|
function play(audioId) {
|
||||||
// TODO: Attach an invisible element for this instead
|
// TODO: Attach an invisible element for this instead
|
||||||
// which listens?
|
// which listens?
|
||||||
var audio = document.getElementById(audioId);
|
const audio = document.getElementById(audioId);
|
||||||
if (audio) {
|
if (audio) {
|
||||||
if (audioPromises[audioId]) {
|
if (audioPromises[audioId]) {
|
||||||
audioPromises[audioId] = audioPromises[audioId].then(()=>{
|
audioPromises[audioId] = audioPromises[audioId].then(()=>{
|
||||||
audio.load();
|
audio.load();
|
||||||
return audio.play();
|
return audio.play();
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
audioPromises[audioId] = audio.play();
|
audioPromises[audioId] = audio.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,12 +87,11 @@ function play(audioId) {
|
||||||
function pause(audioId) {
|
function pause(audioId) {
|
||||||
// TODO: Attach an invisible element for this instead
|
// TODO: Attach an invisible element for this instead
|
||||||
// which listens?
|
// which listens?
|
||||||
var audio = document.getElementById(audioId);
|
const audio = document.getElementById(audioId);
|
||||||
if (audio) {
|
if (audio) {
|
||||||
if (audioPromises[audioId]) {
|
if (audioPromises[audioId]) {
|
||||||
audioPromises[audioId] = audioPromises[audioId].then(()=>audio.pause());
|
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();
|
// pause doesn't actually return a promise, but might as well do this for symmetry with play();
|
||||||
audioPromises[audioId] = audio.pause();
|
audioPromises[audioId] = audio.pause();
|
||||||
}
|
}
|
||||||
|
@ -125,38 +123,32 @@ function _setCallListeners(call) {
|
||||||
if (newState === "ringing") {
|
if (newState === "ringing") {
|
||||||
_setCallState(call, call.roomId, "ringing");
|
_setCallState(call, call.roomId, "ringing");
|
||||||
pause("ringbackAudio");
|
pause("ringbackAudio");
|
||||||
}
|
} else if (newState === "invite_sent") {
|
||||||
else if (newState === "invite_sent") {
|
|
||||||
_setCallState(call, call.roomId, "ringback");
|
_setCallState(call, call.roomId, "ringback");
|
||||||
play("ringbackAudio");
|
play("ringbackAudio");
|
||||||
}
|
} else if (newState === "ended" && oldState === "connected") {
|
||||||
else if (newState === "ended" && oldState === "connected") {
|
|
||||||
_setCallState(undefined, call.roomId, "ended");
|
_setCallState(undefined, call.roomId, "ended");
|
||||||
pause("ringbackAudio");
|
pause("ringbackAudio");
|
||||||
play("callendAudio");
|
play("callendAudio");
|
||||||
}
|
} else if (newState === "ended" && oldState === "invite_sent" &&
|
||||||
else if (newState === "ended" && oldState === "invite_sent" &&
|
|
||||||
(call.hangupParty === "remote" ||
|
(call.hangupParty === "remote" ||
|
||||||
(call.hangupParty === "local" && call.hangupReason === "invite_timeout")
|
(call.hangupParty === "local" && call.hangupReason === "invite_timeout")
|
||||||
)) {
|
)) {
|
||||||
_setCallState(call, call.roomId, "busy");
|
_setCallState(call, call.roomId, "busy");
|
||||||
pause("ringbackAudio");
|
pause("ringbackAudio");
|
||||||
play("busyAudio");
|
play("busyAudio");
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
Modal.createTrackedDialog('Call Handler', 'Call Timeout', ErrorDialog, {
|
Modal.createTrackedDialog('Call Handler', 'Call Timeout', ErrorDialog, {
|
||||||
title: _t('Call Timeout'),
|
title: _t('Call Timeout'),
|
||||||
description: _t('The remote side failed to pick up') + '.',
|
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");
|
_setCallState(call, call.roomId, "stop_ringback");
|
||||||
pause("ringbackAudio");
|
pause("ringbackAudio");
|
||||||
}
|
} else if (oldState === "ringing") {
|
||||||
else if (oldState === "ringing") {
|
|
||||||
_setCallState(call, call.roomId, "stop_ringing");
|
_setCallState(call, call.roomId, "stop_ringing");
|
||||||
pause("ringbackAudio");
|
pause("ringbackAudio");
|
||||||
}
|
} else if (newState === "connected") {
|
||||||
else if (newState === "connected") {
|
|
||||||
_setCallState(call, call.roomId, "connected");
|
_setCallState(call, call.roomId, "connected");
|
||||||
pause("ringbackAudio");
|
pause("ringbackAudio");
|
||||||
}
|
}
|
||||||
|
@ -165,14 +157,13 @@ function _setCallListeners(call) {
|
||||||
|
|
||||||
function _setCallState(call, roomId, status) {
|
function _setCallState(call, roomId, status) {
|
||||||
console.log(
|
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;
|
calls[roomId] = call;
|
||||||
|
|
||||||
if (status === "ringing") {
|
if (status === "ringing") {
|
||||||
play("ringAudio");
|
play("ringAudio");
|
||||||
}
|
} else if (call && call.call_state === "ringing") {
|
||||||
else if (call && call.call_state === "ringing") {
|
|
||||||
pause("ringAudio");
|
pause("ringAudio");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,14 +183,12 @@ function _onAction(payload) {
|
||||||
_setCallState(newCall, newCall.roomId, "ringback");
|
_setCallState(newCall, newCall.roomId, "ringback");
|
||||||
if (payload.type === 'voice') {
|
if (payload.type === 'voice') {
|
||||||
newCall.placeVoiceCall();
|
newCall.placeVoiceCall();
|
||||||
}
|
} else if (payload.type === 'video') {
|
||||||
else if (payload.type === 'video') {
|
|
||||||
newCall.placeVideoCall(
|
newCall.placeVideoCall(
|
||||||
payload.remote_element,
|
payload.remote_element,
|
||||||
payload.local_element
|
payload.local_element,
|
||||||
);
|
);
|
||||||
}
|
} else if (payload.type === 'screensharing') {
|
||||||
else if (payload.type === 'screensharing') {
|
|
||||||
const screenCapErrorString = PlatformPeg.get().screenCaptureErrorString();
|
const screenCapErrorString = PlatformPeg.get().screenCaptureErrorString();
|
||||||
if (screenCapErrorString) {
|
if (screenCapErrorString) {
|
||||||
_setCallState(undefined, newCall.roomId, "ended");
|
_setCallState(undefined, newCall.roomId, "ended");
|
||||||
|
@ -213,10 +202,9 @@ function _onAction(payload) {
|
||||||
}
|
}
|
||||||
newCall.placeScreenSharingCall(
|
newCall.placeScreenSharingCall(
|
||||||
payload.remote_element,
|
payload.remote_element,
|
||||||
payload.local_element
|
payload.local_element,
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
console.error("Unknown conf call type: %s", payload.type);
|
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.'),
|
description: _t('You cannot place a call with yourself.'),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
} else if (members.length === 2) {
|
||||||
else if (members.length === 2) {
|
|
||||||
console.log("Place %s call in %s", payload.type, payload.room_id);
|
console.log("Place %s call in %s", payload.type, payload.room_id);
|
||||||
const call = Matrix.createNewMatrixCall(MatrixClientPeg.get(), payload.room_id, {
|
const call = Matrix.createNewMatrixCall(MatrixClientPeg.get(), payload.room_id, {
|
||||||
forceTURN: UserSettingsStore.getLocalSetting('webRtcForceTURN', false),
|
forceTURN: UserSettingsStore.getLocalSetting('webRtcForceTURN', false),
|
||||||
});
|
});
|
||||||
placeCall(call);
|
placeCall(call);
|
||||||
}
|
} else { // > 2
|
||||||
else { // > 2
|
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: "place_conference_call",
|
action: "place_conference_call",
|
||||||
room_id: payload.room_id,
|
room_id: payload.room_id,
|
||||||
type: payload.type,
|
type: payload.type,
|
||||||
remote_element: payload.remote_element,
|
remote_element: payload.remote_element,
|
||||||
local_element: payload.local_element
|
local_element: payload.local_element,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -280,15 +266,13 @@ function _onAction(payload) {
|
||||||
Modal.createTrackedDialog('Call Handler', 'Conference call unsupported client', ErrorDialog, {
|
Modal.createTrackedDialog('Call Handler', 'Conference call unsupported client', ErrorDialog, {
|
||||||
description: _t('Conference calls are not supported in this client'),
|
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");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
Modal.createTrackedDialog('Call Handler', 'VoIP is unsupported', ErrorDialog, {
|
Modal.createTrackedDialog('Call Handler', 'VoIP is unsupported', ErrorDialog, {
|
||||||
title: _t('VoIP is unsupported'),
|
title: _t('VoIP is unsupported'),
|
||||||
description: _t('You cannot place VoIP calls in this browser.'),
|
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
|
// Conference calls are implemented by sending the media to central
|
||||||
// server which combines the audio from all the participants together
|
// server which combines the audio from all the participants together
|
||||||
// into a single stream. This is incompatible with end-to-end encryption
|
// 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, {
|
Modal.createTrackedDialog('Call Handler', 'Conference calls unsupported e2e', ErrorDialog, {
|
||||||
description: _t('Conference calls are not supported in encrypted rooms'),
|
description: _t('Conference calls are not supported in encrypted rooms'),
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
|
||||||
Modal.createTrackedDialog('Call Handler', 'Conference calling in development', QuestionDialog, {
|
Modal.createTrackedDialog('Call Handler', 'Conference calling in development', QuestionDialog, {
|
||||||
title: _t('Warning!'),
|
title: _t('Warning!'),
|
||||||
description: _t('Conference calling is in development and may not be reliable.'),
|
description: _t('Conference calling is in development and may not be reliable.'),
|
||||||
onFinished: confirm=>{
|
onFinished: (confirm)=>{
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
ConferenceHandler.createNewMatrixCall(
|
ConferenceHandler.createNewMatrixCall(
|
||||||
MatrixClientPeg.get(), payload.room_id
|
MatrixClientPeg.get(), payload.room_id,
|
||||||
).done(function(call) {
|
).done(function(call) {
|
||||||
placeCall(call);
|
placeCall(call);
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
|
@ -357,7 +340,7 @@ function _onAction(payload) {
|
||||||
_setCallState(calls[payload.room_id], payload.room_id, "connected");
|
_setCallState(calls[payload.room_id], payload.room_id, "connected");
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: "view_room",
|
action: "view_room",
|
||||||
room_id: payload.room_id
|
room_id: payload.room_id,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -368,9 +351,9 @@ if (!global.mxCallHandler) {
|
||||||
dis.register(_onAction);
|
dis.register(_onAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
var callHandler = {
|
const callHandler = {
|
||||||
getCallForRoom: function(roomId) {
|
getCallForRoom: function(roomId) {
|
||||||
var call = module.exports.getCall(roomId);
|
let call = module.exports.getCall(roomId);
|
||||||
if (call) return call;
|
if (call) return call;
|
||||||
|
|
||||||
if (ConferenceHandler) {
|
if (ConferenceHandler) {
|
||||||
|
@ -386,8 +369,8 @@ var callHandler = {
|
||||||
},
|
},
|
||||||
|
|
||||||
getAnyActiveCall: function() {
|
getAnyActiveCall: function() {
|
||||||
var roomsWithCalls = Object.keys(calls);
|
const roomsWithCalls = Object.keys(calls);
|
||||||
for (var i = 0; i < roomsWithCalls.length; i++) {
|
for (let i = 0; i < roomsWithCalls.length; i++) {
|
||||||
if (calls[roomsWithCalls[i]] &&
|
if (calls[roomsWithCalls[i]] &&
|
||||||
calls[roomsWithCalls[i]].call_state !== "ended") {
|
calls[roomsWithCalls[i]].call_state !== "ended") {
|
||||||
return calls[roomsWithCalls[i]];
|
return calls[roomsWithCalls[i]];
|
||||||
|
@ -402,7 +385,7 @@ var callHandler = {
|
||||||
|
|
||||||
getConferenceHandler: function() {
|
getConferenceHandler: function() {
|
||||||
return ConferenceHandler;
|
return ConferenceHandler;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
// Only things in here which actually need to be global are the
|
// Only things in here which actually need to be global are the
|
||||||
// calls list (done separately) and making sure we only register
|
// calls list (done separately) and making sure we only register
|
||||||
|
|
|
@ -17,14 +17,14 @@ limitations under the License.
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import Promise from 'bluebird';
|
import Promise from 'bluebird';
|
||||||
var extend = require('./extend');
|
const extend = require('./extend');
|
||||||
var dis = require('./dispatcher');
|
const dis = require('./dispatcher');
|
||||||
var MatrixClientPeg = require('./MatrixClientPeg');
|
const MatrixClientPeg = require('./MatrixClientPeg');
|
||||||
var sdk = require('./index');
|
const sdk = require('./index');
|
||||||
import { _t } from './languageHandler';
|
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
|
// Polyfill for Canvas.toBlob API using Canvas.toDataURL
|
||||||
require("blueimp-canvas-to-blob");
|
require("blueimp-canvas-to-blob");
|
||||||
|
@ -54,8 +54,8 @@ const MAX_HEIGHT = 600;
|
||||||
function createThumbnail(element, inputWidth, inputHeight, mimeType) {
|
function createThumbnail(element, inputWidth, inputHeight, mimeType) {
|
||||||
const deferred = Promise.defer();
|
const deferred = Promise.defer();
|
||||||
|
|
||||||
var targetWidth = inputWidth;
|
let targetWidth = inputWidth;
|
||||||
var targetHeight = inputHeight;
|
let targetHeight = inputHeight;
|
||||||
if (targetHeight > MAX_HEIGHT) {
|
if (targetHeight > MAX_HEIGHT) {
|
||||||
targetWidth = Math.floor(targetWidth * (MAX_HEIGHT / targetHeight));
|
targetWidth = Math.floor(targetWidth * (MAX_HEIGHT / targetHeight));
|
||||||
targetHeight = MAX_HEIGHT;
|
targetHeight = MAX_HEIGHT;
|
||||||
|
@ -81,7 +81,7 @@ function createThumbnail(element, inputWidth, inputHeight, mimeType) {
|
||||||
w: inputWidth,
|
w: inputWidth,
|
||||||
h: inputHeight,
|
h: inputHeight,
|
||||||
},
|
},
|
||||||
thumbnail: thumbnail
|
thumbnail: thumbnail,
|
||||||
});
|
});
|
||||||
}, mimeType);
|
}, mimeType);
|
||||||
|
|
||||||
|
@ -129,12 +129,12 @@ function loadImageElement(imageFile) {
|
||||||
* @return {Promise} A promise that resolves with the attachment info.
|
* @return {Promise} A promise that resolves with the attachment info.
|
||||||
*/
|
*/
|
||||||
function infoForImageFile(matrixClient, roomId, imageFile) {
|
function infoForImageFile(matrixClient, roomId, imageFile) {
|
||||||
var thumbnailType = "image/png";
|
let thumbnailType = "image/png";
|
||||||
if (imageFile.type == "image/jpeg") {
|
if (imageFile.type == "image/jpeg") {
|
||||||
thumbnailType = "image/jpeg";
|
thumbnailType = "image/jpeg";
|
||||||
}
|
}
|
||||||
|
|
||||||
var imageInfo;
|
let imageInfo;
|
||||||
return loadImageElement(imageFile).then(function(img) {
|
return loadImageElement(imageFile).then(function(img) {
|
||||||
return createThumbnail(img, img.width, img.height, thumbnailType);
|
return createThumbnail(img, img.width, img.height, thumbnailType);
|
||||||
}).then(function(result) {
|
}).then(function(result) {
|
||||||
|
@ -191,7 +191,7 @@ function loadVideoElement(videoFile) {
|
||||||
function infoForVideoFile(matrixClient, roomId, videoFile) {
|
function infoForVideoFile(matrixClient, roomId, videoFile) {
|
||||||
const thumbnailType = "image/jpeg";
|
const thumbnailType = "image/jpeg";
|
||||||
|
|
||||||
var videoInfo;
|
let videoInfo;
|
||||||
return loadVideoElement(videoFile).then(function(video) {
|
return loadVideoElement(videoFile).then(function(video) {
|
||||||
return createThumbnail(video, video.videoWidth, video.videoHeight, thumbnailType);
|
return createThumbnail(video, video.videoWidth, video.videoHeight, thumbnailType);
|
||||||
}).then(function(result) {
|
}).then(function(result) {
|
||||||
|
@ -286,7 +286,7 @@ class ContentMessages {
|
||||||
body: file.name || 'Attachment',
|
body: file.name || 'Attachment',
|
||||||
info: {
|
info: {
|
||||||
size: file.size,
|
size: file.size,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// if we have a mime type for the file, add it to the message metadata
|
// 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();
|
const def = Promise.defer();
|
||||||
if (file.type.indexOf('image/') == 0) {
|
if (file.type.indexOf('image/') == 0) {
|
||||||
content.msgtype = 'm.image';
|
content.msgtype = 'm.image';
|
||||||
infoForImageFile(matrixClient, roomId, file).then(imageInfo=>{
|
infoForImageFile(matrixClient, roomId, file).then((imageInfo)=>{
|
||||||
extend(content.info, imageInfo);
|
extend(content.info, imageInfo);
|
||||||
def.resolve();
|
def.resolve();
|
||||||
}, error=>{
|
}, (error)=>{
|
||||||
console.error(error);
|
console.error(error);
|
||||||
content.msgtype = 'm.file';
|
content.msgtype = 'm.file';
|
||||||
def.resolve();
|
def.resolve();
|
||||||
|
@ -310,10 +310,10 @@ class ContentMessages {
|
||||||
def.resolve();
|
def.resolve();
|
||||||
} else if (file.type.indexOf('video/') == 0) {
|
} else if (file.type.indexOf('video/') == 0) {
|
||||||
content.msgtype = 'm.video';
|
content.msgtype = 'm.video';
|
||||||
infoForVideoFile(matrixClient, roomId, file).then(videoInfo=>{
|
infoForVideoFile(matrixClient, roomId, file).then((videoInfo)=>{
|
||||||
extend(content.info, videoInfo);
|
extend(content.info, videoInfo);
|
||||||
def.resolve();
|
def.resolve();
|
||||||
}, error=>{
|
}, (error)=>{
|
||||||
content.msgtype = 'm.file';
|
content.msgtype = 'm.file';
|
||||||
def.resolve();
|
def.resolve();
|
||||||
});
|
});
|
||||||
|
@ -331,7 +331,7 @@ class ContentMessages {
|
||||||
this.inprogress.push(upload);
|
this.inprogress.push(upload);
|
||||||
dis.dispatch({action: 'upload_started'});
|
dis.dispatch({action: 'upload_started'});
|
||||||
|
|
||||||
var error;
|
let error;
|
||||||
|
|
||||||
function onProgress(ev) {
|
function onProgress(ev) {
|
||||||
upload.total = ev.total;
|
upload.total = ev.total;
|
||||||
|
@ -355,11 +355,11 @@ class ContentMessages {
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
error = err;
|
error = err;
|
||||||
if (!upload.canceled) {
|
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) {
|
if (err.http_status == 413) {
|
||||||
desc = _t('The file \'%(fileName)s\' exceeds this home server\'s size limit for uploads', {fileName: upload.fileName});
|
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, {
|
Modal.createTrackedDialog('Upload failed', '', ErrorDialog, {
|
||||||
title: _t('Upload Failed'),
|
title: _t('Upload Failed'),
|
||||||
description: desc,
|
description: desc,
|
||||||
|
@ -367,8 +367,8 @@ class ContentMessages {
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
const inprogressKeys = Object.keys(this.inprogress);
|
const inprogressKeys = Object.keys(this.inprogress);
|
||||||
for (var i = 0; i < this.inprogress.length; ++i) {
|
for (let i = 0; i < this.inprogress.length; ++i) {
|
||||||
var k = inprogressKeys[i];
|
const k = inprogressKeys[i];
|
||||||
if (this.inprogress[k].promise === upload.promise) {
|
if (this.inprogress[k].promise === upload.promise) {
|
||||||
this.inprogress.splice(k, 1);
|
this.inprogress.splice(k, 1);
|
||||||
break;
|
break;
|
||||||
|
@ -376,8 +376,7 @@ class ContentMessages {
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
dis.dispatch({action: 'upload_failed', upload: upload});
|
dis.dispatch({action: 'upload_failed', upload: upload});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
dis.dispatch({action: 'upload_finished', upload: upload});
|
dis.dispatch({action: 'upload_finished', upload: upload});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -389,9 +388,9 @@ class ContentMessages {
|
||||||
|
|
||||||
cancelUpload(promise) {
|
cancelUpload(promise) {
|
||||||
const inprogressKeys = Object.keys(this.inprogress);
|
const inprogressKeys = Object.keys(this.inprogress);
|
||||||
var upload;
|
let upload;
|
||||||
for (var i = 0; i < this.inprogress.length; ++i) {
|
for (let i = 0; i < this.inprogress.length; ++i) {
|
||||||
var k = inprogressKeys[i];
|
const k = inprogressKeys[i];
|
||||||
if (this.inprogress[k].promise === promise) {
|
if (this.inprogress[k].promise === promise) {
|
||||||
upload = this.inprogress[k];
|
upload = this.inprogress[k];
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -17,10 +17,10 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var sanitizeHtml = require('sanitize-html');
|
const sanitizeHtml = require('sanitize-html');
|
||||||
var highlight = require('highlight.js');
|
const highlight = require('highlight.js');
|
||||||
var linkifyMatrix = require('./linkify-matrix');
|
const linkifyMatrix = require('./linkify-matrix');
|
||||||
import escape from 'lodash/escape';
|
import escape from 'lodash/escape';
|
||||||
import emojione from 'emojione';
|
import emojione from 'emojione';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
@ -66,8 +66,7 @@ function unicodeToImage(str) {
|
||||||
if ( (typeof unicodeChar === 'undefined') || (unicodeChar === '') || (!(unicodeChar in emojione.jsEscapeMap)) ) {
|
if ( (typeof unicodeChar === 'undefined') || (unicodeChar === '') || (!(unicodeChar in emojione.jsEscapeMap)) ) {
|
||||||
// if the unicodeChar doesnt exist just return the entire match
|
// if the unicodeChar doesnt exist just return the entire match
|
||||||
return unicodeChar;
|
return unicodeChar;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// get the unicode codepoint from the actual char
|
// get the unicode codepoint from the actual char
|
||||||
unicode = emojione.jsEscapeMap[unicodeChar];
|
unicode = emojione.jsEscapeMap[unicodeChar];
|
||||||
|
|
||||||
|
@ -183,21 +182,19 @@ const sanitizeHtmlParams = {
|
||||||
if (attribs.href) {
|
if (attribs.href) {
|
||||||
attribs.target = '_blank'; // by default
|
attribs.target = '_blank'; // by default
|
||||||
|
|
||||||
var m;
|
let m;
|
||||||
// FIXME: horrible duplication with linkify-matrix
|
// FIXME: horrible duplication with linkify-matrix
|
||||||
m = attribs.href.match(linkifyMatrix.VECTOR_URL_PATTERN);
|
m = attribs.href.match(linkifyMatrix.VECTOR_URL_PATTERN);
|
||||||
if (m) {
|
if (m) {
|
||||||
attribs.href = m[1];
|
attribs.href = m[1];
|
||||||
delete attribs.target;
|
delete attribs.target;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
m = attribs.href.match(linkifyMatrix.MATRIXTO_URL_PATTERN);
|
m = attribs.href.match(linkifyMatrix.MATRIXTO_URL_PATTERN);
|
||||||
if (m) {
|
if (m) {
|
||||||
var entity = m[1];
|
const entity = m[1];
|
||||||
if (entity[0] === '@') {
|
if (entity[0] === '@') {
|
||||||
attribs.href = '#/user/' + entity;
|
attribs.href = '#/user/' + entity;
|
||||||
}
|
} else if (entity[0] === '#' || entity[0] === '!') {
|
||||||
else if (entity[0] === '#' || entity[0] === '!') {
|
|
||||||
attribs.href = '#/room/' + entity;
|
attribs.href = '#/room/' + entity;
|
||||||
}
|
}
|
||||||
delete attribs.target;
|
delete attribs.target;
|
||||||
|
@ -224,7 +221,7 @@ const sanitizeHtmlParams = {
|
||||||
'code': function(tagName, attribs) {
|
'code': function(tagName, attribs) {
|
||||||
if (typeof attribs.class !== 'undefined') {
|
if (typeof attribs.class !== 'undefined') {
|
||||||
// Filter out all classes other than ones starting with language- for syntax highlighting.
|
// 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-');
|
return cl.startsWith('language-');
|
||||||
});
|
});
|
||||||
attribs.class = classes.join(' ');
|
attribs.class = classes.join(' ');
|
||||||
|
@ -287,11 +284,11 @@ class BaseHighlighter {
|
||||||
* TextHighlighter).
|
* TextHighlighter).
|
||||||
*/
|
*/
|
||||||
applyHighlights(safeSnippet, safeHighlights) {
|
applyHighlights(safeSnippet, safeHighlights) {
|
||||||
var lastOffset = 0;
|
let lastOffset = 0;
|
||||||
var offset;
|
let offset;
|
||||||
var nodes = [];
|
let nodes = [];
|
||||||
|
|
||||||
var safeHighlight = safeHighlights[0];
|
const safeHighlight = safeHighlights[0];
|
||||||
while ((offset = safeSnippet.toLowerCase().indexOf(safeHighlight.toLowerCase(), lastOffset)) >= 0) {
|
while ((offset = safeSnippet.toLowerCase().indexOf(safeHighlight.toLowerCase(), lastOffset)) >= 0) {
|
||||||
// handle preamble
|
// handle preamble
|
||||||
if (offset > lastOffset) {
|
if (offset > lastOffset) {
|
||||||
|
@ -301,7 +298,7 @@ class BaseHighlighter {
|
||||||
|
|
||||||
// do highlight. use the original string rather than safeHighlight
|
// do highlight. use the original string rather than safeHighlight
|
||||||
// to preserve the original casing.
|
// to preserve the original casing.
|
||||||
var endOffset = offset + safeHighlight.length;
|
const endOffset = offset + safeHighlight.length;
|
||||||
nodes.push(this._processSnippet(safeSnippet.substring(offset, endOffset), true));
|
nodes.push(this._processSnippet(safeSnippet.substring(offset, endOffset), true));
|
||||||
|
|
||||||
lastOffset = endOffset;
|
lastOffset = endOffset;
|
||||||
|
@ -319,8 +316,7 @@ class BaseHighlighter {
|
||||||
if (safeHighlights[1]) {
|
if (safeHighlights[1]) {
|
||||||
// recurse into this range to check for the next set of highlight matches
|
// recurse into this range to check for the next set of highlight matches
|
||||||
return this.applyHighlights(safeSnippet, safeHighlights.slice(1));
|
return this.applyHighlights(safeSnippet, safeHighlights.slice(1));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// no more highlights to be found, just return the unhighlighted string
|
// no more highlights to be found, just return the unhighlighted string
|
||||||
return [this._processSnippet(safeSnippet, false)];
|
return [this._processSnippet(safeSnippet, false)];
|
||||||
}
|
}
|
||||||
|
@ -341,7 +337,7 @@ class HtmlHighlighter extends BaseHighlighter {
|
||||||
return snippet;
|
return snippet;
|
||||||
}
|
}
|
||||||
|
|
||||||
var span = "<span class=\""+this.highlightClass+"\">"
|
let span = "<span class=\""+this.highlightClass+"\">"
|
||||||
+ snippet + "</span>";
|
+ snippet + "</span>";
|
||||||
|
|
||||||
if (this.highlightLink) {
|
if (this.highlightLink) {
|
||||||
|
@ -366,9 +362,9 @@ class TextHighlighter extends BaseHighlighter {
|
||||||
* returns a React node
|
* returns a React node
|
||||||
*/
|
*/
|
||||||
_processSnippet(snippet, highlight) {
|
_processSnippet(snippet, highlight) {
|
||||||
var key = this._key++;
|
const key = this._key++;
|
||||||
|
|
||||||
var node =
|
let node =
|
||||||
<span key={key} className={highlight ? this.highlightClass : null}>
|
<span key={key} className={highlight ? this.highlightClass : null}>
|
||||||
{ snippet }
|
{ snippet }
|
||||||
</span>;
|
</span>;
|
||||||
|
@ -393,20 +389,20 @@ class TextHighlighter extends BaseHighlighter {
|
||||||
export function bodyToHtml(content, highlights, opts) {
|
export function bodyToHtml(content, highlights, opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
|
||||||
var isHtml = (content.format === "org.matrix.custom.html");
|
const isHtml = (content.format === "org.matrix.custom.html");
|
||||||
let body = isHtml ? content.formatted_body : escape(content.body);
|
const body = isHtml ? content.formatted_body : escape(content.body);
|
||||||
|
|
||||||
let bodyHasEmoji = false;
|
let bodyHasEmoji = false;
|
||||||
|
|
||||||
var safeBody;
|
let safeBody;
|
||||||
// XXX: We sanitize the HTML whilst also highlighting its text nodes, to avoid accidentally trying
|
// 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
|
// 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
|
// 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
|
// by an attempt to search for 'foobar'. Then again, the search query probably wouldn't work either
|
||||||
try {
|
try {
|
||||||
if (highlights && highlights.length > 0) {
|
if (highlights && highlights.length > 0) {
|
||||||
var highlighter = new HtmlHighlighter("mx_EventTile_searchHighlight", opts.highlightLink);
|
const highlighter = new HtmlHighlighter("mx_EventTile_searchHighlight", opts.highlightLink);
|
||||||
var safeHighlights = highlights.map(function(highlight) {
|
const safeHighlights = highlights.map(function(highlight) {
|
||||||
return sanitizeHtml(highlight, sanitizeHtmlParams);
|
return sanitizeHtml(highlight, sanitizeHtmlParams);
|
||||||
});
|
});
|
||||||
// XXX: hacky bodge to temporarily apply a textFilter to the sanitizeHtmlParams structure.
|
// 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);
|
safeBody = sanitizeHtml(body, sanitizeHtmlParams);
|
||||||
bodyHasEmoji = containsEmoji(body);
|
bodyHasEmoji = containsEmoji(body);
|
||||||
if (bodyHasEmoji) safeBody = unicodeToImage(safeBody);
|
if (bodyHasEmoji) safeBody = unicodeToImage(safeBody);
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
delete sanitizeHtmlParams.textFilter;
|
delete sanitizeHtmlParams.textFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
let emojiBody = false;
|
let emojiBody = false;
|
||||||
if (bodyHasEmoji) {
|
if (bodyHasEmoji) {
|
||||||
EMOJI_REGEX.lastIndex = 0;
|
EMOJI_REGEX.lastIndex = 0;
|
||||||
let contentBodyTrimmed = content.body !== undefined ? content.body.trim() : '';
|
const contentBodyTrimmed = content.body !== undefined ? content.body.trim() : '';
|
||||||
let match = EMOJI_REGEX.exec(contentBodyTrimmed);
|
const match = EMOJI_REGEX.exec(contentBodyTrimmed);
|
||||||
emojiBody = match && match[0] && match[0].length === contentBodyTrimmed.length;
|
emojiBody = match && match[0] && match[0].length === contentBodyTrimmed.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,13 +42,12 @@ module.exports = {
|
||||||
// no scaling needs to be applied
|
// no scaling needs to be applied
|
||||||
return fullHeight;
|
return fullHeight;
|
||||||
}
|
}
|
||||||
var widthMulti = thumbWidth / fullWidth;
|
const widthMulti = thumbWidth / fullWidth;
|
||||||
var heightMulti = thumbHeight / fullHeight;
|
const heightMulti = thumbHeight / fullHeight;
|
||||||
if (widthMulti < heightMulti) {
|
if (widthMulti < heightMulti) {
|
||||||
// width is the dominant dimension so scaling will be fixed on that
|
// width is the dominant dimension so scaling will be fixed on that
|
||||||
return Math.floor(widthMulti * fullHeight);
|
return Math.floor(widthMulti * fullHeight);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// height is the dominant dimension so scaling will be fixed on that
|
// height is the dominant dimension so scaling will be fixed on that
|
||||||
return Math.floor(heightMulti * fullHeight);
|
return Math.floor(heightMulti * fullHeight);
|
||||||
}
|
}
|
||||||
|
|
16
src/Login.js
16
src/Login.js
|
@ -59,8 +59,8 @@ export default class Login {
|
||||||
}
|
}
|
||||||
|
|
||||||
getFlows() {
|
getFlows() {
|
||||||
var self = this;
|
const self = this;
|
||||||
var client = this._createTemporaryClient();
|
const client = this._createTemporaryClient();
|
||||||
return client.loginFlows().then(function(result) {
|
return client.loginFlows().then(function(result) {
|
||||||
self._flows = result.flows;
|
self._flows = result.flows;
|
||||||
self._currentFlowIndex = 0;
|
self._currentFlowIndex = 0;
|
||||||
|
@ -77,12 +77,12 @@ export default class Login {
|
||||||
getCurrentFlowStep() {
|
getCurrentFlowStep() {
|
||||||
// technically the flow can have multiple steps, but no one does this
|
// technically the flow can have multiple steps, but no one does this
|
||||||
// for login so we can ignore it.
|
// for login so we can ignore it.
|
||||||
var flowStep = this._flows[this._currentFlowIndex];
|
const flowStep = this._flows[this._currentFlowIndex];
|
||||||
return flowStep ? flowStep.type : null;
|
return flowStep ? flowStep.type : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
loginAsGuest() {
|
loginAsGuest() {
|
||||||
var client = this._createTemporaryClient();
|
const client = this._createTemporaryClient();
|
||||||
return client.registerGuest({
|
return client.registerGuest({
|
||||||
body: {
|
body: {
|
||||||
initial_device_display_name: this._defaultDeviceDisplayName,
|
initial_device_display_name: this._defaultDeviceDisplayName,
|
||||||
|
@ -94,7 +94,7 @@ export default class Login {
|
||||||
accessToken: creds.access_token,
|
accessToken: creds.access_token,
|
||||||
homeserverUrl: this._hsUrl,
|
homeserverUrl: this._hsUrl,
|
||||||
identityServerUrl: this._isUrl,
|
identityServerUrl: this._isUrl,
|
||||||
guest: true
|
guest: true,
|
||||||
};
|
};
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
throw error;
|
throw error;
|
||||||
|
@ -149,12 +149,12 @@ export default class Login {
|
||||||
identityServerUrl: self._isUrl,
|
identityServerUrl: self._isUrl,
|
||||||
userId: data.user_id,
|
userId: data.user_id,
|
||||||
deviceId: data.device_id,
|
deviceId: data.device_id,
|
||||||
accessToken: data.access_token
|
accessToken: data.access_token,
|
||||||
});
|
});
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
if (error.httpStatus === 403) {
|
if (error.httpStatus === 403) {
|
||||||
if (self._fallbackHsUrl) {
|
if (self._fallbackHsUrl) {
|
||||||
var fbClient = Matrix.createClient({
|
const fbClient = Matrix.createClient({
|
||||||
baseUrl: self._fallbackHsUrl,
|
baseUrl: self._fallbackHsUrl,
|
||||||
idBaseUrl: this._isUrl,
|
idBaseUrl: this._isUrl,
|
||||||
});
|
});
|
||||||
|
@ -165,7 +165,7 @@ export default class Login {
|
||||||
identityServerUrl: self._isUrl,
|
identityServerUrl: self._isUrl,
|
||||||
userId: data.user_id,
|
userId: data.user_id,
|
||||||
deviceId: data.device_id,
|
deviceId: data.device_id,
|
||||||
accessToken: data.access_token
|
accessToken: data.access_token,
|
||||||
});
|
});
|
||||||
}, function(fallback_error) {
|
}, function(fallback_error) {
|
||||||
// throw the original error
|
// throw the original error
|
||||||
|
|
|
@ -48,7 +48,7 @@ function html_if_tag_allowed(node) {
|
||||||
* or false if it is only a single line.
|
* or false if it is only a single line.
|
||||||
*/
|
*/
|
||||||
function is_multi_line(node) {
|
function is_multi_line(node) {
|
||||||
var par = node;
|
let par = node;
|
||||||
while (par.parent) {
|
while (par.parent) {
|
||||||
par = par.parent;
|
par = par.parent;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ export default class Markdown {
|
||||||
if (isMultiLine) this.cr();
|
if (isMultiLine) this.cr();
|
||||||
html_if_tag_allowed.call(this, node);
|
html_if_tag_allowed.call(this, node);
|
||||||
if (isMultiLine) this.cr();
|
if (isMultiLine) this.cr();
|
||||||
}
|
};
|
||||||
|
|
||||||
return renderer.render(this.parsed);
|
return renderer.render(this.parsed);
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ export default class Markdown {
|
||||||
renderer.html_block = function(node) {
|
renderer.html_block = function(node) {
|
||||||
this.lit(node.literal);
|
this.lit(node.literal);
|
||||||
if (is_multi_line(node) && node.next) this.lit('\n\n');
|
if (is_multi_line(node) && node.next) this.lit('\n\n');
|
||||||
}
|
};
|
||||||
|
|
||||||
return renderer.render(this.parsed);
|
return renderer.render(this.parsed);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ class MatrixClientPeg {
|
||||||
opts.pendingEventOrdering = "detached";
|
opts.pendingEventOrdering = "detached";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let promise = this.matrixClient.store.startup();
|
const promise = this.matrixClient.store.startup();
|
||||||
console.log(`MatrixClientPeg: waiting for MatrixClient store to initialise`);
|
console.log(`MatrixClientPeg: waiting for MatrixClient store to initialise`);
|
||||||
await promise;
|
await promise;
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
@ -136,7 +136,7 @@ class MatrixClientPeg {
|
||||||
}
|
}
|
||||||
|
|
||||||
_createClient(creds: MatrixClientCreds) {
|
_createClient(creds: MatrixClientCreds) {
|
||||||
var opts = {
|
const opts = {
|
||||||
baseUrl: creds.homeserverUrl,
|
baseUrl: creds.homeserverUrl,
|
||||||
idBaseUrl: creds.identityServerUrl,
|
idBaseUrl: creds.identityServerUrl,
|
||||||
accessToken: creds.accessToken,
|
accessToken: creds.accessToken,
|
||||||
|
@ -153,8 +153,8 @@ class MatrixClientPeg {
|
||||||
|
|
||||||
this.matrixClient.setGuest(Boolean(creds.guest));
|
this.matrixClient.setGuest(Boolean(creds.guest));
|
||||||
|
|
||||||
var notifTimelineSet = new EventTimelineSet(null, {
|
const notifTimelineSet = new EventTimelineSet(null, {
|
||||||
timelineSupport: true
|
timelineSupport: true,
|
||||||
});
|
});
|
||||||
// XXX: what is our initial pagination token?! it somehow needs to be synchronised with /sync.
|
// XXX: what is our initial pagination token?! it somehow needs to be synchronised with /sync.
|
||||||
notifTimelineSet.getLiveTimeline().setPaginationToken("", EventTimeline.BACKWARDS);
|
notifTimelineSet.getLiveTimeline().setPaginationToken("", EventTimeline.BACKWARDS);
|
||||||
|
|
14
src/Modal.js
14
src/Modal.js
|
@ -17,8 +17,8 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var ReactDOM = require('react-dom');
|
const ReactDOM = require('react-dom');
|
||||||
import Analytics from './Analytics';
|
import Analytics from './Analytics';
|
||||||
import sdk from './index';
|
import sdk from './index';
|
||||||
|
|
||||||
|
@ -137,15 +137,15 @@ class ModalManager {
|
||||||
* @param {String} className CSS class to apply to the modal wrapper
|
* @param {String} className CSS class to apply to the modal wrapper
|
||||||
*/
|
*/
|
||||||
createDialogAsync(loader, props, className) {
|
createDialogAsync(loader, props, className) {
|
||||||
var self = this;
|
const self = this;
|
||||||
const modal = {};
|
const modal = {};
|
||||||
|
|
||||||
// never call this from onFinished() otherwise it will loop
|
// never call this from onFinished() otherwise it will loop
|
||||||
//
|
//
|
||||||
// nb explicit function() rather than arrow function, to get `arguments`
|
// 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);
|
if (props && props.onFinished) props.onFinished.apply(null, arguments);
|
||||||
var i = self._modals.indexOf(modal);
|
const i = self._modals.indexOf(modal);
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
self._modals.splice(i, 1);
|
self._modals.splice(i, 1);
|
||||||
}
|
}
|
||||||
|
@ -191,8 +191,8 @@ class ModalManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var modal = this._modals[0];
|
const modal = this._modals[0];
|
||||||
var dialog = (
|
const dialog = (
|
||||||
<div className={"mx_Dialog_wrapper " + (modal.className ? modal.className : '')}>
|
<div className={"mx_Dialog_wrapper " + (modal.className ? modal.className : '')}>
|
||||||
<div className="mx_Dialog">
|
<div className="mx_Dialog">
|
||||||
{ modal.elem }
|
{ modal.elem }
|
||||||
|
|
|
@ -81,7 +81,7 @@ const Notifier = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const avatarUrl = ev.sender ? Avatar.avatarUrlForMember(
|
const avatarUrl = ev.sender ? Avatar.avatarUrlForMember(
|
||||||
ev.sender, 40, 40, 'crop'
|
ev.sender, 40, 40, 'crop',
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
const notif = plaf.displayNotification(title, msg, avatarUrl, room);
|
const notif = plaf.displayNotification(title, msg, avatarUrl, room);
|
||||||
|
@ -303,7 +303,7 @@ const Notifier = {
|
||||||
this._playAudioNotification(ev, room);
|
this._playAudioNotification(ev, room);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!global.mxNotifier) {
|
if (!global.mxNotifier) {
|
||||||
|
|
|
@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var MatrixClientPeg = require("./MatrixClientPeg");
|
const MatrixClientPeg = require("./MatrixClientPeg");
|
||||||
var dis = require("./dispatcher");
|
const dis = require("./dispatcher");
|
||||||
|
|
||||||
// Time in ms after that a user is considered as unavailable/away
|
// Time in ms after that a user is considered as unavailable/away
|
||||||
var UNAVAILABLE_TIME_MS = 3 * 60 * 1000; // 3 mins
|
const UNAVAILABLE_TIME_MS = 3 * 60 * 1000; // 3 mins
|
||||||
var PRESENCE_STATES = ["online", "offline", "unavailable"];
|
const PRESENCE_STATES = ["online", "offline", "unavailable"];
|
||||||
|
|
||||||
class Presence {
|
class Presence {
|
||||||
|
|
||||||
|
@ -71,14 +71,14 @@ class Presence {
|
||||||
if (!this.running) {
|
if (!this.running) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var old_state = this.state;
|
const old_state = this.state;
|
||||||
this.state = newState;
|
this.state = newState;
|
||||||
|
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
return; // don't try to set presence when a guest; it won't work.
|
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() {
|
MatrixClientPeg.get().setPresence(this.state).done(function() {
|
||||||
console.log("Presence: %s", newState);
|
console.log("Presence: %s", newState);
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
|
@ -104,7 +104,7 @@ class Presence {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_resetTimer() {
|
_resetTimer() {
|
||||||
var self = this;
|
const self = this;
|
||||||
this.setState("online");
|
this.setState("online");
|
||||||
// Re-arm the timer
|
// Re-arm the timer
|
||||||
clearTimeout(this.timer);
|
clearTimeout(this.timer);
|
||||||
|
|
|
@ -44,9 +44,9 @@ export const contentStateToHTML = (contentState: ContentState) => {
|
||||||
return stateToHTML(contentState, {
|
return stateToHTML(contentState, {
|
||||||
inlineStyles: {
|
inlineStyles: {
|
||||||
UNDERLINE: {
|
UNDERLINE: {
|
||||||
element: 'u'
|
element: 'u',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ function unicodeToEmojiUri(str) {
|
||||||
let replaceWith, unicode, alt;
|
let replaceWith, unicode, alt;
|
||||||
if ((!emojione.unicodeAlt) || (emojione.sprites)) {
|
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
|
// 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) {
|
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
|
// Workaround for https://github.com/facebook/draft-js/issues/414
|
||||||
let emojiDecorator = {
|
const emojiDecorator = {
|
||||||
strategy: (contentState, contentBlock, callback) => {
|
strategy: (contentState, contentBlock, callback) => {
|
||||||
findWithRegex(EMOJI_REGEX, contentBlock, callback);
|
findWithRegex(EMOJI_REGEX, contentBlock, callback);
|
||||||
},
|
},
|
||||||
component: (props) => {
|
component: (props) => {
|
||||||
let uri = unicodeToEmojiUri(props.children[0].props.text);
|
const uri = unicodeToEmojiUri(props.children[0].props.text);
|
||||||
let shortname = emojione.toShort(props.children[0].props.text);
|
const shortname = emojione.toShort(props.children[0].props.text);
|
||||||
let style = {
|
const style = {
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
width: '1em',
|
width: '1em',
|
||||||
maxHeight: '1em',
|
maxHeight: '1em',
|
||||||
|
@ -118,7 +118,7 @@ export function getScopedRTDecorators(scope: any): CompositeDecorator {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getScopedMDDecorators(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) => ({
|
(style) => ({
|
||||||
strategy: (contentState, contentBlock, callback) => {
|
strategy: (contentState, contentBlock, callback) => {
|
||||||
return findWithRegex(MARKDOWN_REGEX[style], contentBlock, callback);
|
return findWithRegex(MARKDOWN_REGEX[style], contentBlock, callback);
|
||||||
|
@ -127,7 +127,7 @@ export function getScopedMDDecorators(scope: any): CompositeDecorator {
|
||||||
<span className={"mx_MarkdownElement mx_Markdown_" + style}>
|
<span className={"mx_MarkdownElement mx_Markdown_" + style}>
|
||||||
{ props.children }
|
{ props.children }
|
||||||
</span>
|
</span>
|
||||||
)
|
),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
markdownDecorators.push({
|
markdownDecorators.push({
|
||||||
|
@ -138,7 +138,7 @@ export function getScopedMDDecorators(scope: any): CompositeDecorator {
|
||||||
<a href="#" className="mx_MarkdownElement mx_Markdown_LINK">
|
<a href="#" className="mx_MarkdownElement mx_Markdown_LINK">
|
||||||
{ props.children }
|
{ props.children }
|
||||||
</a>
|
</a>
|
||||||
)
|
),
|
||||||
});
|
});
|
||||||
// markdownDecorators.push(emojiDecorator);
|
// markdownDecorators.push(emojiDecorator);
|
||||||
// TODO Consider renabling "syntax highlighting" when we can do it properly
|
// 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;
|
for (let currentKey = startKey;
|
||||||
currentKey && currentKey !== endKey;
|
currentKey && currentKey !== endKey;
|
||||||
currentKey = contentState.getKeyAfter(currentKey)) {
|
currentKey = contentState.getKeyAfter(currentKey)) {
|
||||||
let blockText = getText(currentKey);
|
const blockText = getText(currentKey);
|
||||||
text += blockText.substring(startOffset, blockText.length);
|
text += blockText.substring(startOffset, blockText.length);
|
||||||
|
|
||||||
// from now on, we'll take whole blocks
|
// from now on, we'll take whole blocks
|
||||||
|
@ -182,7 +182,7 @@ export function modifyText(contentState: ContentState, rangeToReplace: Selection
|
||||||
export function selectionStateToTextOffsets(selectionState: SelectionState,
|
export function selectionStateToTextOffsets(selectionState: SelectionState,
|
||||||
contentBlocks: Array<ContentBlock>): {start: number, end: number} {
|
contentBlocks: Array<ContentBlock>): {start: number, end: number} {
|
||||||
let offset = 0, start = 0, end = 0;
|
let offset = 0, start = 0, end = 0;
|
||||||
for (let block of contentBlocks) {
|
for (const block of contentBlocks) {
|
||||||
if (selectionState.getStartKey() === block.getKey()) {
|
if (selectionState.getStartKey() === block.getKey()) {
|
||||||
start = offset + selectionState.getStartOffset();
|
start = offset + selectionState.getStartOffset();
|
||||||
}
|
}
|
||||||
|
@ -259,7 +259,7 @@ export function attachImmutableEntitiesToEmoji(editorState: EditorState): Editor
|
||||||
.set('focusOffset', end);
|
.set('focusOffset', end);
|
||||||
const emojiText = plainText.substring(start, end);
|
const emojiText = plainText.substring(start, end);
|
||||||
newContentState = newContentState.createEntity(
|
newContentState = newContentState.createEntity(
|
||||||
'emoji', 'IMMUTABLE', { emojiUnicode: emojiText }
|
'emoji', 'IMMUTABLE', { emojiUnicode: emojiText },
|
||||||
);
|
);
|
||||||
const entityKey = newContentState.getLastCreatedEntityKey();
|
const entityKey = newContentState.getLastCreatedEntityKey();
|
||||||
newContentState = Modifier.replaceText(
|
newContentState = Modifier.replaceText(
|
||||||
|
|
|
@ -62,8 +62,7 @@ export function isConfCallRoom(room, me, conferenceHandler) {
|
||||||
|
|
||||||
export function looksLikeDirectMessageRoom(room, me) {
|
export function looksLikeDirectMessageRoom(room, me) {
|
||||||
if (me.membership == "join" || me.membership === "ban" ||
|
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
|
// Used to split rooms via tags
|
||||||
const tagNames = Object.keys(room.tags);
|
const tagNames = Object.keys(room.tags);
|
||||||
// Used for 1:1 direct chats
|
// Used for 1:1 direct chats
|
||||||
|
|
|
@ -15,10 +15,10 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Promise from 'bluebird';
|
import Promise from 'bluebird';
|
||||||
var request = require('browser-request');
|
const request = require('browser-request');
|
||||||
|
|
||||||
var SdkConfig = require('./SdkConfig');
|
const SdkConfig = require('./SdkConfig');
|
||||||
var MatrixClientPeg = require('./MatrixClientPeg');
|
const MatrixClientPeg = require('./MatrixClientPeg');
|
||||||
|
|
||||||
class ScalarAuthClient {
|
class ScalarAuthClient {
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ class ScalarAuthClient {
|
||||||
|
|
||||||
// Returns a scalar_token string
|
// Returns a scalar_token string
|
||||||
getScalarToken() {
|
getScalarToken() {
|
||||||
var tok = window.localStorage.getItem("mx_scalar_token");
|
const tok = window.localStorage.getItem("mx_scalar_token");
|
||||||
if (tok) return Promise.resolve(tok);
|
if (tok) return Promise.resolve(tok);
|
||||||
|
|
||||||
// No saved token, so do the dance to get one. First, we
|
// No saved token, so do the dance to get one. First, we
|
||||||
|
@ -53,9 +53,9 @@ class ScalarAuthClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
exchangeForScalarToken(openid_token_object) {
|
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({
|
request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
uri: scalar_rest_url+'/register',
|
uri: scalar_rest_url+'/register',
|
||||||
|
@ -77,7 +77,7 @@ class ScalarAuthClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
getScalarInterfaceUrlForRoom(roomId, screen, id) {
|
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 += "?scalar_token=" + encodeURIComponent(this.scalarToken);
|
||||||
url += "&room_id=" + encodeURIComponent(roomId);
|
url += "&room_id=" + encodeURIComponent(roomId);
|
||||||
if (id) {
|
if (id) {
|
||||||
|
|
|
@ -356,12 +356,12 @@ function getWidgets(event, roomId) {
|
||||||
}
|
}
|
||||||
const stateEvents = room.currentState.getStateEvents("im.vector.modular.widgets");
|
const stateEvents = room.currentState.getStateEvents("im.vector.modular.widgets");
|
||||||
// Only return widgets which have required fields
|
// Only return widgets which have required fields
|
||||||
let widgetStateEvents = [];
|
const widgetStateEvents = [];
|
||||||
stateEvents.forEach((ev) => {
|
stateEvents.forEach((ev) => {
|
||||||
if (ev.getContent().type && ev.getContent().url) {
|
if (ev.getContent().type && ev.getContent().url) {
|
||||||
widgetStateEvents.push(ev.event); // return the raw event
|
widgetStateEvents.push(ev.event); // return the raw event
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
sendResponse(event, widgetStateEvents);
|
sendResponse(event, widgetStateEvents);
|
||||||
}
|
}
|
||||||
|
@ -415,11 +415,11 @@ function setBotPower(event, roomId, userId, level) {
|
||||||
}
|
}
|
||||||
|
|
||||||
client.getStateEvent(roomId, "m.room.power_levels", "").then((powerLevels) => {
|
client.getStateEvent(roomId, "m.room.power_levels", "").then((powerLevels) => {
|
||||||
let powerEvent = new MatrixEvent(
|
const powerEvent = new MatrixEvent(
|
||||||
{
|
{
|
||||||
type: "m.room.power_levels",
|
type: "m.room.power_levels",
|
||||||
content: powerLevels,
|
content: powerLevels,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
client.setPowerLevel(roomId, userId, level, powerEvent).done(() => {
|
client.setPowerLevel(roomId, userId, level, powerEvent).done(() => {
|
||||||
|
@ -485,8 +485,7 @@ function canSendEvent(event, roomId) {
|
||||||
let canSend = false;
|
let canSend = false;
|
||||||
if (isState) {
|
if (isState) {
|
||||||
canSend = room.currentState.maySendStateEvent(evType, me);
|
canSend = room.currentState.maySendStateEvent(evType, me);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
canSend = room.currentState.maySendEvent(evType, me);
|
canSend = room.currentState.maySendEvent(evType, me);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,8 +516,8 @@ function returnStateEvent(event, roomId, eventType, stateKey) {
|
||||||
sendResponse(event, stateEvent.getContent());
|
sendResponse(event, stateEvent.getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentRoomId = null;
|
let currentRoomId = null;
|
||||||
var currentRoomAlias = null;
|
let currentRoomAlias = null;
|
||||||
|
|
||||||
// Listen for when a room is viewed
|
// Listen for when a room is viewed
|
||||||
dis.register(onAction);
|
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
|
// All strings start with the empty string, so for sanity return if the length
|
||||||
// of the event origin is 0.
|
// 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) {
|
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
|
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
|
// Make an error so we get a stack trace
|
||||||
const e = new Error(
|
const e = new Error(
|
||||||
"ScalarMessaging: mismatched startListening / stopListening detected." +
|
"ScalarMessaging: mismatched startListening / stopListening detected." +
|
||||||
" Negative count"
|
" Negative count",
|
||||||
);
|
);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,10 @@ limitations under the License.
|
||||||
// module.exports otherwise this will break when included by both
|
// module.exports otherwise this will break when included by both
|
||||||
// react-sdk and apps layered on top.
|
// react-sdk and apps layered on top.
|
||||||
|
|
||||||
var DEBUG = 0;
|
const DEBUG = 0;
|
||||||
|
|
||||||
// The colour keys to be replaced as referred to in CSS
|
// The colour keys to be replaced as referred to in CSS
|
||||||
var keyRgb = [
|
const keyRgb = [
|
||||||
"rgb(118, 207, 166)", // Vector Green
|
"rgb(118, 207, 166)", // Vector Green
|
||||||
"rgb(234, 245, 240)", // Vector Light Green
|
"rgb(234, 245, 240)", // Vector Light Green
|
||||||
"rgb(211, 239, 225)", // BottomLeftMenu overlay (20% Vector Green)
|
"rgb(211, 239, 225)", // BottomLeftMenu overlay (20% Vector Green)
|
||||||
|
@ -35,7 +35,7 @@ var keyRgb = [
|
||||||
// x = (255 - 234) / (255 - 118) = 0.16
|
// x = (255 - 234) / (255 - 118) = 0.16
|
||||||
|
|
||||||
// The colour keys to be replaced as referred to in SVGs
|
// The colour keys to be replaced as referred to in SVGs
|
||||||
var keyHex = [
|
const keyHex = [
|
||||||
"#76CFA6", // Vector Green
|
"#76CFA6", // Vector Green
|
||||||
"#EAF5F0", // Vector Light Green
|
"#EAF5F0", // Vector Light Green
|
||||||
"#D3EFE1", // BottomLeftMenu overlay (20% Vector Green overlaid on 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
|
// cache of our replacement colours
|
||||||
// defaults to our keys.
|
// defaults to our keys.
|
||||||
var colors = [
|
const colors = [
|
||||||
keyHex[0],
|
keyHex[0],
|
||||||
keyHex[1],
|
keyHex[1],
|
||||||
keyHex[2],
|
keyHex[2],
|
||||||
keyHex[3],
|
keyHex[3],
|
||||||
];
|
];
|
||||||
|
|
||||||
var cssFixups = [
|
const cssFixups = [
|
||||||
// {
|
// {
|
||||||
// style: a style object that should be fixed up taken from a stylesheet
|
// style: a style object that should be fixed up taken from a stylesheet
|
||||||
// attr: name of the attribute to be clobbered, e.g. 'color'
|
// attr: name of the attribute to be clobbered, e.g. 'color'
|
||||||
|
@ -60,7 +60,7 @@ var cssFixups = [
|
||||||
];
|
];
|
||||||
|
|
||||||
// CSS attributes to be fixed up
|
// CSS attributes to be fixed up
|
||||||
var cssAttrs = [
|
const cssAttrs = [
|
||||||
"color",
|
"color",
|
||||||
"backgroundColor",
|
"backgroundColor",
|
||||||
"borderColor",
|
"borderColor",
|
||||||
|
@ -69,17 +69,17 @@ var cssAttrs = [
|
||||||
"borderLeftColor",
|
"borderLeftColor",
|
||||||
];
|
];
|
||||||
|
|
||||||
var svgAttrs = [
|
const svgAttrs = [
|
||||||
"fill",
|
"fill",
|
||||||
"stroke",
|
"stroke",
|
||||||
];
|
];
|
||||||
|
|
||||||
var cached = false;
|
let cached = false;
|
||||||
|
|
||||||
function calcCssFixups() {
|
function calcCssFixups() {
|
||||||
if (DEBUG) console.log("calcSvgFixups start");
|
if (DEBUG) console.log("calcSvgFixups start");
|
||||||
for (var i = 0; i < document.styleSheets.length; i++) {
|
for (let i = 0; i < document.styleSheets.length; i++) {
|
||||||
var ss = document.styleSheets[i];
|
const ss = document.styleSheets[i];
|
||||||
if (!ss) continue; // well done safari >:(
|
if (!ss) continue; // well done safari >:(
|
||||||
// Chromium apparently sometimes returns null here; unsure why.
|
// Chromium apparently sometimes returns null here; unsure why.
|
||||||
// see $14534907369972FRXBx:matrix.org in HQ
|
// see $14534907369972FRXBx:matrix.org in HQ
|
||||||
|
@ -104,12 +104,12 @@ function calcCssFixups() {
|
||||||
if (ss.href && !ss.href.match(/\/bundle.*\.css$/)) continue;
|
if (ss.href && !ss.href.match(/\/bundle.*\.css$/)) continue;
|
||||||
|
|
||||||
if (!ss.cssRules) continue;
|
if (!ss.cssRules) continue;
|
||||||
for (var j = 0; j < ss.cssRules.length; j++) {
|
for (let j = 0; j < ss.cssRules.length; j++) {
|
||||||
var rule = ss.cssRules[j];
|
const rule = ss.cssRules[j];
|
||||||
if (!rule.style) continue;
|
if (!rule.style) continue;
|
||||||
for (var k = 0; k < cssAttrs.length; k++) {
|
for (let k = 0; k < cssAttrs.length; k++) {
|
||||||
var attr = cssAttrs[k];
|
const attr = cssAttrs[k];
|
||||||
for (var l = 0; l < keyRgb.length; l++) {
|
for (let l = 0; l < keyRgb.length; l++) {
|
||||||
if (rule.style[attr] === keyRgb[l]) {
|
if (rule.style[attr] === keyRgb[l]) {
|
||||||
cssFixups.push({
|
cssFixups.push({
|
||||||
style: rule.style,
|
style: rule.style,
|
||||||
|
@ -126,8 +126,8 @@ function calcCssFixups() {
|
||||||
|
|
||||||
function applyCssFixups() {
|
function applyCssFixups() {
|
||||||
if (DEBUG) console.log("applyCssFixups start");
|
if (DEBUG) console.log("applyCssFixups start");
|
||||||
for (var i = 0; i < cssFixups.length; i++) {
|
for (let i = 0; i < cssFixups.length; i++) {
|
||||||
var cssFixup = cssFixups[i];
|
const cssFixup = cssFixups[i];
|
||||||
cssFixup.style[cssFixup.attr] = colors[cssFixup.index];
|
cssFixup.style[cssFixup.attr] = colors[cssFixup.index];
|
||||||
}
|
}
|
||||||
if (DEBUG) console.log("applyCssFixups end");
|
if (DEBUG) console.log("applyCssFixups end");
|
||||||
|
@ -140,15 +140,15 @@ function hexToRgb(color) {
|
||||||
color[1] + color[1] +
|
color[1] + color[1] +
|
||||||
color[2] + color[2];
|
color[2] + color[2];
|
||||||
}
|
}
|
||||||
var val = parseInt(color, 16);
|
const val = parseInt(color, 16);
|
||||||
var r = (val >> 16) & 255;
|
const r = (val >> 16) & 255;
|
||||||
var g = (val >> 8) & 255;
|
const g = (val >> 8) & 255;
|
||||||
var b = val & 255;
|
const b = val & 255;
|
||||||
return [r, g, b];
|
return [r, g, b];
|
||||||
}
|
}
|
||||||
|
|
||||||
function rgbToHex(rgb) {
|
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);
|
return '#' + (0x1000000 + val).toString(16).slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +172,6 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
tint: function(primaryColor, secondaryColor, tertiaryColor) {
|
tint: function(primaryColor, secondaryColor, tertiaryColor) {
|
||||||
|
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
calcCssFixups();
|
calcCssFixups();
|
||||||
cached = true;
|
cached = true;
|
||||||
|
@ -185,7 +184,7 @@ module.exports = {
|
||||||
|
|
||||||
if (!secondaryColor) {
|
if (!secondaryColor) {
|
||||||
const x = 0.16; // average weighting factor calculated from vector green & light green
|
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[0] = x * rgb[0] + (1 - x) * 255;
|
||||||
rgb[1] = x * rgb[1] + (1 - x) * 255;
|
rgb[1] = x * rgb[1] + (1 - x) * 255;
|
||||||
rgb[2] = x * rgb[2] + (1 - x) * 255;
|
rgb[2] = x * rgb[2] + (1 - x) * 255;
|
||||||
|
@ -194,8 +193,8 @@ module.exports = {
|
||||||
|
|
||||||
if (!tertiaryColor) {
|
if (!tertiaryColor) {
|
||||||
const x = 0.19;
|
const x = 0.19;
|
||||||
var rgb1 = hexToRgb(primaryColor);
|
const rgb1 = hexToRgb(primaryColor);
|
||||||
var rgb2 = hexToRgb(secondaryColor);
|
const rgb2 = hexToRgb(secondaryColor);
|
||||||
rgb1[0] = x * rgb1[0] + (1 - x) * rgb2[0];
|
rgb1[0] = x * rgb1[0] + (1 - x) * rgb2[0];
|
||||||
rgb1[1] = x * rgb1[1] + (1 - x) * rgb2[1];
|
rgb1[1] = x * rgb1[1] + (1 - x) * rgb2[1];
|
||||||
rgb1[2] = x * rgb1[2] + (1 - x) * rgb2[2];
|
rgb1[2] = x * rgb1[2] + (1 - x) * rgb2[2];
|
||||||
|
@ -204,8 +203,7 @@ module.exports = {
|
||||||
|
|
||||||
if (colors[0] === primaryColor &&
|
if (colors[0] === primaryColor &&
|
||||||
colors[1] === secondaryColor &&
|
colors[1] === secondaryColor &&
|
||||||
colors[2] === tertiaryColor)
|
colors[2] === tertiaryColor) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,14 +246,13 @@ module.exports = {
|
||||||
// key colour; cache the element and apply.
|
// key colour; cache the element and apply.
|
||||||
|
|
||||||
if (DEBUG) console.log("calcSvgFixups start for " + svgs);
|
if (DEBUG) console.log("calcSvgFixups start for " + svgs);
|
||||||
var fixups = [];
|
const fixups = [];
|
||||||
for (var i = 0; i < svgs.length; i++) {
|
for (let i = 0; i < svgs.length; i++) {
|
||||||
var svgDoc;
|
var svgDoc;
|
||||||
try {
|
try {
|
||||||
svgDoc = svgs[i].contentDocument;
|
svgDoc = svgs[i].contentDocument;
|
||||||
}
|
} catch(e) {
|
||||||
catch(e) {
|
let msg = 'Failed to get svg.contentDocument of ' + svgs[i].toString();
|
||||||
var msg = 'Failed to get svg.contentDocument of ' + svgs[i].toString();
|
|
||||||
if (e.message) {
|
if (e.message) {
|
||||||
msg += e.message;
|
msg += e.message;
|
||||||
}
|
}
|
||||||
|
@ -265,12 +262,12 @@ module.exports = {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
if (!svgDoc) continue;
|
if (!svgDoc) continue;
|
||||||
var tags = svgDoc.getElementsByTagName("*");
|
const tags = svgDoc.getElementsByTagName("*");
|
||||||
for (var j = 0; j < tags.length; j++) {
|
for (let j = 0; j < tags.length; j++) {
|
||||||
var tag = tags[j];
|
const tag = tags[j];
|
||||||
for (var k = 0; k < svgAttrs.length; k++) {
|
for (let k = 0; k < svgAttrs.length; k++) {
|
||||||
var attr = svgAttrs[k];
|
const attr = svgAttrs[k];
|
||||||
for (var l = 0; l < keyHex.length; l++) {
|
for (let l = 0; l < keyHex.length; l++) {
|
||||||
if (tag.getAttribute(attr) && tag.getAttribute(attr).toUpperCase() === keyHex[l]) {
|
if (tag.getAttribute(attr) && tag.getAttribute(attr).toUpperCase() === keyHex[l]) {
|
||||||
fixups.push({
|
fixups.push({
|
||||||
node: tag,
|
node: tag,
|
||||||
|
@ -289,10 +286,10 @@ module.exports = {
|
||||||
|
|
||||||
applySvgFixups: function(fixups) {
|
applySvgFixups: function(fixups) {
|
||||||
if (DEBUG) console.log("applySvgFixups start for " + fixups);
|
if (DEBUG) console.log("applySvgFixups start for " + fixups);
|
||||||
for (var i = 0; i < fixups.length; i++) {
|
for (let i = 0; i < fixups.length; i++) {
|
||||||
var svgFixup = fixups[i];
|
const svgFixup = fixups[i];
|
||||||
svgFixup.node.setAttribute(svgFixup.attr, colors[svgFixup.index]);
|
svgFixup.node.setAttribute(svgFixup.attr, colors[svgFixup.index]);
|
||||||
}
|
}
|
||||||
if (DEBUG) console.log("applySvgFixups end");
|
if (DEBUG) console.log("applySvgFixups end");
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,10 +14,10 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var MatrixClientPeg = require('./MatrixClientPeg');
|
const MatrixClientPeg = require('./MatrixClientPeg');
|
||||||
import UserSettingsStore from './UserSettingsStore';
|
import UserSettingsStore from './UserSettingsStore';
|
||||||
import shouldHideEvent from './shouldHideEvent';
|
import shouldHideEvent from './shouldHideEvent';
|
||||||
var sdk = require('./index');
|
const sdk = require('./index');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
/**
|
/**
|
||||||
|
@ -34,17 +34,17 @@ module.exports = {
|
||||||
} else if (ev.getType == 'm.room.message' && ev.getContent().msgtype == 'm.notify') {
|
} else if (ev.getType == 'm.room.message' && ev.getContent().msgtype == 'm.notify') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var EventTile = sdk.getComponent('rooms.EventTile');
|
const EventTile = sdk.getComponent('rooms.EventTile');
|
||||||
return EventTile.haveTileForEvent(ev);
|
return EventTile.haveTileForEvent(ev);
|
||||||
},
|
},
|
||||||
|
|
||||||
doesRoomHaveUnreadMessages: function(room) {
|
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.
|
// get the most recent read receipt sent by our account.
|
||||||
// N.B. this is NOT a read marker (RM, aka "read up to marker"),
|
// N.B. this is NOT a read marker (RM, aka "read up to marker"),
|
||||||
// despite the name of the method :((
|
// 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
|
// 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!
|
// 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
|
// https://github.com/vector-im/riot-web/issues/3363
|
||||||
if (room.timeline.length &&
|
if (room.timeline.length &&
|
||||||
room.timeline[room.timeline.length - 1].sender &&
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,8 +66,8 @@ module.exports = {
|
||||||
|
|
||||||
const syncedSettings = UserSettingsStore.getSyncedSettings();
|
const syncedSettings = UserSettingsStore.getSyncedSettings();
|
||||||
// Loop through messages, starting with the most recent...
|
// Loop through messages, starting with the most recent...
|
||||||
for (var i = room.timeline.length - 1; i >= 0; --i) {
|
for (let i = room.timeline.length - 1; i >= 0; --i) {
|
||||||
var ev = room.timeline[i];
|
const ev = room.timeline[i];
|
||||||
|
|
||||||
if (ev.getId() == readUpToId) {
|
if (ev.getId() == readUpToId) {
|
||||||
// If we've read up to this event, there's nothing more recents
|
// 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
|
// is unread on the theory that false positives are better than
|
||||||
// false negatives here.
|
// false negatives here.
|
||||||
return true;
|
return true;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var ReactDom = require('react-dom');
|
const ReactDom = require('react-dom');
|
||||||
var Velocity = require('velocity-vector');
|
const Velocity = require('velocity-vector');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Velociraptor contains components and animates transitions with velocity.
|
* 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
|
* update `this.children` according to the new list of children given
|
||||||
*/
|
*/
|
||||||
_updateChildren: function(newChildren) {
|
_updateChildren: function(newChildren) {
|
||||||
var self = this;
|
const self = this;
|
||||||
var oldChildren = this.children || {};
|
const oldChildren = this.children || {};
|
||||||
this.children = {};
|
this.children = {};
|
||||||
React.Children.toArray(newChildren).forEach(function(c) {
|
React.Children.toArray(newChildren).forEach(function(c) {
|
||||||
if (oldChildren[c.key]) {
|
if (oldChildren[c.key]) {
|
||||||
var old = oldChildren[c.key];
|
const old = oldChildren[c.key];
|
||||||
var oldNode = ReactDom.findDOMNode(self.nodes[old.key]);
|
const oldNode = ReactDom.findDOMNode(self.nodes[old.key]);
|
||||||
|
|
||||||
if (oldNode && oldNode.style.left != c.props.style.left) {
|
if (oldNode && oldNode.style.left != c.props.style.left) {
|
||||||
Velocity(oldNode, { left: c.props.style.left }, self.props.transition).then(function() {
|
Velocity(oldNode, { left: c.props.style.left }, self.props.transition).then(function() {
|
||||||
|
@ -71,18 +71,18 @@ module.exports = React.createClass({
|
||||||
} else {
|
} else {
|
||||||
// new element. If we have a startStyle, use that as the style and go through
|
// new element. If we have a startStyle, use that as the style and go through
|
||||||
// the enter animations
|
// the enter animations
|
||||||
var newProps = {};
|
const newProps = {};
|
||||||
var restingStyle = c.props.style;
|
const restingStyle = c.props.style;
|
||||||
|
|
||||||
var startStyles = self.props.startStyles;
|
const startStyles = self.props.startStyles;
|
||||||
if (startStyles.length > 0) {
|
if (startStyles.length > 0) {
|
||||||
var startStyle = startStyles[0];
|
const startStyle = startStyles[0];
|
||||||
newProps.style = startStyle;
|
newProps.style = startStyle;
|
||||||
// console.log("mounted@startstyle0: "+JSON.stringify(startStyle));
|
// console.log("mounted@startstyle0: "+JSON.stringify(startStyle));
|
||||||
}
|
}
|
||||||
|
|
||||||
newProps.ref = (n => self._collectNode(
|
newProps.ref = ((n) => self._collectNode(
|
||||||
c.key, n, restingStyle
|
c.key, n, restingStyle,
|
||||||
));
|
));
|
||||||
|
|
||||||
self.children[c.key] = React.cloneElement(c, newProps);
|
self.children[c.key] = React.cloneElement(c, newProps);
|
||||||
|
@ -103,8 +103,8 @@ module.exports = React.createClass({
|
||||||
this.nodes[k] === undefined &&
|
this.nodes[k] === undefined &&
|
||||||
this.props.startStyles.length > 0
|
this.props.startStyles.length > 0
|
||||||
) {
|
) {
|
||||||
var startStyles = this.props.startStyles;
|
const startStyles = this.props.startStyles;
|
||||||
var transitionOpts = this.props.enterTransitionOpts;
|
const transitionOpts = this.props.enterTransitionOpts;
|
||||||
const domNode = ReactDom.findDOMNode(node);
|
const domNode = ReactDom.findDOMNode(node);
|
||||||
// start from startStyle 1: 0 is the one we gave it
|
// start from startStyle 1: 0 is the one we gave it
|
||||||
// to start with, so now we animate 1 etc.
|
// to start with, so now we animate 1 etc.
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
var Velocity = require('velocity-vector');
|
const Velocity = require('velocity-vector');
|
||||||
|
|
||||||
// courtesy of https://github.com/julianshapiro/velocity/issues/283
|
// courtesy of https://github.com/julianshapiro/velocity/issues/283
|
||||||
// We only use easeOutBounce (easeInBounce is just sort of nonsensical)
|
// We only use easeOutBounce (easeInBounce is just sort of nonsensical)
|
||||||
function bounce( p ) {
|
function bounce( p ) {
|
||||||
var pow2,
|
let pow2,
|
||||||
bounce = 4;
|
bounce = 4;
|
||||||
|
|
||||||
while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {
|
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.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var MatrixClientPeg = require("./MatrixClientPeg");
|
const MatrixClientPeg = require("./MatrixClientPeg");
|
||||||
import { _t } from './languageHandler';
|
import { _t } from './languageHandler';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
usersTypingApartFromMeAndIgnored: function(room) {
|
usersTypingApartFromMeAndIgnored: function(room) {
|
||||||
return this.usersTyping(
|
return this.usersTyping(
|
||||||
room, [MatrixClientPeg.get().credentials.userId].concat(MatrixClientPeg.get().getIgnoredUsers())
|
room, [MatrixClientPeg.get().credentials.userId].concat(MatrixClientPeg.get().getIgnoredUsers()),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
usersTypingApartFromMe: function(room) {
|
usersTypingApartFromMe: function(room) {
|
||||||
return this.usersTyping(
|
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.
|
* to exclude, return a list of user objects who are typing.
|
||||||
*/
|
*/
|
||||||
usersTyping: function(room, exclude) {
|
usersTyping: function(room, exclude) {
|
||||||
var whoIsTyping = [];
|
const whoIsTyping = [];
|
||||||
|
|
||||||
if (exclude === undefined) {
|
if (exclude === undefined) {
|
||||||
exclude = [];
|
exclude = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
var memberKeys = Object.keys(room.currentState.members);
|
const memberKeys = Object.keys(room.currentState.members);
|
||||||
for (var i = 0; i < memberKeys.length; ++i) {
|
for (let i = 0; i < memberKeys.length; ++i) {
|
||||||
var userId = memberKeys[i];
|
const userId = memberKeys[i];
|
||||||
|
|
||||||
if (room.currentState.members[userId].typing) {
|
if (room.currentState.members[userId].typing) {
|
||||||
if (exclude.indexOf(userId) == -1) {
|
if (exclude.indexOf(userId) == -1) {
|
||||||
|
@ -76,5 +76,5 @@ module.exports = {
|
||||||
const lastPerson = names.pop();
|
const lastPerson = names.pop();
|
||||||
return _t('%(names)s and %(lastPerson)s are typing', {names: names.join(', '), lastPerson: lastPerson});
|
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.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var React = require("react");
|
const React = require("react");
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
const MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'EncryptedEventDialog',
|
displayName: 'EncryptedEventDialog',
|
||||||
|
@ -33,7 +33,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
this._unmounted = false;
|
this._unmounted = false;
|
||||||
var client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
|
|
||||||
// first try to load the device from our store.
|
// first try to load the device from our store.
|
||||||
//
|
//
|
||||||
|
@ -60,7 +60,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
this._unmounted = true;
|
this._unmounted = true;
|
||||||
var client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
if (client) {
|
if (client) {
|
||||||
client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
|
client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
|
||||||
}
|
}
|
||||||
|
@ -89,12 +89,12 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_renderDeviceInfo: function() {
|
_renderDeviceInfo: function() {
|
||||||
var device = this.state.device;
|
const device = this.state.device;
|
||||||
if (!device) {
|
if (!device) {
|
||||||
return (<i>{ _t('unknown device') }</i>);
|
return (<i>{ _t('unknown device') }</i>);
|
||||||
}
|
}
|
||||||
|
|
||||||
var verificationStatus = (<b>{ _t('NOT verified') }</b>);
|
let verificationStatus = (<b>{ _t('NOT verified') }</b>);
|
||||||
if (device.isBlocked()) {
|
if (device.isBlocked()) {
|
||||||
verificationStatus = (<b>{ _t('Blacklisted') }</b>);
|
verificationStatus = (<b>{ _t('Blacklisted') }</b>);
|
||||||
} else if (device.isVerified()) {
|
} else if (device.isVerified()) {
|
||||||
|
@ -126,7 +126,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_renderEventInfo: function() {
|
_renderEventInfo: function() {
|
||||||
var event = this.props.event;
|
const event = this.props.event;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<table>
|
<table>
|
||||||
|
@ -165,9 +165,9 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var DeviceVerifyButtons = sdk.getComponent('elements.DeviceVerifyButtons');
|
const DeviceVerifyButtons = sdk.getComponent('elements.DeviceVerifyButtons');
|
||||||
|
|
||||||
var buttons = null;
|
let buttons = null;
|
||||||
if (this.state.device) {
|
if (this.state.device) {
|
||||||
buttons = (
|
buttons = (
|
||||||
<DeviceVerifyButtons device={this.state.device}
|
<DeviceVerifyButtons device={this.state.device}
|
||||||
|
@ -196,5 +196,5 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -45,7 +45,7 @@ const PROVIDERS = [
|
||||||
EmojiProvider,
|
EmojiProvider,
|
||||||
CommandProvider,
|
CommandProvider,
|
||||||
DuckDuckGoProvider,
|
DuckDuckGoProvider,
|
||||||
].map(completer => completer.getInstance());
|
].map((completer) => completer.getInstance());
|
||||||
|
|
||||||
// Providers will get rejected if they take longer than this.
|
// Providers will get rejected if they take longer than this.
|
||||||
const PROVIDER_COMPLETION_TIMEOUT = 3000;
|
const PROVIDER_COMPLETION_TIMEOUT = 3000;
|
||||||
|
|
|
@ -30,7 +30,7 @@ export class TextualCompletion extends React.Component {
|
||||||
subtitle,
|
subtitle,
|
||||||
description,
|
description,
|
||||||
className,
|
className,
|
||||||
...restProps,
|
...restProps
|
||||||
} = this.props;
|
} = this.props;
|
||||||
return (
|
return (
|
||||||
<div className={classNames('mx_Autocomplete_Completion_block', className)} {...restProps}>
|
<div className={classNames('mx_Autocomplete_Completion_block', className)} {...restProps}>
|
||||||
|
@ -56,7 +56,7 @@ export class PillCompletion extends React.Component {
|
||||||
description,
|
description,
|
||||||
initialComponent,
|
initialComponent,
|
||||||
className,
|
className,
|
||||||
...restProps,
|
...restProps
|
||||||
} = this.props;
|
} = this.props;
|
||||||
return (
|
return (
|
||||||
<div className={classNames('mx_Autocomplete_Completion_pill', className)} {...restProps}>
|
<div className={classNames('mx_Autocomplete_Completion_pill', className)} {...restProps}>
|
||||||
|
|
|
@ -38,7 +38,7 @@ export default class DuckDuckGoProvider extends AutocompleteProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getCompletions(query: string, selection: {start: number, end: number}) {
|
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) {
|
if (!query || !command) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ export default class DuckDuckGoProvider extends AutocompleteProvider {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
});
|
});
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
let results = json.Results.map(result => {
|
const results = json.Results.map((result) => {
|
||||||
return {
|
return {
|
||||||
completion: result.Text,
|
completion: result.Text,
|
||||||
component: (
|
component: (
|
||||||
|
|
|
@ -152,8 +152,7 @@ export default class EmojiProvider extends AutocompleteProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
static getInstance() {
|
static getInstance() {
|
||||||
if (instance == null)
|
if (instance == null) {instance = new EmojiProvider();}
|
||||||
{instance = new EmojiProvider();}
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ export default class UserProvider extends AutocompleteProvider {
|
||||||
if (this.users === null) this._makeUsers();
|
if (this.users === null) this._makeUsers();
|
||||||
|
|
||||||
let completions = [];
|
let completions = [];
|
||||||
let {command, range} = this.getCurrentCommand(query, selection, force);
|
const {command, range} = this.getCurrentCommand(query, selection, force);
|
||||||
if (command) {
|
if (command) {
|
||||||
completions = this.matcher.match(command[0]).map((user) => {
|
completions = this.matcher.match(command[0]).map((user) => {
|
||||||
const displayName = (user.name || user.userId || '').replace(' (IRC)', ''); // FIXME when groups are done
|
const displayName = (user.name || user.userId || '').replace(' (IRC)', ''); // FIXME when groups are done
|
||||||
|
|
|
@ -17,9 +17,9 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var classNames = require('classnames');
|
const classNames = require('classnames');
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var ReactDOM = require('react-dom');
|
const ReactDOM = require('react-dom');
|
||||||
|
|
||||||
// Shamelessly ripped off Modal.js. There's probably a better way
|
// Shamelessly ripped off Modal.js. There's probably a better way
|
||||||
// of doing reusable widgets like dialog boxes & menus where we go and
|
// of doing reusable widgets like dialog boxes & menus where we go and
|
||||||
|
@ -36,7 +36,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
getOrCreateContainer: function() {
|
getOrCreateContainer: function() {
|
||||||
var container = document.getElementById(this.ContextualMenuContainerId);
|
let container = document.getElementById(this.ContextualMenuContainerId);
|
||||||
|
|
||||||
if (!container) {
|
if (!container) {
|
||||||
container = document.createElement("div");
|
container = document.createElement("div");
|
||||||
|
@ -48,9 +48,9 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
createMenu: function(Element, props) {
|
createMenu: function(Element, props) {
|
||||||
var self = this;
|
const self = this;
|
||||||
|
|
||||||
var closeMenu = function() {
|
const closeMenu = function() {
|
||||||
ReactDOM.unmountComponentAtNode(self.getOrCreateContainer());
|
ReactDOM.unmountComponentAtNode(self.getOrCreateContainer());
|
||||||
|
|
||||||
if (props && props.onFinished) {
|
if (props && props.onFinished) {
|
||||||
|
@ -58,17 +58,17 @@ module.exports = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var position = {
|
const position = {
|
||||||
top: props.top,
|
top: props.top,
|
||||||
};
|
};
|
||||||
|
|
||||||
var chevronOffset = {};
|
const chevronOffset = {};
|
||||||
if (props.chevronOffset) {
|
if (props.chevronOffset) {
|
||||||
chevronOffset.top = props.chevronOffset;
|
chevronOffset.top = props.chevronOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// To override the default chevron colour, if it's been set
|
// To override the default chevron colour, if it's been set
|
||||||
var chevronCSS = "";
|
let chevronCSS = "";
|
||||||
if (props.menuColour) {
|
if (props.menuColour) {
|
||||||
chevronCSS = `
|
chevronCSS = `
|
||||||
.mx_ContextualMenu_chevron_left:after {
|
.mx_ContextualMenu_chevron_left:after {
|
||||||
|
@ -81,7 +81,7 @@ module.exports = {
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
var chevron = null;
|
let chevron = null;
|
||||||
if (props.left) {
|
if (props.left) {
|
||||||
chevron = <div style={chevronOffset} className="mx_ContextualMenu_chevron_left"></div>;
|
chevron = <div style={chevronOffset} className="mx_ContextualMenu_chevron_left"></div>;
|
||||||
position.left = props.left;
|
position.left = props.left;
|
||||||
|
@ -90,15 +90,15 @@ module.exports = {
|
||||||
position.right = props.right;
|
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': true,
|
||||||
'mx_ContextualMenu_left': props.left,
|
'mx_ContextualMenu_left': props.left,
|
||||||
'mx_ContextualMenu_right': !props.left,
|
'mx_ContextualMenu_right': !props.left,
|
||||||
});
|
});
|
||||||
|
|
||||||
var menuStyle = {};
|
const menuStyle = {};
|
||||||
if (props.menuWidth) {
|
if (props.menuWidth) {
|
||||||
menuStyle.width = props.menuWidth;
|
menuStyle.width = props.menuWidth;
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ module.exports = {
|
||||||
|
|
||||||
// FIXME: If a menu uses getDefaultProps it clobbers the onFinished
|
// FIXME: If a menu uses getDefaultProps it clobbers the onFinished
|
||||||
// property set here so you can't close the menu from a button click!
|
// 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={className} style={position}>
|
||||||
<div className={menuClasses} style={menuStyle}>
|
<div className={menuClasses} style={menuStyle}>
|
||||||
{ chevron }
|
{ chevron }
|
||||||
|
|
|
@ -61,7 +61,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onCreateRoom: function() {
|
onCreateRoom: function() {
|
||||||
var options = {};
|
const options = {};
|
||||||
|
|
||||||
if (this.state.room_name) {
|
if (this.state.room_name) {
|
||||||
options.name = this.state.room_name;
|
options.name = this.state.room_name;
|
||||||
|
@ -79,14 +79,14 @@ module.exports = React.createClass({
|
||||||
{
|
{
|
||||||
type: "m.room.join_rules",
|
type: "m.room.join_rules",
|
||||||
content: {
|
content: {
|
||||||
"join_rule": this.state.is_private ? "invite" : "public"
|
"join_rule": this.state.is_private ? "invite" : "public",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "m.room.history_visibility",
|
type: "m.room.history_visibility",
|
||||||
content: {
|
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;
|
options.invite = this.state.invited_users;
|
||||||
|
|
||||||
var alias = this.getAliasLocalpart();
|
const alias = this.getAliasLocalpart();
|
||||||
if (alias) {
|
if (alias) {
|
||||||
options.room_alias_name = alias;
|
options.room_alias_name = alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
if (!cli) {
|
if (!cli) {
|
||||||
// TODO: Error.
|
// TODO: Error.
|
||||||
console.error("Cannot create room: No matrix client.");
|
console.error("Cannot create room: No matrix client.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var deferred = cli.createRoom(options);
|
const deferred = cli.createRoom(options);
|
||||||
|
|
||||||
if (this.state.encrypt) {
|
if (this.state.encrypt) {
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -116,7 +116,7 @@ module.exports = React.createClass({
|
||||||
phase: this.phases.CREATING,
|
phase: this.phases.CREATING,
|
||||||
});
|
});
|
||||||
|
|
||||||
var self = this;
|
const self = this;
|
||||||
|
|
||||||
deferred.then(function(resp) {
|
deferred.then(function(resp) {
|
||||||
self.setState({
|
self.setState({
|
||||||
|
@ -209,7 +209,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
onAliasChanged: function(alias) {
|
onAliasChanged: function(alias) {
|
||||||
this.setState({
|
this.setState({
|
||||||
alias: alias
|
alias: alias,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -220,14 +220,14 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var curr_phase = this.state.phase;
|
const curr_phase = this.state.phase;
|
||||||
if (curr_phase == this.phases.CREATING) {
|
if (curr_phase == this.phases.CREATING) {
|
||||||
var Loader = sdk.getComponent("elements.Spinner");
|
const Loader = sdk.getComponent("elements.Spinner");
|
||||||
return (
|
return (
|
||||||
<Loader />
|
<Loader />
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
var error_box = "";
|
let error_box = "";
|
||||||
if (curr_phase == this.phases.ERROR) {
|
if (curr_phase == this.phases.ERROR) {
|
||||||
error_box = (
|
error_box = (
|
||||||
<div className="mx_Error">
|
<div className="mx_Error">
|
||||||
|
@ -236,13 +236,13 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var CreateRoomButton = sdk.getComponent("create_room.CreateRoomButton");
|
const CreateRoomButton = sdk.getComponent("create_room.CreateRoomButton");
|
||||||
var RoomAlias = sdk.getComponent("create_room.RoomAlias");
|
const RoomAlias = sdk.getComponent("create_room.RoomAlias");
|
||||||
var Presets = sdk.getComponent("create_room.Presets");
|
const Presets = sdk.getComponent("create_room.Presets");
|
||||||
var UserSelector = sdk.getComponent("elements.UserSelector");
|
const UserSelector = sdk.getComponent("elements.UserSelector");
|
||||||
var SimpleRoomHeader = sdk.getComponent("rooms.SimpleRoomHeader");
|
const SimpleRoomHeader = sdk.getComponent("rooms.SimpleRoomHeader");
|
||||||
|
|
||||||
var domain = MatrixClientPeg.get().getDomain();
|
const domain = MatrixClientPeg.get().getDomain();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_CreateRoom">
|
<div className="mx_CreateRoom">
|
||||||
|
@ -279,5 +279,5 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { _t, _tJsx } from '../../languageHandler';
|
||||||
/*
|
/*
|
||||||
* Component which shows the filtered file using a TimelinePanel
|
* Component which shows the filtered file using a TimelinePanel
|
||||||
*/
|
*/
|
||||||
var FilePanel = React.createClass({
|
const FilePanel = React.createClass({
|
||||||
displayName: 'FilePanel',
|
displayName: 'FilePanel',
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -55,33 +55,33 @@ var FilePanel = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
updateTimelineSet: function(roomId) {
|
updateTimelineSet: function(roomId) {
|
||||||
var client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
var room = client.getRoom(roomId);
|
const room = client.getRoom(roomId);
|
||||||
|
|
||||||
this.noRoom = !room;
|
this.noRoom = !room;
|
||||||
|
|
||||||
if (room) {
|
if (room) {
|
||||||
var filter = new Matrix.Filter(client.credentials.userId);
|
const filter = new Matrix.Filter(client.credentials.userId);
|
||||||
filter.setDefinition(
|
filter.setDefinition(
|
||||||
{
|
{
|
||||||
"room": {
|
"room": {
|
||||||
"timeline": {
|
"timeline": {
|
||||||
"contains_url": true
|
"contains_url": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// FIXME: we shouldn't be doing this every time we change room - see comment above.
|
// FIXME: we shouldn't be doing this every time we change room - see comment above.
|
||||||
client.getOrCreateFilter("FILTER_FILES_" + client.credentials.userId, filter).then(
|
client.getOrCreateFilter("FILTER_FILES_" + client.credentials.userId, filter).then(
|
||||||
(filterId)=>{
|
(filterId)=>{
|
||||||
filter.filterId = filterId;
|
filter.filterId = filterId;
|
||||||
var timelineSet = room.getOrCreateFilteredTimelineSet(filter);
|
const timelineSet = room.getOrCreateFilteredTimelineSet(filter);
|
||||||
this.setState({ timelineSet: timelineSet });
|
this.setState({ timelineSet: timelineSet });
|
||||||
},
|
},
|
||||||
(error)=>{
|
(error)=>{
|
||||||
console.error("Failed to get or create file panel filter", error);
|
console.error("Failed to get or create file panel filter", error);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
console.error("Failed to add filtered timelineSet for FilePanel as no room!");
|
console.error("Failed to add filtered timelineSet for FilePanel as no room!");
|
||||||
|
@ -102,8 +102,8 @@ var FilePanel = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
// wrap a TimelinePanel with the jump-to-event bits turned off.
|
// wrap a TimelinePanel with the jump-to-event bits turned off.
|
||||||
var TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
||||||
var Loader = sdk.getComponent("elements.Spinner");
|
const Loader = sdk.getComponent("elements.Spinner");
|
||||||
|
|
||||||
if (this.state.timelineSet) {
|
if (this.state.timelineSet) {
|
||||||
// console.log("rendering TimelinePanel for timelineSet " + this.state.timelineSet.room.roomId + " " +
|
// console.log("rendering TimelinePanel for timelineSet " + this.state.timelineSet.room.roomId + " " +
|
||||||
|
@ -120,8 +120,7 @@ var FilePanel = React.createClass({
|
||||||
empty={_t('There are no visible files in this room')}
|
empty={_t('There are no visible files in this room')}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_FilePanel">
|
<div className="mx_FilePanel">
|
||||||
<Loader />
|
<Loader />
|
||||||
|
|
|
@ -107,7 +107,7 @@ export default React.createClass({
|
||||||
|
|
||||||
const msg = error.message || error.toString();
|
const msg = error.message || error.toString();
|
||||||
this.setState({
|
this.setState({
|
||||||
errorText: msg
|
errorText: msg,
|
||||||
});
|
});
|
||||||
}).done();
|
}).done();
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ export default React.createClass({
|
||||||
case KeyCode.UP:
|
case KeyCode.UP:
|
||||||
case KeyCode.DOWN:
|
case KeyCode.DOWN:
|
||||||
if (ev.altKey && !ev.shiftKey && !ev.ctrlKey && !ev.metaKey) {
|
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';
|
'view_prev_room' : 'view_next_room';
|
||||||
dis.dispatch({action: action});
|
dis.dispatch({action: action});
|
||||||
handled = true;
|
handled = true;
|
||||||
|
@ -206,8 +206,7 @@ export default React.createClass({
|
||||||
_onScrollKeyPressed: function(ev) {
|
_onScrollKeyPressed: function(ev) {
|
||||||
if (this.refs.roomView) {
|
if (this.refs.roomView) {
|
||||||
this.refs.roomView.handleScrollKey(ev);
|
this.refs.roomView.handleScrollKey(ev);
|
||||||
}
|
} else if (this.refs.roomDirectory) {
|
||||||
else if (this.refs.roomDirectory) {
|
|
||||||
this.refs.roomDirectory.handleScrollKey(ev);
|
this.refs.roomDirectory.handleScrollKey(ev);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -320,7 +319,7 @@ export default React.createClass({
|
||||||
topBar = <MatrixToolbar />;
|
topBar = <MatrixToolbar />;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bodyClasses = 'mx_MatrixChat';
|
let bodyClasses = 'mx_MatrixChat';
|
||||||
if (topBar) {
|
if (topBar) {
|
||||||
bodyClasses += ' mx_MatrixChat_toolbarShowing';
|
bodyClasses += ' mx_MatrixChat_toolbarShowing';
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,15 +154,15 @@ module.exports = React.createClass({
|
||||||
// 0: read marker is within the window
|
// 0: read marker is within the window
|
||||||
// +1: read marker is below the window
|
// +1: read marker is below the window
|
||||||
getReadMarkerPosition: function() {
|
getReadMarkerPosition: function() {
|
||||||
var readMarker = this.refs.readMarkerNode;
|
const readMarker = this.refs.readMarkerNode;
|
||||||
var messageWrapper = this.refs.scrollPanel;
|
const messageWrapper = this.refs.scrollPanel;
|
||||||
|
|
||||||
if (!readMarker || !messageWrapper) {
|
if (!readMarker || !messageWrapper) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var wrapperRect = ReactDOM.findDOMNode(messageWrapper).getBoundingClientRect();
|
const wrapperRect = ReactDOM.findDOMNode(messageWrapper).getBoundingClientRect();
|
||||||
var readMarkerRect = readMarker.getBoundingClientRect();
|
const readMarkerRect = readMarker.getBoundingClientRect();
|
||||||
|
|
||||||
// the read-marker pretends to have zero height when it is actually
|
// the read-marker pretends to have zero height when it is actually
|
||||||
// two pixels high; +2 here to account for that.
|
// two pixels high; +2 here to account for that.
|
||||||
|
@ -262,7 +262,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
this.eventNodes = {};
|
this.eventNodes = {};
|
||||||
|
|
||||||
var i;
|
let i;
|
||||||
|
|
||||||
// first figure out which is the last event in the list which we're
|
// first figure out which is the last event in the list which we're
|
||||||
// actually going to show; this allows us to behave slightly
|
// 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.
|
// a local echo, to manage the read-marker.
|
||||||
let lastShownEvent;
|
let lastShownEvent;
|
||||||
|
|
||||||
var lastShownNonLocalEchoIndex = -1;
|
let lastShownNonLocalEchoIndex = -1;
|
||||||
for (i = this.props.events.length-1; i >= 0; i--) {
|
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)) {
|
if (!this._shouldShowEvent(mxEv)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -292,12 +292,12 @@ module.exports = React.createClass({
|
||||||
break;
|
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
|
// 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 the readmarker has moved, cancel any active ghost.
|
||||||
if (this.currentReadMarkerEventId && this.props.readMarkerEventId &&
|
if (this.currentReadMarkerEventId && this.props.readMarkerEventId &&
|
||||||
|
@ -309,16 +309,16 @@ module.exports = React.createClass({
|
||||||
const isMembershipChange = (e) => e.getType() === 'm.room.member';
|
const isMembershipChange = (e) => e.getType() === 'm.room.member';
|
||||||
|
|
||||||
for (i = 0; i < this.props.events.length; i++) {
|
for (i = 0; i < this.props.events.length; i++) {
|
||||||
let mxEv = this.props.events[i];
|
const mxEv = this.props.events[i];
|
||||||
let eventId = mxEv.getId();
|
const eventId = mxEv.getId();
|
||||||
let last = (mxEv === lastShownEvent);
|
const last = (mxEv === lastShownEvent);
|
||||||
|
|
||||||
const wantTile = this._shouldShowEvent(mxEv);
|
const wantTile = this._shouldShowEvent(mxEv);
|
||||||
|
|
||||||
// Wrap consecutive member events in a ListSummary, ignore if redacted
|
// Wrap consecutive member events in a ListSummary, ignore if redacted
|
||||||
if (isMembershipChange(mxEv) && wantTile) {
|
if (isMembershipChange(mxEv) && wantTile) {
|
||||||
let readMarkerInMels = false;
|
let readMarkerInMels = false;
|
||||||
let ts1 = mxEv.getTs();
|
const ts1 = mxEv.getTs();
|
||||||
// Ensure that the key of the MemberEventListSummary does not change with new
|
// Ensure that the key of the MemberEventListSummary does not change with new
|
||||||
// member events. This will prevent it from being re-created unnecessarily, and
|
// member events. This will prevent it from being re-created unnecessarily, and
|
||||||
// instead will allow new props to be provided. In turn, the shouldComponentUpdate
|
// 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");
|
const key = "membereventlistsummary-" + (prevEvent ? mxEv.getId() : "initial");
|
||||||
|
|
||||||
if (this._wantsDateSeparator(prevEvent, mxEv.getDate())) {
|
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);
|
ret.push(dateSeparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@ module.exports = React.createClass({
|
||||||
readMarkerInMels = true;
|
readMarkerInMels = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let summarisedEvents = [mxEv];
|
const summarisedEvents = [mxEv];
|
||||||
for (;i + 1 < this.props.events.length; i++) {
|
for (;i + 1 < this.props.events.length; i++) {
|
||||||
const collapsedMxEv = this.props.events[i + 1];
|
const collapsedMxEv = this.props.events[i + 1];
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ module.exports = React.createClass({
|
||||||
prevEvent = mxEv;
|
prevEvent = mxEv;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isVisibleReadMarker = false;
|
let isVisibleReadMarker = false;
|
||||||
|
|
||||||
if (eventId == this.props.readMarkerEventId) {
|
if (eventId == this.props.readMarkerEventId) {
|
||||||
var visible = this.props.readMarkerVisible;
|
var visible = this.props.readMarkerVisible;
|
||||||
|
@ -448,10 +448,10 @@ module.exports = React.createClass({
|
||||||
_getTilesForEvent: function(prevEvent, mxEv, last) {
|
_getTilesForEvent: function(prevEvent, mxEv, last) {
|
||||||
const EventTile = sdk.getComponent('rooms.EventTile');
|
const EventTile = sdk.getComponent('rooms.EventTile');
|
||||||
const DateSeparator = sdk.getComponent('messages.DateSeparator');
|
const DateSeparator = sdk.getComponent('messages.DateSeparator');
|
||||||
var ret = [];
|
const ret = [];
|
||||||
|
|
||||||
// is this a continuation of the previous message?
|
// is this a continuation of the previous message?
|
||||||
var continuation = false;
|
let continuation = false;
|
||||||
|
|
||||||
if (prevEvent !== null
|
if (prevEvent !== null
|
||||||
&& prevEvent.sender && mxEv.sender
|
&& 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
|
// local echoes have a fake date, which could even be yesterday. Treat them
|
||||||
// as 'today' for the date separators.
|
// as 'today' for the date separators.
|
||||||
var ts1 = mxEv.getTs();
|
let ts1 = mxEv.getTs();
|
||||||
var eventDate = mxEv.getDate();
|
let eventDate = mxEv.getDate();
|
||||||
if (mxEv.status) {
|
if (mxEv.status) {
|
||||||
eventDate = new Date();
|
eventDate = new Date();
|
||||||
ts1 = eventDate.getTime();
|
ts1 = eventDate.getTime();
|
||||||
|
@ -485,19 +485,19 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// do we need a date separator since the last event?
|
// do we need a date separator since the last event?
|
||||||
if (this._wantsDateSeparator(prevEvent, eventDate)) {
|
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);
|
ret.push(dateSeparator);
|
||||||
continuation = false;
|
continuation = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var eventId = mxEv.getId();
|
const eventId = mxEv.getId();
|
||||||
var highlight = (eventId == this.props.highlightedEventId);
|
const highlight = (eventId == this.props.highlightedEventId);
|
||||||
|
|
||||||
// we can't use local echoes as scroll tokens, because their event IDs change.
|
// we can't use local echoes as scroll tokens, because their event IDs change.
|
||||||
// Local echos have a send "status".
|
// 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) {
|
if (this.props.showReadReceipts) {
|
||||||
readReceipts = this._getReadReceiptsForEvent(mxEv);
|
readReceipts = this._getReadReceiptsForEvent(mxEv);
|
||||||
}
|
}
|
||||||
|
@ -516,7 +516,7 @@ module.exports = React.createClass({
|
||||||
tileShape={this.props.tileShape}
|
tileShape={this.props.tileShape}
|
||||||
isTwelveHour={this.props.isTwelveHour}
|
isTwelveHour={this.props.isTwelveHour}
|
||||||
last={last} isSelectedEvent={highlight} />
|
last={last} isSelectedEvent={highlight} />
|
||||||
</li>
|
</li>,
|
||||||
);
|
);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -551,7 +551,7 @@ module.exports = React.createClass({
|
||||||
if (!room) {
|
if (!room) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let receipts = [];
|
const receipts = [];
|
||||||
room.getReceiptsForEvent(event).forEach((r) => {
|
room.getReceiptsForEvent(event).forEach((r) => {
|
||||||
if (!r.userId || r.type !== "m.read" || r.userId === myUserId) {
|
if (!r.userId || r.type !== "m.read" || r.userId === myUserId) {
|
||||||
return; // ignore non-read receipts and receipts from self.
|
return; // ignore non-read receipts and receipts from self.
|
||||||
|
@ -559,7 +559,7 @@ module.exports = React.createClass({
|
||||||
if (MatrixClientPeg.get().isUserIgnored(r.userId)) {
|
if (MatrixClientPeg.get().isUserIgnored(r.userId)) {
|
||||||
return; // ignore ignored users
|
return; // ignore ignored users
|
||||||
}
|
}
|
||||||
let member = room.getMember(r.userId);
|
const member = room.getMember(r.userId);
|
||||||
if (!member) {
|
if (!member) {
|
||||||
return; // ignore unknown user IDs
|
return; // ignore unknown user IDs
|
||||||
}
|
}
|
||||||
|
@ -575,7 +575,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_getReadMarkerTile: function(visible) {
|
_getReadMarkerTile: function(visible) {
|
||||||
var hr;
|
let hr;
|
||||||
if (visible) {
|
if (visible) {
|
||||||
hr = <hr className="mx_RoomView_myReadMarker"
|
hr = <hr className="mx_RoomView_myReadMarker"
|
||||||
style={{opacity: 1, width: '99%'}}
|
style={{opacity: 1, width: '99%'}}
|
||||||
|
@ -604,7 +604,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_getReadMarkerGhostTile: function() {
|
_getReadMarkerGhostTile: function() {
|
||||||
var hr = <hr className="mx_RoomView_myReadMarker"
|
const hr = <hr className="mx_RoomView_myReadMarker"
|
||||||
style={{opacity: 1, width: '99%'}}
|
style={{opacity: 1, width: '99%'}}
|
||||||
ref={this._startAnimation}
|
ref={this._startAnimation}
|
||||||
/>;
|
/>;
|
||||||
|
@ -627,7 +627,7 @@ module.exports = React.createClass({
|
||||||
// once dynamic content in the events load, make the scrollPanel check the
|
// once dynamic content in the events load, make the scrollPanel check the
|
||||||
// scroll offsets.
|
// scroll offsets.
|
||||||
_onWidgetLoad: function() {
|
_onWidgetLoad: function() {
|
||||||
var scrollPanel = this.refs.scrollPanel;
|
const scrollPanel = this.refs.scrollPanel;
|
||||||
if (scrollPanel) {
|
if (scrollPanel) {
|
||||||
scrollPanel.forceUpdate();
|
scrollPanel.forceUpdate();
|
||||||
}
|
}
|
||||||
|
@ -638,9 +638,9 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var ScrollPanel = sdk.getComponent("structures.ScrollPanel");
|
const ScrollPanel = sdk.getComponent("structures.ScrollPanel");
|
||||||
var Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
var topSpinner, bottomSpinner;
|
let topSpinner, bottomSpinner;
|
||||||
if (this.props.backPaginating) {
|
if (this.props.backPaginating) {
|
||||||
topSpinner = <li key="_topSpinner"><Spinner /></li>;
|
topSpinner = <li key="_topSpinner"><Spinner /></li>;
|
||||||
}
|
}
|
||||||
|
@ -648,10 +648,10 @@ module.exports = React.createClass({
|
||||||
bottomSpinner = <li key="_bottomSpinner"><Spinner /></li>;
|
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;
|
style.opacity = this.props.opacity;
|
||||||
|
|
||||||
var className = this.props.className + " mx_fadable";
|
let className = this.props.className + " mx_fadable";
|
||||||
if (this.props.alwaysShowTimestamps) {
|
if (this.props.alwaysShowTimestamps) {
|
||||||
className += " mx_MessagePanel_alwaysShowTimestamps";
|
className += " mx_MessagePanel_alwaysShowTimestamps";
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,18 +14,18 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var ReactDOM = require("react-dom");
|
const ReactDOM = require("react-dom");
|
||||||
import { _t } from '../../languageHandler';
|
import { _t } from '../../languageHandler';
|
||||||
var Matrix = require("matrix-js-sdk");
|
const Matrix = require("matrix-js-sdk");
|
||||||
var sdk = require('../../index');
|
const sdk = require('../../index');
|
||||||
var MatrixClientPeg = require("../../MatrixClientPeg");
|
const MatrixClientPeg = require("../../MatrixClientPeg");
|
||||||
var dis = require("../../dispatcher");
|
const dis = require("../../dispatcher");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Component which shows the global notification list using a TimelinePanel
|
* Component which shows the global notification list using a TimelinePanel
|
||||||
*/
|
*/
|
||||||
var NotificationPanel = React.createClass({
|
const NotificationPanel = React.createClass({
|
||||||
displayName: 'NotificationPanel',
|
displayName: 'NotificationPanel',
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -33,10 +33,10 @@ var NotificationPanel = React.createClass({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
// wrap a TimelinePanel with the jump-to-event bits turned off.
|
// wrap a TimelinePanel with the jump-to-event bits turned off.
|
||||||
var TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
|
||||||
var Loader = sdk.getComponent("elements.Spinner");
|
const Loader = sdk.getComponent("elements.Spinner");
|
||||||
|
|
||||||
var timelineSet = MatrixClientPeg.get().getNotifTimelineSet();
|
const timelineSet = MatrixClientPeg.get().getNotifTimelineSet();
|
||||||
if (timelineSet) {
|
if (timelineSet) {
|
||||||
return (
|
return (
|
||||||
<TimelinePanel key={"NotificationPanel_" + this.props.roomId}
|
<TimelinePanel key={"NotificationPanel_" + this.props.roomId}
|
||||||
|
@ -50,8 +50,7 @@ var NotificationPanel = React.createClass({
|
||||||
empty={_t('You have no visible notifications')}
|
empty={_t('You have no visible notifications')}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
console.error("No notifTimelineSet available!");
|
console.error("No notifTimelineSet available!");
|
||||||
return (
|
return (
|
||||||
<div className="mx_NotificationPanel">
|
<div className="mx_NotificationPanel">
|
||||||
|
|
|
@ -103,7 +103,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
// we may have entirely lost our client as we're logging out before clicking login on the guest bar...
|
// 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) {
|
if (client) {
|
||||||
client.removeListener("sync", this.onSyncStateChange);
|
client.removeListener("sync", this.onSyncStateChange);
|
||||||
client.removeListener("RoomMember.typing", this.onRoomMemberTyping);
|
client.removeListener("RoomMember.typing", this.onRoomMemberTyping);
|
||||||
|
@ -115,7 +115,7 @@ module.exports = React.createClass({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
syncState: state
|
syncState: state,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.hasActiveCall) {
|
if (this.props.hasActiveCall) {
|
||||||
var TintableSvg = sdk.getComponent("elements.TintableSvg");
|
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||||
return (
|
return (
|
||||||
<TintableSvg src="img/sound-indicator.svg" width="23" height="20" />
|
<TintableSvg src="img/sound-indicator.svg" width="23" height="20" />
|
||||||
);
|
);
|
||||||
|
@ -222,7 +222,7 @@ module.exports = React.createClass({
|
||||||
avatars.push(
|
avatars.push(
|
||||||
<span className="mx_RoomStatusBar_typingIndicatorRemaining" key="others">
|
<span className="mx_RoomStatusBar_typingIndicatorRemaining" key="others">
|
||||||
+{ othersCount }
|
+{ othersCount }
|
||||||
</span>
|
</span>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ module.exports = React.createClass({
|
||||||
[
|
[
|
||||||
(sub) => <a className="mx_RoomStatusBar_resend_link" key="resend" onClick={this.props.onResendAllClick}>{ 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>,
|
(sub) => <a className="mx_RoomStatusBar_resend_link" key="cancel" onClick={this.props.onCancelAllClick}>{ sub }</a>,
|
||||||
]
|
],
|
||||||
) }
|
) }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -275,7 +275,7 @@ module.exports = React.createClass({
|
||||||
// set when you've scrolled up
|
// set when you've scrolled up
|
||||||
if (this.props.numUnreadMessages) {
|
if (this.props.numUnreadMessages) {
|
||||||
// MUST use var name "count" for pluralization to kick in
|
// 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 (
|
return (
|
||||||
<div className="mx_RoomStatusBar_unreadMessagesBar"
|
<div className="mx_RoomStatusBar_unreadMessagesBar"
|
||||||
|
@ -287,7 +287,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
const typingString = WhoIsTyping.whoIsTypingString(
|
const typingString = WhoIsTyping.whoIsTypingString(
|
||||||
this.state.usersTyping,
|
this.state.usersTyping,
|
||||||
this.props.whoIsTypingLimit
|
this.props.whoIsTypingLimit,
|
||||||
);
|
);
|
||||||
if (typingString) {
|
if (typingString) {
|
||||||
return (
|
return (
|
||||||
|
@ -310,8 +310,8 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var content = this._getContent();
|
const content = this._getContent();
|
||||||
var indicator = this._getIndicator(this.state.usersTyping.length > 0);
|
const indicator = this._getIndicator(this.state.usersTyping.length > 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_RoomStatusBar">
|
<div className="mx_RoomStatusBar">
|
||||||
|
|
|
@ -22,25 +22,25 @@ limitations under the License.
|
||||||
|
|
||||||
import shouldHideEvent from "../../shouldHideEvent";
|
import shouldHideEvent from "../../shouldHideEvent";
|
||||||
|
|
||||||
var React = require("react");
|
const React = require("react");
|
||||||
var ReactDOM = require("react-dom");
|
const ReactDOM = require("react-dom");
|
||||||
import Promise from 'bluebird';
|
import Promise from 'bluebird';
|
||||||
var classNames = require("classnames");
|
const classNames = require("classnames");
|
||||||
var Matrix = require("matrix-js-sdk");
|
const Matrix = require("matrix-js-sdk");
|
||||||
import { _t } from '../../languageHandler';
|
import { _t } from '../../languageHandler';
|
||||||
|
|
||||||
var UserSettingsStore = require('../../UserSettingsStore');
|
const UserSettingsStore = require('../../UserSettingsStore');
|
||||||
var MatrixClientPeg = require("../../MatrixClientPeg");
|
const MatrixClientPeg = require("../../MatrixClientPeg");
|
||||||
var ContentMessages = require("../../ContentMessages");
|
const ContentMessages = require("../../ContentMessages");
|
||||||
var Modal = require("../../Modal");
|
const Modal = require("../../Modal");
|
||||||
var sdk = require('../../index');
|
const sdk = require('../../index');
|
||||||
var CallHandler = require('../../CallHandler');
|
const CallHandler = require('../../CallHandler');
|
||||||
var Resend = require("../../Resend");
|
const Resend = require("../../Resend");
|
||||||
var dis = require("../../dispatcher");
|
const dis = require("../../dispatcher");
|
||||||
var Tinter = require("../../Tinter");
|
const Tinter = require("../../Tinter");
|
||||||
var rate_limited_func = require('../../ratelimitedfunc');
|
const rate_limited_func = require('../../ratelimitedfunc');
|
||||||
var ObjectUtils = require('../../ObjectUtils');
|
const ObjectUtils = require('../../ObjectUtils');
|
||||||
var Rooms = require('../../Rooms');
|
const Rooms = require('../../Rooms');
|
||||||
|
|
||||||
import KeyCode from '../../KeyCode';
|
import KeyCode from '../../KeyCode';
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ import UserProvider from '../../autocomplete/UserProvider';
|
||||||
import RoomViewStore from '../../stores/RoomViewStore';
|
import RoomViewStore from '../../stores/RoomViewStore';
|
||||||
import RoomScrollStateStore from '../../stores/RoomScrollStateStore';
|
import RoomScrollStateStore from '../../stores/RoomScrollStateStore';
|
||||||
|
|
||||||
let DEBUG = false;
|
const DEBUG = false;
|
||||||
let debuglog = function() {};
|
let debuglog = function() {};
|
||||||
|
|
||||||
const BROWSER_SUPPORTS_SANDBOX = 'sandbox' in document.createElement('iframe');
|
const BROWSER_SUPPORTS_SANDBOX = 'sandbox' in document.createElement('iframe');
|
||||||
|
@ -307,10 +307,10 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
var call = this._getCallForRoom();
|
const call = this._getCallForRoom();
|
||||||
var callState = call ? call.call_state : "ended";
|
const callState = call ? call.call_state : "ended";
|
||||||
this.setState({
|
this.setState({
|
||||||
callState: callState
|
callState: callState,
|
||||||
});
|
});
|
||||||
|
|
||||||
this._updateConfCallNotification();
|
this._updateConfCallNotification();
|
||||||
|
@ -327,9 +327,8 @@ module.exports = React.createClass({
|
||||||
this.state.room.getJoinedMembers().length == 1 &&
|
this.state.room.getJoinedMembers().length == 1 &&
|
||||||
this.state.room.getLiveTimeline() &&
|
this.state.room.getLiveTimeline() &&
|
||||||
this.state.room.getLiveTimeline().getEvents() &&
|
this.state.room.getLiveTimeline().getEvents() &&
|
||||||
this.state.room.getLiveTimeline().getEvents().length <= 6)
|
this.state.room.getLiveTimeline().getEvents().length <= 6) {
|
||||||
{
|
const inviteBox = document.getElementById("mx_SearchableEntityList_query");
|
||||||
var inviteBox = document.getElementById("mx_SearchableEntityList_query");
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (inviteBox) {
|
if (inviteBox) {
|
||||||
inviteBox.focus();
|
inviteBox.focus();
|
||||||
|
@ -345,7 +344,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
componentDidUpdate: function() {
|
componentDidUpdate: function() {
|
||||||
if (this.refs.roomView) {
|
if (this.refs.roomView) {
|
||||||
var roomView = ReactDOM.findDOMNode(this.refs.roomView);
|
const roomView = ReactDOM.findDOMNode(this.refs.roomView);
|
||||||
if (!roomView.ondrop) {
|
if (!roomView.ondrop) {
|
||||||
roomView.addEventListener('drop', this.onDrop);
|
roomView.addEventListener('drop', this.onDrop);
|
||||||
roomView.addEventListener('dragover', this.onDragOver);
|
roomView.addEventListener('dragover', this.onDragOver);
|
||||||
|
@ -372,7 +371,7 @@ module.exports = React.createClass({
|
||||||
// is really just for hygiene - we're going to be
|
// is really just for hygiene - we're going to be
|
||||||
// deleted anyway, so it doesn't matter if the event listeners
|
// deleted anyway, so it doesn't matter if the event listeners
|
||||||
// don't get cleaned up.
|
// 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('drop', this.onDrop);
|
||||||
roomView.removeEventListener('dragover', this.onDragOver);
|
roomView.removeEventListener('dragover', this.onDragOver);
|
||||||
roomView.removeEventListener('dragleave', this.onDragLeaveOrEnd);
|
roomView.removeEventListener('dragleave', this.onDragLeaveOrEnd);
|
||||||
|
@ -478,8 +477,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
if (call) {
|
if (call) {
|
||||||
callState = call.call_state;
|
callState = call.call_state;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
callState = "ended";
|
callState = "ended";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,17 +589,17 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_calculatePeekRules: function(room) {
|
_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") {
|
if (guestAccessEvent && guestAccessEvent.getContent().guest_access === "can_join") {
|
||||||
this.setState({
|
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") {
|
if (historyVisibility && historyVisibility.getContent().history_visibility === "world_readable") {
|
||||||
this.setState({
|
this.setState({
|
||||||
canPeek: true
|
canPeek: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -610,35 +608,35 @@ module.exports = React.createClass({
|
||||||
// console.log("_updatePreviewUrlVisibility");
|
// console.log("_updatePreviewUrlVisibility");
|
||||||
|
|
||||||
// check our per-room overrides
|
// 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) {
|
if (roomPreviewUrls && roomPreviewUrls.getContent().disable !== undefined) {
|
||||||
this.setState({
|
this.setState({
|
||||||
showUrlPreview: !roomPreviewUrls.getContent().disable
|
showUrlPreview: !roomPreviewUrls.getContent().disable,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check our global disable override
|
// 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) {
|
if (userRoomPreviewUrls && userRoomPreviewUrls.getContent().disable) {
|
||||||
this.setState({
|
this.setState({
|
||||||
showUrlPreview: false
|
showUrlPreview: false,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the room state event
|
// 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) {
|
if (roomStatePreviewUrls && roomStatePreviewUrls.getContent().disable) {
|
||||||
this.setState({
|
this.setState({
|
||||||
showUrlPreview: false
|
showUrlPreview: false,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, we assume they're on.
|
// otherwise, we assume they're on.
|
||||||
this.setState({
|
this.setState({
|
||||||
showUrlPreview: true
|
showUrlPreview: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -654,11 +652,11 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
updateTint: function() {
|
updateTint: function() {
|
||||||
var room = this.state.room;
|
const room = this.state.room;
|
||||||
if (!room) return;
|
if (!room) return;
|
||||||
|
|
||||||
var color_scheme_event = room.getAccountData("org.matrix.room.color_scheme");
|
const color_scheme_event = room.getAccountData("org.matrix.room.color_scheme");
|
||||||
var color_scheme = {};
|
let color_scheme = {};
|
||||||
if (color_scheme_event) {
|
if (color_scheme_event) {
|
||||||
color_scheme = color_scheme_event.getContent();
|
color_scheme = color_scheme_event.getContent();
|
||||||
// XXX: we should validate the event
|
// XXX: we should validate the event
|
||||||
|
@ -676,12 +674,11 @@ module.exports = React.createClass({
|
||||||
onRoomAccountData: function(event, room) {
|
onRoomAccountData: function(event, room) {
|
||||||
if (room.roomId == this.state.roomId) {
|
if (room.roomId == this.state.roomId) {
|
||||||
if (event.getType() === "org.matrix.room.color_scheme") {
|
if (event.getType() === "org.matrix.room.color_scheme") {
|
||||||
var color_scheme = event.getContent();
|
const color_scheme = event.getContent();
|
||||||
// XXX: we should validate the event
|
// XXX: we should validate the event
|
||||||
console.log("Tinter.tint from onRoomAccountData");
|
console.log("Tinter.tint from onRoomAccountData");
|
||||||
Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
|
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);
|
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
|
// 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
|
// means we have finished joining a room we were previously peeking
|
||||||
// into.
|
// into.
|
||||||
var me = MatrixClientPeg.get().credentials.userId;
|
const me = MatrixClientPeg.get().credentials.userId;
|
||||||
if (this.state.joining && this.state.room.hasMembershipState(me, "join")) {
|
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,
|
// 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
|
// 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() {
|
_updateConfCallNotification: function() {
|
||||||
var room = this.state.room;
|
const room = this.state.room;
|
||||||
if (!room || !this.props.ConferenceHandler) {
|
if (!room || !this.props.ConferenceHandler) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var confMember = room.getMember(
|
const confMember = room.getMember(
|
||||||
this.props.ConferenceHandler.getConferenceUserIdForRoom(room.roomId)
|
this.props.ConferenceHandler.getConferenceUserIdForRoom(room.roomId),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!confMember) {
|
if (!confMember) {
|
||||||
return;
|
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
|
// A conf call notification should be displayed if there is an ongoing
|
||||||
// conf call but this cilent isn't a part of it.
|
// conf call but this cilent isn't a part of it.
|
||||||
|
@ -773,7 +770,7 @@ module.exports = React.createClass({
|
||||||
displayConfCallNotification: (
|
displayConfCallNotification: (
|
||||||
(!confCall || confCall.call_state === "ended") &&
|
(!confCall || confCall.call_state === "ended") &&
|
||||||
confMember.membership === "join"
|
confMember.membership === "join"
|
||||||
)
|
),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -788,7 +785,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
if (this.state.searchResults.next_batch) {
|
if (this.state.searchResults.next_batch) {
|
||||||
debuglog("requesting more search results");
|
debuglog("requesting more search results");
|
||||||
var searchPromise = MatrixClientPeg.get().backPaginateRoomEventsSearch(
|
const searchPromise = MatrixClientPeg.get().backPaginateRoomEventsSearch(
|
||||||
this.state.searchResults);
|
this.state.searchResults);
|
||||||
return this._handleSearchResult(searchPromise);
|
return this._handleSearchResult(searchPromise);
|
||||||
} else {
|
} else {
|
||||||
|
@ -883,8 +880,7 @@ module.exports = React.createClass({
|
||||||
numUnreadMessages: 0,
|
numUnreadMessages: 0,
|
||||||
atEndOfLiveTimeline: true,
|
atEndOfLiveTimeline: true,
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.setState({
|
this.setState({
|
||||||
atEndOfLiveTimeline: false,
|
atEndOfLiveTimeline: false,
|
||||||
});
|
});
|
||||||
|
@ -898,7 +894,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
ev.dataTransfer.dropEffect = 'none';
|
ev.dataTransfer.dropEffect = 'none';
|
||||||
|
|
||||||
var items = ev.dataTransfer.items;
|
const items = ev.dataTransfer.items;
|
||||||
if (items.length == 1) {
|
if (items.length == 1) {
|
||||||
if (items[0].kind == 'file') {
|
if (items[0].kind == 'file') {
|
||||||
this.setState({ draggingFile: true });
|
this.setState({ draggingFile: true });
|
||||||
|
@ -911,7 +907,7 @@ module.exports = React.createClass({
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
this.setState({ draggingFile: false });
|
this.setState({ draggingFile: false });
|
||||||
var files = ev.dataTransfer.files;
|
const files = ev.dataTransfer.files;
|
||||||
if (files.length == 1) {
|
if (files.length == 1) {
|
||||||
this.uploadFile(files[0]);
|
this.uploadFile(files[0]);
|
||||||
}
|
}
|
||||||
|
@ -930,7 +926,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentMessages.sendContentToRoom(
|
ContentMessages.sendContentToRoom(
|
||||||
file, this.state.room.roomId, MatrixClientPeg.get()
|
file, this.state.room.roomId, MatrixClientPeg.get(),
|
||||||
).done(undefined, (error) => {
|
).done(undefined, (error) => {
|
||||||
if (error.name === "UnknownDeviceError") {
|
if (error.name === "UnknownDeviceError") {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
|
@ -969,19 +965,19 @@ module.exports = React.createClass({
|
||||||
// todo: should cancel any previous search requests.
|
// todo: should cancel any previous search requests.
|
||||||
this.searchId = new Date().getTime();
|
this.searchId = new Date().getTime();
|
||||||
|
|
||||||
var filter;
|
let filter;
|
||||||
if (scope === "Room") {
|
if (scope === "Room") {
|
||||||
filter = {
|
filter = {
|
||||||
// XXX: it's unintuitive that the filter for searching doesn't have the same shape as the v2 filter API :(
|
// XXX: it's unintuitive that the filter for searching doesn't have the same shape as the v2 filter API :(
|
||||||
rooms: [
|
rooms: [
|
||||||
this.state.room.roomId
|
this.state.room.roomId,
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
debuglog("sending search request");
|
debuglog("sending search request");
|
||||||
|
|
||||||
var searchPromise = MatrixClientPeg.get().searchRoomEvents({
|
const searchPromise = MatrixClientPeg.get().searchRoomEvents({
|
||||||
filter: filter,
|
filter: filter,
|
||||||
term: term,
|
term: term,
|
||||||
});
|
});
|
||||||
|
@ -989,11 +985,11 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleSearchResult: function(searchPromise) {
|
_handleSearchResult: function(searchPromise) {
|
||||||
var self = this;
|
const self = this;
|
||||||
|
|
||||||
// keep a record of the current search id, so that if the search terms
|
// 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.
|
// change before we get a response, we can ignore the results.
|
||||||
var localSearchId = this.searchId;
|
const localSearchId = this.searchId;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
searchInProgress: true,
|
searchInProgress: true,
|
||||||
|
@ -1012,7 +1008,7 @@ module.exports = React.createClass({
|
||||||
// In either case, we want to highlight the literal search term
|
// In either case, we want to highlight the literal search term
|
||||||
// whether it was used by the search engine or not.
|
// 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) {
|
if (highlights.indexOf(self.state.searchTerm) < 0) {
|
||||||
highlights = highlights.concat(self.state.searchTerm);
|
highlights = highlights.concat(self.state.searchTerm);
|
||||||
}
|
}
|
||||||
|
@ -1020,14 +1016,15 @@ module.exports = React.createClass({
|
||||||
// For overlapping highlights,
|
// For overlapping highlights,
|
||||||
// favour longer (more specific) terms first
|
// favour longer (more specific) terms first
|
||||||
highlights = highlights.sort(function(a, b) {
|
highlights = highlights.sort(function(a, b) {
|
||||||
return b.length - a.length; });
|
return b.length - a.length;
|
||||||
|
});
|
||||||
|
|
||||||
self.setState({
|
self.setState({
|
||||||
searchHighlights: highlights,
|
searchHighlights: highlights,
|
||||||
searchResults: results,
|
searchResults: results,
|
||||||
});
|
});
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
console.error("Search failed: " + error);
|
console.error("Search failed: " + error);
|
||||||
Modal.createTrackedDialog('Search failed', '', ErrorDialog, {
|
Modal.createTrackedDialog('Search failed', '', ErrorDialog, {
|
||||||
title: _t("Search failed"),
|
title: _t("Search failed"),
|
||||||
|
@ -1035,17 +1032,17 @@ module.exports = React.createClass({
|
||||||
});
|
});
|
||||||
}).finally(function() {
|
}).finally(function() {
|
||||||
self.setState({
|
self.setState({
|
||||||
searchInProgress: false
|
searchInProgress: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getSearchResultTiles: function() {
|
getSearchResultTiles: function() {
|
||||||
var EventTile = sdk.getComponent('rooms.EventTile');
|
const EventTile = sdk.getComponent('rooms.EventTile');
|
||||||
var SearchResultTile = sdk.getComponent('rooms.SearchResultTile');
|
const SearchResultTile = sdk.getComponent('rooms.SearchResultTile');
|
||||||
var Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
|
|
||||||
var cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
|
|
||||||
// XXX: todo: merge overlapping results somehow?
|
// XXX: todo: merge overlapping results somehow?
|
||||||
// XXX: why doesn't searching on name work?
|
// XXX: why doesn't searching on name work?
|
||||||
|
@ -1055,7 +1052,7 @@ module.exports = React.createClass({
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret = [];
|
const ret = [];
|
||||||
|
|
||||||
if (this.state.searchInProgress) {
|
if (this.state.searchInProgress) {
|
||||||
ret.push(<li key="search-spinner">
|
ret.push(<li key="search-spinner">
|
||||||
|
@ -1067,32 +1064,32 @@ module.exports = React.createClass({
|
||||||
if (this.state.searchResults.results.length == 0) {
|
if (this.state.searchResults.results.length == 0) {
|
||||||
ret.push(<li key="search-top-marker">
|
ret.push(<li key="search-top-marker">
|
||||||
<h2 className="mx_RoomView_topMarker">{ _t("No results") }</h2>
|
<h2 className="mx_RoomView_topMarker">{ _t("No results") }</h2>
|
||||||
</li>
|
</li>,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
ret.push(<li key="search-top-marker">
|
ret.push(<li key="search-top-marker">
|
||||||
<h2 className="mx_RoomView_topMarker">{ _t("No more results") }</h2>
|
<h2 className="mx_RoomView_topMarker">{ _t("No more results") }</h2>
|
||||||
</li>
|
</li>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// once dynamic content in the search results load, make the scrollPanel check
|
// once dynamic content in the search results load, make the scrollPanel check
|
||||||
// the scroll offsets.
|
// the scroll offsets.
|
||||||
var onWidgetLoad = () => {
|
const onWidgetLoad = () => {
|
||||||
var scrollPanel = this.refs.searchResultsPanel;
|
const scrollPanel = this.refs.searchResultsPanel;
|
||||||
if (scrollPanel) {
|
if (scrollPanel) {
|
||||||
scrollPanel.checkScroll();
|
scrollPanel.checkScroll();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var lastRoomId;
|
let lastRoomId;
|
||||||
|
|
||||||
for (var i = this.state.searchResults.results.length - 1; i >= 0; i--) {
|
for (let i = this.state.searchResults.results.length - 1; i >= 0; i--) {
|
||||||
var result = this.state.searchResults.results[i];
|
const result = this.state.searchResults.results[i];
|
||||||
|
|
||||||
var mxEv = result.context.getEvent();
|
const mxEv = result.context.getEvent();
|
||||||
var roomId = mxEv.getRoomId();
|
const roomId = mxEv.getRoomId();
|
||||||
|
|
||||||
if (!EventTile.haveTileForEvent(mxEv)) {
|
if (!EventTile.haveTileForEvent(mxEv)) {
|
||||||
// XXX: can this ever happen? It will make the result count
|
// 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 (this.state.searchScope === 'All') {
|
||||||
if(roomId != lastRoomId) {
|
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
|
// 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. We should tell the js sdk to go and find out about
|
||||||
// it. But that's not an issue currently, as synapse only
|
// it. But that's not an issue currently, as synapse only
|
||||||
// returns results for rooms we're joined to.
|
// 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"}>
|
ret.push(<li key={mxEv.getId() + "-room"}>
|
||||||
<h1>{ _t("Room") }: { roomName }</h1>
|
<h1>{ _t("Room") }: { roomName }</h1>
|
||||||
|
@ -1117,7 +1114,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var resultLink = "#/room/"+roomId+"/"+mxEv.getId();
|
const resultLink = "#/room/"+roomId+"/"+mxEv.getId();
|
||||||
|
|
||||||
ret.push(<SearchResultTile key={mxEv.getId()}
|
ret.push(<SearchResultTile key={mxEv.getId()}
|
||||||
searchResult={result}
|
searchResult={result}
|
||||||
|
@ -1139,38 +1136,37 @@ module.exports = React.createClass({
|
||||||
uploadingRoomSettings: true,
|
uploadingRoomSettings: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
var newName = this.refs.header.getEditedName();
|
const newName = this.refs.header.getEditedName();
|
||||||
if (newName !== undefined) {
|
if (newName !== undefined) {
|
||||||
this.refs.room_settings.setName(newName);
|
this.refs.room_settings.setName(newName);
|
||||||
}
|
}
|
||||||
var newTopic = this.refs.header.getEditedTopic();
|
const newTopic = this.refs.header.getEditedTopic();
|
||||||
if (newTopic !== undefined) {
|
if (newTopic !== undefined) {
|
||||||
this.refs.room_settings.setTopic(newTopic);
|
this.refs.room_settings.setTopic(newTopic);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.refs.room_settings.save().then((results) => {
|
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);
|
console.log("Settings saved with %s errors", fails.length);
|
||||||
if (fails.length) {
|
if (fails.length) {
|
||||||
fails.forEach(function(result) {
|
fails.forEach(function(result) {
|
||||||
console.error(result.reason);
|
console.error(result.reason);
|
||||||
});
|
});
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
Modal.createTrackedDialog('Failed to save room settings', '', ErrorDialog, {
|
Modal.createTrackedDialog('Failed to save room settings', '', ErrorDialog, {
|
||||||
title: _t("Failed to save settings"),
|
title: _t("Failed to save settings"),
|
||||||
description: fails.map(function(result) { return result.reason; }).join("\n"),
|
description: fails.map(function(result) { return result.reason; }).join("\n"),
|
||||||
});
|
});
|
||||||
// still editing room settings
|
// still editing room settings
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.setState({
|
this.setState({
|
||||||
editingRoomSettings: false
|
editingRoomSettings: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.setState({
|
this.setState({
|
||||||
uploadingRoomSettings: false,
|
uploadingRoomSettings: false,
|
||||||
editingRoomSettings: false
|
editingRoomSettings: false,
|
||||||
});
|
});
|
||||||
}).done();
|
}).done();
|
||||||
},
|
},
|
||||||
|
@ -1201,8 +1197,8 @@ module.exports = React.createClass({
|
||||||
MatrixClientPeg.get().forget(this.state.room.roomId).done(function() {
|
MatrixClientPeg.get().forget(this.state.room.roomId).done(function() {
|
||||||
dis.dispatch({ action: 'view_next_room' });
|
dis.dispatch({ action: 'view_next_room' });
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
var errCode = err.errcode || _t("unknown error code");
|
const errCode = err.errcode || _t("unknown error code");
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
Modal.createTrackedDialog('Failed to forget room', '', ErrorDialog, {
|
Modal.createTrackedDialog('Failed to forget room', '', ErrorDialog, {
|
||||||
title: _t("Error"),
|
title: _t("Error"),
|
||||||
description: _t("Failed to forget room %(errCode)s", { errCode: errCode }),
|
description: _t("Failed to forget room %(errCode)s", { errCode: errCode }),
|
||||||
|
@ -1211,20 +1207,20 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onRejectButtonClicked: function(ev) {
|
onRejectButtonClicked: function(ev) {
|
||||||
var self = this;
|
const self = this;
|
||||||
this.setState({
|
this.setState({
|
||||||
rejecting: true
|
rejecting: true,
|
||||||
});
|
});
|
||||||
MatrixClientPeg.get().leave(this.state.roomId).done(function() {
|
MatrixClientPeg.get().leave(this.state.roomId).done(function() {
|
||||||
dis.dispatch({ action: 'view_next_room' });
|
dis.dispatch({ action: 'view_next_room' });
|
||||||
self.setState({
|
self.setState({
|
||||||
rejecting: false
|
rejecting: false,
|
||||||
});
|
});
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
console.error("Failed to reject invite: %s", error);
|
console.error("Failed to reject invite: %s", error);
|
||||||
|
|
||||||
var msg = error.message ? error.message : JSON.stringify(error);
|
const msg = error.message ? error.message : JSON.stringify(error);
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
Modal.createTrackedDialog('Failed to reject invite', '', ErrorDialog, {
|
Modal.createTrackedDialog('Failed to reject invite', '', ErrorDialog, {
|
||||||
title: _t("Failed to reject invite"),
|
title: _t("Failed to reject invite"),
|
||||||
description: msg,
|
description: msg,
|
||||||
|
@ -1232,7 +1228,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
self.setState({
|
self.setState({
|
||||||
rejecting: false,
|
rejecting: false,
|
||||||
rejectError: error
|
rejectError: error,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -1292,7 +1288,7 @@ module.exports = React.createClass({
|
||||||
// restored when we switch back to it.
|
// restored when we switch back to it.
|
||||||
//
|
//
|
||||||
_getScrollState: function() {
|
_getScrollState: function() {
|
||||||
var messagePanel = this.refs.messagePanel;
|
const messagePanel = this.refs.messagePanel;
|
||||||
if (!messagePanel) return null;
|
if (!messagePanel) return null;
|
||||||
|
|
||||||
// if we're following the live timeline, we want to return null; that
|
// if we're following the live timeline, we want to return null; that
|
||||||
|
@ -1307,7 +1303,7 @@ module.exports = React.createClass({
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var scrollState = messagePanel.getScrollState();
|
const scrollState = messagePanel.getScrollState();
|
||||||
|
|
||||||
if (scrollState.stuckAtBottom) {
|
if (scrollState.stuckAtBottom) {
|
||||||
// we don't really expect to be in this state, but it will
|
// 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.
|
// a maxHeight on the underlying remote video tag.
|
||||||
|
|
||||||
// header + footer + status + give us at least 120px of scrollback at all times.
|
// 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
|
(83 + // height of RoomHeader
|
||||||
36 + // height of the status area
|
36 + // height of the status area
|
||||||
72 + // minimum height of the message compmoser
|
72 + // minimum height of the message compmoser
|
||||||
|
@ -1353,26 +1349,26 @@ module.exports = React.createClass({
|
||||||
onFullscreenClick: function() {
|
onFullscreenClick: function() {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'video_fullscreen',
|
action: 'video_fullscreen',
|
||||||
fullscreen: true
|
fullscreen: true,
|
||||||
}, true);
|
}, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
onMuteAudioClick: function() {
|
onMuteAudioClick: function() {
|
||||||
var call = this._getCallForRoom();
|
const call = this._getCallForRoom();
|
||||||
if (!call) {
|
if (!call) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var newState = !call.isMicrophoneMuted();
|
const newState = !call.isMicrophoneMuted();
|
||||||
call.setMicrophoneMuted(newState);
|
call.setMicrophoneMuted(newState);
|
||||||
this.forceUpdate(); // TODO: just update the voip buttons
|
this.forceUpdate(); // TODO: just update the voip buttons
|
||||||
},
|
},
|
||||||
|
|
||||||
onMuteVideoClick: function() {
|
onMuteVideoClick: function() {
|
||||||
var call = this._getCallForRoom();
|
const call = this._getCallForRoom();
|
||||||
if (!call) {
|
if (!call) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var newState = !call.isLocalVideoMuted();
|
const newState = !call.isLocalVideoMuted();
|
||||||
call.setLocalVideoMuted(newState);
|
call.setLocalVideoMuted(newState);
|
||||||
this.forceUpdate(); // TODO: just update the voip buttons
|
this.forceUpdate(); // TODO: just update the voip buttons
|
||||||
},
|
},
|
||||||
|
@ -1408,7 +1404,7 @@ module.exports = React.createClass({
|
||||||
* We pass it down to the scroll panel.
|
* We pass it down to the scroll panel.
|
||||||
*/
|
*/
|
||||||
handleScrollKey: function(ev) {
|
handleScrollKey: function(ev) {
|
||||||
var panel;
|
let panel;
|
||||||
if(this.refs.searchResultsPanel) {
|
if(this.refs.searchResultsPanel) {
|
||||||
panel = this.refs.searchResultsPanel;
|
panel = this.refs.searchResultsPanel;
|
||||||
} else if(this.refs.messagePanel) {
|
} else if(this.refs.messagePanel) {
|
||||||
|
@ -1498,8 +1494,8 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||||
var myMember = this.state.room.getMember(myUserId);
|
const myMember = this.state.room.getMember(myUserId);
|
||||||
if (myMember && myMember.membership == 'invite') {
|
if (myMember && myMember.membership == 'invite') {
|
||||||
if (this.state.joining || this.state.rejecting) {
|
if (this.state.joining || this.state.rejecting) {
|
||||||
return (
|
return (
|
||||||
|
@ -1508,7 +1504,7 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
var inviteEvent = myMember.events.member;
|
const inviteEvent = myMember.events.member;
|
||||||
var inviterName = inviteEvent.sender ? inviteEvent.sender.name : inviteEvent.getSender();
|
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
|
// We deliberately don't try to peek into invites, even if we have permission to peek
|
||||||
|
@ -1542,24 +1538,24 @@ module.exports = React.createClass({
|
||||||
// We have successfully loaded this room, and are not previewing.
|
// We have successfully loaded this room, and are not previewing.
|
||||||
// Display the "normal" room view.
|
// Display the "normal" room view.
|
||||||
|
|
||||||
var call = this._getCallForRoom();
|
const call = this._getCallForRoom();
|
||||||
var inCall = false;
|
let inCall = false;
|
||||||
if (call && (this.state.callState !== 'ended' && this.state.callState !== 'ringing')) {
|
if (call && (this.state.callState !== 'ended' && this.state.callState !== 'ringing')) {
|
||||||
inCall = true;
|
inCall = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var scrollheader_classes = classNames({
|
const scrollheader_classes = classNames({
|
||||||
mx_RoomView_scrollheader: true,
|
mx_RoomView_scrollheader: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
var statusBar;
|
let statusBar;
|
||||||
let isStatusAreaExpanded = true;
|
let isStatusAreaExpanded = true;
|
||||||
|
|
||||||
if (ContentMessages.getCurrentUploads().length > 0) {
|
if (ContentMessages.getCurrentUploads().length > 0) {
|
||||||
var UploadBar = sdk.getComponent('structures.UploadBar');
|
const UploadBar = sdk.getComponent('structures.UploadBar');
|
||||||
statusBar = <UploadBar room={this.state.room} />;
|
statusBar = <UploadBar room={this.state.room} />;
|
||||||
} else if (!this.state.searchResults) {
|
} else if (!this.state.searchResults) {
|
||||||
var RoomStatusBar = sdk.getComponent('structures.RoomStatusBar');
|
const RoomStatusBar = sdk.getComponent('structures.RoomStatusBar');
|
||||||
isStatusAreaExpanded = this.state.statusBarVisible;
|
isStatusAreaExpanded = this.state.statusBarVisible;
|
||||||
statusBar = <RoomStatusBar
|
statusBar = <RoomStatusBar
|
||||||
room={this.state.room}
|
room={this.state.room}
|
||||||
|
@ -1613,7 +1609,7 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var auxPanel = (
|
const auxPanel = (
|
||||||
<AuxPanel ref="auxPanel" room={this.state.room}
|
<AuxPanel ref="auxPanel" room={this.state.room}
|
||||||
userId={MatrixClientPeg.get().credentials.userId}
|
userId={MatrixClientPeg.get().credentials.userId}
|
||||||
conferenceHandler={this.props.ConferenceHandler}
|
conferenceHandler={this.props.ConferenceHandler}
|
||||||
|
@ -1626,8 +1622,8 @@ module.exports = React.createClass({
|
||||||
</AuxPanel>
|
</AuxPanel>
|
||||||
);
|
);
|
||||||
|
|
||||||
var messageComposer, searchInfo;
|
let messageComposer, searchInfo;
|
||||||
var canSpeak = (
|
const canSpeak = (
|
||||||
// joined and not showing search results
|
// joined and not showing search results
|
||||||
myMember && (myMember.membership == 'join') && !this.state.searchResults
|
myMember && (myMember.membership == 'join') && !this.state.searchResults
|
||||||
);
|
);
|
||||||
|
@ -1654,7 +1650,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inCall) {
|
if (inCall) {
|
||||||
var zoomButton, voiceMuteButton, videoMuteButton;
|
let zoomButton, voiceMuteButton, videoMuteButton;
|
||||||
|
|
||||||
if (call.type === "video") {
|
if (call.type === "video") {
|
||||||
zoomButton = (
|
zoomButton = (
|
||||||
|
@ -1690,8 +1686,8 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// if we have search results, we keep the messagepanel (so that it preserves its
|
// if we have search results, we keep the messagepanel (so that it preserves its
|
||||||
// scroll state), but hide it.
|
// scroll state), but hide it.
|
||||||
var searchResultsPanel;
|
let searchResultsPanel;
|
||||||
var hideMessagePanel = false;
|
let hideMessagePanel = false;
|
||||||
|
|
||||||
if (this.state.searchResults) {
|
if (this.state.searchResults) {
|
||||||
searchResultsPanel = (
|
searchResultsPanel = (
|
||||||
|
@ -1717,7 +1713,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log("ShowUrlPreview for %s is %s", this.state.room.roomId, this.state.showUrlPreview);
|
// console.log("ShowUrlPreview for %s is %s", this.state.room.roomId, this.state.showUrlPreview);
|
||||||
var messagePanel = (
|
const messagePanel = (
|
||||||
<TimelinePanel ref={this._gatherTimelinePanelRef}
|
<TimelinePanel ref={this._gatherTimelinePanelRef}
|
||||||
timelineSet={this.state.room.getUnfilteredTimelineSet()}
|
timelineSet={this.state.room.getUnfilteredTimelineSet()}
|
||||||
showReadReceipts={!UserSettingsStore.getSyncedSetting('hideReadReceipts', false)}
|
showReadReceipts={!UserSettingsStore.getSyncedSetting('hideReadReceipts', false)}
|
||||||
|
@ -1734,9 +1730,9 @@ module.exports = React.createClass({
|
||||||
className="mx_RoomView_messagePanel"
|
className="mx_RoomView_messagePanel"
|
||||||
/>);
|
/>);
|
||||||
|
|
||||||
var topUnreadMessagesBar = null;
|
let topUnreadMessagesBar = null;
|
||||||
if (this.state.showTopUnreadMessagesBar) {
|
if (this.state.showTopUnreadMessagesBar) {
|
||||||
var TopUnreadMessagesBar = sdk.getComponent('rooms.TopUnreadMessagesBar');
|
const TopUnreadMessagesBar = sdk.getComponent('rooms.TopUnreadMessagesBar');
|
||||||
topUnreadMessagesBar = (
|
topUnreadMessagesBar = (
|
||||||
<div className="mx_RoomView_topUnreadMessagesBar mx_fadable" style={{ opacity: this.props.opacity }}>
|
<div className="mx_RoomView_topUnreadMessagesBar mx_fadable" style={{ opacity: this.props.opacity }}>
|
||||||
<TopUnreadMessagesBar
|
<TopUnreadMessagesBar
|
||||||
|
|
|
@ -14,13 +14,13 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var React = require("react");
|
const React = require("react");
|
||||||
var ReactDOM = require("react-dom");
|
const ReactDOM = require("react-dom");
|
||||||
var GeminiScrollbar = require('react-gemini-scrollbar');
|
const GeminiScrollbar = require('react-gemini-scrollbar');
|
||||||
import Promise from 'bluebird';
|
import Promise from 'bluebird';
|
||||||
var KeyCode = require('../../KeyCode');
|
const KeyCode = require('../../KeyCode');
|
||||||
|
|
||||||
var DEBUG_SCROLL = false;
|
const DEBUG_SCROLL = false;
|
||||||
// var DEBUG_SCROLL = true;
|
// var DEBUG_SCROLL = true;
|
||||||
|
|
||||||
// The amount of extra scroll distance to allow prior to unfilling.
|
// The amount of extra scroll distance to allow prior to unfilling.
|
||||||
|
@ -178,7 +178,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onScroll: function(ev) {
|
onScroll: function(ev) {
|
||||||
var sn = this._getScrollNode();
|
const sn = this._getScrollNode();
|
||||||
debuglog("Scroll event: offset now:", sn.scrollTop,
|
debuglog("Scroll event: offset now:", sn.scrollTop,
|
||||||
"_lastSetScroll:", this._lastSetScroll);
|
"_lastSetScroll:", this._lastSetScroll);
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ module.exports = React.createClass({
|
||||||
// about whether the the content is scrolled down right now, irrespective of
|
// about whether the the content is scrolled down right now, irrespective of
|
||||||
// whether it will stay that way when the children update.
|
// whether it will stay that way when the children update.
|
||||||
isAtBottom: function() {
|
isAtBottom: function() {
|
||||||
var sn = this._getScrollNode();
|
const sn = this._getScrollNode();
|
||||||
|
|
||||||
// there seems to be some bug with flexbox/gemini/chrome/richvdh's
|
// there seems to be some bug with flexbox/gemini/chrome/richvdh's
|
||||||
// understanding of the box model, wherein the scrollNode ends up 2
|
// understanding of the box model, wherein the scrollNode ends up 2
|
||||||
|
@ -281,7 +281,7 @@ module.exports = React.createClass({
|
||||||
// |#########| |
|
// |#########| |
|
||||||
// `---------' -
|
// `---------' -
|
||||||
_getExcessHeight: function(backwards) {
|
_getExcessHeight: function(backwards) {
|
||||||
var sn = this._getScrollNode();
|
const sn = this._getScrollNode();
|
||||||
if (backwards) {
|
if (backwards) {
|
||||||
return sn.scrollTop - sn.clientHeight - UNPAGINATION_PADDING;
|
return sn.scrollTop - sn.clientHeight - UNPAGINATION_PADDING;
|
||||||
} else {
|
} else {
|
||||||
|
@ -295,7 +295,7 @@ module.exports = React.createClass({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var sn = this._getScrollNode();
|
const sn = this._getScrollNode();
|
||||||
|
|
||||||
// if there is less than a screenful of messages above or below the
|
// if there is less than a screenful of messages above or below the
|
||||||
// viewport, try to get some more messages.
|
// 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.
|
// check if there is already a pending fill request. If not, set one off.
|
||||||
_maybeFill: function(backwards) {
|
_maybeFill: function(backwards) {
|
||||||
var dir = backwards ? 'b' : 'f';
|
const dir = backwards ? 'b' : 'f';
|
||||||
if (this._pendingFillRequests[dir]) {
|
if (this._pendingFillRequests[dir]) {
|
||||||
debuglog("ScrollPanel: Already a "+dir+" fill in progress - not starting another");
|
debuglog("ScrollPanel: Already a "+dir+" fill in progress - not starting another");
|
||||||
return;
|
return;
|
||||||
|
@ -470,8 +470,8 @@ module.exports = React.createClass({
|
||||||
* mult: -1 to page up, +1 to page down
|
* mult: -1 to page up, +1 to page down
|
||||||
*/
|
*/
|
||||||
scrollRelative: function(mult) {
|
scrollRelative: function(mult) {
|
||||||
var scrollNode = this._getScrollNode();
|
const scrollNode = this._getScrollNode();
|
||||||
var delta = mult * scrollNode.clientHeight * 0.5;
|
const delta = mult * scrollNode.clientHeight * 0.5;
|
||||||
this._setScrollTop(scrollNode.scrollTop + delta);
|
this._setScrollTop(scrollNode.scrollTop + delta);
|
||||||
this._saveScrollState();
|
this._saveScrollState();
|
||||||
},
|
},
|
||||||
|
@ -535,7 +535,7 @@ module.exports = React.createClass({
|
||||||
this.scrollState = {
|
this.scrollState = {
|
||||||
stuckAtBottom: false,
|
stuckAtBottom: false,
|
||||||
trackedScrollToken: scrollToken,
|
trackedScrollToken: scrollToken,
|
||||||
pixelOffset: pixelOffset
|
pixelOffset: pixelOffset,
|
||||||
};
|
};
|
||||||
|
|
||||||
// ... then make it so.
|
// ... then make it so.
|
||||||
|
@ -546,10 +546,10 @@ module.exports = React.createClass({
|
||||||
// given offset in the window. A helper for _restoreSavedScrollState.
|
// given offset in the window. A helper for _restoreSavedScrollState.
|
||||||
_scrollToToken: function(scrollToken, pixelOffset) {
|
_scrollToToken: function(scrollToken, pixelOffset) {
|
||||||
/* find the dom node with the right scrolltoken */
|
/* find the dom node with the right scrolltoken */
|
||||||
var node;
|
let node;
|
||||||
var messages = this.refs.itemlist.children;
|
const messages = this.refs.itemlist.children;
|
||||||
for (var i = messages.length-1; i >= 0; --i) {
|
for (let i = messages.length-1; i >= 0; --i) {
|
||||||
var m = messages[i];
|
const m = messages[i];
|
||||||
// 'data-scroll-tokens' is a DOMString of comma-separated scroll tokens
|
// 'data-scroll-tokens' is a DOMString of comma-separated scroll tokens
|
||||||
// There might only be one scroll token
|
// There might only be one scroll token
|
||||||
if (m.dataset.scrollTokens &&
|
if (m.dataset.scrollTokens &&
|
||||||
|
@ -564,10 +564,10 @@ module.exports = React.createClass({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var scrollNode = this._getScrollNode();
|
const scrollNode = this._getScrollNode();
|
||||||
var wrapperRect = ReactDOM.findDOMNode(this).getBoundingClientRect();
|
const wrapperRect = ReactDOM.findDOMNode(this).getBoundingClientRect();
|
||||||
var boundingRect = node.getBoundingClientRect();
|
const boundingRect = node.getBoundingClientRect();
|
||||||
var scrollDelta = boundingRect.bottom + pixelOffset - wrapperRect.bottom;
|
const scrollDelta = boundingRect.bottom + pixelOffset - wrapperRect.bottom;
|
||||||
|
|
||||||
debuglog("ScrollPanel: scrolling to token '" + scrollToken + "'+" +
|
debuglog("ScrollPanel: scrolling to token '" + scrollToken + "'+" +
|
||||||
pixelOffset + " (delta: "+scrollDelta+")");
|
pixelOffset + " (delta: "+scrollDelta+")");
|
||||||
|
@ -575,7 +575,6 @@ module.exports = React.createClass({
|
||||||
if(scrollDelta != 0) {
|
if(scrollDelta != 0) {
|
||||||
this._setScrollTop(scrollNode.scrollTop + scrollDelta);
|
this._setScrollTop(scrollNode.scrollTop + scrollDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_saveScrollState: function() {
|
_saveScrollState: function() {
|
||||||
|
@ -585,16 +584,16 @@ module.exports = React.createClass({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var itemlist = this.refs.itemlist;
|
const itemlist = this.refs.itemlist;
|
||||||
var wrapperRect = ReactDOM.findDOMNode(this).getBoundingClientRect();
|
const wrapperRect = ReactDOM.findDOMNode(this).getBoundingClientRect();
|
||||||
var messages = itemlist.children;
|
const messages = itemlist.children;
|
||||||
let newScrollState = null;
|
let newScrollState = null;
|
||||||
|
|
||||||
for (var i = messages.length-1; i >= 0; --i) {
|
for (let i = messages.length-1; i >= 0; --i) {
|
||||||
var node = messages[i];
|
const node = messages[i];
|
||||||
if (!node.dataset.scrollTokens) continue;
|
if (!node.dataset.scrollTokens) continue;
|
||||||
|
|
||||||
var boundingRect = node.getBoundingClientRect();
|
const boundingRect = node.getBoundingClientRect();
|
||||||
newScrollState = {
|
newScrollState = {
|
||||||
stuckAtBottom: false,
|
stuckAtBottom: false,
|
||||||
trackedScrollToken: node.dataset.scrollTokens.split(',')[0],
|
trackedScrollToken: node.dataset.scrollTokens.split(',')[0],
|
||||||
|
@ -619,8 +618,8 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_restoreSavedScrollState: function() {
|
_restoreSavedScrollState: function() {
|
||||||
var scrollState = this.scrollState;
|
const scrollState = this.scrollState;
|
||||||
var scrollNode = this._getScrollNode();
|
const scrollNode = this._getScrollNode();
|
||||||
|
|
||||||
if (scrollState.stuckAtBottom) {
|
if (scrollState.stuckAtBottom) {
|
||||||
this._setScrollTop(Number.MAX_VALUE);
|
this._setScrollTop(Number.MAX_VALUE);
|
||||||
|
@ -631,9 +630,9 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_setScrollTop: function(scrollTop) {
|
_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
|
// FF ignores attempts to set scrollTop to very large numbers
|
||||||
scrollNode.scrollTop = Math.min(scrollTop, scrollNode.scrollHeight);
|
scrollNode.scrollTop = Math.min(scrollTop, scrollNode.scrollHeight);
|
||||||
|
|
|
@ -15,27 +15,27 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var ReactDOM = require("react-dom");
|
const ReactDOM = require("react-dom");
|
||||||
import Promise from 'bluebird';
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
var Matrix = require("matrix-js-sdk");
|
const Matrix = require("matrix-js-sdk");
|
||||||
var EventTimeline = Matrix.EventTimeline;
|
const EventTimeline = Matrix.EventTimeline;
|
||||||
|
|
||||||
var sdk = require('../../index');
|
const sdk = require('../../index');
|
||||||
import { _t } from '../../languageHandler';
|
import { _t } from '../../languageHandler';
|
||||||
var MatrixClientPeg = require("../../MatrixClientPeg");
|
const MatrixClientPeg = require("../../MatrixClientPeg");
|
||||||
var dis = require("../../dispatcher");
|
const dis = require("../../dispatcher");
|
||||||
var ObjectUtils = require('../../ObjectUtils');
|
const ObjectUtils = require('../../ObjectUtils');
|
||||||
var Modal = require("../../Modal");
|
const Modal = require("../../Modal");
|
||||||
var UserActivity = require("../../UserActivity");
|
const UserActivity = require("../../UserActivity");
|
||||||
var KeyCode = require('../../KeyCode');
|
const KeyCode = require('../../KeyCode');
|
||||||
import UserSettingsStore from '../../UserSettingsStore';
|
import UserSettingsStore from '../../UserSettingsStore';
|
||||||
|
|
||||||
var PAGINATE_SIZE = 20;
|
const PAGINATE_SIZE = 20;
|
||||||
var INITIAL_SIZE = 20;
|
const INITIAL_SIZE = 20;
|
||||||
|
|
||||||
var DEBUG = false;
|
const DEBUG = false;
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
// using bind means that we get to keep useful line numbers in the console
|
// 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);
|
dis.unregister(this.dispatcherRef);
|
||||||
|
|
||||||
var client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
if (client) {
|
if (client) {
|
||||||
client.removeListener("Room.timeline", this.onRoomTimeline);
|
client.removeListener("Room.timeline", this.onRoomTimeline);
|
||||||
client.removeListener("Room.timelineReset", this.onRoomTimelineReset);
|
client.removeListener("Room.timelineReset", this.onRoomTimelineReset);
|
||||||
|
@ -275,20 +275,20 @@ var TimelinePanel = React.createClass({
|
||||||
|
|
||||||
onMessageListUnfillRequest: function(backwards, scrollToken) {
|
onMessageListUnfillRequest: function(backwards, scrollToken) {
|
||||||
// If backwards, unpaginate from the back (i.e. the start of the timeline)
|
// 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);
|
debuglog("TimelinePanel: unpaginating events in direction", dir);
|
||||||
|
|
||||||
// All tiles are inserted by MessagePanel to have a scrollToken === eventId, and
|
// All tiles are inserted by MessagePanel to have a scrollToken === eventId, and
|
||||||
// this particular event should be the first or last to be unpaginated.
|
// 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) => {
|
(ev) => {
|
||||||
return ev.getId() === eventId;
|
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) {
|
if (count > 0) {
|
||||||
debuglog("TimelinePanel: Unpaginating", count, "in direction", dir);
|
debuglog("TimelinePanel: Unpaginating", count, "in direction", dir);
|
||||||
|
@ -305,9 +305,9 @@ var TimelinePanel = React.createClass({
|
||||||
|
|
||||||
// set off a pagination request.
|
// set off a pagination request.
|
||||||
onMessageListFillRequest: function(backwards) {
|
onMessageListFillRequest: function(backwards) {
|
||||||
var dir = backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS;
|
const dir = backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS;
|
||||||
var canPaginateKey = backwards ? 'canBackPaginate' : 'canForwardPaginate';
|
const canPaginateKey = backwards ? 'canBackPaginate' : 'canForwardPaginate';
|
||||||
var paginatingKey = backwards ? 'backPaginating' : 'forwardPaginating';
|
const paginatingKey = backwards ? 'backPaginating' : 'forwardPaginating';
|
||||||
|
|
||||||
if (!this.state[canPaginateKey]) {
|
if (!this.state[canPaginateKey]) {
|
||||||
debuglog("TimelinePanel: have given up", dir, "paginating this timeline");
|
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);
|
debuglog("TimelinePanel: paginate complete backwards:"+backwards+"; success:"+r);
|
||||||
|
|
||||||
var newState = {
|
const newState = {
|
||||||
[paginatingKey]: false,
|
[paginatingKey]: false,
|
||||||
[canPaginateKey]: r,
|
[canPaginateKey]: r,
|
||||||
events: this._getEvents(),
|
events: this._getEvents(),
|
||||||
|
@ -336,8 +336,8 @@ var TimelinePanel = React.createClass({
|
||||||
|
|
||||||
// moving the window in this direction may mean that we can now
|
// moving the window in this direction may mean that we can now
|
||||||
// paginate in the other where we previously could not.
|
// paginate in the other where we previously could not.
|
||||||
var otherDirection = backwards ? EventTimeline.FORWARDS : EventTimeline.BACKWARDS;
|
const otherDirection = backwards ? EventTimeline.FORWARDS : EventTimeline.BACKWARDS;
|
||||||
var canPaginateOtherWayKey = backwards ? 'canForwardPaginate' : 'canBackPaginate';
|
const canPaginateOtherWayKey = backwards ? 'canForwardPaginate' : 'canBackPaginate';
|
||||||
if (!this.state[canPaginateOtherWayKey] &&
|
if (!this.state[canPaginateOtherWayKey] &&
|
||||||
this._timelineWindow.canPaginate(otherDirection)) {
|
this._timelineWindow.canPaginate(otherDirection)) {
|
||||||
debuglog('TimelinePanel: can now', otherDirection, 'paginate again');
|
debuglog('TimelinePanel: can now', otherDirection, 'paginate again');
|
||||||
|
@ -420,15 +420,15 @@ var TimelinePanel = React.createClass({
|
||||||
this._timelineWindow.paginate(EventTimeline.FORWARDS, 1, false).done(() => {
|
this._timelineWindow.paginate(EventTimeline.FORWARDS, 1, false).done(() => {
|
||||||
if (this.unmounted) { return; }
|
if (this.unmounted) { return; }
|
||||||
|
|
||||||
var events = this._timelineWindow.getEvents();
|
const events = this._timelineWindow.getEvents();
|
||||||
var lastEv = events[events.length-1];
|
const lastEv = events[events.length-1];
|
||||||
|
|
||||||
// if we're at the end of the live timeline, append the pending events
|
// if we're at the end of the live timeline, append the pending events
|
||||||
if (this.props.timelineSet.room && !this._timelineWindow.canPaginate(EventTimeline.FORWARDS)) {
|
if (this.props.timelineSet.room && !this._timelineWindow.canPaginate(EventTimeline.FORWARDS)) {
|
||||||
events.push(...this.props.timelineSet.room.getPendingEvents());
|
events.push(...this.props.timelineSet.room.getPendingEvents());
|
||||||
}
|
}
|
||||||
|
|
||||||
var updatedState = {events: events};
|
const updatedState = {events: events};
|
||||||
|
|
||||||
if (this.props.manageReadMarkers) {
|
if (this.props.manageReadMarkers) {
|
||||||
// when a new event arrives when the user is not watching the
|
// 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
|
// read-marker when a remote echo of an event we have just sent takes
|
||||||
// more than the timeout on userCurrentlyActive.
|
// more than the timeout on userCurrentlyActive.
|
||||||
//
|
//
|
||||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||||
var sender = ev.sender ? ev.sender.userId : null;
|
const sender = ev.sender ? ev.sender.userId : null;
|
||||||
var callback = null;
|
var callback = null;
|
||||||
if (sender != myUserId && !UserActivity.userCurrentlyActive()) {
|
if (sender != myUserId && !UserActivity.userCurrentlyActive()) {
|
||||||
updatedState.readMarkerVisible = true;
|
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
|
// 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
|
// where the RM is pointing to. The read marker will be invisible for
|
||||||
// now anyway, so this doesn't really matter.
|
// now anyway, so this doesn't really matter.
|
||||||
var lastDisplayedIndex = this._getLastDisplayedEventIndex({
|
const lastDisplayedIndex = this._getLastDisplayedEventIndex({
|
||||||
allowPartial: true,
|
allowPartial: true,
|
||||||
ignoreEchoes: true,
|
ignoreEchoes: true,
|
||||||
});
|
});
|
||||||
|
@ -655,7 +655,7 @@ var TimelinePanel = React.createClass({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastDisplayedEvent = this.state.events[lastDisplayedIndex];
|
const lastDisplayedEvent = this.state.events[lastDisplayedIndex];
|
||||||
this._setReadMarker(lastDisplayedEvent.getId(),
|
this._setReadMarker(lastDisplayedEvent.getId(),
|
||||||
lastDisplayedEvent.getTs());
|
lastDisplayedEvent.getTs());
|
||||||
|
|
||||||
|
@ -676,7 +676,7 @@ var TimelinePanel = React.createClass({
|
||||||
// we call _timelineWindow.getEvents() rather than using
|
// we call _timelineWindow.getEvents() rather than using
|
||||||
// this.state.events, because react batches the update to the latter, so it
|
// this.state.events, because react batches the update to the latter, so it
|
||||||
// may not have been updated yet.
|
// may not have been updated yet.
|
||||||
var events = this._timelineWindow.getEvents();
|
const events = this._timelineWindow.getEvents();
|
||||||
|
|
||||||
// first find where the current RM is
|
// first find where the current RM is
|
||||||
for (var i = 0; i < events.length; i++) {
|
for (var i = 0; i < events.length; i++) {
|
||||||
|
@ -689,7 +689,7 @@ var TimelinePanel = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
// now think about advancing it
|
// now think about advancing it
|
||||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||||
for (i++; i < events.length; i++) {
|
for (i++; i < events.length; i++) {
|
||||||
var ev = events[i];
|
var ev = events[i];
|
||||||
if (!ev.sender || ev.sender.userId != myUserId) {
|
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
|
// 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.
|
// 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) {
|
if (ret !== null) {
|
||||||
// The messagepanel knows where the RM is, so we must have loaded
|
// The messagepanel knows where the RM is, so we must have loaded
|
||||||
// the relevant event.
|
// the relevant event.
|
||||||
|
@ -755,13 +755,13 @@ var TimelinePanel = React.createClass({
|
||||||
forgetReadMarker: function() {
|
forgetReadMarker: function() {
|
||||||
if (!this.props.manageReadMarkers) return;
|
if (!this.props.manageReadMarkers) return;
|
||||||
|
|
||||||
var rmId = this._getCurrentReadReceipt();
|
const rmId = this._getCurrentReadReceipt();
|
||||||
|
|
||||||
// see if we know the timestamp for the rr event
|
// see if we know the timestamp for the rr event
|
||||||
var tl = this.props.timelineSet.getTimelineForEvent(rmId);
|
const tl = this.props.timelineSet.getTimelineForEvent(rmId);
|
||||||
var rmTs;
|
let rmTs;
|
||||||
if (tl) {
|
if (tl) {
|
||||||
var event = tl.getEvents().find((e) => { return e.getId() == rmId; });
|
const event = tl.getEvents().find((e) => { return e.getId() == rmId; });
|
||||||
if (event) {
|
if (event) {
|
||||||
rmTs = event.getTs();
|
rmTs = event.getTs();
|
||||||
}
|
}
|
||||||
|
@ -801,7 +801,7 @@ var TimelinePanel = React.createClass({
|
||||||
if (!this.props.manageReadMarkers) return null;
|
if (!this.props.manageReadMarkers) return null;
|
||||||
if (!this.refs.messagePanel) return null;
|
if (!this.refs.messagePanel) return null;
|
||||||
|
|
||||||
var ret = this.refs.messagePanel.getReadMarkerPosition();
|
const ret = this.refs.messagePanel.getReadMarkerPosition();
|
||||||
if (ret !== null) {
|
if (ret !== null) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -844,8 +844,7 @@ var TimelinePanel = React.createClass({
|
||||||
// jump to the live timeline on ctrl-end, rather than the end of the
|
// jump to the live timeline on ctrl-end, rather than the end of the
|
||||||
// timeline window.
|
// timeline window.
|
||||||
if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey &&
|
if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey &&
|
||||||
ev.keyCode == KeyCode.END)
|
ev.keyCode == KeyCode.END) {
|
||||||
{
|
|
||||||
this.jumpToLiveTimeline();
|
this.jumpToLiveTimeline();
|
||||||
} else {
|
} else {
|
||||||
this.refs.messagePanel.handleScrollKey(ev);
|
this.refs.messagePanel.handleScrollKey(ev);
|
||||||
|
@ -853,12 +852,12 @@ var TimelinePanel = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_initTimeline: function(props) {
|
_initTimeline: function(props) {
|
||||||
var initialEvent = props.eventId;
|
const initialEvent = props.eventId;
|
||||||
var pixelOffset = props.eventPixelOffset;
|
const pixelOffset = props.eventPixelOffset;
|
||||||
|
|
||||||
// if a pixelOffset is given, it is relative to the bottom of the
|
// 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.
|
// container. If not, put the event in the middle of the container.
|
||||||
var offsetBase = 1;
|
let offsetBase = 1;
|
||||||
if (pixelOffset == null) {
|
if (pixelOffset == null) {
|
||||||
offsetBase = 0.5;
|
offsetBase = 0.5;
|
||||||
}
|
}
|
||||||
|
@ -887,7 +886,7 @@ var TimelinePanel = React.createClass({
|
||||||
MatrixClientPeg.get(), this.props.timelineSet,
|
MatrixClientPeg.get(), this.props.timelineSet,
|
||||||
{windowLimit: this.props.timelineCap});
|
{windowLimit: this.props.timelineCap});
|
||||||
|
|
||||||
var onLoaded = () => {
|
const onLoaded = () => {
|
||||||
this._reloadEvents();
|
this._reloadEvents();
|
||||||
|
|
||||||
// If we switched away from the room while there were pending
|
// 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});
|
this.setState({timelineLoading: false});
|
||||||
console.error(
|
console.error(
|
||||||
`Error loading timeline panel at ${eventId}: ${error}`,
|
`Error loading timeline panel at ${eventId}: ${error}`,
|
||||||
);
|
);
|
||||||
var msg = error.message ? error.message : JSON.stringify(error);
|
const msg = error.message ? error.message : JSON.stringify(error);
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
|
|
||||||
var onFinished;
|
let onFinished;
|
||||||
|
|
||||||
// if we were given an event ID, then when the user closes the
|
// 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,
|
// 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 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.");
|
: _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, {
|
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
|
// if we already have the event in question, TimelineWindow.load
|
||||||
// returns a resolved promise.
|
// 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
|
// get the list of events from the timeline window and the pending event list
|
||||||
_getEvents: function() {
|
_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 we're at the end of the live timeline, append the pending events
|
||||||
if (!this._timelineWindow.canPaginate(EventTimeline.FORWARDS)) {
|
if (!this._timelineWindow.canPaginate(EventTimeline.FORWARDS)) {
|
||||||
|
@ -1007,7 +1006,7 @@ var TimelinePanel = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_indexForEventId: function(evId) {
|
_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()) {
|
if (evId == this.state.events[i].getId()) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -1017,18 +1016,18 @@ var TimelinePanel = React.createClass({
|
||||||
|
|
||||||
_getLastDisplayedEventIndex: function(opts) {
|
_getLastDisplayedEventIndex: function(opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
var ignoreOwn = opts.ignoreOwn || false;
|
const ignoreOwn = opts.ignoreOwn || false;
|
||||||
var ignoreEchoes = opts.ignoreEchoes || false;
|
const ignoreEchoes = opts.ignoreEchoes || false;
|
||||||
var allowPartial = opts.allowPartial || false;
|
const allowPartial = opts.allowPartial || false;
|
||||||
|
|
||||||
var messagePanel = this.refs.messagePanel;
|
const messagePanel = this.refs.messagePanel;
|
||||||
if (messagePanel === undefined) return null;
|
if (messagePanel === undefined) return null;
|
||||||
|
|
||||||
var wrapperRect = ReactDOM.findDOMNode(messagePanel).getBoundingClientRect();
|
const wrapperRect = ReactDOM.findDOMNode(messagePanel).getBoundingClientRect();
|
||||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||||
|
|
||||||
for (var i = this.state.events.length-1; i >= 0; --i) {
|
for (let i = this.state.events.length-1; i >= 0; --i) {
|
||||||
var ev = this.state.events[i];
|
const ev = this.state.events[i];
|
||||||
|
|
||||||
if (ignoreOwn && ev.sender && ev.sender.userId == myUserId) {
|
if (ignoreOwn && ev.sender && ev.sender.userId == myUserId) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1039,10 +1038,10 @@ var TimelinePanel = React.createClass({
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var node = messagePanel.getNodeForEventId(ev.getId());
|
const node = messagePanel.getNodeForEventId(ev.getId());
|
||||||
if (!node) continue;
|
if (!node) continue;
|
||||||
|
|
||||||
var boundingRect = node.getBoundingClientRect();
|
const boundingRect = node.getBoundingClientRect();
|
||||||
if ((allowPartial && boundingRect.top < wrapperRect.bottom) ||
|
if ((allowPartial && boundingRect.top < wrapperRect.bottom) ||
|
||||||
(!allowPartial && boundingRect.bottom < wrapperRect.bottom)) {
|
(!allowPartial && boundingRect.bottom < wrapperRect.bottom)) {
|
||||||
return i;
|
return i;
|
||||||
|
@ -1060,18 +1059,18 @@ var TimelinePanel = React.createClass({
|
||||||
* SDK.
|
* SDK.
|
||||||
*/
|
*/
|
||||||
_getCurrentReadReceipt: function(ignoreSynthesized) {
|
_getCurrentReadReceipt: function(ignoreSynthesized) {
|
||||||
var client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
// the client can be null on logout
|
// the client can be null on logout
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var myUserId = client.credentials.userId;
|
const myUserId = client.credentials.userId;
|
||||||
return this.props.timelineSet.room.getEventReadUpTo(myUserId, ignoreSynthesized);
|
return this.props.timelineSet.room.getEventReadUpTo(myUserId, ignoreSynthesized);
|
||||||
},
|
},
|
||||||
|
|
||||||
_setReadMarker: function(eventId, eventTs, inhibitSetState) {
|
_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
|
// don't update the state (and cause a re-render) if there is
|
||||||
// no change to the RM.
|
// no change to the RM.
|
||||||
|
@ -1096,8 +1095,8 @@ var TimelinePanel = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var MessagePanel = sdk.getComponent("structures.MessagePanel");
|
const MessagePanel = sdk.getComponent("structures.MessagePanel");
|
||||||
var Loader = sdk.getComponent("elements.Spinner");
|
const Loader = sdk.getComponent("elements.Spinner");
|
||||||
|
|
||||||
// just show a spinner while the timeline loads.
|
// just show a spinner while the timeline loads.
|
||||||
//
|
//
|
||||||
|
@ -1134,7 +1133,7 @@ var TimelinePanel = React.createClass({
|
||||||
// forwards, otherwise if somebody hits the bottom of the loaded
|
// forwards, otherwise if somebody hits the bottom of the loaded
|
||||||
// events when viewing historical messages, we get stuck in a loop
|
// events when viewing historical messages, we get stuck in a loop
|
||||||
// of paginating our way through the entire history of the room.
|
// 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
|
// 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.
|
// the HS and fetch the latest events, so we are effectively forward paginating.
|
||||||
|
|
|
@ -14,15 +14,15 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var ContentMessages = require('../../ContentMessages');
|
const ContentMessages = require('../../ContentMessages');
|
||||||
var dis = require('../../dispatcher');
|
const dis = require('../../dispatcher');
|
||||||
var filesize = require('filesize');
|
const filesize = require('filesize');
|
||||||
import { _t } from '../../languageHandler';
|
import { _t } from '../../languageHandler';
|
||||||
|
|
||||||
module.exports = React.createClass({displayName: 'UploadBar',
|
module.exports = React.createClass({displayName: 'UploadBar',
|
||||||
propTypes: {
|
propTypes: {
|
||||||
room: React.PropTypes.object
|
room: React.PropTypes.object,
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
@ -46,7 +46,7 @@ module.exports = React.createClass({displayName: 'UploadBar',
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var uploads = ContentMessages.getCurrentUploads();
|
const uploads = ContentMessages.getCurrentUploads();
|
||||||
|
|
||||||
// for testing UI... - also fix up the ContentMessages.getCurrentUploads().length
|
// for testing UI... - also fix up the ContentMessages.getCurrentUploads().length
|
||||||
// check in RoomView
|
// check in RoomView
|
||||||
|
@ -62,8 +62,8 @@ module.exports = React.createClass({displayName: 'UploadBar',
|
||||||
return <div />;
|
return <div />;
|
||||||
}
|
}
|
||||||
|
|
||||||
var upload;
|
let upload;
|
||||||
for (var i = 0; i < uploads.length; ++i) {
|
for (let i = 0; i < uploads.length; ++i) {
|
||||||
if (uploads[i].roomId == this.props.room.roomId) {
|
if (uploads[i].roomId == this.props.room.roomId) {
|
||||||
upload = uploads[i];
|
upload = uploads[i];
|
||||||
break;
|
break;
|
||||||
|
@ -73,17 +73,17 @@ module.exports = React.createClass({displayName: 'UploadBar',
|
||||||
return <div />;
|
return <div />;
|
||||||
}
|
}
|
||||||
|
|
||||||
var innerProgressStyle = {
|
const innerProgressStyle = {
|
||||||
width: ((upload.loaded / (upload.total || 1)) * 100) + '%'
|
width: ((upload.loaded / (upload.total || 1)) * 100) + '%',
|
||||||
};
|
};
|
||||||
var uploadedSize = filesize(upload.loaded);
|
let uploadedSize = filesize(upload.loaded);
|
||||||
var totalSize = filesize(upload.total);
|
const totalSize = filesize(upload.total);
|
||||||
if (uploadedSize.replace(/^.* /, '') === totalSize.replace(/^.* /, '')) {
|
if (uploadedSize.replace(/^.* /, '') === totalSize.replace(/^.* /, '')) {
|
||||||
uploadedSize = uploadedSize.replace(/ .*/, '');
|
uploadedSize = uploadedSize.replace(/ .*/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
// MUST use var name 'count' for pluralization to kick in
|
// 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 (
|
return (
|
||||||
<div className="mx_UploadBar">
|
<div className="mx_UploadBar">
|
||||||
|
@ -100,5 +100,5 @@ module.exports = React.createClass({displayName: 'UploadBar',
|
||||||
<div className="mx_UploadBar_uploadFilename">{ uploadText }</div>
|
<div className="mx_UploadBar_uploadFilename">{ uploadText }</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,13 +17,13 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
var Modal = require("../../../Modal");
|
const Modal = require("../../../Modal");
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
|
|
||||||
var PasswordReset = require("../../../PasswordReset");
|
const PasswordReset = require("../../../PasswordReset");
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'ForgotPassword',
|
displayName: 'ForgotPassword',
|
||||||
|
@ -35,30 +35,30 @@ module.exports = React.createClass({
|
||||||
customIsUrl: React.PropTypes.string,
|
customIsUrl: React.PropTypes.string,
|
||||||
onLoginClick: React.PropTypes.func,
|
onLoginClick: React.PropTypes.func,
|
||||||
onRegisterClick: React.PropTypes.func,
|
onRegisterClick: React.PropTypes.func,
|
||||||
onComplete: React.PropTypes.func.isRequired
|
onComplete: React.PropTypes.func.isRequired,
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
enteredHomeserverUrl: this.props.customHsUrl || this.props.defaultHsUrl,
|
enteredHomeserverUrl: this.props.customHsUrl || this.props.defaultHsUrl,
|
||||||
enteredIdentityServerUrl: this.props.customIsUrl || this.props.defaultIsUrl,
|
enteredIdentityServerUrl: this.props.customIsUrl || this.props.defaultIsUrl,
|
||||||
progress: null
|
progress: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
submitPasswordReset: function(hsUrl, identityUrl, email, password) {
|
submitPasswordReset: function(hsUrl, identityUrl, email, password) {
|
||||||
this.setState({
|
this.setState({
|
||||||
progress: "sending_email"
|
progress: "sending_email",
|
||||||
});
|
});
|
||||||
this.reset = new PasswordReset(hsUrl, identityUrl);
|
this.reset = new PasswordReset(hsUrl, identityUrl);
|
||||||
this.reset.resetPassword(email, password).done(() => {
|
this.reset.resetPassword(email, password).done(() => {
|
||||||
this.setState({
|
this.setState({
|
||||||
progress: "sent_email"
|
progress: "sent_email",
|
||||||
});
|
});
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
this.showErrorDialog(_t('Failed to send email') + ": " + err.message);
|
this.showErrorDialog(_t('Failed to send email') + ": " + err.message);
|
||||||
this.setState({
|
this.setState({
|
||||||
progress: null
|
progress: null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -81,15 +81,12 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
if (!this.state.email) {
|
if (!this.state.email) {
|
||||||
this.showErrorDialog(_t('The email address linked to your account must be entered.'));
|
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.'));
|
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.'));
|
this.showErrorDialog(_t('New passwords must match each other.'));
|
||||||
}
|
} else {
|
||||||
else {
|
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
|
||||||
Modal.createTrackedDialog('Forgot Password Warning', '', QuestionDialog, {
|
Modal.createTrackedDialog('Forgot Password Warning', '', QuestionDialog, {
|
||||||
title: _t('Warning!'),
|
title: _t('Warning!'),
|
||||||
description:
|
description:
|
||||||
|
@ -99,7 +96,7 @@ module.exports = React.createClass({
|
||||||
'end-to-end encryption keys on all devices, ' +
|
'end-to-end encryption keys on all devices, ' +
|
||||||
'making encrypted chat history unreadable, ' +
|
'making encrypted chat history unreadable, ' +
|
||||||
'unless you first export your room keys and re-import ' +
|
'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>,
|
</div>,
|
||||||
button: _t('Continue'),
|
button: _t('Continue'),
|
||||||
|
@ -107,13 +104,13 @@ module.exports = React.createClass({
|
||||||
<button className="mx_Dialog_primary"
|
<button className="mx_Dialog_primary"
|
||||||
onClick={this._onExportE2eKeysClicked}>
|
onClick={this._onExportE2eKeysClicked}>
|
||||||
{ _t('Export E2E room keys') }
|
{ _t('Export E2E room keys') }
|
||||||
</button>
|
</button>,
|
||||||
],
|
],
|
||||||
onFinished: (confirmed) => {
|
onFinished: (confirmed) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
this.submitPasswordReset(
|
this.submitPasswordReset(
|
||||||
this.state.enteredHomeserverUrl, this.state.enteredIdentityServerUrl,
|
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) {
|
onInputChanged: function(stateKey, ev) {
|
||||||
this.setState({
|
this.setState({
|
||||||
[stateKey]: ev.target.value
|
[stateKey]: ev.target.value,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -149,7 +146,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
showErrorDialog: function(body, title) {
|
showErrorDialog: function(body, title) {
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
Modal.createTrackedDialog('Forgot Password Error', '', ErrorDialog, {
|
Modal.createTrackedDialog('Forgot Password Error', '', ErrorDialog, {
|
||||||
title: title,
|
title: title,
|
||||||
description: body,
|
description: body,
|
||||||
|
@ -157,17 +154,16 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var LoginHeader = sdk.getComponent("login.LoginHeader");
|
const LoginHeader = sdk.getComponent("login.LoginHeader");
|
||||||
var LoginFooter = sdk.getComponent("login.LoginFooter");
|
const LoginFooter = sdk.getComponent("login.LoginFooter");
|
||||||
var ServerConfig = sdk.getComponent("login.ServerConfig");
|
const ServerConfig = sdk.getComponent("login.ServerConfig");
|
||||||
var Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
|
|
||||||
var resetPasswordJsx;
|
let resetPasswordJsx;
|
||||||
|
|
||||||
if (this.state.progress === "sending_email") {
|
if (this.state.progress === "sending_email") {
|
||||||
resetPasswordJsx = <Spinner />;
|
resetPasswordJsx = <Spinner />;
|
||||||
}
|
} else if (this.state.progress === "sent_email") {
|
||||||
else if (this.state.progress === "sent_email") {
|
|
||||||
resetPasswordJsx = (
|
resetPasswordJsx = (
|
||||||
<div>
|
<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") }.
|
||||||
|
@ -176,8 +172,7 @@ module.exports = React.createClass({
|
||||||
value={_t('I have verified my email address')} />
|
value={_t('I have verified my email address')} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
} else if (this.state.progress === "complete") {
|
||||||
else if (this.state.progress === "complete") {
|
|
||||||
resetPasswordJsx = (
|
resetPasswordJsx = (
|
||||||
<div>
|
<div>
|
||||||
<p>{ _t('Your password has been reset') }.</p>
|
<p>{ _t('Your password has been reset') }.</p>
|
||||||
|
@ -186,8 +181,7 @@ module.exports = React.createClass({
|
||||||
value={_t('Return to login screen')} />
|
value={_t('Return to login screen')} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
resetPasswordJsx = (
|
resetPasswordJsx = (
|
||||||
<div>
|
<div>
|
||||||
<div className="mx_Login_prompt">
|
<div className="mx_Login_prompt">
|
||||||
|
@ -246,5 +240,5 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -134,7 +134,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_onLoginAsGuestClick: function() {
|
_onLoginAsGuestClick: function() {
|
||||||
var self = this;
|
const self = this;
|
||||||
self.setState({
|
self.setState({
|
||||||
busy: true,
|
busy: true,
|
||||||
errorText: null,
|
errorText: null,
|
||||||
|
@ -156,7 +156,7 @@ module.exports = React.createClass({
|
||||||
});
|
});
|
||||||
}).finally(function() {
|
}).finally(function() {
|
||||||
self.setState({
|
self.setState({
|
||||||
busy: false
|
busy: false,
|
||||||
});
|
});
|
||||||
}).done();
|
}).done();
|
||||||
},
|
},
|
||||||
|
@ -183,8 +183,8 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onServerConfigChange: function(config) {
|
onServerConfigChange: function(config) {
|
||||||
var self = this;
|
const self = this;
|
||||||
let newState = {
|
const newState = {
|
||||||
errorText: null, // reset err messages
|
errorText: null, // reset err messages
|
||||||
};
|
};
|
||||||
if (config.hsUrl !== undefined) {
|
if (config.hsUrl !== undefined) {
|
||||||
|
@ -199,13 +199,13 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_initLoginLogic: function(hsUrl, isUrl) {
|
_initLoginLogic: function(hsUrl, isUrl) {
|
||||||
var self = this;
|
const self = this;
|
||||||
hsUrl = hsUrl || this.state.enteredHomeserverUrl;
|
hsUrl = hsUrl || this.state.enteredHomeserverUrl;
|
||||||
isUrl = isUrl || this.state.enteredIdentityServerUrl;
|
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,
|
defaultDeviceDisplayName: this.props.defaultDeviceDisplayName,
|
||||||
});
|
});
|
||||||
this._loginLogic = loginLogic;
|
this._loginLogic = loginLogic;
|
||||||
|
@ -259,14 +259,14 @@ module.exports = React.createClass({
|
||||||
{ _tJsx("Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. " +
|
{ _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>.",
|
"Either use HTTPS or <a>enable unsafe scripts</a>.",
|
||||||
/<a>(.*?)<\/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>;
|
</span>;
|
||||||
} else {
|
} else {
|
||||||
errorText = <span>
|
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.",
|
{ _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>/,
|
/<a>(.*?)<\/a>/,
|
||||||
(sub) => { return <a href={this.state.enteredHomeserverUrl}>{ sub }</a>; }
|
(sub) => { return <a href={this.state.enteredHomeserverUrl}>{ sub }</a>; },
|
||||||
) }
|
) }
|
||||||
</span>;
|
</span>;
|
||||||
}
|
}
|
||||||
|
@ -334,7 +334,7 @@ module.exports = React.createClass({
|
||||||
const ServerConfig = sdk.getComponent("login.ServerConfig");
|
const ServerConfig = sdk.getComponent("login.ServerConfig");
|
||||||
const loader = this.state.busy ? <div className="mx_Login_loader"><Loader /></div> : null;
|
const loader = this.state.busy ? <div className="mx_Login_loader"><Loader /></div> : null;
|
||||||
|
|
||||||
var loginAsGuestJsx;
|
let loginAsGuestJsx;
|
||||||
if (this.props.enableGuest) {
|
if (this.props.enableGuest) {
|
||||||
loginAsGuestJsx =
|
loginAsGuestJsx =
|
||||||
<a className="mx_Login_create" onClick={this._onLoginAsGuestClick} href="#">
|
<a className="mx_Login_create" onClick={this._onLoginAsGuestClick} href="#">
|
||||||
|
@ -342,7 +342,7 @@ module.exports = React.createClass({
|
||||||
</a>;
|
</a>;
|
||||||
}
|
}
|
||||||
|
|
||||||
var returnToAppJsx;
|
let returnToAppJsx;
|
||||||
if (this.props.onCancelClick) {
|
if (this.props.onCancelClick) {
|
||||||
returnToAppJsx =
|
returnToAppJsx =
|
||||||
<a className="mx_Login_create" onClick={this.props.onCancelClick} href="#">
|
<a className="mx_Login_create" onClick={this.props.onCancelClick} href="#">
|
||||||
|
@ -381,5 +381,5 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -25,14 +25,14 @@ module.exports = React.createClass({
|
||||||
displayName: 'PostRegistration',
|
displayName: 'PostRegistration',
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
onComplete: React.PropTypes.func.isRequired
|
onComplete: React.PropTypes.func.isRequired,
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
avatarUrl: null,
|
avatarUrl: null,
|
||||||
errorString: null,
|
errorString: null,
|
||||||
busy: false
|
busy: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -40,26 +40,26 @@ module.exports = React.createClass({
|
||||||
// There is some assymetry between ChangeDisplayName and ChangeAvatar,
|
// There is some assymetry between ChangeDisplayName and ChangeAvatar,
|
||||||
// as ChangeDisplayName will auto-get the name but ChangeAvatar expects
|
// 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).
|
// 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});
|
this.setState({busy: true});
|
||||||
var self = this;
|
const self = this;
|
||||||
cli.getProfileInfo(cli.credentials.userId).done(function(result) {
|
cli.getProfileInfo(cli.credentials.userId).done(function(result) {
|
||||||
self.setState({
|
self.setState({
|
||||||
avatarUrl: MatrixClientPeg.get().mxcUrlToHttp(result.avatar_url),
|
avatarUrl: MatrixClientPeg.get().mxcUrlToHttp(result.avatar_url),
|
||||||
busy: false
|
busy: false,
|
||||||
});
|
});
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
self.setState({
|
self.setState({
|
||||||
errorString: _t("Failed to fetch avatar URL"),
|
errorString: _t("Failed to fetch avatar URL"),
|
||||||
busy: false
|
busy: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var ChangeDisplayName = sdk.getComponent('settings.ChangeDisplayName');
|
const ChangeDisplayName = sdk.getComponent('settings.ChangeDisplayName');
|
||||||
var ChangeAvatar = sdk.getComponent('settings.ChangeAvatar');
|
const ChangeAvatar = sdk.getComponent('settings.ChangeAvatar');
|
||||||
var LoginHeader = sdk.getComponent('login.LoginHeader');
|
const LoginHeader = sdk.getComponent('login.LoginHeader');
|
||||||
return (
|
return (
|
||||||
<div className="mx_Login">
|
<div className="mx_Login">
|
||||||
<div className="mx_Login_box">
|
<div className="mx_Login_box">
|
||||||
|
@ -76,5 +76,5 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -57,7 +57,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// registration shouldn't know or care how login is done.
|
// registration shouldn't know or care how login is done.
|
||||||
onLoginClick: React.PropTypes.func.isRequired,
|
onLoginClick: React.PropTypes.func.isRequired,
|
||||||
onCancelClick: React.PropTypes.func
|
onCancelClick: React.PropTypes.func,
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
|
@ -121,7 +121,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onServerConfigChange: function(config) {
|
onServerConfigChange: function(config) {
|
||||||
let newState = {};
|
const newState = {};
|
||||||
if (config.hsUrl !== undefined) {
|
if (config.hsUrl !== undefined) {
|
||||||
newState.hsUrl = config.hsUrl;
|
newState.hsUrl = config.hsUrl;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
this._rtsClient.getTeam(teamToken).then((team) => {
|
this._rtsClient.getTeam(teamToken).then((team) => {
|
||||||
console.log(
|
console.log(
|
||||||
`User successfully registered with team ${team.name}`
|
`User successfully registered with team ${team.name}`,
|
||||||
);
|
);
|
||||||
if (!team.rooms) {
|
if (!team.rooms) {
|
||||||
return;
|
return;
|
||||||
|
@ -223,7 +223,7 @@ module.exports = React.createClass({
|
||||||
deviceId: response.device_id,
|
deviceId: response.device_id,
|
||||||
homeserverUrl: this._matrixClient.getHomeserverUrl(),
|
homeserverUrl: this._matrixClient.getHomeserverUrl(),
|
||||||
identityServerUrl: this._matrixClient.getIdentityServerUrl(),
|
identityServerUrl: this._matrixClient.getIdentityServerUrl(),
|
||||||
accessToken: response.access_token
|
accessToken: response.access_token,
|
||||||
}, teamToken);
|
}, teamToken);
|
||||||
}).then((cli) => {
|
}).then((cli) => {
|
||||||
return this._setupPushers(cli);
|
return this._setupPushers(cli);
|
||||||
|
@ -253,7 +253,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onFormValidationFailed: function(errCode) {
|
onFormValidationFailed: function(errCode) {
|
||||||
var errMsg;
|
let errMsg;
|
||||||
switch (errCode) {
|
switch (errCode) {
|
||||||
case "RegistrationForm.ERR_PASSWORD_MISSING":
|
case "RegistrationForm.ERR_PASSWORD_MISSING":
|
||||||
errMsg = _t('Missing password.');
|
errMsg = _t('Missing password.');
|
||||||
|
@ -282,7 +282,7 @@ module.exports = React.createClass({
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
errorText: errMsg
|
errorText: errMsg,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ module.exports = React.createClass({
|
||||||
emailAddress: this.state.formVals.email,
|
emailAddress: this.state.formVals.email,
|
||||||
phoneCountry: this.state.formVals.phoneCountry,
|
phoneCountry: this.state.formVals.phoneCountry,
|
||||||
phoneNumber: this.state.formVals.phoneNumber,
|
phoneNumber: this.state.formVals.phoneNumber,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
@ -403,5 +403,5 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,7 +32,7 @@ module.exports = React.createClass({
|
||||||
height: React.PropTypes.number,
|
height: React.PropTypes.number,
|
||||||
// XXX resizeMethod not actually used.
|
// XXX resizeMethod not actually used.
|
||||||
resizeMethod: React.PropTypes.string,
|
resizeMethod: React.PropTypes.string,
|
||||||
defaultToInitialLetter: React.PropTypes.bool // true to add default url
|
defaultToInitialLetter: React.PropTypes.bool, // true to add default url
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
|
@ -40,7 +40,7 @@ module.exports = React.createClass({
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
resizeMethod: 'crop',
|
resizeMethod: 'crop',
|
||||||
defaultToInitialLetter: true
|
defaultToInitialLetter: true,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -50,15 +50,14 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
componentWillReceiveProps: function(nextProps) {
|
componentWillReceiveProps: function(nextProps) {
|
||||||
// work out if we need to call setState (if the image URLs array has changed)
|
// work out if we need to call setState (if the image URLs array has changed)
|
||||||
var newState = this._getState(nextProps);
|
const newState = this._getState(nextProps);
|
||||||
var newImageUrls = newState.imageUrls;
|
const newImageUrls = newState.imageUrls;
|
||||||
var oldImageUrls = this.state.imageUrls;
|
const oldImageUrls = this.state.imageUrls;
|
||||||
if (newImageUrls.length !== oldImageUrls.length) {
|
if (newImageUrls.length !== oldImageUrls.length) {
|
||||||
this.setState(newState); // detected a new entry
|
this.setState(newState); // detected a new entry
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// check each one to see if they are the same
|
// 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]) {
|
if (oldImageUrls[i] !== newImageUrls[i]) {
|
||||||
this.setState(newState); // detected a diff
|
this.setState(newState); // detected a diff
|
||||||
break;
|
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:
|
// work out the full set of urls to try to load. This is formed like so:
|
||||||
// imageUrls: [ props.url, props.urls, default image ]
|
// imageUrls: [ props.url, props.urls, default image ]
|
||||||
|
|
||||||
var urls = props.urls || [];
|
const urls = props.urls || [];
|
||||||
if (props.url) {
|
if (props.url) {
|
||||||
urls.unshift(props.url); // put in urls[0]
|
urls.unshift(props.url); // put in urls[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultImageUrl = null;
|
let defaultImageUrl = null;
|
||||||
if (props.defaultToInitialLetter) {
|
if (props.defaultToInitialLetter) {
|
||||||
defaultImageUrl = AvatarLogic.defaultAvatarUrlForString(
|
defaultImageUrl = AvatarLogic.defaultAvatarUrlForString(
|
||||||
props.idName || props.name
|
props.idName || props.name,
|
||||||
);
|
);
|
||||||
urls.push(defaultImageUrl); // lowest priority
|
urls.push(defaultImageUrl); // lowest priority
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
imageUrls: urls,
|
imageUrls: urls,
|
||||||
defaultImageUrl: defaultImageUrl,
|
defaultImageUrl: defaultImageUrl,
|
||||||
urlsIndex: 0
|
urlsIndex: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
onError: function(ev) {
|
onError: function(ev) {
|
||||||
var nextIndex = this.state.urlsIndex + 1;
|
const nextIndex = this.state.urlsIndex + 1;
|
||||||
if (nextIndex < this.state.imageUrls.length) {
|
if (nextIndex < this.state.imageUrls.length) {
|
||||||
// try the next one
|
// try the next one
|
||||||
this.setState({
|
this.setState({
|
||||||
urlsIndex: nextIndex
|
urlsIndex: nextIndex,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -109,32 +108,32 @@ module.exports = React.createClass({
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
var idx = 0;
|
let idx = 0;
|
||||||
var initial = name[0];
|
const initial = name[0];
|
||||||
if ((initial === '@' || initial === '#') && name[1]) {
|
if ((initial === '@' || initial === '#') && name[1]) {
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// string.codePointAt(0) would do this, but that isn't supported by
|
// string.codePointAt(0) would do this, but that isn't supported by
|
||||||
// some browsers (notably PhantomJS).
|
// some browsers (notably PhantomJS).
|
||||||
var chars = 1;
|
let chars = 1;
|
||||||
var first = name.charCodeAt(idx);
|
const first = name.charCodeAt(idx);
|
||||||
|
|
||||||
// check if it’s the start of a surrogate pair
|
// check if it’s the start of a surrogate pair
|
||||||
if (first >= 0xD800 && first <= 0xDBFF && name[idx+1]) {
|
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) {
|
if (second >= 0xDC00 && second <= 0xDFFF) {
|
||||||
chars++;
|
chars++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstChar = name.substring(idx, idx+chars);
|
const firstChar = name.substring(idx, idx+chars);
|
||||||
return firstChar.toUpperCase();
|
return firstChar.toUpperCase();
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||||
var imageUrl = this.state.imageUrls[this.state.urlsIndex];
|
const imageUrl = this.state.imageUrls[this.state.urlsIndex];
|
||||||
|
|
||||||
const {
|
const {
|
||||||
name, idName, title, url, urls, width, height, resizeMethod,
|
name, idName, title, url, urls, width, height, resizeMethod,
|
||||||
|
@ -196,5 +195,5 @@ module.exports = React.createClass({
|
||||||
{...otherProps} />
|
{...otherProps} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,9 +16,9 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var Avatar = require('../../../Avatar');
|
const Avatar = require('../../../Avatar');
|
||||||
var sdk = require("../../../index");
|
const sdk = require("../../../index");
|
||||||
const dispatcher = require("../../../dispatcher");
|
const dispatcher = require("../../../dispatcher");
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
|
@ -63,14 +63,14 @@ module.exports = React.createClass({
|
||||||
imageUrl: Avatar.avatarUrlForMember(props.member,
|
imageUrl: Avatar.avatarUrlForMember(props.member,
|
||||||
props.width,
|
props.width,
|
||||||
props.height,
|
props.height,
|
||||||
props.resizeMethod)
|
props.resizeMethod),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
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) {
|
if (viewUserOnClick) {
|
||||||
onClick = () => {
|
onClick = () => {
|
||||||
|
@ -85,5 +85,5 @@ module.exports = React.createClass({
|
||||||
<BaseAvatar {...otherProps} name={this.state.name} title={this.state.title}
|
<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} />
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,5 +38,5 @@ module.exports = React.createClass({
|
||||||
return (
|
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';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
var Presets = {
|
const Presets = {
|
||||||
PrivateChat: "private_chat",
|
PrivateChat: "private_chat",
|
||||||
PublicChat: "public_chat",
|
PublicChat: "public_chat",
|
||||||
Custom: "custom",
|
Custom: "custom",
|
||||||
|
@ -29,7 +29,7 @@ module.exports = React.createClass({
|
||||||
displayName: 'CreateRoomPresets',
|
displayName: 'CreateRoomPresets',
|
||||||
propTypes: {
|
propTypes: {
|
||||||
onChange: React.PropTypes.func,
|
onChange: React.PropTypes.func,
|
||||||
preset: React.PropTypes.string
|
preset: React.PropTypes.string,
|
||||||
},
|
},
|
||||||
|
|
||||||
Presets: Presets,
|
Presets: Presets,
|
||||||
|
@ -52,5 +52,5 @@ module.exports = React.createClass({
|
||||||
<option value={this.Presets.Custom}>{ _t("Custom") }</option>
|
<option value={this.Presets.Custom}>{ _t("Custom") }</option>
|
||||||
</select>
|
</select>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
|
@ -35,10 +35,10 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
getAliasLocalpart: function() {
|
getAliasLocalpart: function() {
|
||||||
var room_alias = this.props.alias;
|
let room_alias = this.props.alias;
|
||||||
|
|
||||||
if (room_alias && this.props.homeserver) {
|
if (room_alias && this.props.homeserver) {
|
||||||
var suffix = ":" + this.props.homeserver;
|
const suffix = ":" + this.props.homeserver;
|
||||||
if (room_alias.startsWith("#") && room_alias.endsWith(suffix)) {
|
if (room_alias.startsWith("#") && room_alias.endsWith(suffix)) {
|
||||||
room_alias = room_alias.slice(1, -suffix.length);
|
room_alias = room_alias.slice(1, -suffix.length);
|
||||||
}
|
}
|
||||||
|
@ -52,22 +52,22 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onFocus: function(ev) {
|
onFocus: function(ev) {
|
||||||
var target = ev.target;
|
const target = ev.target;
|
||||||
var curr_val = ev.target.value;
|
const curr_val = ev.target.value;
|
||||||
|
|
||||||
if (this.props.homeserver) {
|
if (this.props.homeserver) {
|
||||||
if (curr_val == "") {
|
if (curr_val == "") {
|
||||||
var self = this;
|
const self = this;
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
target.value = "#:" + self.props.homeserver;
|
target.value = "#:" + self.props.homeserver;
|
||||||
target.setSelectionRange(1, 1);
|
target.setSelectionRange(1, 1);
|
||||||
}, 0);
|
}, 0);
|
||||||
} else {
|
} else {
|
||||||
var suffix = ":" + this.props.homeserver;
|
const suffix = ":" + this.props.homeserver;
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
target.setSelectionRange(
|
target.setSelectionRange(
|
||||||
curr_val.startsWith("#") ? 1 : 0,
|
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);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onBlur: function(ev) {
|
onBlur: function(ev) {
|
||||||
var curr_val = ev.target.value;
|
const curr_val = ev.target.value;
|
||||||
|
|
||||||
if (this.props.homeserver) {
|
if (this.props.homeserver) {
|
||||||
if (curr_val == "#:" + this.props.homeserver) {
|
if (curr_val == "#:" + this.props.homeserver) {
|
||||||
|
@ -84,8 +84,8 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curr_val != "") {
|
if (curr_val != "") {
|
||||||
var new_val = ev.target.value;
|
let new_val = ev.target.value;
|
||||||
var suffix = ":" + this.props.homeserver;
|
const suffix = ":" + this.props.homeserver;
|
||||||
if (!curr_val.startsWith("#")) new_val = "#" + new_val;
|
if (!curr_val.startsWith("#")) new_val = "#" + new_val;
|
||||||
if (!curr_val.endsWith(suffix)) new_val = new_val + suffix;
|
if (!curr_val.endsWith(suffix)) new_val = new_val + suffix;
|
||||||
ev.target.value = new_val;
|
ev.target.value = new_val;
|
||||||
|
@ -99,5 +99,5 @@ module.exports = React.createClass({
|
||||||
onChange={this.onValueChanged} onFocus={this.onFocus} onBlur={this.onBlur}
|
onChange={this.onValueChanged} onFocus={this.onFocus} onBlur={this.onBlur}
|
||||||
value={this.props.alias} />
|
value={this.props.alias} />
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -48,7 +48,7 @@ export default React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
authError: null,
|
authError: null,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
_onAuthFinished: function(success, result) {
|
_onAuthFinished: function(success, result) {
|
||||||
|
|
|
@ -82,5 +82,5 @@ export default React.createClass({
|
||||||
{ tooltip }
|
{ tooltip }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -46,8 +46,8 @@ export default React.createClass({
|
||||||
|
|
||||||
componentWillReceiveProps: function(props) {
|
componentWillReceiveProps: function(props) {
|
||||||
// Make sure the selected item isn't outside the list bounds
|
// Make sure the selected item isn't outside the list bounds
|
||||||
var selected = this.state.selected;
|
const selected = this.state.selected;
|
||||||
var maxSelected = this._maxSelected(props.addressList);
|
const maxSelected = this._maxSelected(props.addressList);
|
||||||
if (selected > maxSelected) {
|
if (selected > maxSelected) {
|
||||||
this.setState({ 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
|
// As the user scrolls with the arrow keys keep the selected item
|
||||||
// at the top of the window.
|
// at the top of the window.
|
||||||
if (this.scrollElement && this.props.addressList.length > 0 && !this.state.hover) {
|
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;
|
this.scrollElement.scrollTop = (this.state.selected * elementHeight) - elementHeight;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -117,15 +117,15 @@ export default React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
createAddressListTiles: function() {
|
createAddressListTiles: function() {
|
||||||
var self = this;
|
const self = this;
|
||||||
var AddressTile = sdk.getComponent("elements.AddressTile");
|
const AddressTile = sdk.getComponent("elements.AddressTile");
|
||||||
var maxSelected = this._maxSelected(this.props.addressList);
|
const maxSelected = this._maxSelected(this.props.addressList);
|
||||||
var addressList = [];
|
const addressList = [];
|
||||||
|
|
||||||
// Only create the address elements if there are address
|
// Only create the address elements if there are address
|
||||||
if (this.props.addressList.length > 0) {
|
if (this.props.addressList.length > 0) {
|
||||||
for (var i = 0; i <= maxSelected; i++) {
|
for (let i = 0; i <= maxSelected; i++) {
|
||||||
var classes = classNames({
|
const classes = classNames({
|
||||||
"mx_AddressSelector_addressListElement": true,
|
"mx_AddressSelector_addressListElement": true,
|
||||||
"mx_AddressSelector_selected": this.state.selected === i,
|
"mx_AddressSelector_selected": this.state.selected === i,
|
||||||
});
|
});
|
||||||
|
@ -143,7 +143,7 @@ export default React.createClass({
|
||||||
ref={(ref) => { this.addressListElement = ref; }}
|
ref={(ref) => { this.addressListElement = ref; }}
|
||||||
>
|
>
|
||||||
<AddressTile address={this.props.addressList[i]} justified={true} networkName="vector" networkUrl="img/search-icon-vector.svg" />
|
<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) {
|
_maxSelected: function(list) {
|
||||||
var listSize = list.length === 0 ? 0 : list.length - 1;
|
const listSize = list.length === 0 ? 0 : list.length - 1;
|
||||||
var maxSelected = listSize > (this.props.truncateAt - 1) ? (this.props.truncateAt - 1) : listSize;
|
const maxSelected = listSize > (this.props.truncateAt - 1) ? (this.props.truncateAt - 1) : listSize;
|
||||||
return maxSelected;
|
return maxSelected;
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var classes = classNames({
|
const classes = classNames({
|
||||||
"mx_AddressSelector": true,
|
"mx_AddressSelector": true,
|
||||||
"mx_AddressSelector_empty": this.props.addressList.length === 0,
|
"mx_AddressSelector_empty": this.props.addressList.length === 0,
|
||||||
});
|
});
|
||||||
|
@ -168,5 +168,5 @@ export default React.createClass({
|
||||||
{ this.createAddressListTiles() }
|
{ this.createAddressListTiles() }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -107,7 +107,7 @@ export default React.createClass({
|
||||||
|
|
||||||
let nameNode = null;
|
let nameNode = null;
|
||||||
if (address.displayName) {
|
if (address.displayName) {
|
||||||
nameNode = <div className={nameClasses}>{ address.displayName }</div>
|
nameNode = <div className={nameClasses}>{ address.displayName }</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
info = (
|
info = (
|
||||||
|
@ -118,7 +118,7 @@ export default React.createClass({
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
error = true;
|
error = true;
|
||||||
var unknownClasses = classNames({
|
const unknownClasses = classNames({
|
||||||
"mx_AddressTile_unknown": true,
|
"mx_AddressTile_unknown": true,
|
||||||
"mx_AddressTile_justified": this.props.justified,
|
"mx_AddressTile_justified": this.props.justified,
|
||||||
});
|
});
|
||||||
|
@ -151,5 +151,5 @@ export default React.createClass({
|
||||||
{ dismiss }
|
{ dismiss }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -30,7 +30,7 @@ export default React.createClass({
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
device: this.props.device
|
device: this.props.device,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -60,24 +60,24 @@ export default React.createClass({
|
||||||
|
|
||||||
onUnverifyClick: function() {
|
onUnverifyClick: function() {
|
||||||
MatrixClientPeg.get().setDeviceVerified(
|
MatrixClientPeg.get().setDeviceVerified(
|
||||||
this.props.userId, this.state.device.deviceId, false
|
this.props.userId, this.state.device.deviceId, false,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
onBlacklistClick: function() {
|
onBlacklistClick: function() {
|
||||||
MatrixClientPeg.get().setDeviceBlocked(
|
MatrixClientPeg.get().setDeviceBlocked(
|
||||||
this.props.userId, this.state.device.deviceId, true
|
this.props.userId, this.state.device.deviceId, true,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
onUnblacklistClick: function() {
|
onUnblacklistClick: function() {
|
||||||
MatrixClientPeg.get().setDeviceBlocked(
|
MatrixClientPeg.get().setDeviceBlocked(
|
||||||
this.props.userId, this.state.device.deviceId, false
|
this.props.userId, this.state.device.deviceId, false,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var blacklistButton = null, verifyButton = null;
|
let blacklistButton = null, verifyButton = null;
|
||||||
|
|
||||||
if (this.state.device.isBlocked()) {
|
if (this.state.device.isBlocked()) {
|
||||||
blacklistButton = (
|
blacklistButton = (
|
||||||
|
|
|
@ -29,7 +29,7 @@ class MenuOption extends React.Component {
|
||||||
getDefaultProps() {
|
getDefaultProps() {
|
||||||
return {
|
return {
|
||||||
disabled: false,
|
disabled: false,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_onMouseEnter() {
|
_onMouseEnter() {
|
||||||
|
@ -53,14 +53,14 @@ class MenuOption extends React.Component {
|
||||||
onMouseEnter={this._onMouseEnter}
|
onMouseEnter={this._onMouseEnter}
|
||||||
>
|
>
|
||||||
{ this.props.children }
|
{ this.props.children }
|
||||||
</div>
|
</div>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
MenuOption.propTypes = {
|
MenuOption.propTypes = {
|
||||||
children: React.PropTypes.oneOfType([
|
children: React.PropTypes.oneOfType([
|
||||||
React.PropTypes.arrayOf(React.PropTypes.node),
|
React.PropTypes.arrayOf(React.PropTypes.node),
|
||||||
React.PropTypes.node
|
React.PropTypes.node,
|
||||||
]),
|
]),
|
||||||
highlighted: React.PropTypes.bool,
|
highlighted: React.PropTypes.bool,
|
||||||
dropdownKey: React.PropTypes.string,
|
dropdownKey: React.PropTypes.string,
|
||||||
|
@ -297,7 +297,7 @@ export default class Dropdown extends React.Component {
|
||||||
this.childrenByKey[this.props.value];
|
this.childrenByKey[this.props.value];
|
||||||
currentValue = <div className="mx_Dropdown_option">
|
currentValue = <div className="mx_Dropdown_option">
|
||||||
{ selectedChild }
|
{ selectedChild }
|
||||||
</div>
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dropdownClasses = {
|
const dropdownClasses = {
|
||||||
|
@ -340,4 +340,4 @@ Dropdown.propTypes = {
|
||||||
value: React.PropTypes.string,
|
value: React.PropTypes.string,
|
||||||
// negative for consistency with HTML
|
// negative for consistency with HTML
|
||||||
disabled: React.PropTypes.bool,
|
disabled: React.PropTypes.bool,
|
||||||
}
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
|
|
||||||
const KEY_TAB = 9;
|
const KEY_TAB = 9;
|
||||||
const KEY_SHIFT = 16;
|
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.refs.editable_div.setAttribute("class", this.props.className + " " + this.props.placeholderClassName);
|
||||||
this.placeholder = true;
|
this.placeholder = true;
|
||||||
this.value = '';
|
this.value = '';
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.refs.editable_div.textContent = this.value;
|
this.refs.editable_div.textContent = this.value;
|
||||||
this.refs.editable_div.setAttribute("class", this.props.className);
|
this.refs.editable_div.setAttribute("class", this.props.className);
|
||||||
this.placeholder = false;
|
this.placeholder = false;
|
||||||
|
@ -152,8 +151,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
if (!ev.target.textContent) {
|
if (!ev.target.textContent) {
|
||||||
this.showPlaceholder(true);
|
this.showPlaceholder(true);
|
||||||
}
|
} else if (!this.placeholder) {
|
||||||
else if (!this.placeholder) {
|
|
||||||
this.value = ev.target.textContent;
|
this.value = ev.target.textContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,21 +175,21 @@ module.exports = React.createClass({
|
||||||
onFocus: function(ev) {
|
onFocus: function(ev) {
|
||||||
//ev.target.setSelectionRange(0, ev.target.textContent.length);
|
//ev.target.setSelectionRange(0, ev.target.textContent.length);
|
||||||
|
|
||||||
var node = ev.target.childNodes[0];
|
const node = ev.target.childNodes[0];
|
||||||
if (node) {
|
if (node) {
|
||||||
var range = document.createRange();
|
const range = document.createRange();
|
||||||
range.setStart(node, 0);
|
range.setStart(node, 0);
|
||||||
range.setEnd(node, node.length);
|
range.setEnd(node, node.length);
|
||||||
|
|
||||||
var sel = window.getSelection();
|
const sel = window.getSelection();
|
||||||
sel.removeAllRanges();
|
sel.removeAllRanges();
|
||||||
sel.addRange(range);
|
sel.addRange(range);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onFinish: function(ev, shouldSubmit) {
|
onFinish: function(ev, shouldSubmit) {
|
||||||
var self = this;
|
const self = this;
|
||||||
var submit = (ev.key === "Enter") || shouldSubmit;
|
const submit = (ev.key === "Enter") || shouldSubmit;
|
||||||
this.setState({
|
this.setState({
|
||||||
phase: this.Phases.Display,
|
phase: this.Phases.Display,
|
||||||
}, function() {
|
}, function() {
|
||||||
|
@ -202,19 +200,16 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onBlur: function(ev) {
|
onBlur: function(ev) {
|
||||||
var sel = window.getSelection();
|
const sel = window.getSelection();
|
||||||
sel.removeAllRanges();
|
sel.removeAllRanges();
|
||||||
|
|
||||||
if (this.props.blurToCancel)
|
if (this.props.blurToCancel) {this.cancelEdit();} else {this.onFinish(ev, this.props.blurToSubmit);}
|
||||||
{this.cancelEdit();}
|
|
||||||
else
|
|
||||||
{this.onFinish(ev, this.props.blurToSubmit);}
|
|
||||||
|
|
||||||
this.showPlaceholder(!this.value);
|
this.showPlaceholder(!this.value);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
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)) {
|
if (!this.props.editable || (this.state.phase == this.Phases.Display && (this.props.label || this.props.labelClassName) && !this.value)) {
|
||||||
// show the label
|
// show the label
|
||||||
|
@ -226,5 +221,5 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
return editable_el;
|
return editable_el;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -64,7 +64,7 @@ export default class EditableTextContainer extends React.Component {
|
||||||
errorString: error.toString(),
|
errorString: error.toString(),
|
||||||
busy: false,
|
busy: false,
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,13 +96,13 @@ export default class EditableTextContainer extends React.Component {
|
||||||
errorString: error.toString(),
|
errorString: error.toString(),
|
||||||
busy: false,
|
busy: false,
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.state.busy) {
|
if (this.state.busy) {
|
||||||
var Loader = sdk.getComponent("elements.Spinner");
|
const Loader = sdk.getComponent("elements.Spinner");
|
||||||
return (
|
return (
|
||||||
<Loader />
|
<Loader />
|
||||||
);
|
);
|
||||||
|
@ -111,7 +111,7 @@ export default class EditableTextContainer extends React.Component {
|
||||||
<div className="error">{ this.state.errorString }</div>
|
<div className="error">{ this.state.errorString }</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
var EditableText = sdk.getComponent('elements.EditableText');
|
const EditableText = sdk.getComponent('elements.EditableText');
|
||||||
return (
|
return (
|
||||||
<EditableText initialValue={this.state.value}
|
<EditableText initialValue={this.state.value}
|
||||||
placeholder={this.props.placeholder}
|
placeholder={this.props.placeholder}
|
||||||
|
|
|
@ -35,7 +35,7 @@ export default class LanguageDropdown extends React.Component {
|
||||||
this.state = {
|
this.state = {
|
||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
langs: null,
|
langs: null,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
|
@ -109,7 +109,7 @@ export default class LanguageDropdown extends React.Component {
|
||||||
searchEnabled={true} value={value}
|
searchEnabled={true} value={value}
|
||||||
>
|
>
|
||||||
{ options }
|
{ options }
|
||||||
</Dropdown>
|
</Dropdown>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,12 +96,12 @@ module.exports = React.createClass({
|
||||||
// Transform into consecutive repetitions of the same transition (like 5
|
// Transform into consecutive repetitions of the same transition (like 5
|
||||||
// consecutive 'joined_and_left's)
|
// consecutive 'joined_and_left's)
|
||||||
const coalescedTransitions = this._coalesceRepeatedTransitions(
|
const coalescedTransitions = this._coalesceRepeatedTransitions(
|
||||||
canonicalTransitions
|
canonicalTransitions,
|
||||||
);
|
);
|
||||||
|
|
||||||
const descs = coalescedTransitions.map((t) => {
|
const descs = coalescedTransitions.map((t) => {
|
||||||
return this._getDescriptionForTransition(
|
return this._getDescriptionForTransition(
|
||||||
t.transitionType, plural, t.repeats
|
t.transitionType, plural, t.repeats,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -370,7 +370,7 @@ module.exports = React.createClass({
|
||||||
*/
|
*/
|
||||||
_renderCommaSeparatedList(items, itemLimit) {
|
_renderCommaSeparatedList(items, itemLimit) {
|
||||||
const remaining = itemLimit === undefined ? 0 : Math.max(
|
const remaining = itemLimit === undefined ? 0 : Math.max(
|
||||||
items.length - itemLimit, 0
|
items.length - itemLimit, 0,
|
||||||
);
|
);
|
||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
return "";
|
return "";
|
||||||
|
@ -419,19 +419,15 @@ module.exports = React.createClass({
|
||||||
case 'join':
|
case 'join':
|
||||||
if (e.mxEvent.getPrevContent().membership === 'join') {
|
if (e.mxEvent.getPrevContent().membership === 'join') {
|
||||||
if (e.mxEvent.getContent().displayname !==
|
if (e.mxEvent.getContent().displayname !==
|
||||||
e.mxEvent.getPrevContent().displayname)
|
e.mxEvent.getPrevContent().displayname) {
|
||||||
{
|
|
||||||
return 'changed_name';
|
return 'changed_name';
|
||||||
}
|
} else if (e.mxEvent.getContent().avatar_url !==
|
||||||
else if (e.mxEvent.getContent().avatar_url !==
|
e.mxEvent.getPrevContent().avatar_url) {
|
||||||
e.mxEvent.getPrevContent().avatar_url)
|
|
||||||
{
|
|
||||||
return 'changed_avatar';
|
return 'changed_avatar';
|
||||||
}
|
}
|
||||||
// console.log("MELS ignoring duplicate membership join event");
|
// console.log("MELS ignoring duplicate membership join event");
|
||||||
return null;
|
return null;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return 'joined';
|
return 'joined';
|
||||||
}
|
}
|
||||||
case 'leave':
|
case 'leave':
|
||||||
|
@ -483,7 +479,7 @@ module.exports = React.createClass({
|
||||||
firstEvent.index < aggregateIndices[seq]) {
|
firstEvent.index < aggregateIndices[seq]) {
|
||||||
aggregateIndices[seq] = firstEvent.index;
|
aggregateIndices[seq] = firstEvent.index;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -494,7 +490,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const eventsToRender = this.props.events;
|
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 fewEvents = eventsToRender.length < this.props.threshold;
|
||||||
const expanded = this.state.expanded || fewEvents;
|
const expanded = this.state.expanded || fewEvents;
|
||||||
|
|
||||||
|
@ -542,7 +538,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// Sort types by order of lowest event index within sequence
|
// Sort types by order of lowest event index within sequence
|
||||||
const orderedTransitionSequences = Object.keys(aggregate.names).sort(
|
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;
|
let summaryContainer = null;
|
||||||
|
|
|
@ -20,8 +20,8 @@ import React from 'react';
|
||||||
import * as Roles from '../../../Roles';
|
import * as Roles from '../../../Roles';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
var LEVEL_ROLE_MAP = {};
|
let LEVEL_ROLE_MAP = {};
|
||||||
var reverseRoles = {};
|
const reverseRoles = {};
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'PowerSelector',
|
displayName: 'PowerSelector',
|
||||||
|
@ -72,7 +72,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
getValue: function() {
|
getValue: function() {
|
||||||
var value;
|
let value;
|
||||||
if (this.refs.select) {
|
if (this.refs.select) {
|
||||||
value = reverseRoles[this.refs.select.value];
|
value = reverseRoles[this.refs.select.value];
|
||||||
if (this.refs.custom) {
|
if (this.refs.custom) {
|
||||||
|
@ -83,30 +83,27 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var customPicker;
|
let customPicker;
|
||||||
if (this.state.custom) {
|
if (this.state.custom) {
|
||||||
var input;
|
let input;
|
||||||
if (this.props.disabled) {
|
if (this.props.disabled) {
|
||||||
input = <span>{ this.props.value }</span>;
|
input = <span>{ this.props.value }</span>;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
input = <input ref="custom" type="text" size="3" defaultValue={this.props.value} onBlur={this.onCustomBlur} onKeyDown={this.onCustomKeyDown} />;
|
input = <input ref="custom" type="text" size="3" defaultValue={this.props.value} onBlur={this.onCustomBlur} onKeyDown={this.onCustomKeyDown} />;
|
||||||
}
|
}
|
||||||
customPicker = <span> of { input }</span>;
|
customPicker = <span> of { input }</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectValue;
|
let selectValue;
|
||||||
if (this.state.custom) {
|
if (this.state.custom) {
|
||||||
selectValue = "Custom";
|
selectValue = "Custom";
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
selectValue = LEVEL_ROLE_MAP[this.props.value] || "Custom";
|
selectValue = LEVEL_ROLE_MAP[this.props.value] || "Custom";
|
||||||
}
|
}
|
||||||
var select;
|
let select;
|
||||||
if (this.props.disabled) {
|
if (this.props.disabled) {
|
||||||
select = <span>{ selectValue }</span>;
|
select = <span>{ selectValue }</span>;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Each level must have a definition in LEVEL_ROLE_MAP
|
// Each level must have a definition in LEVEL_ROLE_MAP
|
||||||
const levels = [0, 50, 100];
|
const levels = [0, 50, 100];
|
||||||
let options = levels.map((level) => {
|
let options = levels.map((level) => {
|
||||||
|
@ -115,7 +112,7 @@ module.exports = React.createClass({
|
||||||
// Give a userDefault (users_default in the power event) of 0 but
|
// Give a userDefault (users_default in the power event) of 0 but
|
||||||
// because level !== undefined, this should never be used.
|
// because level !== undefined, this should never be used.
|
||||||
text: Roles.textualPowerLevel(level, 0),
|
text: Roles.textualPowerLevel(level, 0),
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
options.push({ value: "Custom", text: _t("Custom level") });
|
options.push({ value: "Custom", text: _t("Custom level") });
|
||||||
options = options.map((op) => {
|
options = options.map((op) => {
|
||||||
|
@ -137,5 +134,5 @@ module.exports = React.createClass({
|
||||||
{ customPicker }
|
{ customPicker }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,23 +16,23 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'ProgressBar',
|
displayName: 'ProgressBar',
|
||||||
propTypes: {
|
propTypes: {
|
||||||
value: React.PropTypes.number,
|
value: React.PropTypes.number,
|
||||||
max: React.PropTypes.number
|
max: React.PropTypes.number,
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
// Would use an HTML5 progress tag but if that doesn't animate if you
|
// Would use an HTML5 progress tag but if that doesn't animate if you
|
||||||
// use the HTML attributes rather than styles
|
// use the HTML attributes rather than styles
|
||||||
var progressStyle = {
|
const progressStyle = {
|
||||||
width: ((this.props.value / this.props.max) * 100)+"%"
|
width: ((this.props.value / this.props.max) * 100)+"%",
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="mx_ProgressBar"><div className="mx_ProgressBar_fill" style={progressStyle}></div></div>
|
<div className="mx_ProgressBar"><div className="mx_ProgressBar_fill" style={progressStyle}></div></div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,9 +16,9 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var ReactDOM = require("react-dom");
|
const ReactDOM = require("react-dom");
|
||||||
var Tinter = require("../../../Tinter");
|
const Tinter = require("../../../Tinter");
|
||||||
|
|
||||||
var TintableSvg = React.createClass({
|
var TintableSvg = React.createClass({
|
||||||
displayName: 'TintableSvg',
|
displayName: 'TintableSvg',
|
||||||
|
@ -72,7 +72,7 @@ var TintableSvg = React.createClass({
|
||||||
tabIndex="-1"
|
tabIndex="-1"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Register with the Tinter so that we will be told if the tint changes
|
// Register with the Tinter so that we will be told if the tint changes
|
||||||
|
|
|
@ -52,7 +52,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var self = this;
|
const self = this;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ul className="mx_UserSelector_UserIdList" ref="list">
|
<ul className="mx_UserSelector_UserIdList" ref="list">
|
||||||
|
@ -66,5 +66,5 @@ module.exports = React.createClass({
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,7 +20,7 @@ import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { _t, _tJsx } from '../../../languageHandler';
|
import { _t, _tJsx } from '../../../languageHandler';
|
||||||
|
|
||||||
var DIV_ID = 'mx_recaptcha';
|
const DIV_ID = 'mx_recaptcha';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A pure UI component which displays a captcha form.
|
* A pure UI component which displays a captcha form.
|
||||||
|
@ -60,9 +60,9 @@ module.exports = React.createClass({
|
||||||
} else {
|
} else {
|
||||||
console.log("Loading recaptcha script...");
|
console.log("Loading recaptcha script...");
|
||||||
window.mx_on_recaptcha_loaded = () => {this._onCaptchaLoaded();};
|
window.mx_on_recaptcha_loaded = () => {this._onCaptchaLoaded();};
|
||||||
var protocol = global.location.protocol;
|
const protocol = global.location.protocol;
|
||||||
if (protocol === "file:") {
|
if (protocol === "file:") {
|
||||||
var warning = document.createElement('div');
|
const warning = document.createElement('div');
|
||||||
// XXX: fix hardcoded app URL. Better solutions include:
|
// XXX: fix hardcoded app URL. Better solutions include:
|
||||||
// * jumping straight to a hosted captcha page (but we don't support that yet)
|
// * jumping straight to a hosted captcha page (but we don't support that yet)
|
||||||
// * embedding the captcha in an iframe (if that works)
|
// * embedding the captcha in an iframe (if that works)
|
||||||
|
@ -72,11 +72,10 @@ module.exports = React.createClass({
|
||||||
/<a>(.*?)<\/a>/,
|
/<a>(.*?)<\/a>/,
|
||||||
(sub) => { return <a href='https://riot.im/app'>{ sub }</a>; }), warning);
|
(sub) => { return <a href='https://riot.im/app'>{ sub }</a>; }), warning);
|
||||||
this.refs.recaptchaContainer.appendChild(warning);
|
this.refs.recaptchaContainer.appendChild(warning);
|
||||||
}
|
} else {
|
||||||
else {
|
const scriptTag = document.createElement('script');
|
||||||
var scriptTag = document.createElement('script');
|
|
||||||
scriptTag.setAttribute(
|
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);
|
this.refs.recaptchaContainer.appendChild(scriptTag);
|
||||||
}
|
}
|
||||||
|
@ -93,7 +92,7 @@ module.exports = React.createClass({
|
||||||
throw new Error("Recaptcha did not load successfully");
|
throw new Error("Recaptcha did not load successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
var publicKey = this.props.sitePublicKey;
|
const publicKey = this.props.sitePublicKey;
|
||||||
if (!publicKey) {
|
if (!publicKey) {
|
||||||
console.error("No public key for recaptcha!");
|
console.error("No public key for recaptcha!");
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -143,5 +142,5 @@ module.exports = React.createClass({
|
||||||
{ error }
|
{ error }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,6 +32,6 @@ module.exports = React.createClass({
|
||||||
<button onClick={this.props.onSubmit}>{ _t("Sign in with CAS") }</button>
|
<button onClick={this.props.onSubmit}>{ _t("Sign in with CAS") }</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -46,5 +46,5 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -178,7 +178,7 @@ export const RecaptchaAuthEntry = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
const CaptchaForm = sdk.getComponent("views.login.CaptchaForm");
|
const CaptchaForm = sdk.getComponent("views.login.CaptchaForm");
|
||||||
var sitePublicKey = this.props.stageParams.public_key;
|
const sitePublicKey = this.props.stageParams.public_key;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<CaptchaForm sitePublicKey={sitePublicKey}
|
<CaptchaForm sitePublicKey={sitePublicKey}
|
||||||
|
@ -333,12 +333,12 @@ export const MsisdnAuthEntry = React.createClass({
|
||||||
});
|
});
|
||||||
|
|
||||||
this.props.matrixClient.submitMsisdnToken(
|
this.props.matrixClient.submitMsisdnToken(
|
||||||
this._sid, this.props.clientSecret, this.state.token
|
this._sid, this.props.clientSecret, this.state.token,
|
||||||
).then((result) => {
|
).then((result) => {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
const idServerParsedUrl = url.parse(
|
const idServerParsedUrl = url.parse(
|
||||||
this.props.matrixClient.getIdentityServerUrl(),
|
this.props.matrixClient.getIdentityServerUrl(),
|
||||||
)
|
);
|
||||||
this.props.submitAuthDict({
|
this.props.submitAuthDict({
|
||||||
type: MsisdnAuthEntry.LOGIN_TYPE,
|
type: MsisdnAuthEntry.LOGIN_TYPE,
|
||||||
threepid_creds: {
|
threepid_creds: {
|
||||||
|
@ -421,9 +421,9 @@ export const FallbackAuthEntry = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_onShowFallbackClick: function() {
|
_onShowFallbackClick: function() {
|
||||||
var url = this.props.matrixClient.getFallbackAuthUrl(
|
const url = this.props.matrixClient.getFallbackAuthUrl(
|
||||||
this.props.loginType,
|
this.props.loginType,
|
||||||
this.props.authSessionId
|
this.props.authSessionId,
|
||||||
);
|
);
|
||||||
this._popupWindow = window.open(url);
|
this._popupWindow = window.open(url);
|
||||||
},
|
},
|
||||||
|
@ -457,7 +457,7 @@ const AuthEntryComponents = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export function getEntryComponentForLoginType(loginType) {
|
export function getEntryComponentForLoginType(loginType) {
|
||||||
for (var c of AuthEntryComponents) {
|
for (const c of AuthEntryComponents) {
|
||||||
if (c.LOGIN_TYPE == loginType) {
|
if (c.LOGIN_TYPE == loginType) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'LoginHeader',
|
displayName: 'LoginHeader',
|
||||||
|
@ -27,5 +27,5 @@ module.exports = React.createClass({
|
||||||
Matrix
|
Matrix
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -94,7 +94,7 @@ class PasswordLogin extends React.Component {
|
||||||
onLoginTypeChange(loginType) {
|
onLoginTypeChange(loginType) {
|
||||||
this.setState({
|
this.setState({
|
||||||
loginType: loginType,
|
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() {
|
render() {
|
||||||
var forgotPasswordJsx;
|
let forgotPasswordJsx;
|
||||||
|
|
||||||
if (this.props.onForgotPasswordClick) {
|
if (this.props.onForgotPasswordClick) {
|
||||||
forgotPasswordJsx = (
|
forgotPasswordJsx = (
|
||||||
|
|
|
@ -64,7 +64,7 @@ module.exports = React.createClass({
|
||||||
minPasswordLength: 6,
|
minPasswordLength: 6,
|
||||||
onError: function(e) {
|
onError: function(e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -91,10 +91,10 @@ module.exports = React.createClass({
|
||||||
this.validateField(FIELD_PHONE_NUMBER);
|
this.validateField(FIELD_PHONE_NUMBER);
|
||||||
this.validateField(FIELD_EMAIL);
|
this.validateField(FIELD_EMAIL);
|
||||||
|
|
||||||
var self = this;
|
const self = this;
|
||||||
if (this.allFieldsValid()) {
|
if (this.allFieldsValid()) {
|
||||||
if (this.refs.email.value == '') {
|
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, {
|
Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, {
|
||||||
title: _t("Warning!"),
|
title: _t("Warning!"),
|
||||||
description:
|
description:
|
||||||
|
@ -116,8 +116,8 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_doSubmit: function(ev) {
|
_doSubmit: function(ev) {
|
||||||
let email = this.refs.email.value.trim();
|
const email = this.refs.email.value.trim();
|
||||||
var promise = this.props.onRegisterClick({
|
const promise = this.props.onRegisterClick({
|
||||||
username: this.refs.username.value.trim(),
|
username: this.refs.username.value.trim(),
|
||||||
password: this.refs.password.value.trim(),
|
password: this.refs.password.value.trim(),
|
||||||
email: email,
|
email: email,
|
||||||
|
@ -138,8 +138,8 @@ module.exports = React.createClass({
|
||||||
* they were validated.
|
* they were validated.
|
||||||
*/
|
*/
|
||||||
allFieldsValid: function() {
|
allFieldsValid: function() {
|
||||||
var keys = Object.keys(this.state.fieldValid);
|
const keys = Object.keys(this.state.fieldValid);
|
||||||
for (var i = 0; i < keys.length; ++i) {
|
for (let i = 0; i < keys.length; ++i) {
|
||||||
if (this.state.fieldValid[keys[i]] == false) {
|
if (this.state.fieldValid[keys[i]] == false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -152,8 +152,8 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
validateField: function(field_id) {
|
validateField: function(field_id) {
|
||||||
var pwd1 = this.refs.password.value.trim();
|
const pwd1 = this.refs.password.value.trim();
|
||||||
var pwd2 = this.refs.passwordConfirm.value.trim();
|
const pwd2 = this.refs.passwordConfirm.value.trim();
|
||||||
|
|
||||||
switch (field_id) {
|
switch (field_id) {
|
||||||
case FIELD_EMAIL:
|
case FIELD_EMAIL:
|
||||||
|
@ -162,7 +162,7 @@ module.exports = React.createClass({
|
||||||
const matchingTeam = this.props.teamsConfig.teams.find(
|
const matchingTeam = this.props.teamsConfig.teams.find(
|
||||||
(team) => {
|
(team) => {
|
||||||
return email.split('@').pop() === team.domain;
|
return email.split('@').pop() === team.domain;
|
||||||
}
|
},
|
||||||
) || null;
|
) || null;
|
||||||
this.setState({
|
this.setState({
|
||||||
selectedTeam: matchingTeam,
|
selectedTeam: matchingTeam,
|
||||||
|
@ -191,13 +191,13 @@ module.exports = React.createClass({
|
||||||
this.markFieldValid(
|
this.markFieldValid(
|
||||||
field_id,
|
field_id,
|
||||||
false,
|
false,
|
||||||
"RegistrationForm.ERR_USERNAME_INVALID"
|
"RegistrationForm.ERR_USERNAME_INVALID",
|
||||||
);
|
);
|
||||||
} else if (username == '') {
|
} else if (username == '') {
|
||||||
this.markFieldValid(
|
this.markFieldValid(
|
||||||
field_id,
|
field_id,
|
||||||
false,
|
false,
|
||||||
"RegistrationForm.ERR_USERNAME_BLANK"
|
"RegistrationForm.ERR_USERNAME_BLANK",
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.markFieldValid(field_id, true);
|
this.markFieldValid(field_id, true);
|
||||||
|
@ -208,13 +208,13 @@ module.exports = React.createClass({
|
||||||
this.markFieldValid(
|
this.markFieldValid(
|
||||||
field_id,
|
field_id,
|
||||||
false,
|
false,
|
||||||
"RegistrationForm.ERR_PASSWORD_MISSING"
|
"RegistrationForm.ERR_PASSWORD_MISSING",
|
||||||
);
|
);
|
||||||
} else if (pwd1.length < this.props.minPasswordLength) {
|
} else if (pwd1.length < this.props.minPasswordLength) {
|
||||||
this.markFieldValid(
|
this.markFieldValid(
|
||||||
field_id,
|
field_id,
|
||||||
false,
|
false,
|
||||||
"RegistrationForm.ERR_PASSWORD_LENGTH"
|
"RegistrationForm.ERR_PASSWORD_LENGTH",
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.markFieldValid(field_id, true);
|
this.markFieldValid(field_id, true);
|
||||||
|
@ -223,14 +223,14 @@ module.exports = React.createClass({
|
||||||
case FIELD_PASSWORD_CONFIRM:
|
case FIELD_PASSWORD_CONFIRM:
|
||||||
this.markFieldValid(
|
this.markFieldValid(
|
||||||
field_id, pwd1 == pwd2,
|
field_id, pwd1 == pwd2,
|
||||||
"RegistrationForm.ERR_PASSWORD_MISMATCH"
|
"RegistrationForm.ERR_PASSWORD_MISMATCH",
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
markFieldValid: function(field_id, val, error_code) {
|
markFieldValid: function(field_id, val, error_code) {
|
||||||
var fieldValid = this.state.fieldValid;
|
const fieldValid = this.state.fieldValid;
|
||||||
fieldValid[field_id] = val;
|
fieldValid[field_id] = val;
|
||||||
this.setState({fieldValid: fieldValid});
|
this.setState({fieldValid: fieldValid});
|
||||||
if (!val) {
|
if (!val) {
|
||||||
|
@ -271,7 +271,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var self = this;
|
const self = this;
|
||||||
|
|
||||||
const emailSection = (
|
const emailSection = (
|
||||||
<div>
|
<div>
|
||||||
|
@ -321,7 +321,7 @@ module.exports = React.createClass({
|
||||||
FIELD_PHONE_NUMBER,
|
FIELD_PHONE_NUMBER,
|
||||||
'mx_Login_phoneNumberField',
|
'mx_Login_phoneNumberField',
|
||||||
'mx_Login_field',
|
'mx_Login_field',
|
||||||
'mx_Login_field_has_prefix'
|
'mx_Login_field_has_prefix',
|
||||||
)}
|
)}
|
||||||
onBlur={function() {self.validateField(FIELD_PHONE_NUMBER);}}
|
onBlur={function() {self.validateField(FIELD_PHONE_NUMBER);}}
|
||||||
value={self.state.phoneNumber}
|
value={self.state.phoneNumber}
|
||||||
|
@ -333,7 +333,7 @@ module.exports = React.createClass({
|
||||||
<input className="mx_Login_submit" type="submit" value={_t("Register")} />
|
<input className="mx_Login_submit" type="submit" value={_t("Register")} />
|
||||||
);
|
);
|
||||||
|
|
||||||
let placeholderUserName = _t("User name");
|
const placeholderUserName = _t("User name");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -361,5 +361,5 @@ module.exports = React.createClass({
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,9 +16,9 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var Modal = require('../../../Modal');
|
const Modal = require('../../../Modal');
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +45,7 @@ module.exports = React.createClass({
|
||||||
customIsUrl: React.PropTypes.string,
|
customIsUrl: React.PropTypes.string,
|
||||||
|
|
||||||
withToggleButton: React.PropTypes.bool,
|
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() {
|
getDefaultProps: function() {
|
||||||
|
@ -54,7 +54,7 @@ module.exports = React.createClass({
|
||||||
customHsUrl: "",
|
customHsUrl: "",
|
||||||
customIsUrl: "",
|
customIsUrl: "",
|
||||||
withToggleButton: false,
|
withToggleButton: false,
|
||||||
delayTimeMs: 0
|
delayTimeMs: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -65,14 +65,14 @@ 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
|
// 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 ||
|
configVisible: !this.props.withToggleButton ||
|
||||||
(this.props.customHsUrl !== this.props.defaultHsUrl) ||
|
(this.props.customHsUrl !== this.props.defaultHsUrl) ||
|
||||||
(this.props.customIsUrl !== this.props.defaultIsUrl)
|
(this.props.customIsUrl !== this.props.defaultIsUrl),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
onHomeserverChanged: function(ev) {
|
onHomeserverChanged: function(ev) {
|
||||||
this.setState({hs_url: ev.target.value}, function() {
|
this.setState({hs_url: ev.target.value}, function() {
|
||||||
this._hsTimeoutId = this._waitThenInvoke(this._hsTimeoutId, 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;
|
if (hsUrl === "") hsUrl = this.props.defaultHsUrl;
|
||||||
this.props.onServerConfigChange({
|
this.props.onServerConfigChange({
|
||||||
hsUrl: this.state.hs_url,
|
hsUrl: this.state.hs_url,
|
||||||
|
@ -85,7 +85,7 @@ module.exports = React.createClass({
|
||||||
onIdentityServerChanged: function(ev) {
|
onIdentityServerChanged: function(ev) {
|
||||||
this.setState({is_url: ev.target.value}, function() {
|
this.setState({is_url: ev.target.value}, function() {
|
||||||
this._isTimeoutId = this._waitThenInvoke(this._isTimeoutId, 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;
|
if (isUrl === "") isUrl = this.props.defaultIsUrl;
|
||||||
this.props.onServerConfigChange({
|
this.props.onServerConfigChange({
|
||||||
hsUrl: this.state.hs_url,
|
hsUrl: this.state.hs_url,
|
||||||
|
@ -104,15 +104,14 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
onServerConfigVisibleChange: function(visible, ev) {
|
onServerConfigVisibleChange: function(visible, ev) {
|
||||||
this.setState({
|
this.setState({
|
||||||
configVisible: visible
|
configVisible: visible,
|
||||||
});
|
});
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
this.props.onServerConfigChange({
|
this.props.onServerConfigChange({
|
||||||
hsUrl: this.props.defaultHsUrl,
|
hsUrl: this.props.defaultHsUrl,
|
||||||
isUrl: this.props.defaultIsUrl,
|
isUrl: this.props.defaultIsUrl,
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.props.onServerConfigChange({
|
this.props.onServerConfigChange({
|
||||||
hsUrl: this.state.hs_url,
|
hsUrl: this.state.hs_url,
|
||||||
isUrl: this.state.is_url,
|
isUrl: this.state.is_url,
|
||||||
|
@ -121,15 +120,15 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
showHelpPopup: function() {
|
showHelpPopup: function() {
|
||||||
var CustomServerDialog = sdk.getComponent('login.CustomServerDialog');
|
const CustomServerDialog = sdk.getComponent('login.CustomServerDialog');
|
||||||
Modal.createTrackedDialog('Custom Server Dialog', '', CustomServerDialog);
|
Modal.createTrackedDialog('Custom Server Dialog', '', CustomServerDialog);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var serverConfigStyle = {};
|
const serverConfigStyle = {};
|
||||||
serverConfigStyle.display = this.state.configVisible ? 'block' : 'none';
|
serverConfigStyle.display = this.state.configVisible ? 'block' : 'none';
|
||||||
|
|
||||||
var toggleButton;
|
let toggleButton;
|
||||||
if (this.props.withToggleButton) {
|
if (this.props.withToggleButton) {
|
||||||
toggleButton = (
|
toggleButton = (
|
||||||
<div className="mx_ServerConfig_selector">
|
<div className="mx_ServerConfig_selector">
|
||||||
|
@ -178,5 +177,5 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -35,7 +35,7 @@ export default class MAudioBody extends React.Component {
|
||||||
}
|
}
|
||||||
onPlayToggle() {
|
onPlayToggle() {
|
||||||
this.setState({
|
this.setState({
|
||||||
playing: !this.state.playing
|
playing: !this.state.playing,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,9 +49,9 @@ export default class MAudioBody extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
var content = this.props.mxEvent.getContent();
|
const content = this.props.mxEvent.getContent();
|
||||||
if (content.file !== undefined && this.state.decryptedUrl === null) {
|
if (content.file !== undefined && this.state.decryptedUrl === null) {
|
||||||
var decryptedBlob;
|
let decryptedBlob;
|
||||||
decryptFile(content.file).then(function(blob) {
|
decryptFile(content.file).then(function(blob) {
|
||||||
decryptedBlob = blob;
|
decryptedBlob = blob;
|
||||||
return readBlobAsDataUri(decryptedBlob);
|
return readBlobAsDataUri(decryptedBlob);
|
||||||
|
@ -70,7 +70,6 @@ export default class MAudioBody extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
const content = this.props.mxEvent.getContent();
|
const content = this.props.mxEvent.getContent();
|
||||||
|
|
||||||
if (this.state.error !== null) {
|
if (this.state.error !== null) {
|
||||||
|
|
|
@ -28,10 +28,10 @@ import Modal from '../../../Modal';
|
||||||
|
|
||||||
|
|
||||||
// A cached tinted copy of "img/download.svg"
|
// A cached tinted copy of "img/download.svg"
|
||||||
var tintedDownloadImageURL;
|
let tintedDownloadImageURL;
|
||||||
// Track a list of mounted MFileBody instances so that we can update
|
// Track a list of mounted MFileBody instances so that we can update
|
||||||
// the "img/download.svg" when the tint changes.
|
// the "img/download.svg" when the tint changes.
|
||||||
var nextMountId = 0;
|
let nextMountId = 0;
|
||||||
const mounts = {};
|
const mounts = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -169,11 +169,11 @@ function computedStyle(element) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
const style = window.getComputedStyle(element, null);
|
const style = window.getComputedStyle(element, null);
|
||||||
var cssText = style.cssText;
|
let cssText = style.cssText;
|
||||||
if (cssText == "") {
|
if (cssText == "") {
|
||||||
// Firefox doesn't implement ".cssText" for computed styles.
|
// Firefox doesn't implement ".cssText" for computed styles.
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=137687
|
// 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[i] + ":";
|
||||||
cssText += style.getPropertyValue(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.
|
* @return {string} the human readable link text for the attachment.
|
||||||
*/
|
*/
|
||||||
presentableTextForFile: function(content) {
|
presentableTextForFile: function(content) {
|
||||||
var linkText = _t("Attachment");
|
let linkText = _t("Attachment");
|
||||||
if (content.body && content.body.length > 0) {
|
if (content.body && content.body.length > 0) {
|
||||||
// The content body should be the name of the file including a
|
// The content body should be the name of the file including a
|
||||||
// file extension.
|
// file extension.
|
||||||
|
@ -270,7 +270,7 @@ module.exports = React.createClass({
|
||||||
// Need to decrypt the attachment
|
// Need to decrypt the attachment
|
||||||
// Wait for the user to click on the link before downloading
|
// Wait for the user to click on the link before downloading
|
||||||
// and decrypting the attachment.
|
// and decrypting the attachment.
|
||||||
var decrypting = false;
|
let decrypting = false;
|
||||||
const decrypt = () => {
|
const decrypt = () => {
|
||||||
if (decrypting) {
|
if (decrypting) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -356,8 +356,7 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return (
|
return (
|
||||||
<span className="mx_MFileBody">
|
<span className="mx_MFileBody">
|
||||||
<div className="mx_MImageBody_download">
|
<div className="mx_MImageBody_download">
|
||||||
|
@ -370,7 +369,7 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var extra = text ? (': ' + text) : '';
|
const extra = text ? (': ' + text) : '';
|
||||||
return <span className="mx_MFileBody">
|
return <span className="mx_MFileBody">
|
||||||
{ _t("Invalid file%(extra)s", { extra: extra }) }
|
{ _t("Invalid file%(extra)s", { extra: extra }) }
|
||||||
</span>;
|
</span>;
|
||||||
|
|
|
@ -54,13 +54,12 @@ module.exports = React.createClass({
|
||||||
// no scaling needs to be applied
|
// no scaling needs to be applied
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
var widthMulti = thumbWidth / fullWidth;
|
const widthMulti = thumbWidth / fullWidth;
|
||||||
var heightMulti = thumbHeight / fullHeight;
|
const heightMulti = thumbHeight / fullHeight;
|
||||||
if (widthMulti < heightMulti) {
|
if (widthMulti < heightMulti) {
|
||||||
// width is the dominant dimension so scaling will be fixed on that
|
// width is the dominant dimension so scaling will be fixed on that
|
||||||
return widthMulti;
|
return widthMulti;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// height is the dominant dimension so scaling will be fixed on that
|
// height is the dominant dimension so scaling will be fixed on that
|
||||||
return heightMulti;
|
return heightMulti;
|
||||||
}
|
}
|
||||||
|
@ -89,15 +88,15 @@ module.exports = React.createClass({
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
const content = this.props.mxEvent.getContent();
|
const content = this.props.mxEvent.getContent();
|
||||||
if (content.file !== undefined && this.state.decryptedUrl === null) {
|
if (content.file !== undefined && this.state.decryptedUrl === null) {
|
||||||
var thumbnailPromise = Promise.resolve(null);
|
let thumbnailPromise = Promise.resolve(null);
|
||||||
if (content.info.thumbnail_file) {
|
if (content.info.thumbnail_file) {
|
||||||
thumbnailPromise = decryptFile(
|
thumbnailPromise = decryptFile(
|
||||||
content.info.thumbnail_file
|
content.info.thumbnail_file,
|
||||||
).then(function(blob) {
|
).then(function(blob) {
|
||||||
return readBlobAsDataUri(blob);
|
return readBlobAsDataUri(blob);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var decryptedBlob;
|
let decryptedBlob;
|
||||||
thumbnailPromise.then((thumbnailUrl) => {
|
thumbnailPromise.then((thumbnailUrl) => {
|
||||||
return decryptFile(content.file).then(function(blob) {
|
return decryptFile(content.file).then(function(blob) {
|
||||||
decryptedBlob = blob;
|
decryptedBlob = blob;
|
||||||
|
|
|
@ -16,8 +16,8 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'MessageEvent',
|
displayName: 'MessageEvent',
|
||||||
|
@ -47,21 +47,21 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
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.text': sdk.getComponent('messages.TextualBody'),
|
||||||
'm.notice': sdk.getComponent('messages.TextualBody'),
|
'm.notice': sdk.getComponent('messages.TextualBody'),
|
||||||
'm.emote': sdk.getComponent('messages.TextualBody'),
|
'm.emote': sdk.getComponent('messages.TextualBody'),
|
||||||
'm.image': sdk.getComponent('messages.MImageBody'),
|
'm.image': sdk.getComponent('messages.MImageBody'),
|
||||||
'm.file': sdk.getComponent('messages.MFileBody'),
|
'm.file': sdk.getComponent('messages.MFileBody'),
|
||||||
'm.audio': sdk.getComponent('messages.MAudioBody'),
|
'm.audio': sdk.getComponent('messages.MAudioBody'),
|
||||||
'm.video': sdk.getComponent('messages.MVideoBody')
|
'm.video': sdk.getComponent('messages.MVideoBody'),
|
||||||
};
|
};
|
||||||
|
|
||||||
var content = this.props.mxEvent.getContent();
|
const content = this.props.mxEvent.getContent();
|
||||||
var msgtype = content.msgtype;
|
const msgtype = content.msgtype;
|
||||||
var BodyType = UnknownBody;
|
let BodyType = UnknownBody;
|
||||||
if (msgtype && bodyTypes[msgtype]) {
|
if (msgtype && bodyTypes[msgtype]) {
|
||||||
BodyType = bodyTypes[msgtype];
|
BodyType = bodyTypes[msgtype];
|
||||||
} else if (content.url) {
|
} else if (content.url) {
|
||||||
|
|
|
@ -31,9 +31,9 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onAvatarClick: function(name) {
|
onAvatarClick: function(name) {
|
||||||
var httpUrl = MatrixClientPeg.get().mxcUrlToHttp(this.props.mxEvent.getContent().url);
|
const httpUrl = MatrixClientPeg.get().mxcUrlToHttp(this.props.mxEvent.getContent().url);
|
||||||
var ImageView = sdk.getComponent("elements.ImageView");
|
const ImageView = sdk.getComponent("elements.ImageView");
|
||||||
var params = {
|
const params = {
|
||||||
src: httpUrl,
|
src: httpUrl,
|
||||||
name: name,
|
name: name,
|
||||||
};
|
};
|
||||||
|
@ -41,12 +41,12 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var ev = this.props.mxEvent;
|
const ev = this.props.mxEvent;
|
||||||
var senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||||
var BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
const BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
||||||
|
|
||||||
var room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
||||||
var name = _t('%(senderDisplayName)s changed the avatar for %(roomName)s', {
|
const name = _t('%(senderDisplayName)s changed the avatar for %(roomName)s', {
|
||||||
senderDisplayName: senderDisplayName,
|
senderDisplayName: senderDisplayName,
|
||||||
roomName: room ? room.name : '',
|
roomName: room ? room.name : '',
|
||||||
});
|
});
|
||||||
|
@ -59,12 +59,12 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = ContentRepo.getHttpUriForMxc(
|
const url = ContentRepo.getHttpUriForMxc(
|
||||||
MatrixClientPeg.get().getHomeserverUrl(),
|
MatrixClientPeg.get().getHomeserverUrl(),
|
||||||
ev.getContent().url,
|
ev.getContent().url,
|
||||||
Math.ceil(14 * window.devicePixelRatio),
|
Math.ceil(14 * window.devicePixelRatio),
|
||||||
Math.ceil(14 * window.devicePixelRatio),
|
Math.ceil(14 * window.devicePixelRatio),
|
||||||
'crop'
|
'crop',
|
||||||
);
|
);
|
||||||
|
|
||||||
// it sucks that _tJsx doesn't support normal _t substitutions :((
|
// it sucks that _tJsx doesn't support normal _t substitutions :((
|
||||||
|
@ -83,7 +83,7 @@ module.exports = React.createClass({
|
||||||
<BaseAvatar width={14} height={14} url={url}
|
<BaseAvatar width={14} height={14} url={url}
|
||||||
name={name} />
|
name={name} />
|
||||||
</AccessibleButton>,
|
</AccessibleButton>,
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -104,10 +104,10 @@ module.exports = React.createClass({
|
||||||
if (this._unmounted) return;
|
if (this._unmounted) return;
|
||||||
for (let i = 0; i < blocks.length; i++) {
|
for (let i = 0; i < blocks.length; i++) {
|
||||||
if (UserSettingsStore.getSyncedSetting("enableSyntaxHighlightLanguageDetection", false)) {
|
if (UserSettingsStore.getSyncedSetting("enableSyntaxHighlightLanguageDetection", false)) {
|
||||||
highlight.highlightBlock(blocks[i])
|
highlight.highlightBlock(blocks[i]);
|
||||||
} else {
|
} else {
|
||||||
// Only syntax highlight if there's a class starting with language-
|
// 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-');
|
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);
|
//console.log("calculateUrlPreview: ShowUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview);
|
||||||
|
|
||||||
if (this.props.showUrlPreview && !this.state.links.length) {
|
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) {
|
if (links.length) {
|
||||||
// de-dup the links (but preserve ordering)
|
// de-dup the links (but preserve ordering)
|
||||||
const seen = new Set();
|
const seen = new Set();
|
||||||
|
@ -160,7 +160,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// lazy-load the hidden state of the preview widget from localstorage
|
// lazy-load the hidden state of the preview widget from localstorage
|
||||||
if (global.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 });
|
this.setState({ widgetHidden: hidden });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,21 +197,18 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
findLinks: function(nodes) {
|
findLinks: function(nodes) {
|
||||||
var links = [];
|
let links = [];
|
||||||
|
|
||||||
for (var i = 0; i < nodes.length; i++) {
|
for (let i = 0; i < nodes.length; i++) {
|
||||||
var node = nodes[i];
|
const node = nodes[i];
|
||||||
if (node.tagName === "A" && node.getAttribute("href"))
|
if (node.tagName === "A" && node.getAttribute("href")) {
|
||||||
{
|
|
||||||
if (this.isLinkPreviewable(node)) {
|
if (this.isLinkPreviewable(node)) {
|
||||||
links.push(node.getAttribute("href"));
|
links.push(node.getAttribute("href"));
|
||||||
}
|
}
|
||||||
}
|
} else if (node.tagName === "PRE" || node.tagName === "CODE" ||
|
||||||
else if (node.tagName === "PRE" || node.tagName === "CODE" ||
|
|
||||||
node.tagName === "BLOCKQUOTE") {
|
node.tagName === "BLOCKQUOTE") {
|
||||||
continue;
|
continue;
|
||||||
}
|
} else if (node.children && node.children.length) {
|
||||||
else if (node.children && node.children.length) {
|
|
||||||
links = links.concat(this.findLinks(node.children));
|
links = links.concat(this.findLinks(node.children));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,8 +218,7 @@ module.exports = React.createClass({
|
||||||
isLinkPreviewable: function(node) {
|
isLinkPreviewable: function(node) {
|
||||||
// don't try to preview relative links
|
// don't try to preview relative links
|
||||||
if (!node.getAttribute("href").startsWith("http://") &&
|
if (!node.getAttribute("href").startsWith("http://") &&
|
||||||
!node.getAttribute("href").startsWith("https://"))
|
!node.getAttribute("href").startsWith("https://")) {
|
||||||
{
|
|
||||||
return false;
|
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
|
// 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.
|
// link, in which case we check the target text differs from the link value.
|
||||||
// TODO: make this configurable?
|
// TODO: make this configurable?
|
||||||
if (node.textContent.indexOf("/") > -1)
|
if (node.textContent.indexOf("/") > -1) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
else {
|
const url = node.getAttribute("href");
|
||||||
var url = node.getAttribute("href");
|
const host = url.match(/^https?:\/\/(.*?)(\/|$)/)[1];
|
||||||
var host = url.match(/^https?:\/\/(.*?)(\/|$)/)[1];
|
|
||||||
|
|
||||||
// never preview matrix.to links (if anything we should give a smart
|
// 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
|
// 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())) {
|
if (node.textContent.toLowerCase().trim().startsWith(host.toLowerCase())) {
|
||||||
// it's a "foo.pl" style link
|
// it's a "foo.pl" style link
|
||||||
return false;
|
return false;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// it's a [foo bar](http://foo.com) style link
|
// it's a [foo bar](http://foo.com) style link
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -314,7 +307,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
getInnerText: () => {
|
getInnerText: () => {
|
||||||
return this.refs.content.innerText;
|
return this.refs.content.innerText;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -328,11 +321,11 @@ module.exports = React.createClass({
|
||||||
// the window.open command occurs in the same stack frame as the onClick callback.
|
// the window.open command occurs in the same stack frame as the onClick callback.
|
||||||
|
|
||||||
// Go fetch a scalar token
|
// Go fetch a scalar token
|
||||||
let scalarClient = new ScalarAuthClient();
|
const scalarClient = new ScalarAuthClient();
|
||||||
scalarClient.connect().then(() => {
|
scalarClient.connect().then(() => {
|
||||||
let completeUrl = scalarClient.getStarterLink(starterLink);
|
const completeUrl = scalarClient.getStarterLink(starterLink);
|
||||||
let QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||||
let integrationsUrl = SdkConfig.get().integrations_ui_url;
|
const integrationsUrl = SdkConfig.get().integrations_ui_url;
|
||||||
Modal.createTrackedDialog('Add an integration', '', QuestionDialog, {
|
Modal.createTrackedDialog('Add an integration', '', QuestionDialog, {
|
||||||
title: _t("Add an Integration"),
|
title: _t("Add an Integration"),
|
||||||
description:
|
description:
|
||||||
|
@ -346,10 +339,10 @@ module.exports = React.createClass({
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let width = window.screen.width > 1024 ? 1024 : window.screen.width;
|
const width = window.screen.width > 1024 ? 1024 : window.screen.width;
|
||||||
let height = window.screen.height > 800 ? 800 : window.screen.height;
|
const height = window.screen.height > 800 ? 800 : window.screen.height;
|
||||||
let left = (window.screen.width - width) / 2;
|
const left = (window.screen.width - width) / 2;
|
||||||
let top = (window.screen.height - height) / 2;
|
const top = (window.screen.height - height) / 2;
|
||||||
window.open(completeUrl, '_blank', `height=${height}, width=${width}, top=${top}, left=${left},`);
|
window.open(completeUrl, '_blank', `height=${height}, width=${width}, top=${top}, left=${left},`);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -358,21 +351,20 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||||
var mxEvent = this.props.mxEvent;
|
const mxEvent = this.props.mxEvent;
|
||||||
var content = mxEvent.getContent();
|
const content = mxEvent.getContent();
|
||||||
|
|
||||||
var body = HtmlUtils.bodyToHtml(content, this.props.highlights, {});
|
let body = HtmlUtils.bodyToHtml(content, this.props.highlights, {});
|
||||||
|
|
||||||
if (this.props.highlightLink) {
|
if (this.props.highlightLink) {
|
||||||
body = <a href={this.props.highlightLink}>{ body }</a>;
|
body = <a href={this.props.highlightLink}>{ body }</a>;
|
||||||
}
|
} else if (content.data && typeof content.data["org.matrix.neb.starter_link"] === "string") {
|
||||||
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="#" 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) {
|
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)=>{
|
widgets = this.state.links.map((link)=>{
|
||||||
return <LinkPreviewWidget
|
return <LinkPreviewWidget
|
||||||
key={link}
|
key={link}
|
||||||
|
|
|
@ -16,9 +16,9 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
|
|
||||||
var TextForEvent = require('../../../TextForEvent');
|
const TextForEvent = require('../../../TextForEvent');
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
|
@ -31,7 +31,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
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;
|
if (text == null || text.length === 0) return null;
|
||||||
return (
|
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';
|
import Promise from 'bluebird';
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var ObjectUtils = require("../../../ObjectUtils");
|
const ObjectUtils = require("../../../ObjectUtils");
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
var sdk = require("../../../index");
|
const sdk = require("../../../index");
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
var Modal = require("../../../Modal");
|
const Modal = require("../../../Modal");
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'AliasSettings',
|
displayName: 'AliasSettings',
|
||||||
|
@ -30,14 +30,14 @@ module.exports = React.createClass({
|
||||||
canSetCanonicalAlias: React.PropTypes.bool.isRequired,
|
canSetCanonicalAlias: React.PropTypes.bool.isRequired,
|
||||||
canSetAliases: React.PropTypes.bool.isRequired,
|
canSetAliases: React.PropTypes.bool.isRequired,
|
||||||
aliasEvents: React.PropTypes.array, // [MatrixEvent]
|
aliasEvents: React.PropTypes.array, // [MatrixEvent]
|
||||||
canonicalAliasEvent: React.PropTypes.object // MatrixEvent
|
canonicalAliasEvent: React.PropTypes.object, // MatrixEvent
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
return {
|
return {
|
||||||
canSetAliases: false,
|
canSetAliases: false,
|
||||||
canSetCanonicalAlias: false,
|
canSetCanonicalAlias: false,
|
||||||
aliasEvents: []
|
aliasEvents: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -48,12 +48,12 @@ module.exports = React.createClass({
|
||||||
recalculateState: function(aliasEvents, canonicalAliasEvent) {
|
recalculateState: function(aliasEvents, canonicalAliasEvent) {
|
||||||
aliasEvents = aliasEvents || [];
|
aliasEvents = aliasEvents || [];
|
||||||
|
|
||||||
var state = {
|
const state = {
|
||||||
domainToAliases: {}, // { domain.com => [#alias1:domain.com, #alias2:domain.com] }
|
domainToAliases: {}, // { domain.com => [#alias1:domain.com, #alias2:domain.com] }
|
||||||
remoteDomains: [], // [ domain.com, foobar.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);
|
state.domainToAliases = this.aliasEventsToDictionary(aliasEvents);
|
||||||
|
|
||||||
|
@ -69,26 +69,26 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
saveSettings: function() {
|
saveSettings: function() {
|
||||||
var promises = [];
|
let promises = [];
|
||||||
|
|
||||||
// save new aliases for m.room.aliases
|
// save new aliases for m.room.aliases
|
||||||
var aliasOperations = this.getAliasOperations();
|
const aliasOperations = this.getAliasOperations();
|
||||||
for (var i = 0; i < aliasOperations.length; i++) {
|
for (let i = 0; i < aliasOperations.length; i++) {
|
||||||
var alias_operation = aliasOperations[i];
|
const alias_operation = aliasOperations[i];
|
||||||
console.log("alias %s %s", alias_operation.place, alias_operation.val);
|
console.log("alias %s %s", alias_operation.place, alias_operation.val);
|
||||||
switch (alias_operation.place) {
|
switch (alias_operation.place) {
|
||||||
case 'add':
|
case 'add':
|
||||||
promises.push(
|
promises.push(
|
||||||
MatrixClientPeg.get().createAlias(
|
MatrixClientPeg.get().createAlias(
|
||||||
alias_operation.val, this.props.roomId
|
alias_operation.val, this.props.roomId,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 'del':
|
case 'del':
|
||||||
promises.push(
|
promises.push(
|
||||||
MatrixClientPeg.get().deleteAlias(
|
MatrixClientPeg.get().deleteAlias(
|
||||||
alias_operation.val
|
alias_operation.val,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -98,7 +98,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
|
|
||||||
// save new canonical alias
|
// save new canonical alias
|
||||||
var oldCanonicalAlias = null;
|
let oldCanonicalAlias = null;
|
||||||
if (this.props.canonicalAliasEvent) {
|
if (this.props.canonicalAliasEvent) {
|
||||||
oldCanonicalAlias = this.props.canonicalAliasEvent.getContent().alias;
|
oldCanonicalAlias = this.props.canonicalAliasEvent.getContent().alias;
|
||||||
}
|
}
|
||||||
|
@ -107,9 +107,9 @@ module.exports = React.createClass({
|
||||||
promises = [Promise.all(promises).then(
|
promises = [Promise.all(promises).then(
|
||||||
MatrixClientPeg.get().sendStateEvent(
|
MatrixClientPeg.get().sendStateEvent(
|
||||||
this.props.roomId, "m.room.canonical_alias", {
|
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
|
aliasEventsToDictionary: function(aliasEvents) { // m.room.alias events
|
||||||
var dict = {};
|
const dict = {};
|
||||||
aliasEvents.forEach((event) => {
|
aliasEvents.forEach((event) => {
|
||||||
dict[event.getStateKey()] = (
|
dict[event.getStateKey()] = (
|
||||||
(event.getContent().aliases || []).slice() // shallow-copy
|
(event.getContent().aliases || []).slice() // shallow-copy
|
||||||
|
@ -132,7 +132,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
getAliasOperations: function() {
|
getAliasOperations: function() {
|
||||||
var oldAliases = this.aliasEventsToDictionary(this.props.aliasEvents);
|
const oldAliases = this.aliasEventsToDictionary(this.props.aliasEvents);
|
||||||
return ObjectUtils.getKeyValueArrayDiffs(oldAliases, this.state.domainToAliases);
|
return ObjectUtils.getKeyValueArrayDiffs(oldAliases, this.state.domainToAliases);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -191,17 +191,17 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
onCanonicalAliasChange: function(event) {
|
onCanonicalAliasChange: function(event) {
|
||||||
this.setState({
|
this.setState({
|
||||||
canonicalAlias: event.target.value
|
canonicalAlias: event.target.value,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var self = this;
|
const self = this;
|
||||||
var EditableText = sdk.getComponent("elements.EditableText");
|
const EditableText = sdk.getComponent("elements.EditableText");
|
||||||
var EditableItemList = sdk.getComponent("elements.EditableItemList");
|
const EditableItemList = sdk.getComponent("elements.EditableItemList");
|
||||||
var localDomain = MatrixClientPeg.get().getDomain();
|
const localDomain = MatrixClientPeg.get().getDomain();
|
||||||
|
|
||||||
var canonical_alias_section;
|
let canonical_alias_section;
|
||||||
if (this.props.canSetCanonicalAlias) {
|
if (this.props.canSetCanonicalAlias) {
|
||||||
canonical_alias_section = (
|
canonical_alias_section = (
|
||||||
<select onChange={this.onCanonicalAliasChange} defaultValue={this.state.canonicalAlias}>
|
<select onChange={this.onCanonicalAliasChange} defaultValue={this.state.canonicalAlias}>
|
||||||
|
@ -219,14 +219,13 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
canonical_alias_section = (
|
canonical_alias_section = (
|
||||||
<b>{ this.state.canonicalAlias || _t('not set') }</b>
|
<b>{ this.state.canonicalAlias || _t('not set') }</b>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var remote_aliases_section;
|
let remote_aliases_section;
|
||||||
if (this.state.remoteDomains.length) {
|
if (this.state.remoteDomains.length) {
|
||||||
remote_aliases_section = (
|
remote_aliases_section = (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -14,16 +14,16 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
import Promise from 'bluebird';
|
import Promise from 'bluebird';
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
|
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
var Tinter = require('../../../Tinter');
|
const Tinter = require('../../../Tinter');
|
||||||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
const MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||||
var Modal = require("../../../Modal");
|
const Modal = require("../../../Modal");
|
||||||
|
|
||||||
import dis from '../../../dispatcher';
|
import dis from '../../../dispatcher';
|
||||||
|
|
||||||
var ROOM_COLORS = [
|
const ROOM_COLORS = [
|
||||||
// magic room default values courtesy of Ribot
|
// magic room default values courtesy of Ribot
|
||||||
["#76cfa6", "#eaf5f0"],
|
["#76cfa6", "#eaf5f0"],
|
||||||
["#81bddb", "#eaf1f4"],
|
["#81bddb", "#eaf1f4"],
|
||||||
|
@ -41,21 +41,21 @@ module.exports = React.createClass({
|
||||||
displayName: 'ColorSettings',
|
displayName: 'ColorSettings',
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
room: React.PropTypes.object.isRequired
|
room: React.PropTypes.object.isRequired,
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
var data = {
|
const data = {
|
||||||
index: 0,
|
index: 0,
|
||||||
primary_color: ROOM_COLORS[0].primary_color,
|
primary_color: ROOM_COLORS[0].primary_color,
|
||||||
secondary_color: ROOM_COLORS[0].secondary_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) {
|
if (!event) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
var scheme = event.getContent();
|
const scheme = event.getContent();
|
||||||
data.primary_color = scheme.primary_color;
|
data.primary_color = scheme.primary_color;
|
||||||
data.secondary_color = scheme.secondary_color;
|
data.secondary_color = scheme.secondary_color;
|
||||||
data.index = this._getColorIndex(data);
|
data.index = this._getColorIndex(data);
|
||||||
|
@ -64,7 +64,7 @@ module.exports = React.createClass({
|
||||||
// append the unrecognised colours to our palette
|
// append the unrecognised colours to our palette
|
||||||
data.index = ROOM_COLORS.length;
|
data.index = ROOM_COLORS.length;
|
||||||
ROOM_COLORS.push([
|
ROOM_COLORS.push([
|
||||||
scheme.primary_color, scheme.secondary_color
|
scheme.primary_color, scheme.secondary_color,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
|
@ -74,7 +74,7 @@ module.exports = React.createClass({
|
||||||
if (!this.state.hasChanged) {
|
if (!this.state.hasChanged) {
|
||||||
return Promise.resolve(); // They didn't explicitly give a color to save.
|
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 ||
|
if (originalState.primary_color !== this.state.primary_color ||
|
||||||
originalState.secondary_color !== this.state.secondary_color) {
|
originalState.secondary_color !== this.state.secondary_color) {
|
||||||
console.log("ColorSettings: Saving new color");
|
console.log("ColorSettings: Saving new color");
|
||||||
|
@ -84,8 +84,8 @@ module.exports = React.createClass({
|
||||||
return MatrixClientPeg.get().setRoomAccountData(
|
return MatrixClientPeg.get().setRoomAccountData(
|
||||||
this.props.room.roomId, "org.matrix.room.color_scheme", {
|
this.props.room.roomId, "org.matrix.room.color_scheme", {
|
||||||
primary_color: this.state.primary_color,
|
primary_color: this.state.primary_color,
|
||||||
secondary_color: this.state.secondary_color
|
secondary_color: this.state.secondary_color,
|
||||||
}
|
},
|
||||||
).catch(function(err) {
|
).catch(function(err) {
|
||||||
if (err.errcode == 'M_GUEST_ACCESS_FORBIDDEN') {
|
if (err.errcode == 'M_GUEST_ACCESS_FORBIDDEN') {
|
||||||
dis.dispatch({action: 'view_set_mxid'});
|
dis.dispatch({action: 'view_set_mxid'});
|
||||||
|
@ -100,8 +100,8 @@ module.exports = React.createClass({
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// XXX: we should validate these values
|
// XXX: we should validate these values
|
||||||
for (var i = 0; i < ROOM_COLORS.length; i++) {
|
for (let i = 0; i < ROOM_COLORS.length; i++) {
|
||||||
var room_color = ROOM_COLORS[i];
|
const room_color = ROOM_COLORS[i];
|
||||||
if (room_color[0] === String(scheme.primary_color).toLowerCase() &&
|
if (room_color[0] === String(scheme.primary_color).toLowerCase() &&
|
||||||
room_color[1] === String(scheme.secondary_color).toLowerCase()) {
|
room_color[1] === String(scheme.secondary_color).toLowerCase()) {
|
||||||
return i;
|
return i;
|
||||||
|
@ -117,7 +117,7 @@ module.exports = React.createClass({
|
||||||
index: index,
|
index: index,
|
||||||
primary_color: ROOM_COLORS[index][0],
|
primary_color: ROOM_COLORS[index][0],
|
||||||
secondary_color: ROOM_COLORS[index][1],
|
secondary_color: ROOM_COLORS[index][1],
|
||||||
hasChanged: true
|
hasChanged: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ module.exports = React.createClass({
|
||||||
return (
|
return (
|
||||||
<div className="mx_RoomSettings_roomColors">
|
<div className="mx_RoomSettings_roomColors">
|
||||||
{ ROOM_COLORS.map((room_color, i) => {
|
{ ROOM_COLORS.map((room_color, i) => {
|
||||||
var selected;
|
let selected;
|
||||||
if (i === this.state.index) {
|
if (i === this.state.index) {
|
||||||
selected = (
|
selected = (
|
||||||
<div className="mx_RoomSettings_roomColor_selected">
|
<div className="mx_RoomSettings_roomColor_selected">
|
||||||
|
@ -133,7 +133,7 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
var boundClick = this._onColorSchemeChanged.bind(this, i);
|
const boundClick = this._onColorSchemeChanged.bind(this, i);
|
||||||
return (
|
return (
|
||||||
<div className="mx_RoomSettings_roomColor"
|
<div className="mx_RoomSettings_roomColor"
|
||||||
key={"room_color_" + i}
|
key={"room_color_" + i}
|
||||||
|
@ -146,5 +146,5 @@ module.exports = React.createClass({
|
||||||
}) }
|
}) }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,11 +15,11 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Promise from 'bluebird';
|
import Promise from 'bluebird';
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
var sdk = require("../../../index");
|
const sdk = require("../../../index");
|
||||||
var Modal = require("../../../Modal");
|
const Modal = require("../../../Modal");
|
||||||
var UserSettingsStore = require('../../../UserSettingsStore');
|
const UserSettingsStore = require('../../../UserSettingsStore');
|
||||||
import { _t, _tJsx } from '../../../languageHandler';
|
import { _t, _tJsx } from '../../../languageHandler';
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,11 +31,11 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
var cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
var roomState = this.props.room.currentState;
|
const roomState = this.props.room.currentState;
|
||||||
|
|
||||||
var roomPreviewUrls = this.props.room.currentState.getStateEvents('org.matrix.room.preview_urls', '');
|
const roomPreviewUrls = this.props.room.currentState.getStateEvents('org.matrix.room.preview_urls', '');
|
||||||
var userPreviewUrls = this.props.room.getAccountData("org.matrix.room.preview_urls");
|
const userPreviewUrls = this.props.room.getAccountData("org.matrix.room.preview_urls");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
globalDisableUrlPreview: (roomPreviewUrls && roomPreviewUrls.getContent().disable) || false,
|
globalDisableUrlPreview: (roomPreviewUrls && roomPreviewUrls.getContent().disable) || false,
|
||||||
|
@ -49,20 +49,20 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
saveSettings: function() {
|
saveSettings: function() {
|
||||||
var promises = [];
|
const promises = [];
|
||||||
|
|
||||||
if (this.state.globalDisableUrlPreview !== this.originalState.globalDisableUrlPreview) {
|
if (this.state.globalDisableUrlPreview !== this.originalState.globalDisableUrlPreview) {
|
||||||
console.log("UrlPreviewSettings: Updating room's preview_urls state event");
|
console.log("UrlPreviewSettings: Updating room's preview_urls state event");
|
||||||
promises.push(
|
promises.push(
|
||||||
MatrixClientPeg.get().sendStateEvent(
|
MatrixClientPeg.get().sendStateEvent(
|
||||||
this.props.room.roomId, "org.matrix.room.preview_urls", {
|
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) {
|
if (this.state.userDisableUrlPreview !== this.originalState.userDisableUrlPreview) {
|
||||||
console.log("UrlPreviewSettings: Disabling user's per-room preview_urls");
|
console.log("UrlPreviewSettings: Disabling user's per-room preview_urls");
|
||||||
content = this.state.userDisableUrlPreview ? { disable: true } : {};
|
content = this.state.userDisableUrlPreview ? { disable: true } : {};
|
||||||
|
@ -78,8 +78,8 @@ module.exports = React.createClass({
|
||||||
if (content) {
|
if (content) {
|
||||||
promises.push(
|
promises.push(
|
||||||
MatrixClientPeg.get().setRoomAccountData(
|
MatrixClientPeg.get().setRoomAccountData(
|
||||||
this.props.room.roomId, "org.matrix.room.preview_urls", content
|
this.props.room.roomId, "org.matrix.room.preview_urls", content,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,12 +109,12 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var self = this;
|
const self = this;
|
||||||
var roomState = this.props.room.currentState;
|
const roomState = this.props.room.currentState;
|
||||||
var cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
|
|
||||||
var maySetRoomPreviewUrls = roomState.mayClientSendStateEvent('org.matrix.room.preview_urls', cli);
|
const maySetRoomPreviewUrls = roomState.mayClientSendStateEvent('org.matrix.room.preview_urls', cli);
|
||||||
var disableRoomPreviewUrls;
|
let disableRoomPreviewUrls;
|
||||||
if (maySetRoomPreviewUrls) {
|
if (maySetRoomPreviewUrls) {
|
||||||
disableRoomPreviewUrls =
|
disableRoomPreviewUrls =
|
||||||
<label>
|
<label>
|
||||||
|
@ -123,8 +123,7 @@ module.exports = React.createClass({
|
||||||
checked={this.state.globalDisableUrlPreview} />
|
checked={this.state.globalDisableUrlPreview} />
|
||||||
{ _t("Disable URL previews by default for participants in this room") }
|
{ _t("Disable URL previews by default for participants in this room") }
|
||||||
</label>;
|
</label>;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
disableRoomPreviewUrls =
|
disableRoomPreviewUrls =
|
||||||
<label>
|
<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")}) }
|
||||||
|
@ -136,8 +135,7 @@ module.exports = React.createClass({
|
||||||
urlPreviewText = (
|
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 = (
|
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>)
|
||||||
);
|
);
|
||||||
|
@ -165,6 +163,5 @@ module.exports = React.createClass({
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
},
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -105,7 +105,7 @@ module.exports = React.createClass({
|
||||||
[
|
[
|
||||||
(sub) => <a onClick={(event)=>{ this.onConferenceNotificationClick(event, 'voice');}} 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>,
|
(sub) => <a onClick={(event)=>{ this.onConferenceNotificationClick(event, 'video');}} href="#">{ sub }</a>,
|
||||||
]
|
],
|
||||||
) }
|
) }
|
||||||
</span>);
|
</span>);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,18 +16,18 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
|
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
|
|
||||||
var PRESENCE_CLASS = {
|
const PRESENCE_CLASS = {
|
||||||
"offline": "mx_EntityTile_offline",
|
"offline": "mx_EntityTile_offline",
|
||||||
"online": "mx_EntityTile_online",
|
"online": "mx_EntityTile_online",
|
||||||
"unavailable": "mx_EntityTile_unavailable"
|
"unavailable": "mx_EntityTile_unavailable",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ module.exports = React.createClass({
|
||||||
showInviteButton: React.PropTypes.bool,
|
showInviteButton: React.PropTypes.bool,
|
||||||
shouldComponentUpdate: React.PropTypes.func,
|
shouldComponentUpdate: React.PropTypes.func,
|
||||||
onClick: React.PropTypes.func,
|
onClick: React.PropTypes.func,
|
||||||
suppressOnHover: React.PropTypes.bool
|
suppressOnHover: React.PropTypes.bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
|
@ -73,13 +73,13 @@ module.exports = React.createClass({
|
||||||
presenceLastActiveAgo: 0,
|
presenceLastActiveAgo: 0,
|
||||||
presenceLastTs: 0,
|
presenceLastTs: 0,
|
||||||
showInviteButton: false,
|
showInviteButton: false,
|
||||||
suppressOnHover: false
|
suppressOnHover: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
hover: false
|
hover: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -98,21 +98,21 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const presenceClass = presenceClassForMember(
|
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) : "");
|
mainClassName += presenceClass + (this.props.className ? (" " + this.props.className) : "");
|
||||||
var nameEl;
|
let nameEl;
|
||||||
const {name} = this.props;
|
const {name} = this.props;
|
||||||
|
|
||||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||||
if (this.state.hover && !this.props.suppressOnHover) {
|
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;
|
(Date.now() - (this.props.presenceLastTs - this.props.presenceLastActiveAgo)) : -1;
|
||||||
|
|
||||||
mainClassName += " mx_EntityTile_hover";
|
mainClassName += " mx_EntityTile_hover";
|
||||||
var PresenceLabel = sdk.getComponent("rooms.PresenceLabel");
|
const PresenceLabel = sdk.getComponent("rooms.PresenceLabel");
|
||||||
nameEl = (
|
nameEl = (
|
||||||
<div className="mx_EntityTile_details">
|
<div className="mx_EntityTile_details">
|
||||||
<img className="mx_EntityTile_chevron" src="img/member_chevron.png" width="8" height="12" />
|
<img className="mx_EntityTile_chevron" src="img/member_chevron.png" width="8" height="12" />
|
||||||
|
@ -122,14 +122,13 @@ module.exports = React.createClass({
|
||||||
presenceState={this.props.presenceState} />
|
presenceState={this.props.presenceState} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
nameEl = (
|
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) {
|
if (this.props.showInviteButton) {
|
||||||
inviteButton = (
|
inviteButton = (
|
||||||
<div className="mx_EntityTile_invite">
|
<div className="mx_EntityTile_invite">
|
||||||
|
@ -138,8 +137,8 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var power;
|
let power;
|
||||||
var powerLevel = this.props.powerLevel;
|
const powerLevel = this.props.powerLevel;
|
||||||
if (powerLevel >= 50 && powerLevel < 99) {
|
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")} />;
|
||||||
}
|
}
|
||||||
|
@ -148,10 +147,10 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||||
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
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 (
|
return (
|
||||||
<AccessibleButton className={mainClassName} title={this.props.title}
|
<AccessibleButton className={mainClassName} title={this.props.title}
|
||||||
|
@ -165,5 +164,5 @@ module.exports = React.createClass({
|
||||||
{ inviteButton }
|
{ inviteButton }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,21 +17,21 @@ limitations under the License.
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var classNames = require("classnames");
|
const classNames = require("classnames");
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
var Modal = require('../../../Modal');
|
const Modal = require('../../../Modal');
|
||||||
|
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
var TextForEvent = require('../../../TextForEvent');
|
const TextForEvent = require('../../../TextForEvent');
|
||||||
import withMatrixClient from '../../../wrappers/withMatrixClient';
|
import withMatrixClient from '../../../wrappers/withMatrixClient';
|
||||||
|
|
||||||
var ContextualMenu = require('../../structures/ContextualMenu');
|
const ContextualMenu = require('../../structures/ContextualMenu');
|
||||||
import dis from '../../../dispatcher';
|
import dis from '../../../dispatcher';
|
||||||
|
|
||||||
var ObjectUtils = require('../../../ObjectUtils');
|
const ObjectUtils = require('../../../ObjectUtils');
|
||||||
|
|
||||||
var eventTileTypes = {
|
const eventTileTypes = {
|
||||||
'm.room.message': 'messages.MessageEvent',
|
'm.room.message': 'messages.MessageEvent',
|
||||||
'm.room.member': 'messages.TextualEvent',
|
'm.room.member': 'messages.TextualEvent',
|
||||||
'm.call.invite': 'messages.TextualEvent',
|
'm.call.invite': 'messages.TextualEvent',
|
||||||
|
@ -48,7 +48,7 @@ var eventTileTypes = {
|
||||||
'im.vector.modular.widgets': '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:
|
// Our component structure for EventTiles on the timeline is:
|
||||||
//
|
//
|
||||||
|
@ -177,7 +177,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
var client = this.props.matrixClient;
|
const client = this.props.matrixClient;
|
||||||
client.removeListener("deviceVerificationChanged",
|
client.removeListener("deviceVerificationChanged",
|
||||||
this.onDeviceVerificationChanged);
|
this.onDeviceVerificationChanged);
|
||||||
this.props.mxEvent.removeListener("Event.decrypted", this._onDecrypted);
|
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);
|
const verified = await this.props.matrixClient.isEventSenderVerified(mxEvent);
|
||||||
this.setState({
|
this.setState({
|
||||||
verified: verified
|
verified: verified,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_propsEqual: function(objA, objB) {
|
_propsEqual: function(objA, objB) {
|
||||||
var keysA = Object.keys(objA);
|
const keysA = Object.keys(objA);
|
||||||
var keysB = Object.keys(objB);
|
const keysB = Object.keys(objB);
|
||||||
|
|
||||||
if (keysA.length !== keysB.length) {
|
if (keysA.length !== keysB.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < keysA.length; i++) {
|
for (let i = 0; i < keysA.length; i++) {
|
||||||
var key = keysA[i];
|
const key = keysA[i];
|
||||||
|
|
||||||
if (!objB.hasOwnProperty(key)) {
|
if (!objB.hasOwnProperty(key)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -225,8 +225,8 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
|
|
||||||
// need to deep-compare readReceipts
|
// need to deep-compare readReceipts
|
||||||
if (key == 'readReceipts') {
|
if (key == 'readReceipts') {
|
||||||
var rA = objA[key];
|
const rA = objA[key];
|
||||||
var rB = objB[key];
|
const rB = objB[key];
|
||||||
if (rA === rB) {
|
if (rA === rB) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
if (rA.length !== rB.length) {
|
if (rA.length !== rB.length) {
|
||||||
return false;
|
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) {
|
if (rA[j].roomMember.userId !== rB[j].roomMember.userId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -253,12 +253,11 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
shouldHighlight: function() {
|
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; }
|
if (!actions || !actions.tweaks) { return false; }
|
||||||
|
|
||||||
// don't show self-highlights from another of our clients
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,13 +265,13 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onEditClicked: function(e) {
|
onEditClicked: function(e) {
|
||||||
var MessageContextMenu = sdk.getComponent('context_menus.MessageContextMenu');
|
const MessageContextMenu = sdk.getComponent('context_menus.MessageContextMenu');
|
||||||
var buttonRect = e.target.getBoundingClientRect();
|
const buttonRect = e.target.getBoundingClientRect();
|
||||||
|
|
||||||
// The window X and Y offsets are to adjust position when zoomed in to page
|
// The window X and Y offsets are to adjust position when zoomed in to page
|
||||||
var x = buttonRect.right + window.pageXOffset;
|
const x = buttonRect.right + window.pageXOffset;
|
||||||
var y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19;
|
const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19;
|
||||||
var self = this;
|
const self = this;
|
||||||
ContextualMenu.createMenu(MessageContextMenu, {
|
ContextualMenu.createMenu(MessageContextMenu, {
|
||||||
chevronOffset: 10,
|
chevronOffset: 10,
|
||||||
mxEvent: this.props.mxEvent,
|
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,
|
eventTileOps: this.refs.tile && this.refs.tile.getEventTileOps ? this.refs.tile.getEventTileOps() : undefined,
|
||||||
onFinished: function() {
|
onFinished: function() {
|
||||||
self.setState({menu: false});
|
self.setState({menu: false});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
this.setState({menu: true});
|
this.setState({menu: true});
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleAllReadAvatars: function() {
|
toggleAllReadAvatars: function() {
|
||||||
this.setState({
|
this.setState({
|
||||||
allReadAvatars: !this.state.allReadAvatars
|
allReadAvatars: !this.state.allReadAvatars,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getReadAvatars: function() {
|
getReadAvatars: function() {
|
||||||
|
|
||||||
// return early if there are no read receipts
|
// return early if there are no read receipts
|
||||||
if (!this.props.readReceipts || this.props.readReceipts.length === 0) {
|
if (!this.props.readReceipts || this.props.readReceipts.length === 0) {
|
||||||
return (<span className="mx_EventTile_readAvatars"></span>);
|
return (<span className="mx_EventTile_readAvatars"></span>);
|
||||||
|
@ -304,11 +302,11 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
const receiptOffset = 15;
|
const receiptOffset = 15;
|
||||||
let left = 0;
|
let left = 0;
|
||||||
|
|
||||||
var receipts = this.props.readReceipts || [];
|
const receipts = this.props.readReceipts || [];
|
||||||
for (var i = 0; i < receipts.length; ++i) {
|
for (let i = 0; i < receipts.length; ++i) {
|
||||||
var receipt = receipts[i];
|
const receipt = receipts[i];
|
||||||
|
|
||||||
var hidden = true;
|
let hidden = true;
|
||||||
if ((i < MAX_READ_AVATARS) || this.state.allReadAvatars) {
|
if ((i < MAX_READ_AVATARS) || this.state.allReadAvatars) {
|
||||||
hidden = false;
|
hidden = false;
|
||||||
}
|
}
|
||||||
|
@ -319,7 +317,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
// else set it proportional to index
|
// else set it proportional to index
|
||||||
left = (hidden ? MAX_READ_AVATARS - 1 : i) * -receiptOffset;
|
left = (hidden ? MAX_READ_AVATARS - 1 : i) * -receiptOffset;
|
||||||
|
|
||||||
var userId = receipt.roomMember.userId;
|
const userId = receipt.roomMember.userId;
|
||||||
var readReceiptInfo;
|
var readReceiptInfo;
|
||||||
|
|
||||||
if (this.props.readReceiptMap) {
|
if (this.props.readReceiptMap) {
|
||||||
|
@ -340,12 +338,12 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
onClick={this.toggleAllReadAvatars}
|
onClick={this.toggleAllReadAvatars}
|
||||||
timestamp={receipt.ts}
|
timestamp={receipt.ts}
|
||||||
showTwelveHour={this.props.isTwelveHour}
|
showTwelveHour={this.props.isTwelveHour}
|
||||||
/>
|
/>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
var remText;
|
let remText;
|
||||||
if (!this.state.allReadAvatars) {
|
if (!this.state.allReadAvatars) {
|
||||||
var remainder = receipts.length - MAX_READ_AVATARS;
|
const remainder = receipts.length - MAX_READ_AVATARS;
|
||||||
if (remainder > 0) {
|
if (remainder > 0) {
|
||||||
remText = <span className="mx_EventTile_readAvatarRemainder"
|
remText = <span className="mx_EventTile_readAvatarRemainder"
|
||||||
onClick={this.toggleAllReadAvatars}
|
onClick={this.toggleAllReadAvatars}
|
||||||
|
@ -369,7 +367,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onCryptoClicked: function(e) {
|
onCryptoClicked: function(e) {
|
||||||
var event = this.props.mxEvent;
|
const event = this.props.mxEvent;
|
||||||
|
|
||||||
Modal.createTrackedDialogAsync('Encrypted Event Dialog', '', (cb) => {
|
Modal.createTrackedDialogAsync('Encrypted Event Dialog', '', (cb) => {
|
||||||
require(['../../../async-components/views/dialogs/EncryptedEventDialog'], cb);
|
require(['../../../async-components/views/dialogs/EncryptedEventDialog'], cb);
|
||||||
|
@ -421,27 +419,27 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var MessageTimestamp = sdk.getComponent('messages.MessageTimestamp');
|
const MessageTimestamp = sdk.getComponent('messages.MessageTimestamp');
|
||||||
var SenderProfile = sdk.getComponent('messages.SenderProfile');
|
const SenderProfile = sdk.getComponent('messages.SenderProfile');
|
||||||
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||||
|
|
||||||
//console.log("EventTile showUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview);
|
//console.log("EventTile showUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview);
|
||||||
|
|
||||||
var content = this.props.mxEvent.getContent();
|
const content = this.props.mxEvent.getContent();
|
||||||
var msgtype = content.msgtype;
|
const msgtype = content.msgtype;
|
||||||
var eventType = this.props.mxEvent.getType();
|
const eventType = this.props.mxEvent.getType();
|
||||||
|
|
||||||
// Info messages are basically information about commands processed on a room
|
// 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
|
// This shouldn't happen: the caller should check we support this type
|
||||||
// before trying to instantiate us
|
// before trying to instantiate us
|
||||||
if (!EventTileType) {
|
if (!EventTileType) {
|
||||||
throw new Error("Event type not supported");
|
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 isRedacted = (eventType === 'm.room.message') && this.props.isRedacted;
|
||||||
|
|
||||||
const classes = classNames({
|
const classes = classNames({
|
||||||
|
@ -468,9 +466,9 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
this.props.mxEvent.getRoomId() + "/" +
|
this.props.mxEvent.getRoomId() + "/" +
|
||||||
this.props.mxEvent.getId();
|
this.props.mxEvent.getId();
|
||||||
|
|
||||||
var readAvatars = this.getReadAvatars();
|
const readAvatars = this.getReadAvatars();
|
||||||
|
|
||||||
var avatar, sender;
|
let avatar, sender;
|
||||||
let avatarSize;
|
let avatarSize;
|
||||||
let needsSenderProfile;
|
let needsSenderProfile;
|
||||||
|
|
||||||
|
@ -509,8 +507,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
else if (msgtype === 'm.video') aux = _t('sent a video');
|
else if (msgtype === 'm.video') aux = _t('sent a video');
|
||||||
else if (msgtype === 'm.file') aux = _t('uploaded a file');
|
else if (msgtype === 'm.file') aux = _t('uploaded a file');
|
||||||
sender = <SenderProfile onClick={this.onSenderProfileClick} mxEvent={this.props.mxEvent} enableFlair={!aux} aux={aux} />;
|
sender = <SenderProfile onClick={this.onSenderProfileClick} mxEvent={this.props.mxEvent} enableFlair={!aux} aux={aux} />;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
sender = <SenderProfile mxEvent={this.props.mxEvent} enableFlair={true} />;
|
sender = <SenderProfile mxEvent={this.props.mxEvent} enableFlair={true} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -548,8 +545,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
} else if (this.props.tileShape === "file_grid") {
|
||||||
else if (this.props.tileShape === "file_grid") {
|
|
||||||
return (
|
return (
|
||||||
<div className={classes}>
|
<div className={classes}>
|
||||||
<div className="mx_EventTile_line" >
|
<div className="mx_EventTile_line" >
|
||||||
|
@ -573,8 +569,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return (
|
return (
|
||||||
<div className={classes}>
|
<div className={classes}>
|
||||||
<div className="mx_EventTile_msgOption">
|
<div className="mx_EventTile_msgOption">
|
||||||
|
|
|
@ -16,16 +16,16 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
|
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
var ImageUtils = require('../../../ImageUtils');
|
const ImageUtils = require('../../../ImageUtils');
|
||||||
var Modal = require('../../../Modal');
|
const Modal = require('../../../Modal');
|
||||||
|
|
||||||
var linkify = require('linkifyjs');
|
const linkify = require('linkifyjs');
|
||||||
var linkifyElement = require('linkifyjs/element');
|
const linkifyElement = require('linkifyjs/element');
|
||||||
var linkifyMatrix = require('../../../linkify-matrix');
|
const linkifyMatrix = require('../../../linkify-matrix');
|
||||||
linkifyMatrix(linkify);
|
linkifyMatrix(linkify);
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
|
@ -40,7 +40,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
preview: null
|
preview: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
this.setState(
|
this.setState(
|
||||||
{ preview: res },
|
{ preview: res },
|
||||||
this.props.onWidgetLoad
|
this.props.onWidgetLoad,
|
||||||
);
|
);
|
||||||
}, (error)=>{
|
}, (error)=>{
|
||||||
console.error("Failed to get preview for " + this.props.link + " " + error);
|
console.error("Failed to get preview for " + this.props.link + " " + error);
|
||||||
|
@ -76,17 +76,17 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onImageClick: function(ev) {
|
onImageClick: function(ev) {
|
||||||
var p = this.state.preview;
|
const p = this.state.preview;
|
||||||
if (ev.button != 0 || ev.metaKey) return;
|
if (ev.button != 0 || ev.metaKey) return;
|
||||||
ev.preventDefault();
|
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://")) {
|
if (src && src.startsWith("mxc://")) {
|
||||||
src = MatrixClientPeg.get().mxcUrlToHttp(src);
|
src = MatrixClientPeg.get().mxcUrlToHttp(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
var params = {
|
const params = {
|
||||||
src: src,
|
src: src,
|
||||||
width: p["og:image:width"],
|
width: p["og:image:width"],
|
||||||
height: p["og:image:height"],
|
height: p["og:image:height"],
|
||||||
|
@ -99,24 +99,24 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var p = this.state.preview;
|
const p = this.state.preview;
|
||||||
if (!p || Object.keys(p).length === 0) {
|
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?
|
// FIXME: do we want to factor out all image displaying between this and MImageBody - especially for lightboxing?
|
||||||
var image = p["og:image"];
|
let image = p["og:image"];
|
||||||
var imageMaxWidth = 100, imageMaxHeight = 100;
|
let imageMaxWidth = 100, imageMaxHeight = 100;
|
||||||
if (image && image.startsWith("mxc://")) {
|
if (image && image.startsWith("mxc://")) {
|
||||||
image = MatrixClientPeg.get().mxcUrlToHttp(image, imageMaxWidth, imageMaxHeight);
|
image = MatrixClientPeg.get().mxcUrlToHttp(image, imageMaxWidth, imageMaxHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
var thumbHeight = imageMaxHeight;
|
let thumbHeight = imageMaxHeight;
|
||||||
if (p["og:image:width"] && p["og:image:height"]) {
|
if (p["og:image:width"] && p["og:image:height"]) {
|
||||||
thumbHeight = ImageUtils.thumbHeight(p["og:image:width"], p["og:image:height"], imageMaxWidth, imageMaxHeight);
|
thumbHeight = ImageUtils.thumbHeight(p["og:image:width"], p["og:image:height"], imageMaxWidth, imageMaxHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
var img;
|
let img;
|
||||||
if (image) {
|
if (image) {
|
||||||
img = <div className="mx_LinkPreviewWidget_image" style={{ height: thumbHeight }}>
|
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} />
|
||||||
|
@ -137,5 +137,5 @@ module.exports = React.createClass({
|
||||||
onClick={this.props.onCancelClick} />
|
onClick={this.props.onCancelClick} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,8 +20,8 @@ import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
export default class MemberDeviceInfo extends React.Component {
|
export default class MemberDeviceInfo extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
var indicator = null;
|
let indicator = null;
|
||||||
var DeviceVerifyButtons = sdk.getComponent('elements.DeviceVerifyButtons');
|
const DeviceVerifyButtons = sdk.getComponent('elements.DeviceVerifyButtons');
|
||||||
|
|
||||||
if (this.props.device.isBlocked()) {
|
if (this.props.device.isBlocked()) {
|
||||||
indicator = (
|
indicator = (
|
||||||
|
@ -43,7 +43,7 @@ export default class MemberDeviceInfo extends React.Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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() ? this.props.device.getDisplayName() : "") + " (" + this.props.device.deviceId + ")" :
|
||||||
this.props.device.getDisplayName();
|
this.props.device.getDisplayName();
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
kick: false,
|
kick: false,
|
||||||
ban: false,
|
ban: false,
|
||||||
mute: false,
|
mute: false,
|
||||||
modifyLevel: false
|
modifyLevel: false,
|
||||||
},
|
},
|
||||||
muted: false,
|
muted: false,
|
||||||
isTargetMod: false,
|
isTargetMod: false,
|
||||||
|
@ -97,7 +97,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
var client = this.props.matrixClient;
|
const client = this.props.matrixClient;
|
||||||
if (client) {
|
if (client) {
|
||||||
client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
|
client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
|
||||||
client.removeListener("Room", this.onRoom);
|
client.removeListener("Room", this.onRoom);
|
||||||
|
@ -120,10 +120,10 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_disambiguateDevices: function(devices) {
|
_disambiguateDevices: function(devices) {
|
||||||
var names = Object.create(null);
|
const names = Object.create(null);
|
||||||
for (var i = 0; i < devices.length; i++) {
|
for (let i = 0; i < devices.length; i++) {
|
||||||
var name = devices[i].getDisplayName();
|
var name = devices[i].getDisplayName();
|
||||||
var indexList = names[name] || [];
|
const indexList = names[name] || [];
|
||||||
indexList.push(i);
|
indexList.push(i);
|
||||||
names[name] = indexList;
|
names[name] = indexList;
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateStateForNewMember: function(member) {
|
_updateStateForNewMember: function(member) {
|
||||||
var newState = this._calculateOpsPermissions(member);
|
const newState = this._calculateOpsPermissions(member);
|
||||||
newState.devicesLoading = true;
|
newState.devicesLoading = true;
|
||||||
newState.devices = null;
|
newState.devices = null;
|
||||||
this.setState(newState);
|
this.setState(newState);
|
||||||
|
@ -211,11 +211,11 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cancelled = false;
|
let cancelled = false;
|
||||||
this._cancelDeviceList = function() { cancelled = true; };
|
this._cancelDeviceList = function() { cancelled = true; };
|
||||||
|
|
||||||
var client = this.props.matrixClient;
|
const client = this.props.matrixClient;
|
||||||
var self = this;
|
const self = this;
|
||||||
client.downloadKeys([member.userId], true).then(() => {
|
client.downloadKeys([member.userId], true).then(() => {
|
||||||
return client.getStoredDevicesForUser(member.userId);
|
return client.getStoredDevicesForUser(member.userId);
|
||||||
}).finally(function() {
|
}).finally(function() {
|
||||||
|
@ -260,7 +260,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
this.setState({ updating: this.state.updating + 1 });
|
this.setState({ updating: this.state.updating + 1 });
|
||||||
this.props.matrixClient.kick(
|
this.props.matrixClient.kick(
|
||||||
this.props.member.roomId, this.props.member.userId,
|
this.props.member.roomId, this.props.member.userId,
|
||||||
reason || undefined
|
reason || undefined,
|
||||||
).then(function() {
|
).then(function() {
|
||||||
// NO-OP; rely on the m.room.member event coming down else we could
|
// NO-OP; rely on the m.room.member event coming down else we could
|
||||||
// get out of sync if we force setState here!
|
// get out of sync if we force setState here!
|
||||||
|
@ -272,11 +272,11 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
title: _t("Failed to kick"),
|
title: _t("Failed to kick"),
|
||||||
description: ((err && err.message) ? err.message : "Operation failed"),
|
description: ((err && err.message) ? err.message : "Operation failed"),
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
).finally(()=>{
|
).finally(()=>{
|
||||||
this.setState({ updating: this.state.updating - 1 });
|
this.setState({ updating: this.state.updating - 1 });
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
} else {
|
} else {
|
||||||
promise = this.props.matrixClient.ban(
|
promise = this.props.matrixClient.ban(
|
||||||
this.props.member.roomId, this.props.member.userId,
|
this.props.member.roomId, this.props.member.userId,
|
||||||
reason || undefined
|
reason || undefined,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
promise.then(
|
promise.then(
|
||||||
|
@ -314,7 +314,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
title: _t("Error"),
|
title: _t("Error"),
|
||||||
description: _t("Failed to ban user"),
|
description: _t("Failed to ban user"),
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
).finally(()=>{
|
).finally(()=>{
|
||||||
this.setState({ updating: this.state.updating - 1 });
|
this.setState({ updating: this.state.updating - 1 });
|
||||||
});
|
});
|
||||||
|
@ -323,30 +323,29 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onMuteToggle: function() {
|
onMuteToggle: function() {
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
var roomId = this.props.member.roomId;
|
const roomId = this.props.member.roomId;
|
||||||
var target = this.props.member.userId;
|
const target = this.props.member.userId;
|
||||||
var room = this.props.matrixClient.getRoom(roomId);
|
const room = this.props.matrixClient.getRoom(roomId);
|
||||||
if (!room) {
|
if (!room) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var powerLevelEvent = room.currentState.getStateEvents(
|
const powerLevelEvent = room.currentState.getStateEvents(
|
||||||
"m.room.power_levels", ""
|
"m.room.power_levels", "",
|
||||||
);
|
);
|
||||||
if (!powerLevelEvent) {
|
if (!powerLevelEvent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var isMuted = this.state.muted;
|
const isMuted = this.state.muted;
|
||||||
var powerLevels = powerLevelEvent.getContent();
|
const powerLevels = powerLevelEvent.getContent();
|
||||||
var levelToSend = (
|
const levelToSend = (
|
||||||
(powerLevels.events ? powerLevels.events["m.room.message"] : null) ||
|
(powerLevels.events ? powerLevels.events["m.room.message"] : null) ||
|
||||||
powerLevels.events_default
|
powerLevels.events_default
|
||||||
);
|
);
|
||||||
var level;
|
let level;
|
||||||
if (isMuted) { // unmute
|
if (isMuted) { // unmute
|
||||||
level = levelToSend;
|
level = levelToSend;
|
||||||
}
|
} else { // mute
|
||||||
else { // mute
|
|
||||||
level = levelToSend - 1;
|
level = levelToSend - 1;
|
||||||
}
|
}
|
||||||
level = parseInt(level);
|
level = parseInt(level);
|
||||||
|
@ -364,7 +363,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
title: _t("Error"),
|
title: _t("Error"),
|
||||||
description: _t("Failed to mute user"),
|
description: _t("Failed to mute user"),
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
).finally(()=>{
|
).finally(()=>{
|
||||||
this.setState({ updating: this.state.updating - 1 });
|
this.setState({ updating: this.state.updating - 1 });
|
||||||
});
|
});
|
||||||
|
@ -372,28 +371,28 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onModToggle: function() {
|
onModToggle: function() {
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
var roomId = this.props.member.roomId;
|
const roomId = this.props.member.roomId;
|
||||||
var target = this.props.member.userId;
|
const target = this.props.member.userId;
|
||||||
var room = this.props.matrixClient.getRoom(roomId);
|
const room = this.props.matrixClient.getRoom(roomId);
|
||||||
if (!room) {
|
if (!room) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var powerLevelEvent = room.currentState.getStateEvents(
|
const powerLevelEvent = room.currentState.getStateEvents(
|
||||||
"m.room.power_levels", ""
|
"m.room.power_levels", "",
|
||||||
);
|
);
|
||||||
if (!powerLevelEvent) {
|
if (!powerLevelEvent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var me = room.getMember(this.props.matrixClient.credentials.userId);
|
const me = room.getMember(this.props.matrixClient.credentials.userId);
|
||||||
if (!me) {
|
if (!me) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var defaultLevel = powerLevelEvent.getContent().users_default;
|
const defaultLevel = powerLevelEvent.getContent().users_default;
|
||||||
var modLevel = me.powerLevel - 1;
|
let modLevel = me.powerLevel - 1;
|
||||||
if (modLevel > 50 && defaultLevel < 50) modLevel = 50; // try to stick with the vector level defaults
|
if (modLevel > 50 && defaultLevel < 50) modLevel = 50; // try to stick with the vector level defaults
|
||||||
// toggle the level
|
// 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.setState({ updating: this.state.updating + 1 });
|
||||||
this.props.matrixClient.setPowerLevel(roomId, target, parseInt(newLevel), powerLevelEvent).then(
|
this.props.matrixClient.setPowerLevel(roomId, target, parseInt(newLevel), powerLevelEvent).then(
|
||||||
function() {
|
function() {
|
||||||
|
@ -410,7 +409,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
description: _t("Failed to toggle moderator status"),
|
description: _t("Failed to toggle moderator status"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
).finally(()=>{
|
).finally(()=>{
|
||||||
this.setState({ updating: this.state.updating - 1 });
|
this.setState({ updating: this.state.updating - 1 });
|
||||||
});
|
});
|
||||||
|
@ -430,31 +429,31 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
title: _t("Error"),
|
title: _t("Error"),
|
||||||
description: _t("Failed to change power level"),
|
description: _t("Failed to change power level"),
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
).finally(()=>{
|
).finally(()=>{
|
||||||
this.setState({ updating: this.state.updating - 1 });
|
this.setState({ updating: this.state.updating - 1 });
|
||||||
}).done();
|
}).done();
|
||||||
},
|
},
|
||||||
|
|
||||||
onPowerChange: function(powerLevel) {
|
onPowerChange: function(powerLevel) {
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
var roomId = this.props.member.roomId;
|
const roomId = this.props.member.roomId;
|
||||||
var target = this.props.member.userId;
|
const target = this.props.member.userId;
|
||||||
var room = this.props.matrixClient.getRoom(roomId);
|
const room = this.props.matrixClient.getRoom(roomId);
|
||||||
var self = this;
|
const self = this;
|
||||||
if (!room) {
|
if (!room) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var powerLevelEvent = room.currentState.getStateEvents(
|
const powerLevelEvent = room.currentState.getStateEvents(
|
||||||
"m.room.power_levels", ""
|
"m.room.power_levels", "",
|
||||||
);
|
);
|
||||||
if (!powerLevelEvent) {
|
if (!powerLevelEvent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (powerLevelEvent.getContent().users) {
|
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)) {
|
if (parseInt(myPower) === parseInt(powerLevel)) {
|
||||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||||
Modal.createTrackedDialog('Promote to PL100 Warning', '', QuestionDialog, {
|
Modal.createTrackedDialog('Promote to PL100 Warning', '', QuestionDialog, {
|
||||||
title: _t("Warning!"),
|
title: _t("Warning!"),
|
||||||
description:
|
description:
|
||||||
|
@ -469,12 +468,10 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this._applyPowerChange(roomId, target, powerLevel, powerLevelEvent);
|
this._applyPowerChange(roomId, target, powerLevel, powerLevelEvent);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this._applyPowerChange(roomId, target, powerLevel, powerLevelEvent);
|
this._applyPowerChange(roomId, target, powerLevel, powerLevelEvent);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -497,14 +494,14 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
const defaultPerms = {
|
const defaultPerms = {
|
||||||
can: {},
|
can: {},
|
||||||
muted: false,
|
muted: false,
|
||||||
modifyLevel: false
|
modifyLevel: false,
|
||||||
};
|
};
|
||||||
const room = this.props.matrixClient.getRoom(member.roomId);
|
const room = this.props.matrixClient.getRoom(member.roomId);
|
||||||
if (!room) {
|
if (!room) {
|
||||||
return defaultPerms;
|
return defaultPerms;
|
||||||
}
|
}
|
||||||
const powerLevels = room.currentState.getStateEvents(
|
const powerLevels = room.currentState.getStateEvents(
|
||||||
"m.room.power_levels", ""
|
"m.room.power_levels", "",
|
||||||
);
|
);
|
||||||
if (!powerLevels) {
|
if (!powerLevels) {
|
||||||
return defaultPerms;
|
return defaultPerms;
|
||||||
|
@ -516,10 +513,10 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
const them = member;
|
const them = member;
|
||||||
return {
|
return {
|
||||||
can: this._calculateCanPermissions(
|
can: this._calculateCanPermissions(
|
||||||
me, them, powerLevels.getContent()
|
me, them, powerLevels.getContent(),
|
||||||
),
|
),
|
||||||
muted: this._isMuted(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,
|
kick: false,
|
||||||
ban: false,
|
ban: false,
|
||||||
mute: false,
|
mute: false,
|
||||||
modifyLevel: false
|
modifyLevel: false,
|
||||||
};
|
};
|
||||||
const canAffectUser = them.powerLevel < me.powerLevel;
|
const canAffectUser = them.powerLevel < me.powerLevel;
|
||||||
if (!canAffectUser) {
|
if (!canAffectUser) {
|
||||||
|
@ -556,7 +553,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
if (!powerLevelContent || !member) {
|
if (!powerLevelContent || !member) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var levelToSend = (
|
const levelToSend = (
|
||||||
(powerLevelContent.events ? powerLevelContent.events["m.room.message"] : null) ||
|
(powerLevelContent.events ? powerLevelContent.events["m.room.message"] : null) ||
|
||||||
powerLevelContent.events_default
|
powerLevelContent.events_default
|
||||||
);
|
);
|
||||||
|
@ -566,19 +563,19 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
onCancel: function(e) {
|
onCancel: function(e) {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: "view_user",
|
action: "view_user",
|
||||||
member: null
|
member: null,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onMemberAvatarClick: function() {
|
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;
|
if(!avatarUrl) return;
|
||||||
|
|
||||||
var httpUrl = this.props.matrixClient.mxcUrlToHttp(avatarUrl);
|
const httpUrl = this.props.matrixClient.mxcUrlToHttp(avatarUrl);
|
||||||
var ImageView = sdk.getComponent("elements.ImageView");
|
const ImageView = sdk.getComponent("elements.ImageView");
|
||||||
var params = {
|
const params = {
|
||||||
src: httpUrl,
|
src: httpUrl,
|
||||||
name: this.props.member.name
|
name: this.props.member.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
Modal.createDialog(ImageView, params, "mx_Dialog_lightbox");
|
Modal.createDialog(ImageView, params, "mx_Dialog_lightbox");
|
||||||
|
@ -596,11 +593,11 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var devices = this.state.devices;
|
const devices = this.state.devices;
|
||||||
var MemberDeviceInfo = sdk.getComponent('rooms.MemberDeviceInfo');
|
const MemberDeviceInfo = sdk.getComponent('rooms.MemberDeviceInfo');
|
||||||
var Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
|
|
||||||
var devComponents;
|
let devComponents;
|
||||||
if (this.state.devicesLoading) {
|
if (this.state.devicesLoading) {
|
||||||
// still loading
|
// still loading
|
||||||
devComponents = <Spinner />;
|
devComponents = <Spinner />;
|
||||||
|
@ -610,7 +607,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
devComponents = _t("No devices with registered encryption keys");
|
devComponents = _t("No devices with registered encryption keys");
|
||||||
} else {
|
} else {
|
||||||
devComponents = [];
|
devComponents = [];
|
||||||
for (var i = 0; i < devices.length; i++) {
|
for (let i = 0; i < devices.length; i++) {
|
||||||
devComponents.push(<MemberDeviceInfo key={i}
|
devComponents.push(<MemberDeviceInfo key={i}
|
||||||
userId={this.props.member.userId}
|
userId={this.props.member.userId}
|
||||||
device={devices[i]} />);
|
device={devices[i]} />);
|
||||||
|
@ -651,7 +648,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
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) {
|
if (this.props.member.userId !== this.props.matrixClient.credentials.userId) {
|
||||||
const dmRoomMap = new DMRoomMap(this.props.matrixClient);
|
const dmRoomMap = new DMRoomMap(this.props.matrixClient);
|
||||||
const dmRooms = dmRoomMap.getDMRoomsForUserId(this.props.member.userId);
|
const dmRooms = dmRoomMap.getDMRoomsForUserId(this.props.member.userId);
|
||||||
|
@ -675,7 +672,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
highlight={highlight}
|
highlight={highlight}
|
||||||
isInvite={me.membership == "invite"}
|
isInvite={me.membership == "invite"}
|
||||||
onClick={this.onRoomTileClick}
|
onClick={this.onRoomTileClick}
|
||||||
/>
|
/>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -702,7 +699,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state.updating) {
|
if (this.state.updating) {
|
||||||
var Loader = sdk.getComponent("elements.Spinner");
|
const Loader = sdk.getComponent("elements.Spinner");
|
||||||
spinner = <Loader imgClassName="mx_ContextualMenu_spinner" />;
|
spinner = <Loader imgClassName="mx_ContextualMenu_spinner" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,7 +735,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (this.state.can.toggleMod) {
|
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}>
|
giveModButton = <AccessibleButton className="mx_MemberInfo_field" onClick={this.onModToggle}>
|
||||||
{ giveOpLabel }
|
{ giveOpLabel }
|
||||||
</AccessibleButton>;
|
</AccessibleButton>;
|
||||||
|
@ -747,7 +744,7 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
// TODO: we should have an invite button if this MemberInfo is showing a user who isn't actually in the current room yet
|
// 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
|
// e.g. clicking on a linkified userid in a room
|
||||||
|
|
||||||
var adminTools;
|
let adminTools;
|
||||||
if (kickButton || banButton || muteButton || giveModButton) {
|
if (kickButton || banButton || muteButton || giveModButton) {
|
||||||
adminTools =
|
adminTools =
|
||||||
<div>
|
<div>
|
||||||
|
@ -767,13 +764,13 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
if (this.props.member.user) {
|
if (this.props.member.user) {
|
||||||
var presenceState = this.props.member.user.presence;
|
var presenceState = this.props.member.user.presence;
|
||||||
var presenceLastActiveAgo = this.props.member.user.lastActiveAgo;
|
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 presenceCurrentlyActive = this.props.member.user.currentlyActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||||
var PowerSelector = sdk.getComponent('elements.PowerSelector');
|
const PowerSelector = sdk.getComponent('elements.PowerSelector');
|
||||||
var PresenceLabel = sdk.getComponent('rooms.PresenceLabel');
|
const PresenceLabel = sdk.getComponent('rooms.PresenceLabel');
|
||||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||||
return (
|
return (
|
||||||
<div className="mx_MemberInfo">
|
<div className="mx_MemberInfo">
|
||||||
|
@ -811,5 +808,5 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
</GeminiScrollbar>
|
</GeminiScrollbar>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -18,11 +18,11 @@ limitations under the License.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
const MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
var GeminiScrollbar = require('react-gemini-scrollbar');
|
const GeminiScrollbar = require('react-gemini-scrollbar');
|
||||||
var rate_limited_func = require('../../../ratelimitedfunc');
|
const rate_limited_func = require('../../../ratelimitedfunc');
|
||||||
var CallHandler = require("../../../CallHandler");
|
const CallHandler = require("../../../CallHandler");
|
||||||
|
|
||||||
const INITIAL_LOAD_NUM_MEMBERS = 30;
|
const INITIAL_LOAD_NUM_MEMBERS = 30;
|
||||||
const INITIAL_LOAD_NUM_INVITED = 5;
|
const INITIAL_LOAD_NUM_INVITED = 5;
|
||||||
|
@ -49,7 +49,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
var cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
cli.on("RoomState.members", this.onRoomStateMember);
|
cli.on("RoomState.members", this.onRoomStateMember);
|
||||||
cli.on("RoomMember.name", this.onRoomMemberName);
|
cli.on("RoomMember.name", this.onRoomMemberName);
|
||||||
cli.on("RoomState.events", this.onRoomStateEvent);
|
cli.on("RoomState.events", this.onRoomStateEvent);
|
||||||
|
@ -62,7 +62,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
var cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
if (cli) {
|
if (cli) {
|
||||||
cli.removeListener("RoomState.members", this.onRoomStateMember);
|
cli.removeListener("RoomState.members", this.onRoomStateMember);
|
||||||
cli.removeListener("RoomMember.name", this.onRoomMemberName);
|
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
|
// member tile and re-render it. This is more efficient than every tile
|
||||||
// evar attaching their own listener.
|
// evar attaching their own listener.
|
||||||
// console.log("explicit presence from " + user.userId);
|
// console.log("explicit presence from " + user.userId);
|
||||||
var tile = this.refs[user.userId];
|
const tile = this.refs[user.userId];
|
||||||
if (tile) {
|
if (tile) {
|
||||||
this._updateList(); // reorder the membership list
|
this._updateList(); // reorder the membership list
|
||||||
}
|
}
|
||||||
|
@ -153,11 +153,11 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
getMemberDict: function() {
|
getMemberDict: function() {
|
||||||
if (!this.props.roomId) return {};
|
if (!this.props.roomId) return {};
|
||||||
var cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
var room = cli.getRoom(this.props.roomId);
|
const room = cli.getRoom(this.props.roomId);
|
||||||
if (!room) return {};
|
if (!room) return {};
|
||||||
|
|
||||||
var all_members = room.currentState.members;
|
const all_members = room.currentState.members;
|
||||||
|
|
||||||
Object.keys(all_members).map(function(userId) {
|
Object.keys(all_members).map(function(userId) {
|
||||||
// work around a race where you might have a room member object
|
// work around a race where you might have a room member object
|
||||||
|
@ -175,17 +175,17 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
roomMembers: function() {
|
roomMembers: function() {
|
||||||
var all_members = this.memberDict || {};
|
const all_members = this.memberDict || {};
|
||||||
var all_user_ids = Object.keys(all_members);
|
const all_user_ids = Object.keys(all_members);
|
||||||
var ConferenceHandler = CallHandler.getConferenceHandler();
|
const ConferenceHandler = CallHandler.getConferenceHandler();
|
||||||
|
|
||||||
all_user_ids.sort(this.memberSort);
|
all_user_ids.sort(this.memberSort);
|
||||||
|
|
||||||
var to_display = [];
|
const to_display = [];
|
||||||
var count = 0;
|
let count = 0;
|
||||||
for (var i = 0; i < all_user_ids.length; ++i) {
|
for (let i = 0; i < all_user_ids.length; ++i) {
|
||||||
var user_id = all_user_ids[i];
|
const user_id = all_user_ids[i];
|
||||||
var m = all_members[user_id];
|
const m = all_members[user_id];
|
||||||
|
|
||||||
if (m.membership == 'join' || m.membership == 'invite') {
|
if (m.membership == 'join' || m.membership == 'invite') {
|
||||||
if ((ConferenceHandler && !ConferenceHandler.isConferenceUser(user_id)) || !ConferenceHandler) {
|
if ((ConferenceHandler && !ConferenceHandler.isConferenceUser(user_id)) || !ConferenceHandler) {
|
||||||
|
@ -233,8 +233,7 @@ module.exports = React.createClass({
|
||||||
memberString: function(member) {
|
memberString: function(member) {
|
||||||
if (!member) {
|
if (!member) {
|
||||||
return "(null)";
|
return "(null)";
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return "(" + member.name + ", " + member.powerLevel + ", " + member.user.lastActiveAgo + ", " + member.user.currentlyActive + ")";
|
return "(" + member.name + ", " + member.powerLevel + ", " + member.user.lastActiveAgo + ", " + member.user.currentlyActive + ")";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -248,10 +247,10 @@ module.exports = React.createClass({
|
||||||
// ...and then alphabetically.
|
// ...and then alphabetically.
|
||||||
// We could tiebreak instead by "last recently spoken in this room" if we wanted to.
|
// We could tiebreak instead by "last recently spoken in this room" if we wanted to.
|
||||||
|
|
||||||
var memberA = this.memberDict[userIdA];
|
const memberA = this.memberDict[userIdA];
|
||||||
var memberB = this.memberDict[userIdB];
|
const memberB = this.memberDict[userIdB];
|
||||||
var userA = memberA.user;
|
const userA = memberA.user;
|
||||||
var userB = memberB.user;
|
const userB = memberB.user;
|
||||||
|
|
||||||
// if (!userA || !userB) {
|
// if (!userA || !userB) {
|
||||||
// console.log("comparing " + memberA.name + " user=" + memberA.user + " with " + memberB.name + " user=" + memberB.user);
|
// 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");
|
// console.log(memberA + " and " + memberB + " have same power level");
|
||||||
if (memberA.name && memberB.name) {
|
if (memberA.name && memberB.name) {
|
||||||
// console.log("comparing names: " + memberA.name + " and " + memberB.name);
|
// console.log("comparing names: " + memberA.name + " and " + memberB.name);
|
||||||
var nameA = memberA.name[0] === '@' ? memberA.name.substr(1) : memberA.name;
|
const nameA = memberA.name[0] === '@' ? memberA.name.substr(1) : memberA.name;
|
||||||
var nameB = memberB.name[0] === '@' ? memberB.name.substr(1) : memberB.name;
|
const nameB = memberB.name[0] === '@' ? memberB.name.substr(1) : memberB.name;
|
||||||
return nameA.localeCompare(nameB);
|
return nameA.localeCompare(nameB);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// console.log("comparing power: " + memberA.powerLevel + " and " + memberB.powerLevel);
|
// console.log("comparing power: " + memberA.powerLevel + " and " + memberB.powerLevel);
|
||||||
return memberB.powerLevel - memberA.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
|
// 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
|
// we shouldn't add them if the 3pid invite state key (token) is in the
|
||||||
// member invite (content.third_party_invite.signed.token)
|
// member invite (content.third_party_invite.signed.token)
|
||||||
var room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
||||||
var EntityTile = sdk.getComponent("rooms.EntityTile");
|
const EntityTile = sdk.getComponent("rooms.EntityTile");
|
||||||
if (room) {
|
if (room) {
|
||||||
room.currentState.getStateEvents("m.room.third_party_invite").forEach(
|
room.currentState.getStateEvents("m.room.third_party_invite").forEach(
|
||||||
function(e) {
|
function(e) {
|
||||||
// any events without these keys are not valid 3pid invites, so we ignore them
|
// any events without these keys are not valid 3pid invites, so we ignore them
|
||||||
var required_keys = ['key_validity_url', 'public_key', 'display_name'];
|
const required_keys = ['key_validity_url', 'public_key', 'display_name'];
|
||||||
for (var i = 0; i < required_keys.length; ++i) {
|
for (let i = 0; i < required_keys.length; ++i) {
|
||||||
if (e.getContent()[required_keys[i]] === undefined) return;
|
if (e.getContent()[required_keys[i]] === undefined) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// discard all invites which have a m.room.member event since we've
|
// discard all invites which have a m.room.member event since we've
|
||||||
// already added them.
|
// already added them.
|
||||||
var memberEvent = room.currentState.getInviteForThreePidToken(e.getStateKey());
|
const memberEvent = room.currentState.getInviteForThreePidToken(e.getStateKey());
|
||||||
if (memberEvent) {
|
if (memberEvent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memberList.push(
|
memberList.push(
|
||||||
<EntityTile key={e.getStateKey()} name={e.getContent().display_name} suppressOnHover={true} />
|
<EntityTile key={e.getStateKey()} name={e.getContent().display_name} suppressOnHover={true} />,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -419,5 +416,5 @@ module.exports = React.createClass({
|
||||||
</GeminiScrollbar>
|
</GeminiScrollbar>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,12 +16,12 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
|
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
var dis = require('../../../dispatcher');
|
const dis = require('../../../dispatcher');
|
||||||
var Modal = require("../../../Modal");
|
const Modal = require("../../../Modal");
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
|
@ -68,16 +68,16 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||||
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||||
var EntityTile = sdk.getComponent('rooms.EntityTile');
|
const EntityTile = sdk.getComponent('rooms.EntityTile');
|
||||||
|
|
||||||
var member = this.props.member;
|
const member = this.props.member;
|
||||||
var name = this._getDisplayName();
|
const name = this._getDisplayName();
|
||||||
var active = -1;
|
const active = -1;
|
||||||
var presenceState = member.user ? member.user.presence : null;
|
const presenceState = member.user ? member.user.presence : null;
|
||||||
|
|
||||||
var av = (
|
const av = (
|
||||||
<MemberAvatar member={member} width={36} height={36} />
|
<MemberAvatar member={member} width={36} height={36} />
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -94,5 +94,5 @@ module.exports = React.createClass({
|
||||||
avatarJsx={av} title={this.getPowerLabel()} onClick={this.onClick}
|
avatarJsx={av} title={this.getPowerLabel()} onClick={this.onClick}
|
||||||
name={name} powerLevel={this.props.member.powerLevel} />
|
name={name} powerLevel={this.props.member.powerLevel} />
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -89,10 +89,10 @@ export default class MessageComposer extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadFiles(files) {
|
uploadFiles(files) {
|
||||||
let QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||||
let TintableSvg = sdk.getComponent("elements.TintableSvg");
|
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||||
|
|
||||||
let fileList = [];
|
const fileList = [];
|
||||||
for (let i=0; i<files.length; i++) {
|
for (let i=0; i<files.length; i++) {
|
||||||
fileList.push(<li key={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') }
|
||||||
|
|
|
@ -286,7 +286,7 @@ export default class MessageComposerInput extends React.Component {
|
||||||
/// XXX: Not doing rich-text quoting from formatted-body because draft-js
|
/// XXX: Not doing rich-text quoting from formatted-body because draft-js
|
||||||
/// has regressed such that when links are quoted, errors are thrown. See
|
/// has regressed such that when links are quoted, errors are thrown. See
|
||||||
/// https://github.com/vector-im/riot-web/issues/4756.
|
/// https://github.com/vector-im/riot-web/issues/4756.
|
||||||
let body = escape(payload.text);
|
const body = escape(payload.text);
|
||||||
if (body) {
|
if (body) {
|
||||||
let content = RichText.htmlToContentState(`<blockquote>${body}</blockquote>`);
|
let content = RichText.htmlToContentState(`<blockquote>${body}</blockquote>`);
|
||||||
if (!this.state.isRichtextEnabled) {
|
if (!this.state.isRichtextEnabled) {
|
||||||
|
@ -464,7 +464,7 @@ export default class MessageComposerInput extends React.Component {
|
||||||
// autocomplete will probably have different completions to show.
|
// autocomplete will probably have different completions to show.
|
||||||
if (
|
if (
|
||||||
!state.editorState.getSelection().equals(
|
!state.editorState.getSelection().equals(
|
||||||
this.state.editorState.getSelection()
|
this.state.editorState.getSelection(),
|
||||||
)
|
)
|
||||||
&& state.editorState.getCurrentContent().getPlainText() ===
|
&& state.editorState.getCurrentContent().getPlainText() ===
|
||||||
this.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 = EditorState.forceSelection(editorState,
|
||||||
editorState.getSelection());
|
editorState.getSelection());
|
||||||
this.setState({editorState});
|
this.setState({editorState});
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,23 +34,23 @@ module.exports = React.createClass({
|
||||||
currentlyActive: React.PropTypes.bool,
|
currentlyActive: React.PropTypes.bool,
|
||||||
|
|
||||||
// offline, online, etc
|
// offline, online, etc
|
||||||
presenceState: React.PropTypes.string
|
presenceState: React.PropTypes.string,
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
return {
|
return {
|
||||||
ago: -1,
|
ago: -1,
|
||||||
presenceState: null
|
presenceState: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
getDuration: function(time) {
|
getDuration: function(time) {
|
||||||
if (!time) return;
|
if (!time) return;
|
||||||
var t = parseInt(time / 1000);
|
const t = parseInt(time / 1000);
|
||||||
var s = t % 60;
|
const s = t % 60;
|
||||||
var m = parseInt(t / 60) % 60;
|
const m = parseInt(t / 60) % 60;
|
||||||
var h = parseInt(t / (60 * 60)) % 24;
|
const h = parseInt(t / (60 * 60)) % 24;
|
||||||
var d = parseInt(t / (60 * 60 * 24));
|
const d = parseInt(t / (60 * 60 * 24));
|
||||||
if (t < 60) {
|
if (t < 60) {
|
||||||
if (t < 0) {
|
if (t < 0) {
|
||||||
return _t("for %(amount)ss", {amount: 0});
|
return _t("for %(amount)ss", {amount: 0});
|
||||||
|
@ -75,20 +75,19 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
if (this.props.activeAgo >= 0) {
|
if (this.props.activeAgo >= 0) {
|
||||||
let duration = this.getDuration(this.props.activeAgo);
|
const duration = this.getDuration(this.props.activeAgo);
|
||||||
let ago = this.props.currentlyActive || !duration ? "" : duration;
|
const ago = this.props.currentlyActive || !duration ? "" : duration;
|
||||||
return (
|
return (
|
||||||
<div className="mx_PresenceLabel">
|
<div className="mx_PresenceLabel">
|
||||||
{ this.getPrettyPresence(this.props.presenceState) } { ago }
|
{ this.getPrettyPresence(this.props.presenceState) } { ago }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_PresenceLabel">
|
<div className="mx_PresenceLabel">
|
||||||
{ this.getPrettyPresence(this.props.presenceState) }
|
{ this.getPrettyPresence(this.props.presenceState) }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,18 +16,18 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var ReactDOM = require('react-dom');
|
const ReactDOM = require('react-dom');
|
||||||
|
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
|
|
||||||
var Velociraptor = require('../../../Velociraptor');
|
const Velociraptor = require('../../../Velociraptor');
|
||||||
require('../../../VelocityBounce');
|
require('../../../VelocityBounce');
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
import DateUtils from '../../../DateUtils';
|
import DateUtils from '../../../DateUtils';
|
||||||
|
|
||||||
var bounce = false;
|
let bounce = false;
|
||||||
try {
|
try {
|
||||||
if (global.localStorage) {
|
if (global.localStorage) {
|
||||||
bounce = global.localStorage.getItem('avatar_bounce') == 'true';
|
bounce = global.localStorage.getItem('avatar_bounce') == 'true';
|
||||||
|
@ -90,7 +90,7 @@ module.exports = React.createClass({
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
// before we remove the rr, store its location in the map, so that if
|
// before we remove the rr, store its location in the map, so that if
|
||||||
// it reappears, it can be animated from the right place.
|
// it reappears, it can be animated from the right place.
|
||||||
var rrInfo = this.props.readReceiptInfo;
|
const rrInfo = this.props.readReceiptInfo;
|
||||||
if (!rrInfo) {
|
if (!rrInfo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ module.exports = React.createClass({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var avatarNode = ReactDOM.findDOMNode(this);
|
const avatarNode = ReactDOM.findDOMNode(this);
|
||||||
rrInfo.top = avatarNode.offsetTop;
|
rrInfo.top = avatarNode.offsetTop;
|
||||||
rrInfo.left = avatarNode.offsetLeft;
|
rrInfo.left = avatarNode.offsetLeft;
|
||||||
rrInfo.parent = avatarNode.offsetParent;
|
rrInfo.parent = avatarNode.offsetParent;
|
||||||
|
@ -115,14 +115,14 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
// treat new RRs as though they were off the top of the screen
|
// treat new RRs as though they were off the top of the screen
|
||||||
var oldTop = -15;
|
let oldTop = -15;
|
||||||
|
|
||||||
var oldInfo = this.props.readReceiptInfo;
|
const oldInfo = this.props.readReceiptInfo;
|
||||||
if (oldInfo && oldInfo.parent) {
|
if (oldInfo && oldInfo.parent) {
|
||||||
oldTop = oldInfo.top + oldInfo.parent.getBoundingClientRect().top;
|
oldTop = oldInfo.top + oldInfo.parent.getBoundingClientRect().top;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newElement = ReactDOM.findDOMNode(this);
|
const newElement = ReactDOM.findDOMNode(this);
|
||||||
let startTopOffset;
|
let startTopOffset;
|
||||||
if (!newElement.offsetParent) {
|
if (!newElement.offsetParent) {
|
||||||
// this seems to happen sometimes for reasons I don't understand
|
// this seems to happen sometimes for reasons I don't understand
|
||||||
|
@ -137,8 +137,8 @@ module.exports = React.createClass({
|
||||||
startTopOffset = oldTop - newElement.offsetParent.getBoundingClientRect().top;
|
startTopOffset = oldTop - newElement.offsetParent.getBoundingClientRect().top;
|
||||||
}
|
}
|
||||||
|
|
||||||
var startStyles = [];
|
const startStyles = [];
|
||||||
var enterTransitionOpts = [];
|
const enterTransitionOpts = [];
|
||||||
|
|
||||||
if (oldInfo && oldInfo.left) {
|
if (oldInfo && oldInfo.left) {
|
||||||
// start at the old height and in the old h pos
|
// start at the old height and in the old h pos
|
||||||
|
@ -146,7 +146,7 @@ module.exports = React.createClass({
|
||||||
startStyles.push({ top: startTopOffset+"px",
|
startStyles.push({ top: startTopOffset+"px",
|
||||||
left: oldInfo.left+"px" });
|
left: oldInfo.left+"px" });
|
||||||
|
|
||||||
var reorderTransitionOpts = {
|
const reorderTransitionOpts = {
|
||||||
duration: 100,
|
duration: 100,
|
||||||
easing: 'easeOut',
|
easing: 'easeOut',
|
||||||
};
|
};
|
||||||
|
@ -171,12 +171,12 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||||
if (this.state.suppressDisplay) {
|
if (this.state.suppressDisplay) {
|
||||||
return <div />;
|
return <div />;
|
||||||
}
|
}
|
||||||
|
|
||||||
var style = {
|
const style = {
|
||||||
left: this.props.leftOffset+'px',
|
left: this.props.leftOffset+'px',
|
||||||
top: '0px',
|
top: '0px',
|
||||||
visibility: this.props.hidden ? 'hidden' : 'visible',
|
visibility: this.props.hidden ? 'hidden' : 'visible',
|
||||||
|
|
|
@ -16,20 +16,20 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
var React = require("react");
|
const React = require("react");
|
||||||
var ReactDOM = require("react-dom");
|
const ReactDOM = require("react-dom");
|
||||||
import { _t, _tJsx } from '../../../languageHandler';
|
import { _t, _tJsx } from '../../../languageHandler';
|
||||||
var GeminiScrollbar = require('react-gemini-scrollbar');
|
const GeminiScrollbar = require('react-gemini-scrollbar');
|
||||||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
const MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||||
var CallHandler = require('../../../CallHandler');
|
const CallHandler = require('../../../CallHandler');
|
||||||
var RoomListSorter = require("../../../RoomListSorter");
|
const RoomListSorter = require("../../../RoomListSorter");
|
||||||
var Unread = require('../../../Unread');
|
const Unread = require('../../../Unread');
|
||||||
var dis = require("../../../dispatcher");
|
const dis = require("../../../dispatcher");
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
var rate_limited_func = require('../../../ratelimitedfunc');
|
const rate_limited_func = require('../../../ratelimitedfunc');
|
||||||
var Rooms = require('../../../Rooms');
|
const Rooms = require('../../../Rooms');
|
||||||
import DMRoomMap from '../../../utils/DMRoomMap';
|
import DMRoomMap from '../../../utils/DMRoomMap';
|
||||||
var Receipt = require('../../../utils/Receipt');
|
const Receipt = require('../../../utils/Receipt');
|
||||||
|
|
||||||
const HIDE_CONFERENCE_CHANS = true;
|
const HIDE_CONFERENCE_CHANS = true;
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ function phraseForSection(section) {
|
||||||
return _t('Drop here to tag %(section)s', {section: section});
|
return _t('Drop here to tag %(section)s', {section: section});
|
||||||
}
|
}
|
||||||
return _t('Drop here %(toAction)s', {toAction: verb});
|
return _t('Drop here %(toAction)s', {toAction: verb});
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'RoomList',
|
displayName: 'RoomList',
|
||||||
|
@ -78,7 +78,7 @@ module.exports = React.createClass({
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
this.mounted = false;
|
this.mounted = false;
|
||||||
|
|
||||||
var cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
cli.on("Room", this.onRoom);
|
cli.on("Room", this.onRoom);
|
||||||
cli.on("deleteRoom", this.onDeleteRoom);
|
cli.on("deleteRoom", this.onDeleteRoom);
|
||||||
cli.on("Room.timeline", this.onRoomTimeline);
|
cli.on("Room.timeline", this.onRoomTimeline);
|
||||||
|
@ -98,7 +98,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// loop count to stop a stack overflow if the user keeps waggling the
|
// loop count to stop a stack overflow if the user keeps waggling the
|
||||||
// mouse for >30s in a row, or if running under mocha
|
// mouse for >30s in a row, or if running under mocha
|
||||||
this._delayedRefreshRoomListLoopCount = 0
|
this._delayedRefreshRoomListLoopCount = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
@ -124,13 +124,12 @@ module.exports = React.createClass({
|
||||||
var call = CallHandler.getCall(payload.room_id);
|
var call = CallHandler.getCall(payload.room_id);
|
||||||
if (call && call.call_state === 'ringing') {
|
if (call && call.call_state === 'ringing') {
|
||||||
this.setState({
|
this.setState({
|
||||||
incomingCall: call
|
incomingCall: call,
|
||||||
});
|
});
|
||||||
this._repositionIncomingCallBox(undefined, true);
|
this._repositionIncomingCallBox(undefined, true);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.setState({
|
this.setState({
|
||||||
incomingCall: null
|
incomingCall: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -174,7 +173,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
onArchivedHeaderClick: function(isHidden, scrollToPosition) {
|
onArchivedHeaderClick: function(isHidden, scrollToPosition) {
|
||||||
if (!isHidden) {
|
if (!isHidden) {
|
||||||
var self = this;
|
const self = this;
|
||||||
this.setState({ isLoadingLeftRooms: true });
|
this.setState({ isLoadingLeftRooms: true });
|
||||||
|
|
||||||
// Try scrolling to position
|
// Try scrolling to position
|
||||||
|
@ -265,7 +264,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
getRoomLists: function() {
|
getRoomLists: function() {
|
||||||
var self = this;
|
const self = this;
|
||||||
const lists = {};
|
const lists = {};
|
||||||
|
|
||||||
lists["im.vector.fake.invite"] = [];
|
lists["im.vector.fake.invite"] = [];
|
||||||
|
@ -288,35 +287,28 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
if (me.membership == "invite") {
|
if (me.membership == "invite") {
|
||||||
lists["im.vector.fake.invite"].push(room);
|
lists["im.vector.fake.invite"].push(room);
|
||||||
}
|
} else if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(room, me, self.props.ConferenceHandler)) {
|
||||||
else if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(room, me, self.props.ConferenceHandler)) {
|
|
||||||
// skip past this room & don't put it in any lists
|
// skip past this room & don't put it in any lists
|
||||||
}
|
} else if (me.membership == "join" || me.membership === "ban" ||
|
||||||
else 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
|
// Used to split rooms via tags
|
||||||
var tagNames = Object.keys(room.tags);
|
const tagNames = Object.keys(room.tags);
|
||||||
|
|
||||||
if (tagNames.length) {
|
if (tagNames.length) {
|
||||||
for (var i = 0; i < tagNames.length; i++) {
|
for (let i = 0; i < tagNames.length; i++) {
|
||||||
var tagName = tagNames[i];
|
const tagName = tagNames[i];
|
||||||
lists[tagName] = lists[tagName] || [];
|
lists[tagName] = lists[tagName] || [];
|
||||||
lists[tagName].push(room);
|
lists[tagName].push(room);
|
||||||
}
|
}
|
||||||
}
|
} else if (dmRoomMap.getUserIdForRoomId(room.roomId)) {
|
||||||
else if (dmRoomMap.getUserIdForRoomId(room.roomId)) {
|
|
||||||
// "Direct Message" rooms (that we're still in and that aren't otherwise tagged)
|
// "Direct Message" rooms (that we're still in and that aren't otherwise tagged)
|
||||||
lists["im.vector.fake.direct"].push(room);
|
lists["im.vector.fake.direct"].push(room);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
lists["im.vector.fake.recent"].push(room);
|
lists["im.vector.fake.recent"].push(room);
|
||||||
}
|
}
|
||||||
}
|
} else if (me.membership === "leave") {
|
||||||
else if (me.membership === "leave") {
|
|
||||||
lists["im.vector.fake.archived"].push(room);
|
lists["im.vector.fake.archived"].push(room);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
console.error("unrecognised membership: " + me.membership + " - this should never happen");
|
console.error("unrecognised membership: " + me.membership + " - this should never happen");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -343,7 +335,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
_getScrollNode: function() {
|
_getScrollNode: function() {
|
||||||
if (!this.mounted) return null;
|
if (!this.mounted) return null;
|
||||||
var panel = ReactDOM.findDOMNode(this);
|
const panel = ReactDOM.findDOMNode(this);
|
||||||
if (!panel) return null;
|
if (!panel) return null;
|
||||||
|
|
||||||
if (panel.classList.contains('gm-prevented')) {
|
if (panel.classList.contains('gm-prevented')) {
|
||||||
|
@ -367,22 +359,22 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_repositionIncomingCallBox: function(e, firstTime) {
|
_repositionIncomingCallBox: function(e, firstTime) {
|
||||||
var incomingCallBox = document.getElementById("incomingCallBox");
|
const incomingCallBox = document.getElementById("incomingCallBox");
|
||||||
if (incomingCallBox && incomingCallBox.parentElement) {
|
if (incomingCallBox && incomingCallBox.parentElement) {
|
||||||
var scrollArea = this._getScrollNode();
|
const scrollArea = this._getScrollNode();
|
||||||
if (!scrollArea) return;
|
if (!scrollArea) return;
|
||||||
// Use the offset of the top of the scroll area from the window
|
// Use the offset of the top of the scroll area from the window
|
||||||
// as this is used to calculate the CSS fixed top position for the stickies
|
// as this is used to calculate the CSS fixed top position for the stickies
|
||||||
var scrollAreaOffset = scrollArea.getBoundingClientRect().top + window.pageYOffset;
|
const scrollAreaOffset = scrollArea.getBoundingClientRect().top + window.pageYOffset;
|
||||||
// Use the offset of the top of the component from the window
|
// Use the offset of the top of the component from the window
|
||||||
// as this is used to calculate the CSS fixed top position for the stickies
|
// as this is used to calculate the CSS fixed top position for the stickies
|
||||||
var scrollAreaHeight = ReactDOM.findDOMNode(this).getBoundingClientRect().height;
|
const scrollAreaHeight = ReactDOM.findDOMNode(this).getBoundingClientRect().height;
|
||||||
|
|
||||||
var top = (incomingCallBox.parentElement.getBoundingClientRect().top + window.pageYOffset);
|
let top = (incomingCallBox.parentElement.getBoundingClientRect().top + window.pageYOffset);
|
||||||
// Make sure we don't go too far up, if the headers aren't sticky
|
// Make sure we don't go too far up, if the headers aren't sticky
|
||||||
top = (top < scrollAreaOffset) ? scrollAreaOffset : top;
|
top = (top < scrollAreaOffset) ? scrollAreaOffset : top;
|
||||||
// make sure we don't go too far down, if the headers aren't sticky
|
// make sure we don't go too far down, if the headers aren't sticky
|
||||||
var bottomMargin = scrollAreaOffset + (scrollAreaHeight - 45);
|
const bottomMargin = scrollAreaOffset + (scrollAreaHeight - 45);
|
||||||
top = (top > bottomMargin) ? bottomMargin : top;
|
top = (top > bottomMargin) ? bottomMargin : top;
|
||||||
|
|
||||||
incomingCallBox.style.top = top + "px";
|
incomingCallBox.style.top = top + "px";
|
||||||
|
@ -393,14 +385,14 @@ module.exports = React.createClass({
|
||||||
// Doing the sticky headers as raw DOM, for speed, as it gets very stuttery if done
|
// Doing the sticky headers as raw DOM, for speed, as it gets very stuttery if done
|
||||||
// properly through React
|
// properly through React
|
||||||
_initAndPositionStickyHeaders: function(initialise, scrollToPosition) {
|
_initAndPositionStickyHeaders: function(initialise, scrollToPosition) {
|
||||||
var scrollArea = this._getScrollNode();
|
const scrollArea = this._getScrollNode();
|
||||||
if (!scrollArea) return;
|
if (!scrollArea) return;
|
||||||
// Use the offset of the top of the scroll area from the window
|
// Use the offset of the top of the scroll area from the window
|
||||||
// as this is used to calculate the CSS fixed top position for the stickies
|
// as this is used to calculate the CSS fixed top position for the stickies
|
||||||
var scrollAreaOffset = scrollArea.getBoundingClientRect().top + window.pageYOffset;
|
const scrollAreaOffset = scrollArea.getBoundingClientRect().top + window.pageYOffset;
|
||||||
// Use the offset of the top of the componet from the window
|
// Use the offset of the top of the componet from the window
|
||||||
// as this is used to calculate the CSS fixed top position for the stickies
|
// as this is used to calculate the CSS fixed top position for the stickies
|
||||||
var scrollAreaHeight = ReactDOM.findDOMNode(this).getBoundingClientRect().height;
|
const scrollAreaHeight = ReactDOM.findDOMNode(this).getBoundingClientRect().height;
|
||||||
|
|
||||||
if (initialise) {
|
if (initialise) {
|
||||||
// Get a collection of sticky header containers references
|
// Get a collection of sticky header containers references
|
||||||
|
@ -420,7 +412,7 @@ module.exports = React.createClass({
|
||||||
sticky.dataset.originalPosition = sticky.offsetTop - scrollArea.offsetTop;
|
sticky.dataset.originalPosition = sticky.offsetTop - scrollArea.offsetTop;
|
||||||
|
|
||||||
// Save and set the sticky heights
|
// Save and set the sticky heights
|
||||||
var originalHeight = sticky.getBoundingClientRect().height;
|
const originalHeight = sticky.getBoundingClientRect().height;
|
||||||
sticky.dataset.originalHeight = originalHeight;
|
sticky.dataset.originalHeight = originalHeight;
|
||||||
sticky.style.height = originalHeight;
|
sticky.style.height = originalHeight;
|
||||||
|
|
||||||
|
@ -429,8 +421,8 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var self = this;
|
const self = this;
|
||||||
var scrollStuckOffset = 0;
|
let scrollStuckOffset = 0;
|
||||||
// Scroll to the passed in position, i.e. a header was clicked and in a scroll to state
|
// Scroll to the passed in position, i.e. a header was clicked and in a scroll to state
|
||||||
// rather than a collapsable one (see RoomSubList.isCollapsableOnClick method for details)
|
// rather than a collapsable one (see RoomSubList.isCollapsableOnClick method for details)
|
||||||
if (scrollToPosition !== undefined) {
|
if (scrollToPosition !== undefined) {
|
||||||
|
@ -438,11 +430,11 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
// Stick headers to top and bottom, or free them
|
// Stick headers to top and bottom, or free them
|
||||||
Array.prototype.forEach.call(this.stickies, function(sticky, i, stickyWrappers) {
|
Array.prototype.forEach.call(this.stickies, function(sticky, i, stickyWrappers) {
|
||||||
var stickyPosition = sticky.dataset.originalPosition;
|
const stickyPosition = sticky.dataset.originalPosition;
|
||||||
var stickyHeight = sticky.dataset.originalHeight;
|
const stickyHeight = sticky.dataset.originalHeight;
|
||||||
var stickyHeader = sticky.childNodes[0];
|
const stickyHeader = sticky.childNodes[0];
|
||||||
var topStuckHeight = stickyHeight * i;
|
const topStuckHeight = stickyHeight * i;
|
||||||
var bottomStuckHeight = stickyHeight * (stickyWrappers.length - i);
|
const bottomStuckHeight = stickyHeight * (stickyWrappers.length - i);
|
||||||
|
|
||||||
if (self.scrollAreaSufficient && stickyPosition < (scrollArea.scrollTop + topStuckHeight)) {
|
if (self.scrollAreaSufficient && stickyPosition < (scrollArea.scrollTop + topStuckHeight)) {
|
||||||
// Top stickies
|
// Top stickies
|
||||||
|
@ -472,7 +464,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateStickyHeaders: function(initialise, scrollToPosition) {
|
_updateStickyHeaders: function(initialise, scrollToPosition) {
|
||||||
var self = this;
|
const self = this;
|
||||||
|
|
||||||
if (initialise) {
|
if (initialise) {
|
||||||
// Useing setTimeout to ensure that the code is run after the painting
|
// Useing setTimeout to ensure that the code is run after the painting
|
||||||
|
@ -511,8 +503,8 @@ module.exports = React.createClass({
|
||||||
"Press <StartChatButton> to start a chat with someone",
|
"Press <StartChatButton> to start a chat with someone",
|
||||||
[/<StartChatButton>/],
|
[/<StartChatButton>/],
|
||||||
[
|
[
|
||||||
(sub) => <StartChatButton size="16" callout={true}/>
|
(sub) => <StartChatButton size="16" callout={true} />,
|
||||||
]
|
],
|
||||||
) }
|
) }
|
||||||
</div>;
|
</div>;
|
||||||
case 'im.vector.fake.recent':
|
case 'im.vector.fake.recent':
|
||||||
|
@ -523,8 +515,8 @@ module.exports = React.createClass({
|
||||||
[/<CreateRoomButton>/, /<RoomDirectoryButton>/],
|
[/<CreateRoomButton>/, /<RoomDirectoryButton>/],
|
||||||
[
|
[
|
||||||
(sub) => <CreateRoomButton size="16" callout={true} />,
|
(sub) => <CreateRoomButton size="16" callout={true} />,
|
||||||
(sub) => <RoomDirectoryButton size="16" callout={true}/>
|
(sub) => <RoomDirectoryButton size="16" callout={true} />,
|
||||||
]
|
],
|
||||||
) }
|
) }
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
@ -574,7 +566,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
const inviteSectionExtraTiles = this._makeGroupInviteTiles();
|
const inviteSectionExtraTiles = this._makeGroupInviteTiles();
|
||||||
|
|
||||||
var self = this;
|
const self = this;
|
||||||
return (
|
return (
|
||||||
<GeminiScrollbar className="mx_RoomList_scrollbar"
|
<GeminiScrollbar className="mx_RoomList_scrollbar"
|
||||||
autoshow={true} onScroll={self._whenScrolling} ref="gemscroll">
|
autoshow={true} onScroll={self._whenScrolling} ref="gemscroll">
|
||||||
|
@ -649,7 +641,6 @@ module.exports = React.createClass({
|
||||||
searchFilter={self.props.searchFilter}
|
searchFilter={self.props.searchFilter}
|
||||||
onHeaderClick={self.onSubListHeaderClick}
|
onHeaderClick={self.onSubListHeaderClick}
|
||||||
onShowMoreRooms={self.onShowMoreRooms} />;
|
onShowMoreRooms={self.onShowMoreRooms} />;
|
||||||
|
|
||||||
}
|
}
|
||||||
}) }
|
}) }
|
||||||
|
|
||||||
|
@ -682,5 +673,5 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</GeminiScrollbar>
|
</GeminiScrollbar>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,9 +16,9 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
|
@ -29,10 +29,10 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
var room = this.props.room;
|
const room = this.props.room;
|
||||||
var name = room.currentState.getStateEvents('m.room.name', '');
|
const name = room.currentState.getStateEvents('m.room.name', '');
|
||||||
var myId = MatrixClientPeg.get().credentials.userId;
|
const myId = MatrixClientPeg.get().credentials.userId;
|
||||||
var defaultName = room.getDefaultRoomName(myId);
|
const defaultName = room.getDefaultRoomName(myId);
|
||||||
|
|
||||||
this._initialName = name ? name.getContent().name : '';
|
this._initialName = name ? name.getContent().name : '';
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var EditableText = sdk.getComponent("elements.EditableText");
|
const EditableText = sdk.getComponent("elements.EditableText");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_RoomHeader_name">
|
<div className="mx_RoomHeader_name">
|
||||||
|
|
|
@ -17,9 +17,9 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
|
|
||||||
import { _t, _tJsx } from '../../../languageHandler';
|
import { _t, _tJsx } from '../../../languageHandler';
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
busy: false
|
busy: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ module.exports = React.createClass({
|
||||||
if (this.props.inviterName && this.props.invitedEmail) {
|
if (this.props.inviterName && this.props.invitedEmail) {
|
||||||
this.setState({busy: true});
|
this.setState({busy: true});
|
||||||
MatrixClientPeg.get().lookupThreePid(
|
MatrixClientPeg.get().lookupThreePid(
|
||||||
'email', this.props.invitedEmail
|
'email', this.props.invitedEmail,
|
||||||
).finally(() => {
|
).finally(() => {
|
||||||
this.setState({busy: false});
|
this.setState({busy: false});
|
||||||
}).done((result) => {
|
}).done((result) => {
|
||||||
|
@ -90,10 +90,10 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var joinBlock, previewBlock;
|
let joinBlock, previewBlock;
|
||||||
|
|
||||||
if (this.props.spinner || this.state.busy) {
|
if (this.props.spinner || this.state.busy) {
|
||||||
var Spinner = sdk.getComponent("elements.Spinner");
|
const Spinner = sdk.getComponent("elements.Spinner");
|
||||||
return (<div className="mx_RoomPreviewBar">
|
return (<div className="mx_RoomPreviewBar">
|
||||||
<Spinner />
|
<Spinner />
|
||||||
</div>);
|
</div>);
|
||||||
|
@ -110,7 +110,7 @@ module.exports = React.createClass({
|
||||||
const banned = myMember && myMember.membership == 'ban';
|
const banned = myMember && myMember.membership == 'ban';
|
||||||
|
|
||||||
if (this.props.inviterName) {
|
if (this.props.inviterName) {
|
||||||
var emailMatchBlock;
|
let emailMatchBlock;
|
||||||
if (this.props.invitedEmail) {
|
if (this.props.invitedEmail) {
|
||||||
if (this.state.threePidFetchError) {
|
if (this.state.threePidFetchError) {
|
||||||
emailMatchBlock = <div className="error">
|
emailMatchBlock = <div className="error">
|
||||||
|
@ -142,24 +142,23 @@ module.exports = React.createClass({
|
||||||
[/<acceptText>(.*?)<\/acceptText>/, /<declineText>(.*?)<\/declineText>/],
|
[/<acceptText>(.*?)<\/acceptText>/, /<declineText>(.*?)<\/declineText>/],
|
||||||
[
|
[
|
||||||
(sub) => <a onClick={this.props.onJoinClick}>{ sub }</a>,
|
(sub) => <a onClick={this.props.onJoinClick}>{ sub }</a>,
|
||||||
(sub) => <a onClick={ this.props.onRejectClick }>{sub}</a>
|
(sub) => <a onClick={this.props.onRejectClick}>{ sub }</a>,
|
||||||
]
|
],
|
||||||
) }
|
) }
|
||||||
</div>
|
</div>
|
||||||
{ emailMatchBlock }
|
{ emailMatchBlock }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
} else if (kicked || banned) {
|
} else if (kicked || banned) {
|
||||||
const roomName = this._roomNameElement(_t('This room'));
|
const roomName = this._roomNameElement(_t('This room'));
|
||||||
const kickerMember = this.props.room.currentState.getMember(
|
const kickerMember = this.props.room.currentState.getMember(
|
||||||
myMember.events.member.getSender()
|
myMember.events.member.getSender(),
|
||||||
);
|
);
|
||||||
const kickerName = kickerMember ?
|
const kickerName = kickerMember ?
|
||||||
kickerMember.name : myMember.events.member.getSender();
|
kickerMember.name : myMember.events.member.getSender();
|
||||||
let reason;
|
let reason;
|
||||||
if (myMember.events.member.getContent().reason) {
|
if (myMember.events.member.getContent().reason) {
|
||||||
reason = <div>{_t("Reason: %(reasonText)s", {reasonText: myMember.events.member.getContent().reason})}</div>
|
reason = <div>{ _t("Reason: %(reasonText)s", {reasonText: myMember.events.member.getContent().reason}) }</div>;
|
||||||
}
|
}
|
||||||
let rejoinBlock;
|
let rejoinBlock;
|
||||||
if (!banned) {
|
if (!banned) {
|
||||||
|
@ -169,8 +168,7 @@ module.exports = React.createClass({
|
||||||
let actionText;
|
let actionText;
|
||||||
if (kicked) {
|
if (kicked) {
|
||||||
actionText = _t("You have been kicked from %(roomName)s by %(userName)s.", {roomName: roomName, userName: kickerName});
|
actionText = _t("You have been kicked from %(roomName)s by %(userName)s.", {roomName: roomName, userName: kickerName});
|
||||||
}
|
} else if (banned) {
|
||||||
else if (banned) {
|
|
||||||
actionText = _t("You have been banned from %(roomName)s by %(userName)s.", {roomName: roomName, userName: kickerName});
|
actionText = _t("You have been banned from %(roomName)s by %(userName)s.", {roomName: roomName, userName: kickerName});
|
||||||
} // no other options possible due to the kicked || banned check above.
|
} // no other options possible due to the kicked || banned check above.
|
||||||
|
|
||||||
|
@ -186,8 +184,8 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (this.props.error) {
|
} else if (this.props.error) {
|
||||||
var name = this.props.roomAlias || _t("This room");
|
const name = this.props.roomAlias || _t("This room");
|
||||||
var error;
|
let error;
|
||||||
if (this.props.error.errcode == 'M_NOT_FOUND') {
|
if (this.props.error.errcode == 'M_NOT_FOUND') {
|
||||||
error = _t("%(roomName)s does not exist.", {roomName: name});
|
error = _t("%(roomName)s does not exist.", {roomName: name});
|
||||||
} else {
|
} else {
|
||||||
|
@ -209,7 +207,7 @@ module.exports = React.createClass({
|
||||||
<br />
|
<br />
|
||||||
{ _tJsx("<a>Click here</a> to join the discussion!",
|
{ _tJsx("<a>Click here</a> to join the discussion!",
|
||||||
/<a>(.*?)<\/a>/,
|
/<a>(.*?)<\/a>/,
|
||||||
(sub) => <a onClick={ this.props.onJoinClick }><b>{sub}</b></a>
|
(sub) => <a onClick={this.props.onJoinClick}><b>{ sub }</b></a>,
|
||||||
) }
|
) }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -232,5 +230,5 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -31,7 +31,7 @@ import AccessibleButton from '../elements/AccessibleButton';
|
||||||
// parse a string as an integer; if the input is undefined, or cannot be parsed
|
// parse a string as an integer; if the input is undefined, or cannot be parsed
|
||||||
// as an integer, return a default.
|
// as an integer, return a default.
|
||||||
function parseIntWithDefault(val, def) {
|
function parseIntWithDefault(val, def) {
|
||||||
var res = parseInt(val);
|
const res = parseInt(val);
|
||||||
return isNaN(res) ? def : res;
|
return isNaN(res) ? def : res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ const plEventsToShow = {
|
||||||
"m.room.topic": {isState: true},
|
"m.room.topic": {isState: true},
|
||||||
|
|
||||||
"im.vector.modular.widgets": {isState: true},
|
"im.vector.modular.widgets": {isState: true},
|
||||||
}
|
};
|
||||||
|
|
||||||
const BannedUser = React.createClass({
|
const BannedUser = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -120,7 +120,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
var tags = {};
|
const tags = {};
|
||||||
Object.keys(this.props.room.tags).forEach(function(tagName) {
|
Object.keys(this.props.room.tags).forEach(function(tagName) {
|
||||||
tags[tagName] = ['yep'];
|
tags[tagName] = ['yep'];
|
||||||
});
|
});
|
||||||
|
@ -149,7 +149,7 @@ module.exports = React.createClass({
|
||||||
MatrixClientPeg.get().on("RoomMember.membership", this._onRoomMemberMembership);
|
MatrixClientPeg.get().on("RoomMember.membership", this._onRoomMemberMembership);
|
||||||
|
|
||||||
MatrixClientPeg.get().getRoomDirectoryVisibility(
|
MatrixClientPeg.get().getRoomDirectoryVisibility(
|
||||||
this.props.room.roomId
|
this.props.room.roomId,
|
||||||
).done((result) => {
|
).done((result) => {
|
||||||
this.setState({ isRoomPublished: result.visibility === "public" });
|
this.setState({ isRoomPublished: result.visibility === "public" });
|
||||||
this._originalIsRoomPublished = result.visibility === "public";
|
this._originalIsRoomPublished = result.visibility === "public";
|
||||||
|
@ -179,13 +179,13 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
setName: function(name) {
|
setName: function(name) {
|
||||||
this.setState({
|
this.setState({
|
||||||
name: name
|
name: name,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setTopic: function(topic) {
|
setTopic: function(topic) {
|
||||||
this.setState({
|
this.setState({
|
||||||
topic: topic
|
topic: topic,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ module.exports = React.createClass({
|
||||||
* `{ state: "fulfilled", value: v }` or `{ state: "rejected", reason: r }`.
|
* `{ state: "fulfilled", value: v }` or `{ state: "rejected", reason: r }`.
|
||||||
*/
|
*/
|
||||||
save: function() {
|
save: function() {
|
||||||
var stateWasSetDefer = Promise.defer();
|
const stateWasSetDefer = Promise.defer();
|
||||||
// the caller may have JUST called setState on stuff, so we need to re-render before saving
|
// the caller may have JUST called setState on stuff, so we need to re-render before saving
|
||||||
// else we won't use the latest values of things.
|
// else we won't use the latest values of things.
|
||||||
// We can be a bit cheeky here and set a loading flag, and listen for the callback on that
|
// We can be a bit cheeky here and set a loading flag, and listen for the callback on that
|
||||||
|
@ -223,8 +223,8 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
_calcSavePromises: function() {
|
_calcSavePromises: function() {
|
||||||
const roomId = this.props.room.roomId;
|
const roomId = this.props.room.roomId;
|
||||||
var promises = this.saveAliases(); // returns Promise[]
|
const promises = this.saveAliases(); // returns Promise[]
|
||||||
var originalState = this.getInitialState();
|
const originalState = this.getInitialState();
|
||||||
|
|
||||||
// diff between original state and this.state to work out what has been changed
|
// diff between original state and this.state to work out what has been changed
|
||||||
console.log("Original: %s", JSON.stringify(originalState));
|
console.log("Original: %s", JSON.stringify(originalState));
|
||||||
|
@ -242,14 +242,14 @@ module.exports = React.createClass({
|
||||||
promises.push(MatrixClientPeg.get().sendStateEvent(
|
promises.push(MatrixClientPeg.get().sendStateEvent(
|
||||||
roomId, "m.room.history_visibility",
|
roomId, "m.room.history_visibility",
|
||||||
{ history_visibility: this.state.history_visibility },
|
{ history_visibility: this.state.history_visibility },
|
||||||
""
|
"",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state.isRoomPublished !== originalState.isRoomPublished) {
|
if (this.state.isRoomPublished !== originalState.isRoomPublished) {
|
||||||
promises.push(MatrixClientPeg.get().setRoomDirectoryVisibility(
|
promises.push(MatrixClientPeg.get().setRoomDirectoryVisibility(
|
||||||
roomId,
|
roomId,
|
||||||
this.state.isRoomPublished ? "public" : "private"
|
this.state.isRoomPublished ? "public" : "private",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ module.exports = React.createClass({
|
||||||
promises.push(MatrixClientPeg.get().sendStateEvent(
|
promises.push(MatrixClientPeg.get().sendStateEvent(
|
||||||
roomId, "m.room.join_rules",
|
roomId, "m.room.join_rules",
|
||||||
{ join_rule: this.state.join_rule },
|
{ join_rule: this.state.join_rule },
|
||||||
""
|
"",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,33 +265,33 @@ module.exports = React.createClass({
|
||||||
promises.push(MatrixClientPeg.get().sendStateEvent(
|
promises.push(MatrixClientPeg.get().sendStateEvent(
|
||||||
roomId, "m.room.guest_access",
|
roomId, "m.room.guest_access",
|
||||||
{ guest_access: this.state.guest_access },
|
{ guest_access: this.state.guest_access },
|
||||||
""
|
"",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// power levels
|
// power levels
|
||||||
var powerLevels = this._getPowerLevels();
|
const powerLevels = this._getPowerLevels();
|
||||||
if (powerLevels) {
|
if (powerLevels) {
|
||||||
promises.push(MatrixClientPeg.get().sendStateEvent(
|
promises.push(MatrixClientPeg.get().sendStateEvent(
|
||||||
roomId, "m.room.power_levels", powerLevels, ""
|
roomId, "m.room.power_levels", powerLevels, "",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// tags
|
// tags
|
||||||
if (this.state.tags_changed) {
|
if (this.state.tags_changed) {
|
||||||
var tagDiffs = ObjectUtils.getKeyValueArrayDiffs(originalState.tags, this.state.tags);
|
const tagDiffs = ObjectUtils.getKeyValueArrayDiffs(originalState.tags, this.state.tags);
|
||||||
// [ {place: add, key: "m.favourite", val: ["yep"]} ]
|
// [ {place: add, key: "m.favourite", val: ["yep"]} ]
|
||||||
tagDiffs.forEach(function(diff) {
|
tagDiffs.forEach(function(diff) {
|
||||||
switch (diff.place) {
|
switch (diff.place) {
|
||||||
case "add":
|
case "add":
|
||||||
promises.push(
|
promises.push(
|
||||||
MatrixClientPeg.get().setRoomTag(roomId, diff.key, {})
|
MatrixClientPeg.get().setRoomTag(roomId, diff.key, {}),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "del":
|
case "del":
|
||||||
promises.push(
|
promises.push(
|
||||||
MatrixClientPeg.get().deleteRoomTag(roomId, diff.key)
|
MatrixClientPeg.get().deleteRoomTag(roomId, diff.key),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -302,14 +302,14 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
// color scheme
|
// color scheme
|
||||||
var p;
|
let p;
|
||||||
p = this.saveColor();
|
p = this.saveColor();
|
||||||
if (!p.isFulfilled()) {
|
if (!p.isFulfilled()) {
|
||||||
promises.push(p);
|
promises.push(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// url preview settings
|
// url preview settings
|
||||||
var ps = this.saveUrlPreviewSettings();
|
const ps = this.saveUrlPreviewSettings();
|
||||||
if (ps.length > 0) {
|
if (ps.length > 0) {
|
||||||
promises.push(ps);
|
promises.push(ps);
|
||||||
}
|
}
|
||||||
|
@ -352,13 +352,13 @@ module.exports = React.createClass({
|
||||||
saveEnableEncryption: function() {
|
saveEnableEncryption: function() {
|
||||||
if (!this.refs.encrypt) { return Promise.resolve(); }
|
if (!this.refs.encrypt) { return Promise.resolve(); }
|
||||||
|
|
||||||
var encrypt = this.refs.encrypt.checked;
|
const encrypt = this.refs.encrypt.checked;
|
||||||
if (!encrypt) { return Promise.resolve(); }
|
if (!encrypt) { return Promise.resolve(); }
|
||||||
|
|
||||||
var roomId = this.props.room.roomId;
|
const roomId = this.props.room.roomId;
|
||||||
return MatrixClientPeg.get().sendStateEvent(
|
return MatrixClientPeg.get().sendStateEvent(
|
||||||
roomId, "m.room.encryption",
|
roomId, "m.room.encryption",
|
||||||
{ algorithm: "m.megolm.v1.aes-sha2" }
|
{ algorithm: "m.megolm.v1.aes-sha2" },
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -370,7 +370,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_isRoomBlacklistUnverified: function() {
|
_isRoomBlacklistUnverified: function() {
|
||||||
var blacklistUnverifiedDevicesPerRoom = UserSettingsStore.getLocalSettings().blacklistUnverifiedDevicesPerRoom;
|
const blacklistUnverifiedDevicesPerRoom = UserSettingsStore.getLocalSettings().blacklistUnverifiedDevicesPerRoom;
|
||||||
if (blacklistUnverifiedDevicesPerRoom) {
|
if (blacklistUnverifiedDevicesPerRoom) {
|
||||||
return blacklistUnverifiedDevicesPerRoom[this.props.room.roomId];
|
return blacklistUnverifiedDevicesPerRoom[this.props.room.roomId];
|
||||||
}
|
}
|
||||||
|
@ -378,7 +378,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_setRoomBlacklistUnverified: function(value) {
|
_setRoomBlacklistUnverified: function(value) {
|
||||||
var blacklistUnverifiedDevicesPerRoom = UserSettingsStore.getLocalSettings().blacklistUnverifiedDevicesPerRoom || {};
|
const blacklistUnverifiedDevicesPerRoom = UserSettingsStore.getLocalSettings().blacklistUnverifiedDevicesPerRoom || {};
|
||||||
blacklistUnverifiedDevicesPerRoom[this.props.room.roomId] = value;
|
blacklistUnverifiedDevicesPerRoom[this.props.room.roomId] = value;
|
||||||
UserSettingsStore.setLocalSetting('blacklistUnverifiedDevicesPerRoom', blacklistUnverifiedDevicesPerRoom);
|
UserSettingsStore.setLocalSetting('blacklistUnverifiedDevicesPerRoom', blacklistUnverifiedDevicesPerRoom);
|
||||||
|
|
||||||
|
@ -396,15 +396,15 @@ module.exports = React.createClass({
|
||||||
_getPowerLevels: function() {
|
_getPowerLevels: function() {
|
||||||
if (!this.state.power_levels_changed) return undefined;
|
if (!this.state.power_levels_changed) return undefined;
|
||||||
|
|
||||||
var powerLevels = this.props.room.currentState.getStateEvents('m.room.power_levels', '');
|
let powerLevels = this.props.room.currentState.getStateEvents('m.room.power_levels', '');
|
||||||
powerLevels = powerLevels ? powerLevels.getContent() : {};
|
powerLevels = powerLevels ? powerLevels.getContent() : {};
|
||||||
|
|
||||||
for (let key of Object.keys(this.refs).filter(k => k.startsWith("event_levels_"))) {
|
for (const key of Object.keys(this.refs).filter((k) => k.startsWith("event_levels_"))) {
|
||||||
const eventType = key.substring("event_levels_".length);
|
const eventType = key.substring("event_levels_".length);
|
||||||
powerLevels.events[eventType] = parseInt(this.refs[key].getValue());
|
powerLevels.events[eventType] = parseInt(this.refs[key].getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
var newPowerLevels = {
|
const newPowerLevels = {
|
||||||
ban: parseInt(this.refs.ban.getValue()),
|
ban: parseInt(this.refs.ban.getValue()),
|
||||||
kick: parseInt(this.refs.kick.getValue()),
|
kick: parseInt(this.refs.kick.getValue()),
|
||||||
redact: parseInt(this.refs.redact.getValue()),
|
redact: parseInt(this.refs.redact.getValue()),
|
||||||
|
@ -421,7 +421,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
onPowerLevelsChanged: function() {
|
onPowerLevelsChanged: function() {
|
||||||
this.setState({
|
this.setState({
|
||||||
power_levels_changed: true
|
power_levels_changed: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -436,12 +436,12 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_onHistoryRadioToggle: function(ev) {
|
_onHistoryRadioToggle: function(ev) {
|
||||||
var self = this;
|
const self = this;
|
||||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||||
|
|
||||||
// cancel the click unless the user confirms it
|
// cancel the click unless the user confirms it
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
var value = ev.target.value;
|
const value = ev.target.value;
|
||||||
|
|
||||||
Modal.createTrackedDialog('Privacy warning', '', QuestionDialog, {
|
Modal.createTrackedDialog('Privacy warning', '', QuestionDialog, {
|
||||||
title: _t('Privacy warning'),
|
title: _t('Privacy warning'),
|
||||||
|
@ -454,7 +454,7 @@ module.exports = React.createClass({
|
||||||
onFinished: function(confirmed) {
|
onFinished: function(confirmed) {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
self.setState({
|
self.setState({
|
||||||
history_visibility: value
|
history_visibility: value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -462,7 +462,6 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_onRoomAccessRadioToggle: function(ev) {
|
_onRoomAccessRadioToggle: function(ev) {
|
||||||
|
|
||||||
// join_rule
|
// join_rule
|
||||||
// INVITE | PUBLIC
|
// INVITE | PUBLIC
|
||||||
// ----------------------+----------------
|
// ----------------------+----------------
|
||||||
|
@ -500,7 +499,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
_onToggle: function(keyName, checkedValue, uncheckedValue, ev) {
|
_onToggle: function(keyName, checkedValue, uncheckedValue, ev) {
|
||||||
console.log("Checkbox toggle: %s %s", keyName, ev.target.checked);
|
console.log("Checkbox toggle: %s %s", keyName, ev.target.checked);
|
||||||
var state = {};
|
const state = {};
|
||||||
state[keyName] = ev.target.checked ? checkedValue : uncheckedValue;
|
state[keyName] = ev.target.checked ? checkedValue : uncheckedValue;
|
||||||
this.setState(state);
|
this.setState(state);
|
||||||
},
|
},
|
||||||
|
@ -509,26 +508,24 @@ module.exports = React.createClass({
|
||||||
if (event.target.checked) {
|
if (event.target.checked) {
|
||||||
if (tagName === 'm.favourite') {
|
if (tagName === 'm.favourite') {
|
||||||
delete this.state.tags['m.lowpriority'];
|
delete this.state.tags['m.lowpriority'];
|
||||||
}
|
} else if (tagName === 'm.lowpriority') {
|
||||||
else if (tagName === 'm.lowpriority') {
|
|
||||||
delete this.state.tags['m.favourite'];
|
delete this.state.tags['m.favourite'];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.state.tags[tagName] = this.state.tags[tagName] || ["yep"];
|
this.state.tags[tagName] = this.state.tags[tagName] || ["yep"];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
delete this.state.tags[tagName];
|
delete this.state.tags[tagName];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
tags: this.state.tags,
|
tags: this.state.tags,
|
||||||
tags_changed: true
|
tags_changed: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
mayChangeRoomAccess: function() {
|
mayChangeRoomAccess: function() {
|
||||||
var cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
var roomState = this.props.room.currentState;
|
const roomState = this.props.room.currentState;
|
||||||
return (roomState.mayClientSendStateEvent("m.room.join_rules", cli) &&
|
return (roomState.mayClientSendStateEvent("m.room.join_rules", cli) &&
|
||||||
roomState.mayClientSendStateEvent("m.room.guest_access", cli));
|
roomState.mayClientSendStateEvent("m.room.guest_access", cli));
|
||||||
},
|
},
|
||||||
|
@ -545,8 +542,8 @@ module.exports = React.createClass({
|
||||||
MatrixClientPeg.get().forget(this.props.room.roomId).done(function() {
|
MatrixClientPeg.get().forget(this.props.room.roomId).done(function() {
|
||||||
dis.dispatch({ action: 'view_next_room' });
|
dis.dispatch({ action: 'view_next_room' });
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
var errCode = err.errcode || _t('unknown error code');
|
const errCode = err.errcode || _t('unknown error code');
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
Modal.createTrackedDialog('Failed to forget room', '', ErrorDialog, {
|
Modal.createTrackedDialog('Failed to forget room', '', ErrorDialog, {
|
||||||
title: _t('Error'),
|
title: _t('Error'),
|
||||||
description: _t("Failed to forget room %(errCode)s", { errCode: errCode }),
|
description: _t("Failed to forget room %(errCode)s", { errCode: errCode }),
|
||||||
|
@ -557,7 +554,7 @@ module.exports = React.createClass({
|
||||||
onEnableEncryptionClick() {
|
onEnableEncryptionClick() {
|
||||||
if (!this.refs.encrypt.checked) return;
|
if (!this.refs.encrypt.checked) return;
|
||||||
|
|
||||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||||
Modal.createTrackedDialog('E2E Enable Warning', '', QuestionDialog, {
|
Modal.createTrackedDialog('E2E Enable Warning', '', QuestionDialog, {
|
||||||
title: _t('Warning!'),
|
title: _t('Warning!'),
|
||||||
description: (
|
description: (
|
||||||
|
@ -569,7 +566,7 @@ module.exports = React.createClass({
|
||||||
<p>{ _t('Encrypted messages will not be visible on clients that do not yet implement encryption') }.</p>
|
<p>{ _t('Encrypted messages will not be visible on clients that do not yet implement encryption') }.</p>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
onFinished: confirm=>{
|
onFinished: (confirm)=>{
|
||||||
if (!confirm) {
|
if (!confirm) {
|
||||||
this.refs.encrypt.checked = false;
|
this.refs.encrypt.checked = false;
|
||||||
}
|
}
|
||||||
|
@ -583,7 +580,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_populateDefaultPlEvents: function(eventsSection, stateLevel, eventsLevel) {
|
_populateDefaultPlEvents: function(eventsSection, stateLevel, eventsLevel) {
|
||||||
for (let desiredEvent of Object.keys(plEventsToShow)) {
|
for (const desiredEvent of Object.keys(plEventsToShow)) {
|
||||||
if (!(desiredEvent in eventsSection)) {
|
if (!(desiredEvent in eventsSection)) {
|
||||||
eventsSection[desiredEvent] = (plEventsToShow[desiredEvent].isState ? stateLevel : eventsLevel);
|
eventsSection[desiredEvent] = (plEventsToShow[desiredEvent].isState ? stateLevel : eventsLevel);
|
||||||
}
|
}
|
||||||
|
@ -591,13 +588,13 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_renderEncryptionSection: function() {
|
_renderEncryptionSection: function() {
|
||||||
var cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
var roomState = this.props.room.currentState;
|
const roomState = this.props.room.currentState;
|
||||||
var isEncrypted = cli.isRoomEncrypted(this.props.room.roomId);
|
const isEncrypted = cli.isRoomEncrypted(this.props.room.roomId);
|
||||||
var isGlobalBlacklistUnverified = UserSettingsStore.getLocalSettings().blacklistUnverifiedDevices;
|
const isGlobalBlacklistUnverified = UserSettingsStore.getLocalSettings().blacklistUnverifiedDevices;
|
||||||
var isRoomBlacklistUnverified = this._isRoomBlacklistUnverified();
|
const isRoomBlacklistUnverified = this._isRoomBlacklistUnverified();
|
||||||
|
|
||||||
var settings =
|
const settings =
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" ref="blacklistUnverified"
|
<input type="checkbox" ref="blacklistUnverified"
|
||||||
defaultChecked={isGlobalBlacklistUnverified || isRoomBlacklistUnverified}
|
defaultChecked={isGlobalBlacklistUnverified || isRoomBlacklistUnverified}
|
||||||
|
@ -636,43 +633,43 @@ module.exports = React.createClass({
|
||||||
// TODO: go through greying out things you don't have permission to change
|
// TODO: go through greying out things you don't have permission to change
|
||||||
// (or turning them into informative stuff)
|
// (or turning them into informative stuff)
|
||||||
|
|
||||||
var AliasSettings = sdk.getComponent("room_settings.AliasSettings");
|
const AliasSettings = sdk.getComponent("room_settings.AliasSettings");
|
||||||
var ColorSettings = sdk.getComponent("room_settings.ColorSettings");
|
const ColorSettings = sdk.getComponent("room_settings.ColorSettings");
|
||||||
var UrlPreviewSettings = sdk.getComponent("room_settings.UrlPreviewSettings");
|
const UrlPreviewSettings = sdk.getComponent("room_settings.UrlPreviewSettings");
|
||||||
var RelatedGroupSettings = sdk.getComponent("room_settings.RelatedGroupSettings");
|
const RelatedGroupSettings = sdk.getComponent("room_settings.RelatedGroupSettings");
|
||||||
var EditableText = sdk.getComponent('elements.EditableText');
|
const EditableText = sdk.getComponent('elements.EditableText');
|
||||||
var PowerSelector = sdk.getComponent('elements.PowerSelector');
|
const PowerSelector = sdk.getComponent('elements.PowerSelector');
|
||||||
var Loader = sdk.getComponent("elements.Spinner");
|
const Loader = sdk.getComponent("elements.Spinner");
|
||||||
|
|
||||||
var cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
var roomState = this.props.room.currentState;
|
const roomState = this.props.room.currentState;
|
||||||
var user_id = cli.credentials.userId;
|
const user_id = cli.credentials.userId;
|
||||||
|
|
||||||
var power_level_event = roomState.getStateEvents('m.room.power_levels', '');
|
const power_level_event = roomState.getStateEvents('m.room.power_levels', '');
|
||||||
var power_levels = power_level_event ? power_level_event.getContent() : {};
|
const power_levels = power_level_event ? power_level_event.getContent() : {};
|
||||||
var events_levels = power_levels.events || {};
|
const events_levels = power_levels.events || {};
|
||||||
var user_levels = power_levels.users || {};
|
const user_levels = power_levels.users || {};
|
||||||
|
|
||||||
var ban_level = parseIntWithDefault(power_levels.ban, 50);
|
const ban_level = parseIntWithDefault(power_levels.ban, 50);
|
||||||
var kick_level = parseIntWithDefault(power_levels.kick, 50);
|
const kick_level = parseIntWithDefault(power_levels.kick, 50);
|
||||||
var redact_level = parseIntWithDefault(power_levels.redact, 50);
|
const redact_level = parseIntWithDefault(power_levels.redact, 50);
|
||||||
var invite_level = parseIntWithDefault(power_levels.invite, 50);
|
const invite_level = parseIntWithDefault(power_levels.invite, 50);
|
||||||
var send_level = parseIntWithDefault(power_levels.events_default, 0);
|
const send_level = parseIntWithDefault(power_levels.events_default, 0);
|
||||||
var state_level = power_level_event ? parseIntWithDefault(power_levels.state_default, 50) : 0;
|
const state_level = power_level_event ? parseIntWithDefault(power_levels.state_default, 50) : 0;
|
||||||
var default_user_level = parseIntWithDefault(power_levels.users_default, 0);
|
const default_user_level = parseIntWithDefault(power_levels.users_default, 0);
|
||||||
|
|
||||||
this._populateDefaultPlEvents(events_levels, state_level, send_level);
|
this._populateDefaultPlEvents(events_levels, state_level, send_level);
|
||||||
|
|
||||||
var current_user_level = user_levels[user_id];
|
let current_user_level = user_levels[user_id];
|
||||||
if (current_user_level === undefined) {
|
if (current_user_level === undefined) {
|
||||||
current_user_level = default_user_level;
|
current_user_level = default_user_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
var can_change_levels = roomState.mayClientSendStateEvent("m.room.power_levels", cli);
|
const can_change_levels = roomState.mayClientSendStateEvent("m.room.power_levels", cli);
|
||||||
|
|
||||||
var canSetTag = !cli.isGuest();
|
const canSetTag = !cli.isGuest();
|
||||||
|
|
||||||
var self = this;
|
const self = this;
|
||||||
|
|
||||||
let relatedGroupsSection;
|
let relatedGroupsSection;
|
||||||
if (UserSettingsStore.isFeatureEnabled('feature_groups')) {
|
if (UserSettingsStore.isFeatureEnabled('feature_groups')) {
|
||||||
|
@ -682,7 +679,7 @@ module.exports = React.createClass({
|
||||||
relatedGroupsEvent={this.props.room.currentState.getStateEvents('m.room.related_groups', '')} />;
|
relatedGroupsEvent={this.props.room.currentState.getStateEvents('m.room.related_groups', '')} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
var userLevelsSection;
|
let userLevelsSection;
|
||||||
if (Object.keys(user_levels).length) {
|
if (Object.keys(user_levels).length) {
|
||||||
userLevelsSection =
|
userLevelsSection =
|
||||||
<div>
|
<div>
|
||||||
|
@ -697,8 +694,7 @@ module.exports = React.createClass({
|
||||||
}) }
|
}) }
|
||||||
</ul>
|
</ul>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
userLevelsSection = <div>{ _t('No users have specific privileges in this room') }.</div>;
|
userLevelsSection = <div>{ _t('No users have specific privileges in this room') }.</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,7 +719,7 @@ module.exports = React.createClass({
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
var unfederatableSection;
|
let unfederatableSection;
|
||||||
if (this._yankValueFromEvent("m.room.create", "m.federate", true) === false) {
|
if (this._yankValueFromEvent("m.room.create", "m.federate", true) === false) {
|
||||||
unfederatableSection = (
|
unfederatableSection = (
|
||||||
<div className="mx_RoomSettings_powerLevel">
|
<div className="mx_RoomSettings_powerLevel">
|
||||||
|
@ -732,8 +728,8 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var leaveButton = null;
|
let leaveButton = null;
|
||||||
var myMember = this.props.room.getMember(user_id);
|
const myMember = this.props.room.getMember(user_id);
|
||||||
if (myMember) {
|
if (myMember) {
|
||||||
if (myMember.membership === "join") {
|
if (myMember.membership === "join") {
|
||||||
leaveButton = (
|
leaveButton = (
|
||||||
|
@ -741,8 +737,7 @@ module.exports = React.createClass({
|
||||||
{ _t('Leave room') }
|
{ _t('Leave room') }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
}
|
} else if (myMember.membership === "leave") {
|
||||||
else if (myMember.membership === "leave") {
|
|
||||||
leaveButton = (
|
leaveButton = (
|
||||||
<AccessibleButton className="mx_RoomSettings_leaveButton" onClick={this.onForgetClick}>
|
<AccessibleButton className="mx_RoomSettings_leaveButton" onClick={this.onForgetClick}>
|
||||||
{ _t('Forget room') }
|
{ _t('Forget room') }
|
||||||
|
@ -754,7 +749,7 @@ module.exports = React.createClass({
|
||||||
// TODO: support editing custom events_levels
|
// TODO: support editing custom events_levels
|
||||||
// TODO: support editing custom user_levels
|
// TODO: support editing custom user_levels
|
||||||
|
|
||||||
var tags = [
|
const tags = [
|
||||||
{ name: "m.favourite", label: _t('Favourite'), ref: "tag_favourite" },
|
{ name: "m.favourite", label: _t('Favourite'), ref: "tag_favourite" },
|
||||||
{ name: "m.lowpriority", label: _t('Low priority'), ref: "tag_lowpriority" },
|
{ name: "m.lowpriority", label: _t('Low priority'), ref: "tag_lowpriority" },
|
||||||
];
|
];
|
||||||
|
@ -785,11 +780,11 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// If there is no history_visibility, it is assumed to be 'shared'.
|
// If there is no history_visibility, it is assumed to be 'shared'.
|
||||||
// http://matrix.org/docs/spec/r0.0.0/client_server.html#id31
|
// http://matrix.org/docs/spec/r0.0.0/client_server.html#id31
|
||||||
var historyVisibility = this.state.history_visibility || "shared";
|
const historyVisibility = this.state.history_visibility || "shared";
|
||||||
|
|
||||||
var addressWarning;
|
let addressWarning;
|
||||||
var aliasEvents = this.props.room.currentState.getStateEvents('m.room.aliases') || [];
|
const aliasEvents = this.props.room.currentState.getStateEvents('m.room.aliases') || [];
|
||||||
var aliasCount = 0;
|
let aliasCount = 0;
|
||||||
aliasEvents.forEach((event) => {
|
aliasEvents.forEach((event) => {
|
||||||
aliasCount += event.getContent().aliases.length;
|
aliasCount += event.getContent().aliases.length;
|
||||||
});
|
});
|
||||||
|
@ -800,12 +795,12 @@ module.exports = React.createClass({
|
||||||
{ _tJsx(
|
{ _tJsx(
|
||||||
'To link to a room it must have <a>an address</a>.',
|
'To link to a room it must have <a>an address</a>.',
|
||||||
/<a>(.*?)<\/a>/,
|
/<a>(.*?)<\/a>/,
|
||||||
(sub) => <a href="#addresses">{sub}</a>
|
(sub) => <a href="#addresses">{ sub }</a>,
|
||||||
) }
|
) }
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
var inviteGuestWarning;
|
let inviteGuestWarning;
|
||||||
if (this.state.join_rule !== "public" && this.state.guest_access === "forbidden") {
|
if (this.state.join_rule !== "public" && this.state.guest_access === "forbidden") {
|
||||||
inviteGuestWarning =
|
inviteGuestWarning =
|
||||||
<div className="mx_RoomSettings_warning">
|
<div className="mx_RoomSettings_warning">
|
||||||
|
@ -970,5 +965,5 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,17 +17,17 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var ReactDOM = require("react-dom");
|
const ReactDOM = require("react-dom");
|
||||||
var classNames = require('classnames');
|
const classNames = require('classnames');
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
import DMRoomMap from '../../../utils/DMRoomMap';
|
import DMRoomMap from '../../../utils/DMRoomMap';
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
var ContextualMenu = require('../../structures/ContextualMenu');
|
const ContextualMenu = require('../../structures/ContextualMenu');
|
||||||
var RoomNotifs = require('../../../RoomNotifs');
|
const RoomNotifs = require('../../../RoomNotifs');
|
||||||
var FormattingUtils = require('../../../utils/FormattingUtils');
|
const FormattingUtils = require('../../../utils/FormattingUtils');
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
var UserSettingsStore = require('../../../UserSettingsStore');
|
const UserSettingsStore = require('../../../UserSettingsStore');
|
||||||
import ActiveRoomObserver from '../../../ActiveRoomObserver';
|
import ActiveRoomObserver from '../../../ActiveRoomObserver';
|
||||||
import RoomViewStore from '../../../stores/RoomViewStore';
|
import RoomViewStore from '../../../stores/RoomViewStore';
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_isDirectMessageRoom: function(roomId) {
|
_isDirectMessageRoom: function(roomId) {
|
||||||
var dmRooms = DMRoomMap.shared().getUserIdForRoomId(roomId);
|
const dmRooms = DMRoomMap.shared().getUserIdForRoomId(roomId);
|
||||||
if (dmRooms) {
|
if (dmRooms) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -102,7 +102,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
var cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
if (cli) {
|
if (cli) {
|
||||||
MatrixClientPeg.get().removeListener("accountData", this.onAccountData);
|
MatrixClientPeg.get().removeListener("accountData", this.onAccountData);
|
||||||
}
|
}
|
||||||
|
@ -140,14 +140,13 @@ module.exports = React.createClass({
|
||||||
onBadgeClicked: function(e) {
|
onBadgeClicked: function(e) {
|
||||||
// Only allow none guests to access the context menu
|
// Only allow none guests to access the context menu
|
||||||
if (!MatrixClientPeg.get().isGuest()) {
|
if (!MatrixClientPeg.get().isGuest()) {
|
||||||
|
|
||||||
// If the badge is clicked, then no longer show tooltip
|
// If the badge is clicked, then no longer show tooltip
|
||||||
if (this.props.collapsed) {
|
if (this.props.collapsed) {
|
||||||
this.setState({ hover: false });
|
this.setState({ hover: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
var RoomTileContextMenu = sdk.getComponent('context_menus.RoomTileContextMenu');
|
const RoomTileContextMenu = sdk.getComponent('context_menus.RoomTileContextMenu');
|
||||||
var elementRect = e.target.getBoundingClientRect();
|
const elementRect = e.target.getBoundingClientRect();
|
||||||
|
|
||||||
// The window X and Y offsets are to adjust position when zoomed in to page
|
// The window X and Y offsets are to adjust position when zoomed in to page
|
||||||
const x = elementRect.right + window.pageXOffset + 3;
|
const x = elementRect.right + window.pageXOffset + 3;
|
||||||
|
@ -155,7 +154,7 @@ module.exports = React.createClass({
|
||||||
let y = (elementRect.top + (elementRect.height / 2) + window.pageYOffset);
|
let y = (elementRect.top + (elementRect.height / 2) + window.pageYOffset);
|
||||||
y = y - (chevronOffset + 8); // where 8 is half the height of the chevron
|
y = y - (chevronOffset + 8); // where 8 is half the height of the chevron
|
||||||
|
|
||||||
var self = this;
|
const self = this;
|
||||||
ContextualMenu.createMenu(RoomTileContextMenu, {
|
ContextualMenu.createMenu(RoomTileContextMenu, {
|
||||||
chevronOffset: chevronOffset,
|
chevronOffset: chevronOffset,
|
||||||
left: x,
|
left: x,
|
||||||
|
@ -164,7 +163,7 @@ module.exports = React.createClass({
|
||||||
onFinished: function() {
|
onFinished: function() {
|
||||||
self.setState({ menuDisplayed: false });
|
self.setState({ menuDisplayed: false });
|
||||||
self.props.refreshSubList();
|
self.props.refreshSubList();
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
this.setState({ menuDisplayed: true });
|
this.setState({ menuDisplayed: true });
|
||||||
}
|
}
|
||||||
|
@ -173,17 +172,17 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
const myUserId = MatrixClientPeg.get().credentials.userId;
|
||||||
var me = this.props.room.currentState.members[myUserId];
|
const me = this.props.room.currentState.members[myUserId];
|
||||||
|
|
||||||
var notificationCount = this.props.room.getUnreadNotificationCount();
|
const notificationCount = this.props.room.getUnreadNotificationCount();
|
||||||
// var highlightCount = this.props.room.getUnreadNotificationCount("highlight");
|
// var highlightCount = this.props.room.getUnreadNotificationCount("highlight");
|
||||||
|
|
||||||
const notifBadges = notificationCount > 0 && this._shouldShowNotifBadge();
|
const notifBadges = notificationCount > 0 && this._shouldShowNotifBadge();
|
||||||
const mentionBadges = this.props.highlight && this._shouldShowMentionBadge();
|
const mentionBadges = this.props.highlight && this._shouldShowMentionBadge();
|
||||||
const badges = notifBadges || mentionBadges;
|
const badges = notifBadges || mentionBadges;
|
||||||
|
|
||||||
var classes = classNames({
|
const classes = classNames({
|
||||||
'mx_RoomTile': true,
|
'mx_RoomTile': true,
|
||||||
'mx_RoomTile_selected': this.state.selected,
|
'mx_RoomTile_selected': this.state.selected,
|
||||||
'mx_RoomTile_unread': this.props.unread,
|
'mx_RoomTile_unread': this.props.unread,
|
||||||
|
@ -194,27 +193,27 @@ module.exports = React.createClass({
|
||||||
'mx_RoomTile_noBadges': !badges,
|
'mx_RoomTile_noBadges': !badges,
|
||||||
});
|
});
|
||||||
|
|
||||||
var avatarClasses = classNames({
|
const avatarClasses = classNames({
|
||||||
'mx_RoomTile_avatar': true,
|
'mx_RoomTile_avatar': true,
|
||||||
});
|
});
|
||||||
|
|
||||||
var badgeClasses = classNames({
|
const badgeClasses = classNames({
|
||||||
'mx_RoomTile_badge': true,
|
'mx_RoomTile_badge': true,
|
||||||
'mx_RoomTile_badgeButton': this.state.badgeHover || this.state.menuDisplayed,
|
'mx_RoomTile_badgeButton': this.state.badgeHover || this.state.menuDisplayed,
|
||||||
});
|
});
|
||||||
|
|
||||||
// XXX: We should never display raw room IDs, but sometimes the
|
// XXX: We should never display raw room IDs, but sometimes the
|
||||||
// room name js sdk gives is undefined (cannot repro this -- k)
|
// room name js sdk gives is undefined (cannot repro this -- k)
|
||||||
var name = this.props.room.name || this.props.room.roomId;
|
let name = this.props.room.name || this.props.room.roomId;
|
||||||
name = name.replace(":", ":\u200b"); // add a zero-width space to allow linewrapping after the colon
|
name = name.replace(":", ":\u200b"); // add a zero-width space to allow linewrapping after the colon
|
||||||
|
|
||||||
var badge;
|
let badge;
|
||||||
var badgeContent;
|
let badgeContent;
|
||||||
|
|
||||||
if (this.state.badgeHover || this.state.menuDisplayed) {
|
if (this.state.badgeHover || this.state.menuDisplayed) {
|
||||||
badgeContent = "\u00B7\u00B7\u00B7";
|
badgeContent = "\u00B7\u00B7\u00B7";
|
||||||
} else if (badges) {
|
} else if (badges) {
|
||||||
var limitedCount = FormattingUtils.formatCount(notificationCount);
|
const limitedCount = FormattingUtils.formatCount(notificationCount);
|
||||||
badgeContent = notificationCount ? limitedCount : '!';
|
badgeContent = notificationCount ? limitedCount : '!';
|
||||||
} else {
|
} else {
|
||||||
badgeContent = '\u200B';
|
badgeContent = '\u200B';
|
||||||
|
@ -223,24 +222,24 @@ module.exports = React.createClass({
|
||||||
badge = <div className={badgeClasses} onClick={this.onBadgeClicked}>{ badgeContent }</div>;
|
badge = <div className={badgeClasses} onClick={this.onBadgeClicked}>{ badgeContent }</div>;
|
||||||
|
|
||||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||||
var label;
|
let label;
|
||||||
var tooltip;
|
let tooltip;
|
||||||
if (!this.props.collapsed) {
|
if (!this.props.collapsed) {
|
||||||
var nameClasses = classNames({
|
const nameClasses = classNames({
|
||||||
'mx_RoomTile_name': true,
|
'mx_RoomTile_name': true,
|
||||||
'mx_RoomTile_invite': this.props.isInvite,
|
'mx_RoomTile_invite': this.props.isInvite,
|
||||||
'mx_RoomTile_badgeShown': badges || this.state.badgeHover || this.state.menuDisplayed,
|
'mx_RoomTile_badgeShown': badges || this.state.badgeHover || this.state.menuDisplayed,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.state.selected) {
|
if (this.state.selected) {
|
||||||
let nameSelected = <EmojiText>{name}</EmojiText>;
|
const nameSelected = <EmojiText>{ name }</EmojiText>;
|
||||||
|
|
||||||
label = <div title={name} className={nameClasses} dir="auto">{ nameSelected }</div>;
|
label = <div title={name} className={nameClasses} dir="auto">{ nameSelected }</div>;
|
||||||
} else {
|
} else {
|
||||||
label = <EmojiText element="div" title={name} className={nameClasses} dir="auto">{ name }</EmojiText>;
|
label = <EmojiText element="div" title={name} className={nameClasses} dir="auto">{ name }</EmojiText>;
|
||||||
}
|
}
|
||||||
} else if (this.state.hover) {
|
} else if (this.state.hover) {
|
||||||
var RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
|
const RoomTooltip = sdk.getComponent("rooms.RoomTooltip");
|
||||||
tooltip = <RoomTooltip className="mx_RoomTile_tooltip" room={this.props.room} dir="auto" />;
|
tooltip = <RoomTooltip className="mx_RoomTile_tooltip" room={this.props.room} dir="auto" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,18 +249,18 @@ module.exports = React.createClass({
|
||||||
// incomingCallBox = <IncomingCallBox incomingCall={ this.props.incomingCall }/>;
|
// incomingCallBox = <IncomingCallBox incomingCall={ this.props.incomingCall }/>;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
var RoomAvatar = sdk.getComponent('avatars.RoomAvatar');
|
const RoomAvatar = sdk.getComponent('avatars.RoomAvatar');
|
||||||
|
|
||||||
var directMessageIndicator;
|
let directMessageIndicator;
|
||||||
if (this._isDirectMessageRoom(this.props.room.roomId)) {
|
if (this._isDirectMessageRoom(this.props.room.roomId)) {
|
||||||
directMessageIndicator = <img src="img/icon_person.svg" className="mx_RoomTile_dm" width="11" height="13" alt="dm" />;
|
directMessageIndicator = <img src="img/icon_person.svg" className="mx_RoomTile_dm" width="11" height="13" alt="dm" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
// These props are injected by React DnD,
|
// These props are injected by React DnD,
|
||||||
// as defined by your `collect` function above:
|
// as defined by your `collect` function above:
|
||||||
var isDragging = this.props.isDragging;
|
const isDragging = this.props.isDragging;
|
||||||
var connectDragSource = this.props.connectDragSource;
|
const connectDragSource = this.props.connectDragSource;
|
||||||
var connectDropTarget = this.props.connectDropTarget;
|
const connectDropTarget = this.props.connectDropTarget;
|
||||||
|
|
||||||
|
|
||||||
let ret = (
|
let ret = (
|
||||||
|
@ -287,5 +286,5 @@ module.exports = React.createClass({
|
||||||
if (connectDragSource) ret = connectDragSource(ret);
|
if (connectDragSource) ret = connectDragSource(ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,8 +16,8 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
|
@ -28,8 +28,8 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
var room = this.props.room;
|
const room = this.props.room;
|
||||||
var topic = room.currentState.getStateEvents('m.room.topic', '');
|
const topic = room.currentState.getStateEvents('m.room.topic', '');
|
||||||
this._initialTopic = topic ? topic.getContent().topic : '';
|
this._initialTopic = topic ? topic.getContent().topic : '';
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var EditableText = sdk.getComponent("elements.EditableText");
|
const EditableText = sdk.getComponent("elements.EditableText");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EditableText ref="editor"
|
<EditableText ref="editor"
|
||||||
|
|
|
@ -16,8 +16,8 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'SearchResult',
|
displayName: 'SearchResult',
|
||||||
|
@ -36,20 +36,20 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var DateSeparator = sdk.getComponent('messages.DateSeparator');
|
const DateSeparator = sdk.getComponent('messages.DateSeparator');
|
||||||
var EventTile = sdk.getComponent('rooms.EventTile');
|
const EventTile = sdk.getComponent('rooms.EventTile');
|
||||||
var result = this.props.searchResult;
|
const result = this.props.searchResult;
|
||||||
var mxEv = result.context.getEvent();
|
const mxEv = result.context.getEvent();
|
||||||
var eventId = mxEv.getId();
|
const eventId = mxEv.getId();
|
||||||
|
|
||||||
var ts1 = mxEv.getTs();
|
const ts1 = mxEv.getTs();
|
||||||
var ret = [<DateSeparator key={ts1 + "-search"} ts={ts1}/>];
|
const ret = [<DateSeparator key={ts1 + "-search"} ts={ts1} />];
|
||||||
|
|
||||||
var timeline = result.context.getTimeline();
|
const timeline = result.context.getTimeline();
|
||||||
for (var j = 0; j < timeline.length; j++) {
|
for (var j = 0; j < timeline.length; j++) {
|
||||||
var ev = timeline[j];
|
const ev = timeline[j];
|
||||||
var highlights;
|
var highlights;
|
||||||
var contextual = (j != result.context.getOurEventIndex());
|
const contextual = (j != result.context.getOurEventIndex());
|
||||||
if (!contextual) {
|
if (!contextual) {
|
||||||
highlights = this.props.searchHighlights;
|
highlights = this.props.searchHighlights;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,16 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
const MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||||
var Modal = require("../../../Modal");
|
const Modal = require("../../../Modal");
|
||||||
var sdk = require("../../../index");
|
const sdk = require("../../../index");
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
var GeminiScrollbar = require('react-gemini-scrollbar');
|
const GeminiScrollbar = require('react-gemini-scrollbar');
|
||||||
|
|
||||||
// A list capable of displaying entities which conform to the SearchableEntity
|
// A list capable of displaying entities which conform to the SearchableEntity
|
||||||
// interface which is an object containing getJsx(): Jsx and matches(query: string): boolean
|
// interface which is an object containing getJsx(): Jsx and matches(query: string): boolean
|
||||||
var SearchableEntityList = React.createClass({
|
const SearchableEntityList = React.createClass({
|
||||||
displayName: 'SearchableEntityList',
|
displayName: 'SearchableEntityList',
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -31,7 +31,7 @@ var SearchableEntityList = React.createClass({
|
||||||
onQueryChanged: React.PropTypes.func, // fn(inputText)
|
onQueryChanged: React.PropTypes.func, // fn(inputText)
|
||||||
onSubmit: React.PropTypes.func, // fn(inputText)
|
onSubmit: React.PropTypes.func, // fn(inputText)
|
||||||
entities: React.PropTypes.array,
|
entities: React.PropTypes.array,
|
||||||
truncateAt: React.PropTypes.number
|
truncateAt: React.PropTypes.number,
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
|
@ -40,7 +40,7 @@ var SearchableEntityList = React.createClass({
|
||||||
entities: [],
|
entities: [],
|
||||||
emptyQueryShowsAll: false,
|
emptyQueryShowsAll: false,
|
||||||
onSubmit: function() {},
|
onSubmit: function() {},
|
||||||
onQueryChanged: function(input) {}
|
onQueryChanged: function(input) {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -49,14 +49,14 @@ var SearchableEntityList = React.createClass({
|
||||||
query: "",
|
query: "",
|
||||||
focused: false,
|
focused: false,
|
||||||
truncateAt: this.props.truncateAt,
|
truncateAt: this.props.truncateAt,
|
||||||
results: this.getSearchResults("", this.props.entities)
|
results: this.getSearchResults("", this.props.entities),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillReceiveProps: function(newProps) {
|
componentWillReceiveProps: function(newProps) {
|
||||||
// recalculate the search results in case we got new entities
|
// recalculate the search results in case we got new entities
|
||||||
this.setState({
|
this.setState({
|
||||||
results: this.getSearchResults(this.state.query, newProps.entities)
|
results: this.getSearchResults(this.state.query, newProps.entities),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -73,17 +73,17 @@ var SearchableEntityList = React.createClass({
|
||||||
setQuery: function(input) {
|
setQuery: function(input) {
|
||||||
this.setState({
|
this.setState({
|
||||||
query: input,
|
query: input,
|
||||||
results: this.getSearchResults(input, this.props.entities)
|
results: this.getSearchResults(input, this.props.entities),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onQueryChanged: function(ev) {
|
onQueryChanged: function(ev) {
|
||||||
var q = ev.target.value;
|
const q = ev.target.value;
|
||||||
this.setState({
|
this.setState({
|
||||||
query: q,
|
query: q,
|
||||||
// reset truncation if they back out the entire text
|
// reset truncation if they back out the entire text
|
||||||
truncateAt: (q.length === 0 ? this.props.truncateAt : this.state.truncateAt),
|
truncateAt: (q.length === 0 ? this.props.truncateAt : this.state.truncateAt),
|
||||||
results: this.getSearchResults(q, this.props.entities)
|
results: this.getSearchResults(q, this.props.entities),
|
||||||
}, () => {
|
}, () => {
|
||||||
// invoke the callback AFTER we've flushed the new state. We need to
|
// invoke the callback AFTER we've flushed the new state. We need to
|
||||||
// do this because onQueryChanged can result in new props being passed
|
// do this because onQueryChanged can result in new props being passed
|
||||||
|
@ -110,13 +110,13 @@ var SearchableEntityList = React.createClass({
|
||||||
|
|
||||||
_showAll: function() {
|
_showAll: function() {
|
||||||
this.setState({
|
this.setState({
|
||||||
truncateAt: -1
|
truncateAt: -1,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_createOverflowEntity: function(overflowCount, totalCount) {
|
_createOverflowEntity: function(overflowCount, totalCount) {
|
||||||
var EntityTile = sdk.getComponent("rooms.EntityTile");
|
const EntityTile = sdk.getComponent("rooms.EntityTile");
|
||||||
var BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
const BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
|
||||||
const text = _t("and %(count)s others...", { count: overflowCount });
|
const text = _t("and %(count)s others...", { count: overflowCount });
|
||||||
return (
|
return (
|
||||||
<EntityTile className="mx_EntityTile_ellipsis" avatarJsx={
|
<EntityTile className="mx_EntityTile_ellipsis" avatarJsx={
|
||||||
|
@ -127,7 +127,7 @@ var SearchableEntityList = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var inputBox;
|
let inputBox;
|
||||||
|
|
||||||
if (this.props.showInputBox) {
|
if (this.props.showInputBox) {
|
||||||
inputBox = (
|
inputBox = (
|
||||||
|
@ -141,10 +141,10 @@ var SearchableEntityList = React.createClass({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var list;
|
let list;
|
||||||
if (this.state.results.length > 1 || this.state.focused) {
|
if (this.state.results.length > 1 || this.state.focused) {
|
||||||
if (this.props.truncateAt) { // caller wants list truncated
|
if (this.props.truncateAt) { // caller wants list truncated
|
||||||
var TruncatedList = sdk.getComponent("elements.TruncatedList");
|
const TruncatedList = sdk.getComponent("elements.TruncatedList");
|
||||||
list = (
|
list = (
|
||||||
<TruncatedList className="mx_SearchableEntityList_list"
|
<TruncatedList className="mx_SearchableEntityList_list"
|
||||||
truncateAt={this.state.truncateAt} // use state truncation as it may be expanded
|
truncateAt={this.state.truncateAt} // use state truncation as it may be expanded
|
||||||
|
@ -154,8 +154,7 @@ var SearchableEntityList = React.createClass({
|
||||||
}) }
|
}) }
|
||||||
</TruncatedList>
|
</TruncatedList>
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
list = (
|
list = (
|
||||||
<div className="mx_SearchableEntityList_list">
|
<div className="mx_SearchableEntityList_list">
|
||||||
{ this.state.results.map((entity) => {
|
{ this.state.results.map((entity) => {
|
||||||
|
@ -179,7 +178,7 @@ var SearchableEntityList = React.createClass({
|
||||||
{ list ? <div className="mx_SearchableEntityList_hrWrapper"><hr /></div> : '' }
|
{ list ? <div className="mx_SearchableEntityList_hrWrapper"><hr /></div> : '' }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = SearchableEntityList;
|
module.exports = SearchableEntityList;
|
||||||
|
|
|
@ -17,9 +17,9 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'TopUnreadMessagesBar',
|
displayName: 'TopUnreadMessagesBar',
|
||||||
|
|
|
@ -16,33 +16,33 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
const React = require('react');
|
||||||
|
|
||||||
var Avatar = require("../../../Avatar");
|
const Avatar = require("../../../Avatar");
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
const MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
var sdk = require('../../../index');
|
const sdk = require('../../../index');
|
||||||
var dis = require('../../../dispatcher');
|
const dis = require('../../../dispatcher');
|
||||||
var Modal = require("../../../Modal");
|
const Modal = require("../../../Modal");
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'UserTile',
|
displayName: 'UserTile',
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
user: React.PropTypes.any.isRequired // User
|
user: React.PropTypes.any.isRequired, // User
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var EntityTile = sdk.getComponent("rooms.EntityTile");
|
const EntityTile = sdk.getComponent("rooms.EntityTile");
|
||||||
var user = this.props.user;
|
const user = this.props.user;
|
||||||
var name = user.displayName || user.userId;
|
const name = user.displayName || user.userId;
|
||||||
var active = -1;
|
let active = -1;
|
||||||
|
|
||||||
// FIXME: make presence data update whenever User.presence changes...
|
// FIXME: make presence data update whenever User.presence changes...
|
||||||
active = user.lastActiveAgo ?
|
active = user.lastActiveAgo ?
|
||||||
(Date.now() - (user.lastPresenceTs - user.lastActiveAgo)) : -1;
|
(Date.now() - (user.lastPresenceTs - user.lastActiveAgo)) : -1;
|
||||||
|
|
||||||
var BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
|
||||||
var avatarJsx = (
|
const avatarJsx = (
|
||||||
<BaseAvatar width={36} height={36} name={name} idName={user.userId}
|
<BaseAvatar width={36} height={36} name={name} idName={user.userId}
|
||||||
url={Avatar.avatarUrlForUser(user, 36, 36, "crop")} />
|
url={Avatar.avatarUrlForUser(user, 36, 36, "crop")} />
|
||||||
);
|
);
|
||||||
|
@ -52,5 +52,5 @@ module.exports = React.createClass({
|
||||||
presenceCurrentlyActive={user.currentlyActive}
|
presenceCurrentlyActive={user.currentlyActive}
|
||||||
name={name} title={user.userId} avatarJsx={avatarJsx} />
|
name={name} title={user.userId} avatarJsx={avatarJsx} />
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue