mirror of
https://github.com/element-hq/element-web
synced 2024-11-27 11:47:23 +03:00
Merge pull request #3618 from matrix-org/t3chguy/remove_bluebird_2
Remove Bluebird: phase 2.1
This commit is contained in:
commit
1ab9b82c25
8 changed files with 46 additions and 35 deletions
|
@ -21,6 +21,7 @@ import MultiInviter from './utils/MultiInviter';
|
||||||
import { _t } from './languageHandler';
|
import { _t } from './languageHandler';
|
||||||
import MatrixClientPeg from './MatrixClientPeg';
|
import MatrixClientPeg from './MatrixClientPeg';
|
||||||
import GroupStore from './stores/GroupStore';
|
import GroupStore from './stores/GroupStore';
|
||||||
|
import {allSettled} from "./utils/promise";
|
||||||
|
|
||||||
export function showGroupInviteDialog(groupId) {
|
export function showGroupInviteDialog(groupId) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -118,7 +119,7 @@ function _onGroupInviteFinished(groupId, addrs) {
|
||||||
function _onGroupAddRoomFinished(groupId, addrs, addRoomsPublicly) {
|
function _onGroupAddRoomFinished(groupId, addrs, addRoomsPublicly) {
|
||||||
const matrixClient = MatrixClientPeg.get();
|
const matrixClient = MatrixClientPeg.get();
|
||||||
const errorList = [];
|
const errorList = [];
|
||||||
return Promise.all(addrs.map((addr) => {
|
return allSettled(addrs.map((addr) => {
|
||||||
return GroupStore
|
return GroupStore
|
||||||
.addRoomToGroup(groupId, addr.address, addRoomsPublicly)
|
.addRoomToGroup(groupId, addr.address, addRoomsPublicly)
|
||||||
.catch(() => { errorList.push(addr.address); })
|
.catch(() => { errorList.push(addr.address); })
|
||||||
|
@ -138,7 +139,7 @@ function _onGroupAddRoomFinished(groupId, addrs, addRoomsPublicly) {
|
||||||
groups.push(groupId);
|
groups.push(groupId);
|
||||||
return MatrixClientPeg.get().sendStateEvent(roomId, 'm.room.related_groups', {groups}, '');
|
return MatrixClientPeg.get().sendStateEvent(roomId, 'm.room.related_groups', {groups}, '');
|
||||||
}
|
}
|
||||||
}).reflect();
|
});
|
||||||
})).then(() => {
|
})).then(() => {
|
||||||
if (errorList.length === 0) {
|
if (errorList.length === 0) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -27,6 +27,7 @@ import UserProvider from './UserProvider';
|
||||||
import EmojiProvider from './EmojiProvider';
|
import EmojiProvider from './EmojiProvider';
|
||||||
import NotifProvider from './NotifProvider';
|
import NotifProvider from './NotifProvider';
|
||||||
import Promise from 'bluebird';
|
import Promise from 'bluebird';
|
||||||
|
import {timeout} from "../utils/promise";
|
||||||
|
|
||||||
export type SelectionRange = {
|
export type SelectionRange = {
|
||||||
beginning: boolean, // whether the selection is in the first block of the editor or not
|
beginning: boolean, // whether the selection is in the first block of the editor or not
|
||||||
|
@ -77,23 +78,16 @@ export default class Autocompleter {
|
||||||
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
|
||||||
*/
|
*/
|
||||||
const completionsList = await Promise.all(
|
const completionsList = await Promise.all(this.providers.map(provider => {
|
||||||
// Array of inspections of promises that might timeout. Instead of allowing a
|
return timeout(provider.getCompletions(query, selection, force), null, PROVIDER_COMPLETION_TIMEOUT);
|
||||||
// single timeout to reject the Promise.all, reflect each one and once they've all
|
}));
|
||||||
// settled, filter for the fulfilled ones
|
|
||||||
this.providers.map(provider =>
|
// map then filter to maintain the index for the map-operation, for this.providers to line up
|
||||||
provider
|
return completionsList.map((completions, i) => {
|
||||||
.getCompletions(query, selection, force)
|
if (!completions || !completions.length) return;
|
||||||
.timeout(PROVIDER_COMPLETION_TIMEOUT)
|
|
||||||
.reflect(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
return completionsList.filter(
|
|
||||||
(inspection) => inspection.isFulfilled(),
|
|
||||||
).map((completionsState, i) => {
|
|
||||||
return {
|
return {
|
||||||
completions: completionsState.value(),
|
completions,
|
||||||
provider: this.providers[i],
|
provider: this.providers[i],
|
||||||
|
|
||||||
/* the currently matched "command" the completer tried to complete
|
/* the currently matched "command" the completer tried to complete
|
||||||
|
@ -102,6 +96,6 @@ export default class Autocompleter {
|
||||||
*/
|
*/
|
||||||
command: this.providers[i].getCurrentCommand(query, selection, force),
|
command: this.providers[i].getCurrentCommand(query, selection, force),
|
||||||
};
|
};
|
||||||
});
|
}).filter(Boolean);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ import FlairStore from '../../stores/FlairStore';
|
||||||
import { showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
import { showGroupAddRoomDialog } from '../../GroupAddressPicker';
|
||||||
import {makeGroupPermalink, makeUserPermalink} from "../../utils/permalinks/Permalinks";
|
import {makeGroupPermalink, makeUserPermalink} from "../../utils/permalinks/Permalinks";
|
||||||
import {Group} from "matrix-js-sdk";
|
import {Group} from "matrix-js-sdk";
|
||||||
import {sleep} from "../../utils/promise";
|
import {allSettled, sleep} from "../../utils/promise";
|
||||||
|
|
||||||
const LONG_DESC_PLACEHOLDER = _td(
|
const LONG_DESC_PLACEHOLDER = _td(
|
||||||
`<h1>HTML for your community's page</h1>
|
`<h1>HTML for your community's page</h1>
|
||||||
|
@ -99,11 +99,10 @@ const CategoryRoomList = createReactClass({
|
||||||
onFinished: (success, addrs) => {
|
onFinished: (success, addrs) => {
|
||||||
if (!success) return;
|
if (!success) return;
|
||||||
const errorList = [];
|
const errorList = [];
|
||||||
Promise.all(addrs.map((addr) => {
|
allSettled(addrs.map((addr) => {
|
||||||
return GroupStore
|
return GroupStore
|
||||||
.addRoomToGroupSummary(this.props.groupId, addr.address)
|
.addRoomToGroupSummary(this.props.groupId, addr.address)
|
||||||
.catch(() => { errorList.push(addr.address); })
|
.catch(() => { errorList.push(addr.address); });
|
||||||
.reflect();
|
|
||||||
})).then(() => {
|
})).then(() => {
|
||||||
if (errorList.length === 0) {
|
if (errorList.length === 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -276,11 +275,10 @@ const RoleUserList = createReactClass({
|
||||||
onFinished: (success, addrs) => {
|
onFinished: (success, addrs) => {
|
||||||
if (!success) return;
|
if (!success) return;
|
||||||
const errorList = [];
|
const errorList = [];
|
||||||
Promise.all(addrs.map((addr) => {
|
allSettled(addrs.map((addr) => {
|
||||||
return GroupStore
|
return GroupStore
|
||||||
.addUserToGroupSummary(addr.address)
|
.addUserToGroupSummary(addr.address)
|
||||||
.catch(() => { errorList.push(addr.address); })
|
.catch(() => { errorList.push(addr.address); });
|
||||||
.reflect();
|
|
||||||
})).then(() => {
|
})).then(() => {
|
||||||
if (errorList.length === 0) {
|
if (errorList.length === 0) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1064,8 +1064,6 @@ const TimelinePanel = createReactClass({
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let prom = this._timelineWindow.load(eventId, INITIAL_SIZE);
|
|
||||||
|
|
||||||
// if we already have the event in question, TimelineWindow.load
|
// if we already have the event in question, TimelineWindow.load
|
||||||
// returns a resolved promise.
|
// returns a resolved promise.
|
||||||
//
|
//
|
||||||
|
@ -1074,9 +1072,13 @@ const TimelinePanel = createReactClass({
|
||||||
// quite slow. So we detect that situation and shortcut straight to
|
// quite slow. So we detect that situation and shortcut straight to
|
||||||
// calling _reloadEvents and updating the state.
|
// calling _reloadEvents and updating the state.
|
||||||
|
|
||||||
if (prom.isFulfilled()) {
|
const timeline = this.props.timelineSet.getTimelineForEvent(eventId);
|
||||||
|
if (timeline) {
|
||||||
|
// This is a hot-path optimization by skipping a promise tick
|
||||||
|
// by repeating a no-op sync branch in TimelineSet.getTimelineForEvent & MatrixClient.getEventTimeline
|
||||||
onLoaded();
|
onLoaded();
|
||||||
} else {
|
} else {
|
||||||
|
const prom = this._timelineWindow.load(eventId, INITIAL_SIZE);
|
||||||
this.setState({
|
this.setState({
|
||||||
events: [],
|
events: [],
|
||||||
liveEvents: [],
|
liveEvents: [],
|
||||||
|
@ -1084,11 +1086,8 @@ const TimelinePanel = createReactClass({
|
||||||
canForwardPaginate: false,
|
canForwardPaginate: false,
|
||||||
timelineLoading: true,
|
timelineLoading: true,
|
||||||
});
|
});
|
||||||
|
prom.then(onLoaded, onError);
|
||||||
prom = prom.then(onLoaded, onError);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prom.done();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// handle the completion of a timeline load or localEchoUpdate, by
|
// handle the completion of a timeline load or localEchoUpdate, by
|
||||||
|
|
|
@ -47,3 +47,20 @@ export function defer(): {resolve: () => {}, reject: () => {}, promise: Promise}
|
||||||
|
|
||||||
return {resolve, reject, promise};
|
return {resolve, reject, promise};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Promise.allSettled polyfill until browser support is stable in Firefox
|
||||||
|
export function allSettled(promises: Promise[]): {status: string, value?: any, reason?: any}[] {
|
||||||
|
if (Promise.allSettled) {
|
||||||
|
return Promise.allSettled(promises);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(promises.map((promise) => {
|
||||||
|
return promise.then(value => ({
|
||||||
|
status: "fulfilled",
|
||||||
|
value,
|
||||||
|
})).catch(reason => ({
|
||||||
|
status: "rejected",
|
||||||
|
reason,
|
||||||
|
}));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import sdk from 'matrix-react-sdk';
|
||||||
import MatrixClientPeg from '../../../../src/MatrixClientPeg';
|
import MatrixClientPeg from '../../../../src/MatrixClientPeg';
|
||||||
|
|
||||||
import * as test_utils from '../../../test-utils';
|
import * as test_utils from '../../../test-utils';
|
||||||
|
import {sleep} from "../../../../src/utils/promise";
|
||||||
|
|
||||||
const InteractiveAuthDialog = sdk.getComponent(
|
const InteractiveAuthDialog = sdk.getComponent(
|
||||||
'views.dialogs.InteractiveAuthDialog',
|
'views.dialogs.InteractiveAuthDialog',
|
||||||
|
@ -107,7 +108,7 @@ describe('InteractiveAuthDialog', function() {
|
||||||
},
|
},
|
||||||
})).toBe(true);
|
})).toBe(true);
|
||||||
// let the request complete
|
// let the request complete
|
||||||
return Promise.delay(1);
|
return sleep(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);
|
||||||
|
|
|
@ -8,6 +8,7 @@ import * as testUtils from '../../../test-utils';
|
||||||
import sdk from 'matrix-react-sdk';
|
import sdk from 'matrix-react-sdk';
|
||||||
const MessageComposerInput = sdk.getComponent('views.rooms.MessageComposerInput');
|
const MessageComposerInput = sdk.getComponent('views.rooms.MessageComposerInput');
|
||||||
import MatrixClientPeg from '../../../../src/MatrixClientPeg';
|
import MatrixClientPeg from '../../../../src/MatrixClientPeg';
|
||||||
|
import {sleep} from "../../../../src/utils/promise";
|
||||||
|
|
||||||
function addTextToDraft(text) {
|
function addTextToDraft(text) {
|
||||||
const components = document.getElementsByClassName('public-DraftEditor-content');
|
const components = document.getElementsByClassName('public-DraftEditor-content');
|
||||||
|
@ -49,7 +50,7 @@ xdescribe('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?)
|
||||||
Promise.delay(10).done(() => {
|
sleep(10).done(() => {
|
||||||
if (parentDiv) {
|
if (parentDiv) {
|
||||||
ReactDOM.unmountComponentAtNode(parentDiv);
|
ReactDOM.unmountComponentAtNode(parentDiv);
|
||||||
parentDiv.remove();
|
parentDiv.remove();
|
||||||
|
|
|
@ -61,7 +61,7 @@ module.exports = async function signup(session, username, password, homeserver)
|
||||||
await session.query(".mx_Field_valid #mx_RegistrationForm_password");
|
await session.query(".mx_Field_valid #mx_RegistrationForm_password");
|
||||||
//check no errors
|
//check no errors
|
||||||
const errorText = await session.tryGetInnertext('.mx_Login_error');
|
const errorText = await session.tryGetInnertext('.mx_Login_error');
|
||||||
assert.strictEqual(!!errorText, false);
|
assert.strictEqual(errorText, null);
|
||||||
//submit form
|
//submit form
|
||||||
//await page.screenshot({path: "beforesubmit.png", fullPage: true});
|
//await page.screenshot({path: "beforesubmit.png", fullPage: true});
|
||||||
await registerButton.click();
|
await registerButton.click();
|
||||||
|
|
Loading…
Reference in a new issue