Merge remote-tracking branch 'origin/develop' into dbkr/groupview_edit
This commit is contained in:
commit
7041106bf2
44 changed files with 363 additions and 203 deletions
2
.babelrc
2
.babelrc
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"presets": ["react", "es2015", "es2016"],
|
"presets": ["react", "es2015", "es2016"],
|
||||||
"plugins": ["transform-class-properties", "transform-object-rest-spread", "transform-async-to-generator", "transform-runtime", "add-module-exports"]
|
"plugins": ["transform-class-properties", "transform-object-rest-spread", "transform-async-to-bluebird", "transform-runtime", "add-module-exports"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"babel-runtime": "^6.11.6",
|
"babel-runtime": "^6.11.6",
|
||||||
|
"bluebird": "^3.5.0",
|
||||||
"blueimp-canvas-to-blob": "^3.5.0",
|
"blueimp-canvas-to-blob": "^3.5.0",
|
||||||
"browser-encrypt-attachment": "^0.3.0",
|
"browser-encrypt-attachment": "^0.3.0",
|
||||||
"browser-request": "^0.3.3",
|
"browser-request": "^0.3.3",
|
||||||
|
@ -68,7 +69,6 @@
|
||||||
"matrix-js-sdk": "matrix-org/matrix-js-sdk#develop",
|
"matrix-js-sdk": "matrix-org/matrix-js-sdk#develop",
|
||||||
"optimist": "^0.6.1",
|
"optimist": "^0.6.1",
|
||||||
"prop-types": "^15.5.8",
|
"prop-types": "^15.5.8",
|
||||||
"q": "^1.4.1",
|
|
||||||
"react": "^15.4.0",
|
"react": "^15.4.0",
|
||||||
"react-addons-css-transition-group": "15.3.2",
|
"react-addons-css-transition-group": "15.3.2",
|
||||||
"react-dom": "^15.4.0",
|
"react-dom": "^15.4.0",
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
"babel-eslint": "^6.1.2",
|
"babel-eslint": "^6.1.2",
|
||||||
"babel-loader": "^6.2.5",
|
"babel-loader": "^6.2.5",
|
||||||
"babel-plugin-add-module-exports": "^0.2.1",
|
"babel-plugin-add-module-exports": "^0.2.1",
|
||||||
"babel-plugin-transform-async-to-generator": "^6.16.0",
|
"babel-plugin-transform-async-to-bluebird": "^1.1.1",
|
||||||
"babel-plugin-transform-class-properties": "^6.16.0",
|
"babel-plugin-transform-class-properties": "^6.16.0",
|
||||||
"babel-plugin-transform-object-rest-spread": "^6.16.0",
|
"babel-plugin-transform-object-rest-spread": "^6.16.0",
|
||||||
"babel-plugin-transform-runtime": "^6.15.0",
|
"babel-plugin-transform-runtime": "^6.15.0",
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var q = require('q');
|
import Promise from 'bluebird';
|
||||||
var extend = require('./extend');
|
var extend = require('./extend');
|
||||||
var dis = require('./dispatcher');
|
var dis = require('./dispatcher');
|
||||||
var MatrixClientPeg = require('./MatrixClientPeg');
|
var MatrixClientPeg = require('./MatrixClientPeg');
|
||||||
|
@ -52,7 +52,7 @@ const MAX_HEIGHT = 600;
|
||||||
* and a thumbnail key.
|
* and a thumbnail key.
|
||||||
*/
|
*/
|
||||||
function createThumbnail(element, inputWidth, inputHeight, mimeType) {
|
function createThumbnail(element, inputWidth, inputHeight, mimeType) {
|
||||||
const deferred = q.defer();
|
const deferred = Promise.defer();
|
||||||
|
|
||||||
var targetWidth = inputWidth;
|
var targetWidth = inputWidth;
|
||||||
var targetHeight = inputHeight;
|
var targetHeight = inputHeight;
|
||||||
|
@ -95,7 +95,7 @@ function createThumbnail(element, inputWidth, inputHeight, mimeType) {
|
||||||
* @return {Promise} A promise that resolves with the html image element.
|
* @return {Promise} A promise that resolves with the html image element.
|
||||||
*/
|
*/
|
||||||
function loadImageElement(imageFile) {
|
function loadImageElement(imageFile) {
|
||||||
const deferred = q.defer();
|
const deferred = Promise.defer();
|
||||||
|
|
||||||
// Load the file into an html element
|
// Load the file into an html element
|
||||||
const img = document.createElement("img");
|
const img = document.createElement("img");
|
||||||
|
@ -154,7 +154,7 @@ function infoForImageFile(matrixClient, roomId, imageFile) {
|
||||||
* @return {Promise} A promise that resolves with the video image element.
|
* @return {Promise} A promise that resolves with the video image element.
|
||||||
*/
|
*/
|
||||||
function loadVideoElement(videoFile) {
|
function loadVideoElement(videoFile) {
|
||||||
const deferred = q.defer();
|
const deferred = Promise.defer();
|
||||||
|
|
||||||
// Load the file into an html element
|
// Load the file into an html element
|
||||||
const video = document.createElement("video");
|
const video = document.createElement("video");
|
||||||
|
@ -210,7 +210,7 @@ function infoForVideoFile(matrixClient, roomId, videoFile) {
|
||||||
* is read.
|
* is read.
|
||||||
*/
|
*/
|
||||||
function readFileAsArrayBuffer(file) {
|
function readFileAsArrayBuffer(file) {
|
||||||
const deferred = q.defer();
|
const deferred = Promise.defer();
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = function(e) {
|
reader.onload = function(e) {
|
||||||
deferred.resolve(e.target.result);
|
deferred.resolve(e.target.result);
|
||||||
|
@ -229,11 +229,13 @@ function readFileAsArrayBuffer(file) {
|
||||||
* @param {MatrixClient} matrixClient The matrix client to upload the file with.
|
* @param {MatrixClient} matrixClient The matrix client to upload the file with.
|
||||||
* @param {String} roomId The ID of the room being uploaded to.
|
* @param {String} roomId The ID of the room being uploaded to.
|
||||||
* @param {File} file The file to upload.
|
* @param {File} file The file to upload.
|
||||||
|
* @param {Function?} progressHandler optional callback to be called when a chunk of
|
||||||
|
* data is uploaded.
|
||||||
* @return {Promise} A promise that resolves with an object.
|
* @return {Promise} A promise that resolves with an object.
|
||||||
* If the file is unencrypted then the object will have a "url" key.
|
* If the file is unencrypted then the object will have a "url" key.
|
||||||
* If the file is encrypted then the object will have a "file" key.
|
* If the file is encrypted then the object will have a "file" key.
|
||||||
*/
|
*/
|
||||||
function uploadFile(matrixClient, roomId, file) {
|
function uploadFile(matrixClient, roomId, file, progressHandler) {
|
||||||
if (matrixClient.isRoomEncrypted(roomId)) {
|
if (matrixClient.isRoomEncrypted(roomId)) {
|
||||||
// If the room is encrypted then encrypt the file before uploading it.
|
// If the room is encrypted then encrypt the file before uploading it.
|
||||||
// First read the file into memory.
|
// First read the file into memory.
|
||||||
|
@ -245,7 +247,9 @@ function uploadFile(matrixClient, roomId, file) {
|
||||||
const encryptInfo = encryptResult.info;
|
const encryptInfo = encryptResult.info;
|
||||||
// Pass the encrypted data as a Blob to the uploader.
|
// Pass the encrypted data as a Blob to the uploader.
|
||||||
const blob = new Blob([encryptResult.data]);
|
const blob = new Blob([encryptResult.data]);
|
||||||
return matrixClient.uploadContent(blob).then(function(url) {
|
return matrixClient.uploadContent(blob, {
|
||||||
|
progressHandler: progressHandler,
|
||||||
|
}).then(function(url) {
|
||||||
// If the attachment is encrypted then bundle the URL along
|
// If the attachment is encrypted then bundle the URL along
|
||||||
// with the information needed to decrypt the attachment and
|
// with the information needed to decrypt the attachment and
|
||||||
// add it under a file key.
|
// add it under a file key.
|
||||||
|
@ -257,7 +261,9 @@ function uploadFile(matrixClient, roomId, file) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const basePromise = matrixClient.uploadContent(file);
|
const basePromise = matrixClient.uploadContent(file, {
|
||||||
|
progressHandler: progressHandler,
|
||||||
|
});
|
||||||
const promise1 = basePromise.then(function(url) {
|
const promise1 = basePromise.then(function(url) {
|
||||||
// If the attachment isn't encrypted then include the URL directly.
|
// If the attachment isn't encrypted then include the URL directly.
|
||||||
return {"url": url};
|
return {"url": url};
|
||||||
|
@ -288,7 +294,7 @@ class ContentMessages {
|
||||||
content.info.mimetype = file.type;
|
content.info.mimetype = file.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
const def = q.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=>{
|
||||||
|
@ -326,23 +332,24 @@ class ContentMessages {
|
||||||
dis.dispatch({action: 'upload_started'});
|
dis.dispatch({action: 'upload_started'});
|
||||||
|
|
||||||
var error;
|
var error;
|
||||||
|
|
||||||
|
function onProgress(ev) {
|
||||||
|
upload.total = ev.total;
|
||||||
|
upload.loaded = ev.loaded;
|
||||||
|
dis.dispatch({action: 'upload_progress', upload: upload});
|
||||||
|
}
|
||||||
|
|
||||||
return def.promise.then(function() {
|
return def.promise.then(function() {
|
||||||
// XXX: upload.promise must be the promise that
|
// XXX: upload.promise must be the promise that
|
||||||
// is returned by uploadFile as it has an abort()
|
// is returned by uploadFile as it has an abort()
|
||||||
// method hacked onto it.
|
// method hacked onto it.
|
||||||
upload.promise = uploadFile(
|
upload.promise = uploadFile(
|
||||||
matrixClient, roomId, file
|
matrixClient, roomId, file, onProgress,
|
||||||
);
|
);
|
||||||
return upload.promise.then(function(result) {
|
return upload.promise.then(function(result) {
|
||||||
content.file = result.file;
|
content.file = result.file;
|
||||||
content.url = result.url;
|
content.url = result.url;
|
||||||
});
|
});
|
||||||
}).progress(function(ev) {
|
|
||||||
if (ev) {
|
|
||||||
upload.total = ev.total;
|
|
||||||
upload.loaded = ev.loaded;
|
|
||||||
dis.dispatch({action: 'upload_progress', upload: upload});
|
|
||||||
}
|
|
||||||
}).then(function(url) {
|
}).then(function(url) {
|
||||||
return matrixClient.sendMessage(roomId, content);
|
return matrixClient.sendMessage(roomId, content);
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
import Matrix from 'matrix-js-sdk';
|
import Matrix from 'matrix-js-sdk';
|
||||||
|
|
||||||
import MatrixClientPeg from './MatrixClientPeg';
|
import MatrixClientPeg from './MatrixClientPeg';
|
||||||
|
@ -116,12 +116,12 @@ export function loadSession(opts) {
|
||||||
*/
|
*/
|
||||||
export function attemptTokenLogin(queryParams, defaultDeviceDisplayName) {
|
export function attemptTokenLogin(queryParams, defaultDeviceDisplayName) {
|
||||||
if (!queryParams.loginToken) {
|
if (!queryParams.loginToken) {
|
||||||
return q(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!queryParams.homeserver) {
|
if (!queryParams.homeserver) {
|
||||||
console.warn("Cannot log in with token: can't determine HS URL to use");
|
console.warn("Cannot log in with token: can't determine HS URL to use");
|
||||||
return q(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a temporary MatrixClient to do the login
|
// create a temporary MatrixClient to do the login
|
||||||
|
@ -197,7 +197,7 @@ function _registerAsGuest(hsUrl, isUrl, defaultDeviceDisplayName) {
|
||||||
// localStorage (e.g. teamToken, isGuest etc.)
|
// localStorage (e.g. teamToken, isGuest etc.)
|
||||||
function _restoreFromLocalStorage() {
|
function _restoreFromLocalStorage() {
|
||||||
if (!localStorage) {
|
if (!localStorage) {
|
||||||
return q(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
const hsUrl = localStorage.getItem("mx_hs_url");
|
const hsUrl = localStorage.getItem("mx_hs_url");
|
||||||
const isUrl = localStorage.getItem("mx_is_url") || 'https://matrix.org';
|
const isUrl = localStorage.getItem("mx_is_url") || 'https://matrix.org';
|
||||||
|
@ -229,14 +229,14 @@ function _restoreFromLocalStorage() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("No previous session found.");
|
console.log("No previous session found.");
|
||||||
return q(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _handleRestoreFailure(e) {
|
function _handleRestoreFailure(e) {
|
||||||
console.log("Unable to restore session", e);
|
console.log("Unable to restore session", e);
|
||||||
|
|
||||||
const def = q.defer();
|
const def = Promise.defer();
|
||||||
const SessionRestoreErrorDialog =
|
const SessionRestoreErrorDialog =
|
||||||
sdk.getComponent('views.dialogs.SessionRestoreErrorDialog');
|
sdk.getComponent('views.dialogs.SessionRestoreErrorDialog');
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
||||||
import Matrix from "matrix-js-sdk";
|
import Matrix from "matrix-js-sdk";
|
||||||
import { _t } from "./languageHandler";
|
import { _t } from "./languageHandler";
|
||||||
|
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
import url from 'url';
|
import url from 'url';
|
||||||
|
|
||||||
export default class Login {
|
export default class Login {
|
||||||
|
@ -144,7 +144,7 @@ export default class Login {
|
||||||
|
|
||||||
const client = this._createTemporaryClient();
|
const client = this._createTemporaryClient();
|
||||||
return client.login('m.login.password', loginParams).then(function(data) {
|
return client.login('m.login.password', loginParams).then(function(data) {
|
||||||
return q({
|
return Promise.resolve({
|
||||||
homeserverUrl: self._hsUrl,
|
homeserverUrl: self._hsUrl,
|
||||||
identityServerUrl: self._isUrl,
|
identityServerUrl: self._isUrl,
|
||||||
userId: data.user_id,
|
userId: data.user_id,
|
||||||
|
@ -160,7 +160,7 @@ export default class Login {
|
||||||
});
|
});
|
||||||
|
|
||||||
return fbClient.login('m.login.password', loginParams).then(function(data) {
|
return fbClient.login('m.login.password', loginParams).then(function(data) {
|
||||||
return q({
|
return Promise.resolve({
|
||||||
homeserverUrl: self._fallbackHsUrl,
|
homeserverUrl: self._fallbackHsUrl,
|
||||||
identityServerUrl: self._isUrl,
|
identityServerUrl: self._isUrl,
|
||||||
userId: data.user_id,
|
userId: data.user_id,
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
import MatrixClientPeg from './MatrixClientPeg';
|
import MatrixClientPeg from './MatrixClientPeg';
|
||||||
import PushProcessor from 'matrix-js-sdk/lib/pushprocessor';
|
import PushProcessor from 'matrix-js-sdk/lib/pushprocessor';
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
export const ALL_MESSAGES_LOUD = 'all_messages_loud';
|
export const ALL_MESSAGES_LOUD = 'all_messages_loud';
|
||||||
export const ALL_MESSAGES = 'all_messages';
|
export const ALL_MESSAGES = 'all_messages';
|
||||||
|
@ -87,7 +87,7 @@ function setRoomNotifsStateMuted(roomId) {
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return q.all(promises);
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setRoomNotifsStateUnmuted(roomId, newState) {
|
function setRoomNotifsStateUnmuted(roomId, newState) {
|
||||||
|
@ -126,7 +126,7 @@ function setRoomNotifsStateUnmuted(roomId, newState) {
|
||||||
promises.push(cli.setPushRuleEnabled('global', 'room', roomId, true));
|
promises.push(cli.setPushRuleEnabled('global', 'room', roomId, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return q.all(promises);
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
function findOverrideMuteRule(roomId) {
|
function findOverrideMuteRule(roomId) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import MatrixClientPeg from './MatrixClientPeg';
|
import MatrixClientPeg from './MatrixClientPeg';
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a room object, return the alias we should use for it,
|
* Given a room object, return the alias we should use for it,
|
||||||
|
@ -102,7 +102,7 @@ export function guessAndSetDMRoom(room, isDirect) {
|
||||||
*/
|
*/
|
||||||
export function setDMRoom(roomId, userId) {
|
export function setDMRoom(roomId, userId) {
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
return q();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
const mDirectEvent = MatrixClientPeg.get().getAccountData('m.direct');
|
const mDirectEvent = MatrixClientPeg.get().getAccountData('m.direct');
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var q = require("q");
|
import Promise from 'bluebird';
|
||||||
var request = require('browser-request');
|
var request = require('browser-request');
|
||||||
|
|
||||||
var SdkConfig = require('./SdkConfig');
|
var SdkConfig = require('./SdkConfig');
|
||||||
|
@ -39,7 +39,7 @@ class ScalarAuthClient {
|
||||||
// Returns a scalar_token string
|
// Returns a scalar_token string
|
||||||
getScalarToken() {
|
getScalarToken() {
|
||||||
var tok = window.localStorage.getItem("mx_scalar_token");
|
var tok = window.localStorage.getItem("mx_scalar_token");
|
||||||
if (tok) return q(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
|
||||||
// need an openid bearer token from the HS.
|
// need an openid bearer token from the HS.
|
||||||
|
@ -53,7 +53,7 @@ class ScalarAuthClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
exchangeForScalarToken(openid_token_object) {
|
exchangeForScalarToken(openid_token_object) {
|
||||||
var defer = q.defer();
|
var defer = Promise.defer();
|
||||||
|
|
||||||
var scalar_rest_url = SdkConfig.get().integrations_rest_url;
|
var scalar_rest_url = SdkConfig.get().integrations_rest_url;
|
||||||
request({
|
request({
|
||||||
|
|
|
@ -491,7 +491,7 @@ function canSendEvent(event, roomId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!canSend) {
|
if (!canSend) {
|
||||||
sendError(event, _t('You do not have permission in this room.'));
|
sendError(event, _t('You do not have permission to do that in this room.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
import MatrixClientPeg from './MatrixClientPeg';
|
import MatrixClientPeg from './MatrixClientPeg';
|
||||||
import Notifier from './Notifier';
|
import Notifier from './Notifier';
|
||||||
import { _t } from './languageHandler';
|
import { _t } from './languageHandler';
|
||||||
|
@ -48,7 +48,7 @@ export default {
|
||||||
|
|
||||||
loadThreePids: function() {
|
loadThreePids: function() {
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
return q({
|
return Promise.resolve({
|
||||||
threepids: [],
|
threepids: [],
|
||||||
}); // guests can't poke 3pid endpoint
|
}); // guests can't poke 3pid endpoint
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import DuckDuckGoProvider from './DuckDuckGoProvider';
|
||||||
import RoomProvider from './RoomProvider';
|
import RoomProvider from './RoomProvider';
|
||||||
import UserProvider from './UserProvider';
|
import UserProvider from './UserProvider';
|
||||||
import EmojiProvider from './EmojiProvider';
|
import EmojiProvider from './EmojiProvider';
|
||||||
import Q from 'q';
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
export type SelectionRange = {
|
export type SelectionRange = {
|
||||||
start: number,
|
start: number,
|
||||||
|
@ -52,28 +52,31 @@ export async function getCompletions(query: string, selection: SelectionRange, f
|
||||||
otherwise, we run into a condition where new completions are displayed
|
otherwise, we run into a condition where new completions are displayed
|
||||||
while the user is interacting with the list, which makes it difficult
|
while the user is interacting with the list, which makes it difficult
|
||||||
to predict whether an action will actually do what is intended
|
to predict whether an action will actually do what is intended
|
||||||
|
*/
|
||||||
It ends up containing a list of Q promise states, which are objects with
|
const completionsList = await Promise.all(
|
||||||
state (== "fulfilled" || "rejected") and value. */
|
// Array of inspections of promises that might timeout. Instead of allowing a
|
||||||
const completionsList = await Q.allSettled(
|
// single timeout to reject the Promise.all, reflect each one and once they've all
|
||||||
PROVIDERS.map(provider => {
|
// settled, filter for the fulfilled ones
|
||||||
return Q(provider.getCompletions(query, selection, force))
|
PROVIDERS.map((provider) => {
|
||||||
.timeout(PROVIDER_COMPLETION_TIMEOUT);
|
return provider
|
||||||
|
.getCompletions(query, selection, force)
|
||||||
|
.timeout(PROVIDER_COMPLETION_TIMEOUT)
|
||||||
|
.reflect();
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
return completionsList
|
return completionsList.filter(
|
||||||
.filter(completion => completion.state === "fulfilled")
|
(inspection) => inspection.isFulfilled(),
|
||||||
.map((completionsState, i) => {
|
).map((completionsState, i) => {
|
||||||
return {
|
return {
|
||||||
completions: completionsState.value,
|
completions: completionsState.value(),
|
||||||
provider: PROVIDERS[i],
|
provider: PROVIDERS[i],
|
||||||
|
|
||||||
/* the currently matched "command" the completer tried to complete
|
/* the currently matched "command" the completer tried to complete
|
||||||
* we pass this through so that Autocomplete can figure out when to
|
* we pass this through so that Autocomplete can figure out when to
|
||||||
* re-show itself once hidden.
|
* re-show itself once hidden.
|
||||||
*/
|
*/
|
||||||
command: PROVIDERS[i].getCurrentCommand(query, selection, force),
|
command: PROVIDERS[i].getCurrentCommand(query, selection, force),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Matrix from "matrix-js-sdk";
|
import Matrix from "matrix-js-sdk";
|
||||||
|
@ -224,7 +224,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// Used by _viewRoom before getting state from sync
|
// Used by _viewRoom before getting state from sync
|
||||||
this.firstSyncComplete = false;
|
this.firstSyncComplete = false;
|
||||||
this.firstSyncPromise = q.defer();
|
this.firstSyncPromise = Promise.defer();
|
||||||
|
|
||||||
if (this.props.config.sync_timeline_limit) {
|
if (this.props.config.sync_timeline_limit) {
|
||||||
MatrixClientPeg.opts.initialSyncLimit = this.props.config.sync_timeline_limit;
|
MatrixClientPeg.opts.initialSyncLimit = this.props.config.sync_timeline_limit;
|
||||||
|
@ -323,9 +323,9 @@ module.exports = React.createClass({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the extra q() ensures that synchronous exceptions hit the same codepath as
|
// the extra Promise.resolve() ensures that synchronous exceptions hit the same codepath as
|
||||||
// asynchronous ones.
|
// asynchronous ones.
|
||||||
return q().then(() => {
|
return Promise.resolve().then(() => {
|
||||||
return Lifecycle.loadSession({
|
return Lifecycle.loadSession({
|
||||||
fragmentQueryParams: this.props.startingFragmentQueryParams,
|
fragmentQueryParams: this.props.startingFragmentQueryParams,
|
||||||
enableGuest: this.props.enableGuest,
|
enableGuest: this.props.enableGuest,
|
||||||
|
@ -694,7 +694,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// Wait for the first sync to complete so that if a room does have an alias,
|
// Wait for the first sync to complete so that if a room does have an alias,
|
||||||
// it would have been retrieved.
|
// it would have been retrieved.
|
||||||
let waitFor = q(null);
|
let waitFor = Promise.resolve(null);
|
||||||
if (!this.firstSyncComplete) {
|
if (!this.firstSyncComplete) {
|
||||||
if (!this.firstSyncPromise) {
|
if (!this.firstSyncPromise) {
|
||||||
console.warn('Cannot view a room before first sync. room_id:', roomInfo.room_id);
|
console.warn('Cannot view a room before first sync. room_id:', roomInfo.room_id);
|
||||||
|
@ -1039,7 +1039,7 @@ module.exports = React.createClass({
|
||||||
// since we're about to start the client and therefore about
|
// since we're about to start the client and therefore about
|
||||||
// to do the first sync
|
// to do the first sync
|
||||||
this.firstSyncComplete = false;
|
this.firstSyncComplete = false;
|
||||||
this.firstSyncPromise = q.defer();
|
this.firstSyncPromise = Promise.defer();
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
|
|
||||||
// Allow the JS SDK to reap timeline events. This reduces the amount of
|
// Allow the JS SDK to reap timeline events. This reduces the amount of
|
||||||
|
|
|
@ -22,7 +22,7 @@ limitations under the License.
|
||||||
|
|
||||||
var React = require("react");
|
var React = require("react");
|
||||||
var ReactDOM = require("react-dom");
|
var ReactDOM = require("react-dom");
|
||||||
var q = require("q");
|
import Promise from 'bluebird';
|
||||||
var classNames = require("classnames");
|
var classNames = require("classnames");
|
||||||
var Matrix = require("matrix-js-sdk");
|
var Matrix = require("matrix-js-sdk");
|
||||||
import { _t } from '../../languageHandler';
|
import { _t } from '../../languageHandler';
|
||||||
|
@ -775,7 +775,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
onSearchResultsFillRequest: function(backwards) {
|
onSearchResultsFillRequest: function(backwards) {
|
||||||
if (!backwards) {
|
if (!backwards) {
|
||||||
return q(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state.searchResults.next_batch) {
|
if (this.state.searchResults.next_batch) {
|
||||||
|
@ -785,7 +785,7 @@ module.exports = React.createClass({
|
||||||
return this._handleSearchResult(searchPromise);
|
return this._handleSearchResult(searchPromise);
|
||||||
} else {
|
} else {
|
||||||
debuglog("no more search results");
|
debuglog("no more search results");
|
||||||
return q(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -846,7 +846,7 @@ module.exports = React.createClass({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
q().then(() => {
|
Promise.resolve().then(() => {
|
||||||
const signUrl = this.props.thirdPartyInvite ?
|
const signUrl = this.props.thirdPartyInvite ?
|
||||||
this.props.thirdPartyInvite.inviteSignUrl : undefined;
|
this.props.thirdPartyInvite.inviteSignUrl : undefined;
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
|
@ -865,7 +865,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return q();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||||
var React = require("react");
|
var React = require("react");
|
||||||
var ReactDOM = require("react-dom");
|
var ReactDOM = require("react-dom");
|
||||||
var GeminiScrollbar = require('react-gemini-scrollbar');
|
var GeminiScrollbar = require('react-gemini-scrollbar');
|
||||||
var q = require("q");
|
import Promise from 'bluebird';
|
||||||
var KeyCode = require('../../KeyCode');
|
var KeyCode = require('../../KeyCode');
|
||||||
|
|
||||||
var DEBUG_SCROLL = false;
|
var DEBUG_SCROLL = false;
|
||||||
|
@ -145,7 +145,7 @@ module.exports = React.createClass({
|
||||||
return {
|
return {
|
||||||
stickyBottom: true,
|
stickyBottom: true,
|
||||||
startAtBottom: true,
|
startAtBottom: true,
|
||||||
onFillRequest: function(backwards) { return q(false); },
|
onFillRequest: function(backwards) { return Promise.resolve(false); },
|
||||||
onUnfillRequest: function(backwards, scrollToken) {},
|
onUnfillRequest: function(backwards, scrollToken) {},
|
||||||
onScroll: function() {},
|
onScroll: function() {},
|
||||||
};
|
};
|
||||||
|
@ -386,19 +386,12 @@ module.exports = React.createClass({
|
||||||
debuglog("ScrollPanel: starting "+dir+" fill");
|
debuglog("ScrollPanel: starting "+dir+" fill");
|
||||||
|
|
||||||
// onFillRequest can end up calling us recursively (via onScroll
|
// onFillRequest can end up calling us recursively (via onScroll
|
||||||
// events) so make sure we set this before firing off the call. That
|
// events) so make sure we set this before firing off the call.
|
||||||
// does present the risk that we might not ever actually fire off the
|
|
||||||
// fill request, so wrap it in a try/catch.
|
|
||||||
this._pendingFillRequests[dir] = true;
|
this._pendingFillRequests[dir] = true;
|
||||||
var fillPromise;
|
|
||||||
try {
|
|
||||||
fillPromise = this.props.onFillRequest(backwards);
|
|
||||||
} catch (e) {
|
|
||||||
this._pendingFillRequests[dir] = false;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
q.finally(fillPromise, () => {
|
Promise.try(() => {
|
||||||
|
return this.props.onFillRequest(backwards);
|
||||||
|
}).finally(() => {
|
||||||
this._pendingFillRequests[dir] = false;
|
this._pendingFillRequests[dir] = false;
|
||||||
}).then((hasMoreResults) => {
|
}).then((hasMoreResults) => {
|
||||||
if (this.unmounted) {
|
if (this.unmounted) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var ReactDOM = require("react-dom");
|
var ReactDOM = require("react-dom");
|
||||||
var q = require("q");
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
var Matrix = require("matrix-js-sdk");
|
var Matrix = require("matrix-js-sdk");
|
||||||
var EventTimeline = Matrix.EventTimeline;
|
var EventTimeline = Matrix.EventTimeline;
|
||||||
|
@ -311,13 +311,13 @@ var TimelinePanel = React.createClass({
|
||||||
|
|
||||||
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");
|
||||||
return q(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this._timelineWindow.canPaginate(dir)) {
|
if(!this._timelineWindow.canPaginate(dir)) {
|
||||||
debuglog("TimelinePanel: can't", dir, "paginate any further");
|
debuglog("TimelinePanel: can't", dir, "paginate any further");
|
||||||
this.setState({[canPaginateKey]: false});
|
this.setState({[canPaginateKey]: false});
|
||||||
return q(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
debuglog("TimelinePanel: Initiating paginate; backwards:"+backwards);
|
debuglog("TimelinePanel: Initiating paginate; backwards:"+backwards);
|
||||||
|
|
|
@ -22,7 +22,7 @@ const PlatformPeg = require("../../PlatformPeg");
|
||||||
const Modal = require('../../Modal');
|
const Modal = require('../../Modal');
|
||||||
const dis = require("../../dispatcher");
|
const dis = require("../../dispatcher");
|
||||||
import sessionStore from '../../stores/SessionStore';
|
import sessionStore from '../../stores/SessionStore';
|
||||||
const q = require('q');
|
import Promise from 'bluebird';
|
||||||
const packageJson = require('../../../package.json');
|
const packageJson = require('../../../package.json');
|
||||||
const UserSettingsStore = require('../../UserSettingsStore');
|
const UserSettingsStore = require('../../UserSettingsStore');
|
||||||
const CallMediaHandler = require('../../CallMediaHandler');
|
const CallMediaHandler = require('../../CallMediaHandler');
|
||||||
|
@ -93,6 +93,10 @@ const SETTINGS_LABELS = [
|
||||||
id: 'enableSyntaxHighlightLanguageDetection',
|
id: 'enableSyntaxHighlightLanguageDetection',
|
||||||
label: 'Enable automatic language detection for syntax highlighting',
|
label: 'Enable automatic language detection for syntax highlighting',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'MessageComposerInput.autoReplaceEmoji',
|
||||||
|
label: 'Automatically replace plain text Emoji',
|
||||||
|
},
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
id: 'useFixedWidthFont',
|
id: 'useFixedWidthFont',
|
||||||
|
@ -199,7 +203,7 @@ module.exports = React.createClass({
|
||||||
this._addThreepid = null;
|
this._addThreepid = null;
|
||||||
|
|
||||||
if (PlatformPeg.get()) {
|
if (PlatformPeg.get()) {
|
||||||
q().then(() => {
|
Promise.resolve().then(() => {
|
||||||
return PlatformPeg.get().getAppVersion();
|
return PlatformPeg.get().getAppVersion();
|
||||||
}).done((appVersion) => {
|
}).done((appVersion) => {
|
||||||
if (this._unmounted) return;
|
if (this._unmounted) return;
|
||||||
|
@ -297,7 +301,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_refreshMediaDevices: function() {
|
_refreshMediaDevices: function() {
|
||||||
q().then(() => {
|
Promise.resolve().then(() => {
|
||||||
return CallMediaHandler.getDevices();
|
return CallMediaHandler.getDevices();
|
||||||
}).then((mediaDevices) => {
|
}).then((mediaDevices) => {
|
||||||
// console.log("got mediaDevices", mediaDevices, this._unmounted);
|
// console.log("got mediaDevices", mediaDevices, this._unmounted);
|
||||||
|
@ -312,7 +316,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
_refreshFromServer: function() {
|
_refreshFromServer: function() {
|
||||||
const self = this;
|
const self = this;
|
||||||
q.all([
|
Promise.all([
|
||||||
UserSettingsStore.loadProfileInfo(), UserSettingsStore.loadThreePids(),
|
UserSettingsStore.loadProfileInfo(), UserSettingsStore.loadThreePids(),
|
||||||
]).done(function(resps) {
|
]).done(function(resps) {
|
||||||
self.setState({
|
self.setState({
|
||||||
|
@ -564,15 +568,16 @@ module.exports = React.createClass({
|
||||||
});
|
});
|
||||||
// reject the invites
|
// reject the invites
|
||||||
const promises = rooms.map((room) => {
|
const promises = rooms.map((room) => {
|
||||||
return MatrixClientPeg.get().leave(room.roomId);
|
return MatrixClientPeg.get().leave(room.roomId).catch((e) => {
|
||||||
|
// purposefully drop errors to the floor: we'll just have a non-zero number on the UI
|
||||||
|
// after trying to reject all the invites.
|
||||||
|
});
|
||||||
});
|
});
|
||||||
// purposefully drop errors to the floor: we'll just have a non-zero number on the UI
|
Promise.all(promises).then(() => {
|
||||||
// after trying to reject all the invites.
|
|
||||||
q.allSettled(promises).then(() => {
|
|
||||||
this.setState({
|
this.setState({
|
||||||
rejectingInvites: false,
|
rejectingInvites: false,
|
||||||
});
|
});
|
||||||
}).done();
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_onExportE2eKeysClicked: function() {
|
_onExportE2eKeysClicked: function() {
|
||||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||||
|
|
||||||
import Matrix from 'matrix-js-sdk';
|
import Matrix from 'matrix-js-sdk';
|
||||||
|
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
|
@ -180,7 +180,7 @@ module.exports = React.createClass({
|
||||||
// will just nop. The point of this being we might not have the email address
|
// will just nop. The point of this being we might not have the email address
|
||||||
// that the user registered with at this stage (depending on whether this
|
// that the user registered with at this stage (depending on whether this
|
||||||
// is the client they initiated registration).
|
// is the client they initiated registration).
|
||||||
let trackPromise = q(null);
|
let trackPromise = Promise.resolve(null);
|
||||||
if (this._rtsClient && extra.emailSid) {
|
if (this._rtsClient && extra.emailSid) {
|
||||||
// Track referral if this.props.referrer set, get team_token in order to
|
// Track referral if this.props.referrer set, get team_token in order to
|
||||||
// retrieve team config and see welcome page etc.
|
// retrieve team config and see welcome page etc.
|
||||||
|
@ -232,7 +232,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
_setupPushers: function(matrixClient) {
|
_setupPushers: function(matrixClient) {
|
||||||
if (!this.props.brand) {
|
if (!this.props.brand) {
|
||||||
return q();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
return matrixClient.getPushers().then((resp)=>{
|
return matrixClient.getPushers().then((resp)=>{
|
||||||
const pushers = resp.pushers;
|
const pushers = resp.pushers;
|
||||||
|
|
|
@ -23,7 +23,7 @@ import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||||
import DMRoomMap from '../../../utils/DMRoomMap';
|
import DMRoomMap from '../../../utils/DMRoomMap';
|
||||||
import Modal from '../../../Modal';
|
import Modal from '../../../Modal';
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
import dis from '../../../dispatcher';
|
import dis from '../../../dispatcher';
|
||||||
|
|
||||||
const TRUNCATE_QUERY_LIST = 40;
|
const TRUNCATE_QUERY_LIST = 40;
|
||||||
|
@ -498,7 +498,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait a bit to let the user finish typing
|
// wait a bit to let the user finish typing
|
||||||
return q.delay(500).then(() => {
|
return Promise.delay(500).then(() => {
|
||||||
if (cancelled) return null;
|
if (cancelled) return null;
|
||||||
return MatrixClientPeg.get().lookupThreePid(medium, address);
|
return MatrixClientPeg.get().lookupThreePid(medium, address);
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
|
|
|
@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||||
|
|
|
@ -21,7 +21,9 @@ import React from 'react';
|
||||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||||
import ScalarAuthClient from '../../../ScalarAuthClient';
|
import ScalarAuthClient from '../../../ScalarAuthClient';
|
||||||
import SdkConfig from '../../../SdkConfig';
|
import SdkConfig from '../../../SdkConfig';
|
||||||
|
import Modal from '../../../Modal';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
import sdk from '../../../index';
|
||||||
|
|
||||||
const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:'];
|
const ALLOWED_APP_URL_SCHEMES = ['https:', 'http:'];
|
||||||
|
|
||||||
|
@ -33,6 +35,7 @@ export default React.createClass({
|
||||||
url: React.PropTypes.string.isRequired,
|
url: React.PropTypes.string.isRequired,
|
||||||
name: React.PropTypes.string.isRequired,
|
name: React.PropTypes.string.isRequired,
|
||||||
room: React.PropTypes.object.isRequired,
|
room: React.PropTypes.object.isRequired,
|
||||||
|
type: React.PropTypes.string.isRequired,
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
|
@ -86,8 +89,13 @@ export default React.createClass({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_onEditClick: function() {
|
_onEditClick: function(e) {
|
||||||
console.log("Edit widget %s", this.props.id);
|
console.log("Edit widget ID ", this.props.id);
|
||||||
|
const IntegrationsManager = sdk.getComponent("views.settings.IntegrationsManager");
|
||||||
|
const src = this._scalarClient.getScalarInterfaceUrlForRoom(this.props.room.roomId, 'type_' + this.props.type);
|
||||||
|
Modal.createDialog(IntegrationsManager, {
|
||||||
|
src: src,
|
||||||
|
}, "mx_IntegrationsManager");
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDeleteClick: function() {
|
_onDeleteClick: function() {
|
||||||
|
@ -120,10 +128,10 @@ export default React.createClass({
|
||||||
<div> Loading... </div>
|
<div> Loading... </div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Note that there is advice saying allow-scripts shouldn;t be used with allow-same-origin
|
// Note that there is advice saying allow-scripts shouldn't be used with allow-same-origin
|
||||||
// because that would allow the iframe to prgramatically remove the sandbox attribute, but
|
// because that would allow the iframe to prgramatically remove the sandbox attribute, but
|
||||||
// this would only be for content hosted on the same origin as the riot client: anything
|
// this would only be for content hosted on the same origin as the riot client: anything
|
||||||
// hosted on the same origin as the client will get the same access access as if you clicked
|
// hosted on the same origin as the client will get the same access as if you clicked
|
||||||
// a link to it.
|
// a link to it.
|
||||||
const sandboxFlags = "allow-forms allow-popups allow-popups-to-escape-sandbox "+
|
const sandboxFlags = "allow-forms allow-popups allow-popups-to-escape-sandbox "+
|
||||||
"allow-same-origin allow-scripts";
|
"allow-same-origin allow-scripts";
|
||||||
|
@ -140,18 +148,22 @@ export default React.createClass({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// editing is done in scalar
|
||||||
|
const showEditButton = Boolean(this._scalarClient);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={this.props.fullWidth ? "mx_AppTileFullWidth" : "mx_AppTile"} id={this.props.id}>
|
<div className={this.props.fullWidth ? "mx_AppTileFullWidth" : "mx_AppTile"} id={this.props.id}>
|
||||||
<div className="mx_AppTileMenuBar">
|
<div className="mx_AppTileMenuBar">
|
||||||
{this.formatAppTileName()}
|
{this.formatAppTileName()}
|
||||||
<span className="mx_AppTileMenuBarWidgets">
|
<span className="mx_AppTileMenuBarWidgets">
|
||||||
{/* Edit widget */}
|
{/* Edit widget */}
|
||||||
{/* <img
|
{showEditButton && <img
|
||||||
src="img/edit.svg"
|
src="img/edit.svg"
|
||||||
className="mx_filterFlipColor mx_AppTileMenuBarWidget mx_AppTileMenuBarWidgetPadding"
|
className="mx_filterFlipColor mx_AppTileMenuBarWidget mx_AppTileMenuBarWidgetPadding"
|
||||||
width="8" height="8" alt="Edit"
|
width="8" height="8" alt="Edit"
|
||||||
onClick={this._onEditClick}
|
onClick={this._onEditClick}
|
||||||
/> */}
|
/>}
|
||||||
|
|
||||||
{/* Delete widget */}
|
{/* Delete widget */}
|
||||||
<img src="img/cancel.svg"
|
<img src="img/cancel.svg"
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A component which wraps an EditableText, with a spinner while updates take
|
* A component which wraps an EditableText, with a spinner while updates take
|
||||||
|
@ -148,5 +148,5 @@ EditableTextContainer.defaultProps = {
|
||||||
initialValue: "",
|
initialValue: "",
|
||||||
placeholder: "",
|
placeholder: "",
|
||||||
blurToSubmit: false,
|
blurToSubmit: false,
|
||||||
onSubmit: function(v) {return q(); },
|
onSubmit: function(v) {return Promise.resolve(); },
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,7 +24,7 @@ import Modal from '../../../Modal';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import dis from '../../../dispatcher';
|
import dis from '../../../dispatcher';
|
||||||
import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
|
import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
import UserSettingsStore from '../../../UserSettingsStore';
|
import UserSettingsStore from '../../../UserSettingsStore';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ module.exports = React.createClass({
|
||||||
this.fixupHeight();
|
this.fixupHeight();
|
||||||
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) {
|
||||||
let thumbnailPromise = q(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,
|
||||||
|
|
|
@ -20,7 +20,7 @@ import React from 'react';
|
||||||
import MFileBody from './MFileBody';
|
import MFileBody from './MFileBody';
|
||||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||||
import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
|
import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
import UserSettingsStore from '../../../UserSettingsStore';
|
import UserSettingsStore from '../../../UserSettingsStore';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ 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 = q(null);
|
var 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
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var q = require("q");
|
import Promise from 'bluebird';
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var ObjectUtils = require("../../../ObjectUtils");
|
var ObjectUtils = require("../../../ObjectUtils");
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
|
@ -104,7 +104,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
if (oldCanonicalAlias !== this.state.canonicalAlias) {
|
if (oldCanonicalAlias !== this.state.canonicalAlias) {
|
||||||
console.log("AliasSettings: Updating canonical alias");
|
console.log("AliasSettings: Updating canonical alias");
|
||||||
promises = [q.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
|
||||||
|
|
|
@ -13,7 +13,7 @@ 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 q = require("q");
|
import Promise from 'bluebird';
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
|
||||||
var sdk = require('../../../index');
|
var sdk = require('../../../index');
|
||||||
|
@ -72,7 +72,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
saveSettings: function() { // : Promise
|
saveSettings: function() { // : Promise
|
||||||
if (!this.state.hasChanged) {
|
if (!this.state.hasChanged) {
|
||||||
return q(); // 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();
|
var originalState = this.getInitialState();
|
||||||
if (originalState.primary_color !== this.state.primary_color ||
|
if (originalState.primary_color !== this.state.primary_color ||
|
||||||
|
@ -92,7 +92,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return q(); // no color diff
|
return Promise.resolve(); // no color diff
|
||||||
},
|
},
|
||||||
|
|
||||||
_getColorIndex: function(scheme) {
|
_getColorIndex: function(scheme) {
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var q = require("q");
|
import Promise from 'bluebird';
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
var sdk = require("../../../index");
|
var sdk = require("../../../index");
|
||||||
|
|
|
@ -169,6 +169,7 @@ module.exports = React.createClass({
|
||||||
id={app.id}
|
id={app.id}
|
||||||
url={app.url}
|
url={app.url}
|
||||||
name={app.name}
|
name={app.name}
|
||||||
|
type={app.type}
|
||||||
fullWidth={arr.length<2 ? true : false}
|
fullWidth={arr.length<2 ? true : false}
|
||||||
room={this.props.room}
|
room={this.props.room}
|
||||||
userId={this.props.userId}
|
userId={this.props.userId}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import flatMap from 'lodash/flatMap';
|
||||||
import isEqual from 'lodash/isEqual';
|
import isEqual from 'lodash/isEqual';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
import type {Completion} from '../../../autocomplete/Autocompleter';
|
import type {Completion} from '../../../autocomplete/Autocompleter';
|
||||||
import Q from 'q';
|
import Promise from 'bluebird';
|
||||||
import UserSettingsStore from '../../../UserSettingsStore';
|
import UserSettingsStore from '../../../UserSettingsStore';
|
||||||
|
|
||||||
import {getCompletions} from '../../../autocomplete/Autocompleter';
|
import {getCompletions} from '../../../autocomplete/Autocompleter';
|
||||||
|
@ -64,7 +64,7 @@ export default class Autocomplete extends React.Component {
|
||||||
// Hide the autocomplete box
|
// Hide the autocomplete box
|
||||||
hide: true,
|
hide: true,
|
||||||
});
|
});
|
||||||
return Q(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
let autocompleteDelay = UserSettingsStore.getLocalSetting('autocompleteDelay', 200);
|
let autocompleteDelay = UserSettingsStore.getLocalSetting('autocompleteDelay', 200);
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ export default class Autocomplete extends React.Component {
|
||||||
autocompleteDelay = 0;
|
autocompleteDelay = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const deferred = Q.defer();
|
const deferred = Promise.defer();
|
||||||
this.debounceCompletionsRequest = setTimeout(() => {
|
this.debounceCompletionsRequest = setTimeout(() => {
|
||||||
this.processQuery(query, selection).then(() => {
|
this.processQuery(query, selection).then(() => {
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
@ -176,7 +176,7 @@ export default class Autocomplete extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
forceComplete() {
|
forceComplete() {
|
||||||
const done = Q.defer();
|
const done = Promise.defer();
|
||||||
this.setState({
|
this.setState({
|
||||||
forceComplete: true,
|
forceComplete: true,
|
||||||
hide: false,
|
hide: false,
|
||||||
|
|
|
@ -17,7 +17,7 @@ var React = require('react');
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
var classNames = require('classnames');
|
var classNames = require('classnames');
|
||||||
var Matrix = require("matrix-js-sdk");
|
var Matrix = require("matrix-js-sdk");
|
||||||
var q = require('q');
|
import Promise from 'bluebird';
|
||||||
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
var MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||||
var Modal = require("../../../Modal");
|
var Modal = require("../../../Modal");
|
||||||
var Entities = require("../../../Entities");
|
var Entities = require("../../../Entities");
|
||||||
|
|
|
@ -41,7 +41,6 @@ export default class MessageComposer extends React.Component {
|
||||||
this.onToggleMarkdownClicked = this.onToggleMarkdownClicked.bind(this);
|
this.onToggleMarkdownClicked = this.onToggleMarkdownClicked.bind(this);
|
||||||
this.onInputStateChanged = this.onInputStateChanged.bind(this);
|
this.onInputStateChanged = this.onInputStateChanged.bind(this);
|
||||||
this.onEvent = this.onEvent.bind(this);
|
this.onEvent = this.onEvent.bind(this);
|
||||||
this.onPageUnload = this.onPageUnload.bind(this);
|
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
autocompleteQuery: '',
|
autocompleteQuery: '',
|
||||||
|
@ -62,21 +61,12 @@ export default class MessageComposer extends React.Component {
|
||||||
// marked as encrypted.
|
// marked as encrypted.
|
||||||
// XXX: fragile as all hell - fixme somehow, perhaps with a dedicated Room.encryption event or something.
|
// XXX: fragile as all hell - fixme somehow, perhaps with a dedicated Room.encryption event or something.
|
||||||
MatrixClientPeg.get().on("event", this.onEvent);
|
MatrixClientPeg.get().on("event", this.onEvent);
|
||||||
|
|
||||||
window.addEventListener('beforeunload', this.onPageUnload);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
if (MatrixClientPeg.get()) {
|
if (MatrixClientPeg.get()) {
|
||||||
MatrixClientPeg.get().removeListener("event", this.onEvent);
|
MatrixClientPeg.get().removeListener("event", this.onEvent);
|
||||||
}
|
}
|
||||||
window.removeEventListener('beforeunload', this.onPageUnload);
|
|
||||||
}
|
|
||||||
|
|
||||||
onPageUnload(event) {
|
|
||||||
if (this.messageComposerInput) {
|
|
||||||
this.messageComposerInput.sentHistory.saveLastTextEntry();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onEvent(event) {
|
onEvent(event) {
|
||||||
|
|
|
@ -16,16 +16,17 @@ limitations under the License.
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type SyntheticKeyboardEvent from 'react/lib/SyntheticKeyboardEvent';
|
import type SyntheticKeyboardEvent from 'react/lib/SyntheticKeyboardEvent';
|
||||||
|
|
||||||
import {Editor, EditorState, RichUtils, CompositeDecorator,
|
import {Editor, EditorState, RichUtils, CompositeDecorator, Modifier,
|
||||||
convertFromRaw, convertToRaw, Modifier, EditorChangeType,
|
getDefaultKeyBinding, KeyBindingUtil, ContentState, ContentBlock, SelectionState,
|
||||||
getDefaultKeyBinding, KeyBindingUtil, ContentState, ContentBlock, SelectionState} from 'draft-js';
|
Entity} from 'draft-js';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import escape from 'lodash/escape';
|
import escape from 'lodash/escape';
|
||||||
import Q from 'q';
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||||
import type {MatrixClient} from 'matrix-js-sdk/lib/matrix';
|
import type {MatrixClient} from 'matrix-js-sdk/lib/matrix';
|
||||||
|
import {RoomMember} from 'matrix-js-sdk';
|
||||||
import SlashCommands from '../../../SlashCommands';
|
import SlashCommands from '../../../SlashCommands';
|
||||||
import KeyCode from '../../../KeyCode';
|
import KeyCode from '../../../KeyCode';
|
||||||
import Modal from '../../../Modal';
|
import Modal from '../../../Modal';
|
||||||
|
@ -43,6 +44,14 @@ import Markdown from '../../../Markdown';
|
||||||
import ComposerHistoryManager from '../../../ComposerHistoryManager';
|
import ComposerHistoryManager from '../../../ComposerHistoryManager';
|
||||||
import MessageComposerStore from '../../../stores/MessageComposerStore';
|
import MessageComposerStore from '../../../stores/MessageComposerStore';
|
||||||
|
|
||||||
|
import {MATRIXTO_URL_PATTERN} from '../../../linkify-matrix';
|
||||||
|
const REGEX_MATRIXTO = new RegExp(MATRIXTO_URL_PATTERN);
|
||||||
|
|
||||||
|
import {asciiRegexp, shortnameToUnicode, emojioneList, asciiList, mapUnicodeToShort} from 'emojione';
|
||||||
|
const EMOJI_SHORTNAMES = Object.keys(emojioneList);
|
||||||
|
const EMOJI_UNICODE_TO_SHORTNAME = mapUnicodeToShort();
|
||||||
|
const REGEX_EMOJI_WHITESPACE = new RegExp('(' + asciiRegexp + ')\\s$');
|
||||||
|
|
||||||
const TYPING_USER_TIMEOUT = 10000, TYPING_SERVER_TIMEOUT = 30000;
|
const TYPING_USER_TIMEOUT = 10000, TYPING_SERVER_TIMEOUT = 30000;
|
||||||
|
|
||||||
const ZWS_CODE = 8203;
|
const ZWS_CODE = 8203;
|
||||||
|
@ -156,15 +165,72 @@ export default class MessageComposerInput extends React.Component {
|
||||||
this.client = MatrixClientPeg.get();
|
this.client = MatrixClientPeg.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findLinkEntities(contentBlock, callback) {
|
||||||
|
contentBlock.findEntityRanges(
|
||||||
|
(character) => {
|
||||||
|
const entityKey = character.getEntity();
|
||||||
|
return (
|
||||||
|
entityKey !== null &&
|
||||||
|
Entity.get(entityKey).getType() === 'LINK'
|
||||||
|
);
|
||||||
|
}, callback,
|
||||||
|
);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* "Does the right thing" to create an EditorState, based on:
|
* "Does the right thing" to create an EditorState, based on:
|
||||||
* - whether we've got rich text mode enabled
|
* - whether we've got rich text mode enabled
|
||||||
* - contentState was passed in
|
* - contentState was passed in
|
||||||
*/
|
*/
|
||||||
createEditorState(richText: boolean, contentState: ?ContentState): EditorState {
|
createEditorState(richText: boolean, contentState: ?ContentState): EditorState {
|
||||||
let decorators = richText ? RichText.getScopedRTDecorators(this.props) :
|
const decorators = richText ? RichText.getScopedRTDecorators(this.props) :
|
||||||
RichText.getScopedMDDecorators(this.props),
|
RichText.getScopedMDDecorators(this.props);
|
||||||
compositeDecorator = new CompositeDecorator(decorators);
|
decorators.push({
|
||||||
|
strategy: this.findLinkEntities.bind(this),
|
||||||
|
component: (props) => {
|
||||||
|
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||||
|
const RoomAvatar = sdk.getComponent('avatars.RoomAvatar');
|
||||||
|
const {url} = Entity.get(props.entityKey).getData();
|
||||||
|
const matrixToMatch = REGEX_MATRIXTO.exec(url);
|
||||||
|
const isUserPill = matrixToMatch[2] === '@';
|
||||||
|
const isRoomPill = matrixToMatch[2] === '#' || matrixToMatch[2] === '!';
|
||||||
|
|
||||||
|
const classes = classNames({
|
||||||
|
"mx_UserPill": isUserPill,
|
||||||
|
"mx_RoomPill": isRoomPill,
|
||||||
|
});
|
||||||
|
|
||||||
|
let avatar = null;
|
||||||
|
if (isUserPill) {
|
||||||
|
// If this user is not a member of this room, default to the empty
|
||||||
|
// member. This could be improved by doing an async profile lookup.
|
||||||
|
const member = this.props.room.getMember(matrixToMatch[1]) ||
|
||||||
|
new RoomMember(null, matrixToMatch[1]);
|
||||||
|
avatar = member ? <MemberAvatar member={member} width={16} height={16}/> : null;
|
||||||
|
} else if (isRoomPill) {
|
||||||
|
const room = matrixToMatch[2] === '#' ?
|
||||||
|
MatrixClientPeg.get().getRooms().find((r) => {
|
||||||
|
return r.getCanonicalAlias() === matrixToMatch[1];
|
||||||
|
}) : MatrixClientPeg.get().getRoom(matrixToMatch[1]);
|
||||||
|
avatar = room ? <RoomAvatar room={room} width={16} height={16}/> : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isUserPill || isRoomPill) {
|
||||||
|
return (
|
||||||
|
<span className={classes}>
|
||||||
|
{avatar}
|
||||||
|
{props.children}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a href={url}>
|
||||||
|
{props.children}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const compositeDecorator = new CompositeDecorator(decorators);
|
||||||
|
|
||||||
let editorState = null;
|
let editorState = null;
|
||||||
if (contentState) {
|
if (contentState) {
|
||||||
|
@ -319,6 +385,60 @@ export default class MessageComposerInput extends React.Component {
|
||||||
onEditorContentChanged = (editorState: EditorState) => {
|
onEditorContentChanged = (editorState: EditorState) => {
|
||||||
editorState = RichText.attachImmutableEntitiesToEmoji(editorState);
|
editorState = RichText.attachImmutableEntitiesToEmoji(editorState);
|
||||||
|
|
||||||
|
const currentBlock = editorState.getSelection().getStartKey();
|
||||||
|
const currentSelection = editorState.getSelection();
|
||||||
|
const currentStartOffset = editorState.getSelection().getStartOffset();
|
||||||
|
|
||||||
|
const block = editorState.getCurrentContent().getBlockForKey(currentBlock);
|
||||||
|
const text = block.getText();
|
||||||
|
|
||||||
|
const entityBeforeCurrentOffset = block.getEntityAt(currentStartOffset - 1);
|
||||||
|
const entityAtCurrentOffset = block.getEntityAt(currentStartOffset);
|
||||||
|
|
||||||
|
// If the cursor is on the boundary between an entity and a non-entity and the
|
||||||
|
// text before the cursor has whitespace at the end, set the entity state of the
|
||||||
|
// character before the cursor (the whitespace) to null. This allows the user to
|
||||||
|
// stop editing the link.
|
||||||
|
if (entityBeforeCurrentOffset && !entityAtCurrentOffset &&
|
||||||
|
/\s$/.test(text.slice(0, currentStartOffset))) {
|
||||||
|
editorState = RichUtils.toggleLink(
|
||||||
|
editorState,
|
||||||
|
currentSelection.merge({
|
||||||
|
anchorOffset: currentStartOffset - 1,
|
||||||
|
focusOffset: currentStartOffset,
|
||||||
|
}),
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
// Reset selection
|
||||||
|
editorState = EditorState.forceSelection(editorState, currentSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Automatic replacement of plaintext emoji to Unicode emoji
|
||||||
|
if (UserSettingsStore.getSyncedSetting('MessageComposerInput.autoReplaceEmoji', false)) {
|
||||||
|
// The first matched group includes just the matched plaintext emoji
|
||||||
|
const emojiMatch = REGEX_EMOJI_WHITESPACE.exec(text.slice(0, currentStartOffset));
|
||||||
|
if(emojiMatch) {
|
||||||
|
// plaintext -> hex unicode
|
||||||
|
const emojiUc = asciiList[emojiMatch[1]];
|
||||||
|
// hex unicode -> shortname -> actual unicode
|
||||||
|
const unicodeEmoji = shortnameToUnicode(EMOJI_UNICODE_TO_SHORTNAME[emojiUc]);
|
||||||
|
const newContentState = Modifier.replaceText(
|
||||||
|
editorState.getCurrentContent(),
|
||||||
|
currentSelection.merge({
|
||||||
|
anchorOffset: currentStartOffset - emojiMatch[0].length,
|
||||||
|
focusOffset: currentStartOffset,
|
||||||
|
}),
|
||||||
|
unicodeEmoji,
|
||||||
|
);
|
||||||
|
editorState = EditorState.push(
|
||||||
|
editorState,
|
||||||
|
newContentState,
|
||||||
|
'insert-characters',
|
||||||
|
);
|
||||||
|
editorState = EditorState.forceSelection(editorState, newContentState.getSelectionAfter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Since a modification was made, set originalEditorState to null, since newState is now our original */
|
/* Since a modification was made, set originalEditorState to null, since newState is now our original */
|
||||||
this.setState({
|
this.setState({
|
||||||
editorState,
|
editorState,
|
||||||
|
@ -517,10 +637,13 @@ export default class MessageComposerInput extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentBlockType = RichUtils.getCurrentBlockType(this.state.editorState);
|
const currentBlockType = RichUtils.getCurrentBlockType(this.state.editorState);
|
||||||
// If we're in any of these three types of blocks, shift enter should insert soft newlines
|
if(
|
||||||
// And just enter should end the block
|
['code-block', 'blockquote', 'unordered-list-item', 'ordered-list-item']
|
||||||
// XXX: Empirically enter does not end these blocks
|
.includes(currentBlockType)
|
||||||
if(['blockquote', 'unordered-list-item', 'ordered-list-item'].includes(currentBlockType)) {
|
) {
|
||||||
|
// By returning false, we allow the default draft-js key binding to occur,
|
||||||
|
// which in this case invokes "split-block". This creates a new block of the
|
||||||
|
// same type, allowing the user to delete it with backspace.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,6 +704,15 @@ export default class MessageComposerInput extends React.Component {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (!shouldSendHTML) {
|
||||||
|
const hasLink = blocks.some((block) => {
|
||||||
|
return block.getCharacterList().filter((c) => {
|
||||||
|
const entityKey = c.getEntity();
|
||||||
|
return entityKey && Entity.get(entityKey).getType() === 'LINK';
|
||||||
|
}).size > 0;
|
||||||
|
});
|
||||||
|
shouldSendHTML = hasLink;
|
||||||
|
}
|
||||||
if (shouldSendHTML) {
|
if (shouldSendHTML) {
|
||||||
contentHTML = HtmlUtils.processHtmlForSending(
|
contentHTML = HtmlUtils.processHtmlForSending(
|
||||||
RichText.contentStateToHTML(contentState),
|
RichText.contentStateToHTML(contentState),
|
||||||
|
|
|
@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { _t, _tJsx } from '../../../languageHandler';
|
import { _t, _tJsx } from '../../../languageHandler';
|
||||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
import MatrixClientPeg from '../../../MatrixClientPeg';
|
||||||
|
@ -183,8 +183,14 @@ module.exports = React.createClass({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a promise which resolves once all of the save operations have completed or failed.
|
||||||
|
*
|
||||||
|
* The result is a list of promise state snapshots, each with the form
|
||||||
|
* `{ state: "fulfilled", value: v }` or `{ state: "rejected", reason: r }`.
|
||||||
|
*/
|
||||||
save: function() {
|
save: function() {
|
||||||
var stateWasSetDefer = q.defer();
|
var 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
|
||||||
|
@ -194,8 +200,18 @@ module.exports = React.createClass({
|
||||||
this.setState({ _loading: false});
|
this.setState({ _loading: false});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function mapPromiseToSnapshot(p) {
|
||||||
|
return p.then((r) => {
|
||||||
|
return { state: "fulfilled", value: r };
|
||||||
|
}, (e) => {
|
||||||
|
return { state: "rejected", reason: e };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return stateWasSetDefer.promise.then(() => {
|
return stateWasSetDefer.promise.then(() => {
|
||||||
return q.allSettled(this._calcSavePromises());
|
return Promise.all(
|
||||||
|
this._calcSavePromises().map(mapPromiseToSnapshot),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -282,7 +298,7 @@ module.exports = React.createClass({
|
||||||
// color scheme
|
// color scheme
|
||||||
var p;
|
var p;
|
||||||
p = this.saveColor();
|
p = this.saveColor();
|
||||||
if (!q.isFulfilled(p)) {
|
if (!p.isFulfilled()) {
|
||||||
promises.push(p);
|
promises.push(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +310,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// encryption
|
// encryption
|
||||||
p = this.saveEnableEncryption();
|
p = this.saveEnableEncryption();
|
||||||
if (!q.isFulfilled(p)) {
|
if (!p.isFulfilled()) {
|
||||||
promises.push(p);
|
promises.push(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,25 +321,25 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
saveAliases: function() {
|
saveAliases: function() {
|
||||||
if (!this.refs.alias_settings) { return [q()]; }
|
if (!this.refs.alias_settings) { return [Promise.resolve()]; }
|
||||||
return this.refs.alias_settings.saveSettings();
|
return this.refs.alias_settings.saveSettings();
|
||||||
},
|
},
|
||||||
|
|
||||||
saveColor: function() {
|
saveColor: function() {
|
||||||
if (!this.refs.color_settings) { return q(); }
|
if (!this.refs.color_settings) { return Promise.resolve(); }
|
||||||
return this.refs.color_settings.saveSettings();
|
return this.refs.color_settings.saveSettings();
|
||||||
},
|
},
|
||||||
|
|
||||||
saveUrlPreviewSettings: function() {
|
saveUrlPreviewSettings: function() {
|
||||||
if (!this.refs.url_preview_settings) { return q(); }
|
if (!this.refs.url_preview_settings) { return Promise.resolve(); }
|
||||||
return this.refs.url_preview_settings.saveSettings();
|
return this.refs.url_preview_settings.saveSettings();
|
||||||
},
|
},
|
||||||
|
|
||||||
saveEnableEncryption: function() {
|
saveEnableEncryption: function() {
|
||||||
if (!this.refs.encrypt) { return q(); }
|
if (!this.refs.encrypt) { return Promise.resolve(); }
|
||||||
|
|
||||||
var encrypt = this.refs.encrypt.checked;
|
var encrypt = this.refs.encrypt.checked;
|
||||||
if (!encrypt) { return q(); }
|
if (!encrypt) { return Promise.resolve(); }
|
||||||
|
|
||||||
var roomId = this.props.room.roomId;
|
var roomId = this.props.room.roomId;
|
||||||
return MatrixClientPeg.get().sendStateEvent(
|
return MatrixClientPeg.get().sendStateEvent(
|
||||||
|
|
|
@ -21,7 +21,7 @@ var MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||||
var Modal = require("../../../Modal");
|
var Modal = require("../../../Modal");
|
||||||
var sdk = require("../../../index");
|
var sdk = require("../../../index");
|
||||||
|
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_optionallySetEmail: function() {
|
_optionallySetEmail: function() {
|
||||||
const deferred = q.defer();
|
const deferred = Promise.defer();
|
||||||
// Ask for an email otherwise the user has no way to reset their password
|
// Ask for an email otherwise the user has no way to reset their password
|
||||||
const SetEmailDialog = sdk.getComponent("dialogs.SetEmailDialog");
|
const SetEmailDialog = sdk.getComponent("dialogs.SetEmailDialog");
|
||||||
Modal.createDialog(SetEmailDialog, {
|
Modal.createDialog(SetEmailDialog, {
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { _t } from './languageHandler';
|
||||||
import dis from "./dispatcher";
|
import dis from "./dispatcher";
|
||||||
import * as Rooms from "./Rooms";
|
import * as Rooms from "./Rooms";
|
||||||
|
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new room, and switch to it.
|
* Create a new room, and switch to it.
|
||||||
|
@ -42,7 +42,7 @@ function createRoom(opts) {
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
if (client.isGuest()) {
|
if (client.isGuest()) {
|
||||||
dis.dispatch({action: 'view_set_mxid'});
|
dis.dispatch({action: 'view_set_mxid'});
|
||||||
return q(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultPreset = opts.dmUserId ? 'trusted_private_chat' : 'private_chat';
|
const defaultPreset = opts.dmUserId ? 'trusted_private_chat' : 'private_chat';
|
||||||
|
@ -92,7 +92,7 @@ function createRoom(opts) {
|
||||||
if (opts.dmUserId) {
|
if (opts.dmUserId) {
|
||||||
return Rooms.setDMRoom(roomId, opts.dmUserId);
|
return Rooms.setDMRoom(roomId, opts.dmUserId);
|
||||||
} else {
|
} else {
|
||||||
return q();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
// NB createRoom doesn't block on the client seeing the echo that the
|
// NB createRoom doesn't block on the client seeing the echo that the
|
||||||
|
|
|
@ -956,5 +956,6 @@
|
||||||
"Featured Rooms:": "Featured Rooms:",
|
"Featured Rooms:": "Featured Rooms:",
|
||||||
"Error whilst fetching joined groups": "Error whilst fetching joined groups",
|
"Error whilst fetching joined groups": "Error whilst fetching joined groups",
|
||||||
"Featured Users:": "Featured Users:",
|
"Featured Users:": "Featured Users:",
|
||||||
"Edit Group": "Edit Group"
|
"Edit Group": "Edit Group",
|
||||||
|
"Automatically replace plain text Emoji": "Automatically replace plain text Emoji"
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
||||||
|
|
||||||
import request from 'browser-request';
|
import request from 'browser-request';
|
||||||
import counterpart from 'counterpart';
|
import counterpart from 'counterpart';
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import UserSettingsStore from './UserSettingsStore';
|
import UserSettingsStore from './UserSettingsStore';
|
||||||
|
@ -231,7 +231,7 @@ export function getCurrentLanguage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLangsJson() {
|
function getLangsJson() {
|
||||||
const deferred = q.defer();
|
const deferred = Promise.defer();
|
||||||
|
|
||||||
request(
|
request(
|
||||||
{ method: "GET", url: i18nFolder + 'languages.json' },
|
{ method: "GET", url: i18nFolder + 'languages.json' },
|
||||||
|
@ -247,7 +247,7 @@ function getLangsJson() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLanguage(langPath) {
|
function getLanguage(langPath) {
|
||||||
const deferred = q.defer();
|
const deferred = Promise.defer();
|
||||||
|
|
||||||
let response_return = {};
|
let response_return = {};
|
||||||
request(
|
request(
|
||||||
|
|
|
@ -20,7 +20,7 @@ import encrypt from 'browser-encrypt-attachment';
|
||||||
import 'isomorphic-fetch';
|
import 'isomorphic-fetch';
|
||||||
// Grab the client so that we can turn mxc:// URLs into https:// URLS.
|
// Grab the client so that we can turn mxc:// URLs into https:// URLS.
|
||||||
import MatrixClientPeg from '../MatrixClientPeg';
|
import MatrixClientPeg from '../MatrixClientPeg';
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +28,7 @@ import q from 'q';
|
||||||
* @return {Promise} A promise that resolves with the data:// URI.
|
* @return {Promise} A promise that resolves with the data:// URI.
|
||||||
*/
|
*/
|
||||||
export function readBlobAsDataUri(file) {
|
export function readBlobAsDataUri(file) {
|
||||||
var deferred = q.defer();
|
var deferred = Promise.defer();
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
reader.onload = function(e) {
|
reader.onload = function(e) {
|
||||||
deferred.resolve(e.target.result);
|
deferred.resolve(e.target.result);
|
||||||
|
@ -53,7 +53,7 @@ export function readBlobAsDataUri(file) {
|
||||||
export function decryptFile(file) {
|
export function decryptFile(file) {
|
||||||
const url = MatrixClientPeg.get().mxcUrlToHttp(file.url);
|
const url = MatrixClientPeg.get().mxcUrlToHttp(file.url);
|
||||||
// Download the encrypted file as an array buffer.
|
// Download the encrypted file as an array buffer.
|
||||||
return q(fetch(url)).then(function(response) {
|
return Promise.resolve(fetch(url)).then(function(response) {
|
||||||
return response.arrayBuffer();
|
return response.arrayBuffer();
|
||||||
}).then(function(responseData) {
|
}).then(function(responseData) {
|
||||||
// Decrypt the array buffer using the information taken from
|
// Decrypt the array buffer using the information taken from
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {getAddressType, inviteToRoom} from '../Invite';
|
import {getAddressType, inviteToRoom} from '../Invite';
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invites multiple addresses to a room, handling rate limiting from the server
|
* Invites multiple addresses to a room, handling rate limiting from the server
|
||||||
|
@ -55,7 +55,7 @@ export default class MultiInviter {
|
||||||
this.errorTexts[addr] = 'Unrecognised address';
|
this.errorTexts[addr] = 'Unrecognised address';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.deferred = q.defer();
|
this.deferred = Promise.defer();
|
||||||
this._inviteMore(0);
|
this._inviteMore(0);
|
||||||
|
|
||||||
return this.deferred.promise;
|
return this.deferred.promise;
|
||||||
|
|
|
@ -18,7 +18,7 @@ var React = require('react');
|
||||||
var ReactDOM = require("react-dom");
|
var ReactDOM = require("react-dom");
|
||||||
var ReactTestUtils = require('react-addons-test-utils');
|
var ReactTestUtils = require('react-addons-test-utils');
|
||||||
var expect = require('expect');
|
var expect = require('expect');
|
||||||
var q = require('q');
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
var sdk = require('matrix-react-sdk');
|
var sdk = require('matrix-react-sdk');
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ var Tester = React.createClass({
|
||||||
if (handler) {
|
if (handler) {
|
||||||
res = handler();
|
res = handler();
|
||||||
} else {
|
} else {
|
||||||
res = q(false);
|
res = Promise.resolve(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defer) {
|
if (defer) {
|
||||||
|
@ -74,7 +74,7 @@ var Tester = React.createClass({
|
||||||
/* returns a promise which will resolve when the fill happens */
|
/* returns a promise which will resolve when the fill happens */
|
||||||
awaitFill: function(dir) {
|
awaitFill: function(dir) {
|
||||||
console.log("ScrollPanel Tester: awaiting " + dir + " fill");
|
console.log("ScrollPanel Tester: awaiting " + dir + " fill");
|
||||||
var defer = q.defer();
|
var defer = Promise.defer();
|
||||||
this._fillDefers[dir] = defer;
|
this._fillDefers[dir] = defer;
|
||||||
return defer.promise;
|
return defer.promise;
|
||||||
},
|
},
|
||||||
|
@ -94,7 +94,7 @@ var Tester = React.createClass({
|
||||||
/* returns a promise which will resolve when a scroll event happens */
|
/* returns a promise which will resolve when a scroll event happens */
|
||||||
awaitScroll: function() {
|
awaitScroll: function() {
|
||||||
console.log("Awaiting scroll");
|
console.log("Awaiting scroll");
|
||||||
this._scrollDefer = q.defer();
|
this._scrollDefer = Promise.defer();
|
||||||
return this._scrollDefer.promise;
|
return this._scrollDefer.promise;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ describe('ScrollPanel', function() {
|
||||||
const sp = tester.scrollPanel();
|
const sp = tester.scrollPanel();
|
||||||
let retriesRemaining = 1;
|
let retriesRemaining = 1;
|
||||||
const awaitReady = function() {
|
const awaitReady = function() {
|
||||||
return q().then(() => {
|
return Promise.resolve().then(() => {
|
||||||
if (sp._pendingFillRequests.b === false &&
|
if (sp._pendingFillRequests.b === false &&
|
||||||
sp._pendingFillRequests.f === false
|
sp._pendingFillRequests.f === false
|
||||||
) {
|
) {
|
||||||
|
@ -195,7 +195,7 @@ describe('ScrollPanel', function() {
|
||||||
it('should handle scrollEvent strangeness', function() {
|
it('should handle scrollEvent strangeness', function() {
|
||||||
const events = [];
|
const events = [];
|
||||||
|
|
||||||
return q().then(() => {
|
return Promise.resolve().then(() => {
|
||||||
// initialise with a load of events
|
// initialise with a load of events
|
||||||
for (let i = 0; i < 20; i++) {
|
for (let i = 0; i < 20; i++) {
|
||||||
events.push(i+80);
|
events.push(i+80);
|
||||||
|
@ -227,7 +227,7 @@ describe('ScrollPanel', function() {
|
||||||
|
|
||||||
it('should not get stuck in #528 workaround', function(done) {
|
it('should not get stuck in #528 workaround', function(done) {
|
||||||
var events = [];
|
var events = [];
|
||||||
q().then(() => {
|
Promise.resolve().then(() => {
|
||||||
// initialise with a bunch of events
|
// initialise with a bunch of events
|
||||||
for (var i = 0; i < 40; i++) {
|
for (var i = 0; i < 40; i++) {
|
||||||
events.push(i);
|
events.push(i);
|
||||||
|
|
|
@ -18,7 +18,7 @@ var React = require('react');
|
||||||
var ReactDOM = require('react-dom');
|
var ReactDOM = require('react-dom');
|
||||||
var ReactTestUtils = require('react-addons-test-utils');
|
var ReactTestUtils = require('react-addons-test-utils');
|
||||||
var expect = require('expect');
|
var expect = require('expect');
|
||||||
var q = require('q');
|
import Promise from 'bluebird';
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
|
|
||||||
var jssdk = require('matrix-js-sdk');
|
var jssdk = require('matrix-js-sdk');
|
||||||
|
@ -145,20 +145,20 @@ describe('TimelinePanel', function() {
|
||||||
// panel isn't paginating
|
// panel isn't paginating
|
||||||
var awaitPaginationCompletion = function() {
|
var awaitPaginationCompletion = function() {
|
||||||
if(!panel.state.forwardPaginating)
|
if(!panel.state.forwardPaginating)
|
||||||
return q();
|
return Promise.resolve();
|
||||||
else
|
else
|
||||||
return q.delay(0).then(awaitPaginationCompletion);
|
return Promise.delay(0).then(awaitPaginationCompletion);
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper function which will return a promise which resolves when
|
// helper function which will return a promise which resolves when
|
||||||
// the TimelinePanel fires a scroll event
|
// the TimelinePanel fires a scroll event
|
||||||
var awaitScroll = function() {
|
var awaitScroll = function() {
|
||||||
scrollDefer = q.defer();
|
scrollDefer = Promise.defer();
|
||||||
return scrollDefer.promise;
|
return scrollDefer.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
// let the first round of pagination finish off
|
// let the first round of pagination finish off
|
||||||
q.delay(5).then(() => {
|
Promise.delay(5).then(() => {
|
||||||
expect(panel.state.canBackPaginate).toBe(false);
|
expect(panel.state.canBackPaginate).toBe(false);
|
||||||
expect(scryEventTiles(panel).length).toEqual(N_EVENTS);
|
expect(scryEventTiles(panel).length).toEqual(N_EVENTS);
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ describe('TimelinePanel', function() {
|
||||||
client.paginateEventTimeline = sinon.spy((tl, opts) => {
|
client.paginateEventTimeline = sinon.spy((tl, opts) => {
|
||||||
console.log("paginate:", opts);
|
console.log("paginate:", opts);
|
||||||
expect(opts.backwards).toBe(true);
|
expect(opts.backwards).toBe(true);
|
||||||
return q(true);
|
return Promise.resolve(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
var rendered = ReactDOM.render(
|
var rendered = ReactDOM.render(
|
||||||
|
@ -279,7 +279,7 @@ describe('TimelinePanel', function() {
|
||||||
// helper function which will return a promise which resolves when
|
// helper function which will return a promise which resolves when
|
||||||
// the TimelinePanel fires a scroll event
|
// the TimelinePanel fires a scroll event
|
||||||
var awaitScroll = function() {
|
var awaitScroll = function() {
|
||||||
scrollDefer = q.defer();
|
scrollDefer = Promise.defer();
|
||||||
|
|
||||||
return scrollDefer.promise.then(() => {
|
return scrollDefer.promise.then(() => {
|
||||||
console.log("got scroll event; scrollTop now " +
|
console.log("got scroll event; scrollTop now " +
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import expect from 'expect';
|
import expect from 'expect';
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import ReactTestUtils from 'react-addons-test-utils';
|
import ReactTestUtils from 'react-addons-test-utils';
|
||||||
|
@ -50,7 +50,7 @@ describe('InteractiveAuthDialog', function () {
|
||||||
|
|
||||||
it('Should successfully complete a password flow', function() {
|
it('Should successfully complete a password flow', function() {
|
||||||
const onFinished = sinon.spy();
|
const onFinished = sinon.spy();
|
||||||
const doRequest = sinon.stub().returns(q({a:1}));
|
const doRequest = sinon.stub().returns(Promise.resolve({a:1}));
|
||||||
|
|
||||||
// tell the stub matrixclient to return a real userid
|
// tell the stub matrixclient to return a real userid
|
||||||
var client = MatrixClientPeg.get();
|
var client = MatrixClientPeg.get();
|
||||||
|
@ -110,7 +110,7 @@ describe('InteractiveAuthDialog', function () {
|
||||||
);
|
);
|
||||||
|
|
||||||
// let the request complete
|
// let the request complete
|
||||||
return q.delay(1);
|
return Promise.delay(1);
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
expect(onFinished.callCount).toEqual(1);
|
expect(onFinished.callCount).toEqual(1);
|
||||||
expect(onFinished.calledWithExactly(true, {a:1})).toBe(true);
|
expect(onFinished.calledWithExactly(true, {a:1})).toBe(true);
|
||||||
|
|
|
@ -3,7 +3,7 @@ import ReactTestUtils from 'react-addons-test-utils';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import expect, {createSpy} from 'expect';
|
import expect, {createSpy} from 'expect';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import Q from 'q';
|
import Promise from 'bluebird';
|
||||||
import * as testUtils from '../../../test-utils';
|
import * as testUtils from '../../../test-utils';
|
||||||
import sdk from 'matrix-react-sdk';
|
import sdk from 'matrix-react-sdk';
|
||||||
import UserSettingsStore from '../../../../src/UserSettingsStore';
|
import UserSettingsStore from '../../../../src/UserSettingsStore';
|
||||||
|
@ -47,7 +47,7 @@ describe('MessageComposerInput', () => {
|
||||||
// warnings
|
// warnings
|
||||||
// (please can we make the components not setState() after
|
// (please can we make the components not setState() after
|
||||||
// they are unmounted?)
|
// they are unmounted?)
|
||||||
Q.delay(10).done(() => {
|
Promise.delay(10).done(() => {
|
||||||
if (parentDiv) {
|
if (parentDiv) {
|
||||||
ReactDOM.unmountComponentAtNode(parentDiv);
|
ReactDOM.unmountComponentAtNode(parentDiv);
|
||||||
parentDiv.remove();
|
parentDiv.remove();
|
||||||
|
|
|
@ -7,7 +7,7 @@ import RoomViewStore from '../../src/stores/RoomViewStore';
|
||||||
import peg from '../../src/MatrixClientPeg';
|
import peg from '../../src/MatrixClientPeg';
|
||||||
|
|
||||||
import * as testUtils from '../test-utils';
|
import * as testUtils from '../test-utils';
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
const dispatch = testUtils.getDispatchForStore(RoomViewStore);
|
const dispatch = testUtils.getDispatchForStore(RoomViewStore);
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ describe('RoomViewStore', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be used to view a room by alias and join', function(done) {
|
it('can be used to view a room by alias and join', function(done) {
|
||||||
peg.get().getRoomIdForAlias.returns(q({room_id: "!randomcharacters:aser.ver"}));
|
peg.get().getRoomIdForAlias.returns(Promise.resolve({room_id: "!randomcharacters:aser.ver"}));
|
||||||
peg.get().joinRoom = (roomAddress) => {
|
peg.get().joinRoom = (roomAddress) => {
|
||||||
expect(roomAddress).toBe("#somealias2:aser.ver");
|
expect(roomAddress).toBe("#somealias2:aser.ver");
|
||||||
done();
|
done();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import q from 'q';
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
import peg from '../src/MatrixClientPeg';
|
import peg from '../src/MatrixClientPeg';
|
||||||
import dis from '../src/dispatcher';
|
import dis from '../src/dispatcher';
|
||||||
|
@ -75,12 +75,12 @@ export function createTestClient() {
|
||||||
on: sinon.stub(),
|
on: sinon.stub(),
|
||||||
removeListener: sinon.stub(),
|
removeListener: sinon.stub(),
|
||||||
isRoomEncrypted: sinon.stub().returns(false),
|
isRoomEncrypted: sinon.stub().returns(false),
|
||||||
peekInRoom: sinon.stub().returns(q(mkStubRoom())),
|
peekInRoom: sinon.stub().returns(Promise.resolve(mkStubRoom())),
|
||||||
|
|
||||||
paginateEventTimeline: sinon.stub().returns(q()),
|
paginateEventTimeline: sinon.stub().returns(Promise.resolve()),
|
||||||
sendReadReceipt: sinon.stub().returns(q()),
|
sendReadReceipt: sinon.stub().returns(Promise.resolve()),
|
||||||
getRoomIdForAlias: sinon.stub().returns(q()),
|
getRoomIdForAlias: sinon.stub().returns(Promise.resolve()),
|
||||||
getProfileInfo: sinon.stub().returns(q({})),
|
getProfileInfo: sinon.stub().returns(Promise.resolve({})),
|
||||||
getAccountData: (type) => {
|
getAccountData: (type) => {
|
||||||
return mkEvent({
|
return mkEvent({
|
||||||
type,
|
type,
|
||||||
|
@ -89,9 +89,9 @@ export function createTestClient() {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setAccountData: sinon.stub(),
|
setAccountData: sinon.stub(),
|
||||||
sendTyping: sinon.stub().returns(q({})),
|
sendTyping: sinon.stub().returns(Promise.resolve({})),
|
||||||
sendTextMessage: () => q({}),
|
sendTextMessage: () => Promise.resolve({}),
|
||||||
sendHtmlMessage: () => q({}),
|
sendHtmlMessage: () => Promise.resolve({}),
|
||||||
getSyncState: () => "SYNCING",
|
getSyncState: () => "SYNCING",
|
||||||
generateClientSecret: () => "t35tcl1Ent5ECr3T",
|
generateClientSecret: () => "t35tcl1Ent5ECr3T",
|
||||||
isGuest: () => false,
|
isGuest: () => false,
|
||||||
|
@ -101,13 +101,13 @@ export function createTestClient() {
|
||||||
export function createTestRtsClient(teamMap, sidMap) {
|
export function createTestRtsClient(teamMap, sidMap) {
|
||||||
return {
|
return {
|
||||||
getTeamsConfig() {
|
getTeamsConfig() {
|
||||||
return q(Object.keys(teamMap).map((token) => teamMap[token]));
|
return Promise.resolve(Object.keys(teamMap).map((token) => teamMap[token]));
|
||||||
},
|
},
|
||||||
trackReferral(referrer, emailSid, clientSecret) {
|
trackReferral(referrer, emailSid, clientSecret) {
|
||||||
return q({team_token: sidMap[emailSid]});
|
return Promise.resolve({team_token: sidMap[emailSid]});
|
||||||
},
|
},
|
||||||
getTeam(teamToken) {
|
getTeam(teamToken) {
|
||||||
return q(teamMap[teamToken]);
|
return Promise.resolve(teamMap[teamToken]);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue