diff --git a/src/ContentMessages.js b/src/ContentMessages.js index dab8de2465..2d58622db8 100644 --- a/src/ContentMessages.js +++ b/src/ContentMessages.js @@ -59,38 +59,40 @@ export class UploadCanceledError extends Error {} * and a thumbnail key. */ function createThumbnail(element, inputWidth, inputHeight, mimeType) { - return new Promise((resolve) => { - let targetWidth = inputWidth; - let targetHeight = inputHeight; - if (targetHeight > MAX_HEIGHT) { - targetWidth = Math.floor(targetWidth * (MAX_HEIGHT / targetHeight)); - targetHeight = MAX_HEIGHT; - } - if (targetWidth > MAX_WIDTH) { - targetHeight = Math.floor(targetHeight * (MAX_WIDTH / targetWidth)); - targetWidth = MAX_WIDTH; - } + const deferred = Promise.defer(); - const canvas = document.createElement("canvas"); - canvas.width = targetWidth; - canvas.height = targetHeight; - canvas.getContext("2d").drawImage(element, 0, 0, targetWidth, targetHeight); - canvas.toBlob(function(thumbnail) { - resolve({ - info: { - thumbnail_info: { - w: targetWidth, - h: targetHeight, - mimetype: thumbnail.type, - size: thumbnail.size, - }, - w: inputWidth, - h: inputHeight, + let targetWidth = inputWidth; + let targetHeight = inputHeight; + if (targetHeight > MAX_HEIGHT) { + targetWidth = Math.floor(targetWidth * (MAX_HEIGHT / targetHeight)); + targetHeight = MAX_HEIGHT; + } + if (targetWidth > MAX_WIDTH) { + targetHeight = Math.floor(targetHeight * (MAX_WIDTH / targetWidth)); + targetWidth = MAX_WIDTH; + } + + const canvas = document.createElement("canvas"); + canvas.width = targetWidth; + canvas.height = targetHeight; + canvas.getContext("2d").drawImage(element, 0, 0, targetWidth, targetHeight); + canvas.toBlob(function(thumbnail) { + deferred.resolve({ + info: { + thumbnail_info: { + w: targetWidth, + h: targetHeight, + mimetype: thumbnail.type, + size: thumbnail.size, }, - thumbnail: thumbnail, - }); - }, mimeType); - }); + w: inputWidth, + h: inputHeight, + }, + thumbnail: thumbnail, + }); + }, mimeType); + + return deferred.promise; } /** @@ -177,29 +179,30 @@ function infoForImageFile(matrixClient, roomId, imageFile) { * @return {Promise} A promise that resolves with the video image element. */ function loadVideoElement(videoFile) { - return new Promise((resolve, reject) => { - // Load the file into an html element - const video = document.createElement("video"); + const deferred = Promise.defer(); - const reader = new FileReader(); + // Load the file into an html element + const video = document.createElement("video"); - reader.onload = function(e) { - video.src = e.target.result; + const reader = new FileReader(); + reader.onload = function(e) { + video.src = e.target.result; - // Once ready, returns its size - // Wait until we have enough data to thumbnail the first frame. - video.onloadeddata = function() { - resolve(video); - }; - video.onerror = function(e) { - reject(e); - }; + // Once ready, returns its size + // Wait until we have enough data to thumbnail the first frame. + video.onloadeddata = function() { + deferred.resolve(video); }; - reader.onerror = function(e) { - reject(e); + video.onerror = function(e) { + deferred.reject(e); }; - reader.readAsDataURL(videoFile); - }); + }; + reader.onerror = function(e) { + deferred.reject(e); + }; + reader.readAsDataURL(videoFile); + + return deferred.promise; } /** @@ -233,16 +236,16 @@ function infoForVideoFile(matrixClient, roomId, videoFile) { * is read. */ function readFileAsArrayBuffer(file) { - return new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.onload = function(e) { - resolve(e.target.result); - }; - reader.onerror = function(e) { - reject(e); - }; - reader.readAsArrayBuffer(file); - }); + const deferred = Promise.defer(); + const reader = new FileReader(); + reader.onload = function(e) { + deferred.resolve(e.target.result); + }; + reader.onerror = function(e) { + deferred.reject(e); + }; + reader.readAsArrayBuffer(file); + return deferred.promise; } /** @@ -458,34 +461,33 @@ export default class ContentMessages { content.info.mimetype = file.type; } - const prom = new Promise((resolve) => { - if (file.type.indexOf('image/') == 0) { - content.msgtype = 'm.image'; - infoForImageFile(matrixClient, roomId, file).then((imageInfo)=>{ - extend(content.info, imageInfo); - resolve(); - }, (error)=>{ - console.error(error); - content.msgtype = 'm.file'; - resolve(); - }); - } else if (file.type.indexOf('audio/') == 0) { - content.msgtype = 'm.audio'; - resolve(); - } else if (file.type.indexOf('video/') == 0) { - content.msgtype = 'm.video'; - infoForVideoFile(matrixClient, roomId, file).then((videoInfo)=>{ - extend(content.info, videoInfo); - resolve(); - }, (error)=>{ - content.msgtype = 'm.file'; - resolve(); - }); - } else { + const def = Promise.defer(); + if (file.type.indexOf('image/') == 0) { + content.msgtype = 'm.image'; + infoForImageFile(matrixClient, roomId, file).then((imageInfo)=>{ + extend(content.info, imageInfo); + def.resolve(); + }, (error)=>{ + console.error(error); content.msgtype = 'm.file'; - resolve(); - } - }); + def.resolve(); + }); + } else if (file.type.indexOf('audio/') == 0) { + content.msgtype = 'm.audio'; + def.resolve(); + } else if (file.type.indexOf('video/') == 0) { + content.msgtype = 'm.video'; + infoForVideoFile(matrixClient, roomId, file).then((videoInfo)=>{ + extend(content.info, videoInfo); + def.resolve(); + }, (error)=>{ + content.msgtype = 'm.file'; + def.resolve(); + }); + } else { + content.msgtype = 'm.file'; + def.resolve(); + } const upload = { fileName: file.name || 'Attachment', @@ -507,7 +509,7 @@ export default class ContentMessages { dis.dispatch({action: 'upload_progress', upload: upload}); } - return prom.then(function() { + return def.promise.then(function() { // XXX: upload.promise must be the promise that // is returned by uploadFile as it has an abort() // method hacked onto it. diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 53a9b7a998..13f3abccb1 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -312,14 +312,18 @@ async function _restoreFromLocalStorage(opts) { function _handleLoadSessionFailure(e) { console.error("Unable to load session", e); + const def = Promise.defer(); const SessionRestoreErrorDialog = sdk.getComponent('views.dialogs.SessionRestoreErrorDialog'); - const modal = Modal.createTrackedDialog('Session Restore Error', '', SessionRestoreErrorDialog, { + Modal.createTrackedDialog('Session Restore Error', '', SessionRestoreErrorDialog, { error: e.message, + onFinished: (success) => { + def.resolve(success); + }, }); - return modal.finished.then(([success]) => { + return def.promise.then((success) => { if (success) { // user clicked continue. _clearStorage(); diff --git a/src/components/views/rooms/Autocomplete.js b/src/components/views/rooms/Autocomplete.js index d4b51081f4..ad5fa198a3 100644 --- a/src/components/views/rooms/Autocomplete.js +++ b/src/components/views/rooms/Autocomplete.js @@ -26,7 +26,6 @@ import { Room } from 'matrix-js-sdk'; import SettingsStore from "../../../settings/SettingsStore"; import Autocompleter from '../../../autocomplete/Autocompleter'; -import {sleep} from "../../../utils/promise"; const COMPOSER_SELECTED = 0; @@ -106,11 +105,13 @@ export default class Autocomplete extends React.Component { autocompleteDelay = 0; } - return new Promise((resolve) => { - this.debounceCompletionsRequest = setTimeout(() => { - resolve(this.processQuery(query, selection)); - }, autocompleteDelay); - }); + const deferred = Promise.defer(); + this.debounceCompletionsRequest = setTimeout(() => { + this.processQuery(query, selection).then(() => { + deferred.resolve(); + }); + }, autocompleteDelay); + return deferred.promise; } processQuery(query, selection) { @@ -196,16 +197,16 @@ export default class Autocomplete extends React.Component { } forceComplete() { - return new Promise((resolve) => { - this.setState({ - forceComplete: true, - hide: false, - }, () => { - this.complete(this.props.query, this.props.selection).then(() => { - resolve(this.countCompletions()); - }); + const done = Promise.defer(); + this.setState({ + forceComplete: true, + hide: false, + }, () => { + this.complete(this.props.query, this.props.selection).then(() => { + done.resolve(this.countCompletions()); }); }); + return done.promise; } onCompletionClicked(selectionOffset: number): boolean { diff --git a/src/components/views/settings/ChangePassword.js b/src/components/views/settings/ChangePassword.js index 91292b19f9..a086efaa6d 100644 --- a/src/components/views/settings/ChangePassword.js +++ b/src/components/views/settings/ChangePassword.js @@ -178,12 +178,17 @@ module.exports = createReactClass({ }, _optionallySetEmail: function() { + const deferred = Promise.defer(); // Ask for an email otherwise the user has no way to reset their password const SetEmailDialog = sdk.getComponent("dialogs.SetEmailDialog"); - const modal = Modal.createTrackedDialog('Do you want to set an email address?', '', SetEmailDialog, { + Modal.createTrackedDialog('Do you want to set an email address?', '', SetEmailDialog, { title: _t('Do you want to set an email address?'), + onFinished: (confirmed) => { + // ignore confirmed, setting an email is optional + deferred.resolve(confirmed); + }, }); - return modal.finished.then(([confirmed]) => confirmed); + return deferred.promise; }, _onExportE2eKeysClicked: function() { diff --git a/src/rageshake/submit-rageshake.js b/src/rageshake/submit-rageshake.js index e772912e48..99c412a6ab 100644 --- a/src/rageshake/submit-rageshake.js +++ b/src/rageshake/submit-rageshake.js @@ -105,22 +105,26 @@ export default async function sendBugReport(bugReportEndpoint, opts) { } function _submitReport(endpoint, body, progressCallback) { - return new Promise((resolve, reject) => { - const req = new XMLHttpRequest(); - req.open("POST", endpoint); - req.timeout = 5 * 60 * 1000; - req.onreadystatechange = function() { - if (req.readyState === XMLHttpRequest.LOADING) { - progressCallback(_t("Waiting for response from server")); - } else if (req.readyState === XMLHttpRequest.DONE) { - // on done - if (req.status < 200 || req.status >= 400) { - reject(new Error(`HTTP ${req.status}`)); - return; - } - resolve(); - } - }; - req.send(body); - }); + const deferred = Promise.defer(); + + const req = new XMLHttpRequest(); + req.open("POST", endpoint); + req.timeout = 5 * 60 * 1000; + req.onreadystatechange = function() { + if (req.readyState === XMLHttpRequest.LOADING) { + progressCallback(_t("Waiting for response from server")); + } else if (req.readyState === XMLHttpRequest.DONE) { + on_done(); + } + }; + req.send(body); + return deferred.promise; + + function on_done() { + if (req.status < 200 || req.status >= 400) { + deferred.reject(new Error(`HTTP ${req.status}`)); + return; + } + deferred.resolve(); + } }