Merge pull request #5665 from matrix-org/t3chguy/spaces1
Discard some dead code
This commit is contained in:
commit
a794bfdd3e
13 changed files with 15 additions and 395 deletions
|
@ -1,113 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2016 OpenMarket Ltd
|
|
||||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For two objects of the form { key: [val1, val2, val3] }, work out the added/removed
|
|
||||||
* values. Entirely new keys will result in the entire value array being added.
|
|
||||||
* @param {Object} before
|
|
||||||
* @param {Object} after
|
|
||||||
* @return {Object[]} An array of objects with the form:
|
|
||||||
* { key: $KEY, val: $VALUE, place: "add|del" }
|
|
||||||
*/
|
|
||||||
export function getKeyValueArrayDiffs(before, after) {
|
|
||||||
const results = [];
|
|
||||||
const delta = {};
|
|
||||||
Object.keys(before).forEach(function(beforeKey) {
|
|
||||||
delta[beforeKey] = delta[beforeKey] || 0; // init to 0 initially
|
|
||||||
delta[beforeKey]--; // keys present in the past have -ve values
|
|
||||||
});
|
|
||||||
Object.keys(after).forEach(function(afterKey) {
|
|
||||||
delta[afterKey] = delta[afterKey] || 0; // init to 0 initially
|
|
||||||
delta[afterKey]++; // keys present in the future have +ve values
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.keys(delta).forEach(function(muxedKey) {
|
|
||||||
switch (delta[muxedKey]) {
|
|
||||||
case 1: // A new key in after
|
|
||||||
after[muxedKey].forEach(function(afterVal) {
|
|
||||||
results.push({ place: "add", key: muxedKey, val: afterVal });
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case -1: // A before key was removed
|
|
||||||
before[muxedKey].forEach(function(beforeVal) {
|
|
||||||
results.push({ place: "del", key: muxedKey, val: beforeVal });
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 0: {// A mix of added/removed keys
|
|
||||||
// compare old & new vals
|
|
||||||
const itemDelta = {};
|
|
||||||
before[muxedKey].forEach(function(beforeVal) {
|
|
||||||
itemDelta[beforeVal] = itemDelta[beforeVal] || 0;
|
|
||||||
itemDelta[beforeVal]--;
|
|
||||||
});
|
|
||||||
after[muxedKey].forEach(function(afterVal) {
|
|
||||||
itemDelta[afterVal] = itemDelta[afterVal] || 0;
|
|
||||||
itemDelta[afterVal]++;
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.keys(itemDelta).forEach(function(item) {
|
|
||||||
if (itemDelta[item] === 1) {
|
|
||||||
results.push({ place: "add", key: muxedKey, val: item });
|
|
||||||
} else if (itemDelta[item] === -1) {
|
|
||||||
results.push({ place: "del", key: muxedKey, val: item });
|
|
||||||
} else {
|
|
||||||
// itemDelta of 0 means it was unchanged between before/after
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
console.error("Calculated key delta of " + delta[muxedKey] + " - this should never happen!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shallow-compare two objects for equality: each key and value must be identical
|
|
||||||
* @param {Object} objA First object to compare against the second
|
|
||||||
* @param {Object} objB Second object to compare against the first
|
|
||||||
* @return {boolean} whether the two objects have same key=values
|
|
||||||
*/
|
|
||||||
export function shallowEqual(objA, objB) {
|
|
||||||
if (objA === objB) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof objA !== 'object' || objA === null ||
|
|
||||||
typeof objB !== 'object' || objB === null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const keysA = Object.keys(objA);
|
|
||||||
const keysB = Object.keys(objB);
|
|
||||||
|
|
||||||
if (keysA.length !== keysB.length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < keysA.length; i++) {
|
|
||||||
const key = keysA[i];
|
|
||||||
if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2018 New Vector Ltd
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import SdkConfig from './SdkConfig';
|
|
||||||
import {hashCode} from './utils/FormattingUtils';
|
|
||||||
|
|
||||||
export function phasedRollOutExpiredForUser(username, feature, now, rollOutConfig = SdkConfig.get().phasedRollOut) {
|
|
||||||
if (!rollOutConfig) {
|
|
||||||
console.log(`no phased rollout configuration, so enabling ${feature}`);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const featureConfig = rollOutConfig[feature];
|
|
||||||
if (!featureConfig) {
|
|
||||||
console.log(`${feature} doesn't have phased rollout configured, so enabling`);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!Number.isFinite(featureConfig.offset) || !Number.isFinite(featureConfig.period)) {
|
|
||||||
console.error(`phased rollout of ${feature} is misconfigured, ` +
|
|
||||||
`offset and/or period are not numbers, so disabling`, featureConfig);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const hash = hashCode(username);
|
|
||||||
//ms -> min, enable users at minute granularity
|
|
||||||
const bucketRatio = 1000 * 60;
|
|
||||||
const bucketCount = featureConfig.period / bucketRatio;
|
|
||||||
const userBucket = hash % bucketCount;
|
|
||||||
const userMs = userBucket * bucketRatio;
|
|
||||||
const enableAt = featureConfig.offset + userMs;
|
|
||||||
const result = now >= enableAt;
|
|
||||||
const bucketStr = `(bucket ${userBucket}/${bucketCount})`;
|
|
||||||
if (result) {
|
|
||||||
console.log(`${feature} enabled for ${username} ${bucketStr}`);
|
|
||||||
} else {
|
|
||||||
console.log(`${feature} will be enabled for ${username} in ${Math.ceil((enableAt - now)/1000)}s ${bucketStr}`);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
|
@ -38,7 +38,6 @@ import CallHandler from '../../CallHandler';
|
||||||
import dis from '../../dispatcher/dispatcher';
|
import dis from '../../dispatcher/dispatcher';
|
||||||
import Tinter from '../../Tinter';
|
import Tinter from '../../Tinter';
|
||||||
import rateLimitedFunc from '../../ratelimitedfunc';
|
import rateLimitedFunc from '../../ratelimitedfunc';
|
||||||
import * as ObjectUtils from '../../ObjectUtils';
|
|
||||||
import * as Rooms from '../../Rooms';
|
import * as Rooms from '../../Rooms';
|
||||||
import eventSearch, { searchPagination } from '../../Searching';
|
import eventSearch, { searchPagination } from '../../Searching';
|
||||||
import { isOnlyCtrlOrCmdIgnoreShiftKeyEvent, Key } from '../../Keyboard';
|
import { isOnlyCtrlOrCmdIgnoreShiftKeyEvent, Key } from '../../Keyboard';
|
||||||
|
@ -80,6 +79,7 @@ import Notifier from "../../Notifier";
|
||||||
import { showToast as showNotificationsToast } from "../../toasts/DesktopNotificationsToast";
|
import { showToast as showNotificationsToast } from "../../toasts/DesktopNotificationsToast";
|
||||||
import { RoomNotificationStateStore } from "../../stores/notifications/RoomNotificationStateStore";
|
import { RoomNotificationStateStore } from "../../stores/notifications/RoomNotificationStateStore";
|
||||||
import { Container, WidgetLayoutStore } from "../../stores/widgets/WidgetLayoutStore";
|
import { Container, WidgetLayoutStore } from "../../stores/widgets/WidgetLayoutStore";
|
||||||
|
import { objectHasDiff } from "../../utils/objects";
|
||||||
|
|
||||||
const DEBUG = false;
|
const DEBUG = false;
|
||||||
let debuglog = function(msg: string) {};
|
let debuglog = function(msg: string) {};
|
||||||
|
@ -523,8 +523,7 @@ export default class RoomView extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
return (!ObjectUtils.shallowEqual(this.props, nextProps) ||
|
return (objectHasDiff(this.props, nextProps) || objectHasDiff(this.state, nextState));
|
||||||
!ObjectUtils.shallowEqual(this.state, nextState));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
|
|
|
@ -26,7 +26,6 @@ import {EventTimeline} from "matrix-js-sdk";
|
||||||
import * as Matrix from "matrix-js-sdk";
|
import * as Matrix from "matrix-js-sdk";
|
||||||
import { _t } from '../../languageHandler';
|
import { _t } from '../../languageHandler';
|
||||||
import {MatrixClientPeg} from "../../MatrixClientPeg";
|
import {MatrixClientPeg} from "../../MatrixClientPeg";
|
||||||
import * as ObjectUtils from "../../ObjectUtils";
|
|
||||||
import UserActivity from "../../UserActivity";
|
import UserActivity from "../../UserActivity";
|
||||||
import Modal from "../../Modal";
|
import Modal from "../../Modal";
|
||||||
import dis from "../../dispatcher/dispatcher";
|
import dis from "../../dispatcher/dispatcher";
|
||||||
|
@ -37,6 +36,7 @@ import shouldHideEvent from '../../shouldHideEvent';
|
||||||
import EditorStateTransfer from '../../utils/EditorStateTransfer';
|
import EditorStateTransfer from '../../utils/EditorStateTransfer';
|
||||||
import {haveTileForEvent} from "../views/rooms/EventTile";
|
import {haveTileForEvent} from "../views/rooms/EventTile";
|
||||||
import {UIFeature} from "../../settings/UIFeature";
|
import {UIFeature} from "../../settings/UIFeature";
|
||||||
|
import {objectHasDiff} from "../../utils/objects";
|
||||||
|
|
||||||
const PAGINATE_SIZE = 20;
|
const PAGINATE_SIZE = 20;
|
||||||
const INITIAL_SIZE = 20;
|
const INITIAL_SIZE = 20;
|
||||||
|
@ -261,7 +261,7 @@ class TimelinePanel extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
if (!ObjectUtils.shallowEqual(this.props, nextProps)) {
|
if (objectHasDiff(this.props, nextProps)) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
console.group("Timeline.shouldComponentUpdate: props change");
|
console.group("Timeline.shouldComponentUpdate: props change");
|
||||||
console.log("props before:", this.props);
|
console.log("props before:", this.props);
|
||||||
|
@ -271,7 +271,7 @@ class TimelinePanel extends React.Component {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ObjectUtils.shallowEqual(this.state, nextState)) {
|
if (objectHasDiff(this.state, nextState)) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
console.group("Timeline.shouldComponentUpdate: state change");
|
console.group("Timeline.shouldComponentUpdate: state change");
|
||||||
console.log("state before:", this.state);
|
console.log("state before:", this.state);
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2017 Vector Creations Ltd
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import * as sdk from '../../../index';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { _t } from '../../../languageHandler';
|
|
||||||
import {Action} from "../../../dispatcher/actions";
|
|
||||||
|
|
||||||
const RoomDirectoryButton = function(props) {
|
|
||||||
const ActionButton = sdk.getComponent('elements.ActionButton');
|
|
||||||
return (
|
|
||||||
<ActionButton action={Action.ViewRoomDirectory}
|
|
||||||
mouseOverAction={props.callout ? "callout_room_directory" : null}
|
|
||||||
label={_t("Room directory")}
|
|
||||||
iconPath={require("../../../../res/img/icons-directory.svg")}
|
|
||||||
size={props.size}
|
|
||||||
tooltip={props.tooltip}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
RoomDirectoryButton.propTypes = {
|
|
||||||
size: PropTypes.string,
|
|
||||||
tooltip: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default RoomDirectoryButton;
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2017 Vector Creations Ltd
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import * as sdk from '../../../index';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { _t } from '../../../languageHandler';
|
|
||||||
|
|
||||||
const StartChatButton = function(props) {
|
|
||||||
const ActionButton = sdk.getComponent('elements.ActionButton');
|
|
||||||
return (
|
|
||||||
<ActionButton action="view_create_chat"
|
|
||||||
mouseOverAction={props.callout ? "callout_start_chat" : null}
|
|
||||||
label={_t("Start chat")}
|
|
||||||
iconPath={require("../../../../res/img/icons-people.svg")}
|
|
||||||
size={props.size}
|
|
||||||
tooltip={props.tooltip}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
StartChatButton.propTypes = {
|
|
||||||
size: PropTypes.string,
|
|
||||||
tooltip: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default StartChatButton;
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2017 New Vector Ltd
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import TintableSvg from './TintableSvg';
|
|
||||||
import AccessibleButton from './AccessibleButton';
|
|
||||||
|
|
||||||
export default class TintableSvgButton extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let classes = "mx_TintableSvgButton";
|
|
||||||
if (this.props.className) {
|
|
||||||
classes += " " + this.props.className;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<span
|
|
||||||
width={this.props.width}
|
|
||||||
height={this.props.height}
|
|
||||||
className={classes}>
|
|
||||||
<TintableSvg
|
|
||||||
src={this.props.src}
|
|
||||||
width={this.props.width}
|
|
||||||
height={this.props.height}
|
|
||||||
></TintableSvg>
|
|
||||||
<AccessibleButton
|
|
||||||
onClick={this.props.onClick}
|
|
||||||
element='span'
|
|
||||||
title={this.props.title}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TintableSvgButton.propTypes = {
|
|
||||||
src: PropTypes.string,
|
|
||||||
title: PropTypes.string,
|
|
||||||
className: PropTypes.string,
|
|
||||||
width: PropTypes.string.isRequired,
|
|
||||||
height: PropTypes.string.isRequired,
|
|
||||||
onClick: PropTypes.func,
|
|
||||||
};
|
|
||||||
|
|
||||||
TintableSvgButton.defaultProps = {
|
|
||||||
onClick: function() {},
|
|
||||||
};
|
|
|
@ -19,7 +19,6 @@ import {MatrixClientPeg} from "../../../MatrixClientPeg";
|
||||||
import { Room } from 'matrix-js-sdk/src/models/room'
|
import { Room } from 'matrix-js-sdk/src/models/room'
|
||||||
import * as sdk from '../../../index';
|
import * as sdk from '../../../index';
|
||||||
import dis from "../../../dispatcher/dispatcher";
|
import dis from "../../../dispatcher/dispatcher";
|
||||||
import * as ObjectUtils from '../../../ObjectUtils';
|
|
||||||
import AppsDrawer from './AppsDrawer';
|
import AppsDrawer from './AppsDrawer';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
@ -29,6 +28,7 @@ import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
|
||||||
import {UIFeature} from "../../../settings/UIFeature";
|
import {UIFeature} from "../../../settings/UIFeature";
|
||||||
import { ResizeNotifier } from "../../../utils/ResizeNotifier";
|
import { ResizeNotifier } from "../../../utils/ResizeNotifier";
|
||||||
import CallViewForRoom from '../voip/CallViewForRoom';
|
import CallViewForRoom from '../voip/CallViewForRoom';
|
||||||
|
import {objectHasDiff} from "../../../utils/objects";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
// js-sdk room object
|
// js-sdk room object
|
||||||
|
@ -89,8 +89,7 @@ export default class AuxPanel extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
return (!ObjectUtils.shallowEqual(this.props, nextProps) ||
|
return objectHasDiff(this.props, nextProps) || objectHasDiff(this.state, nextState);
|
||||||
!ObjectUtils.shallowEqual(this.state, nextState));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
componentDidUpdate(prevProps, prevState) {
|
||||||
|
|
|
@ -32,13 +32,13 @@ import {EventStatus} from 'matrix-js-sdk';
|
||||||
import {formatTime} from "../../../DateUtils";
|
import {formatTime} from "../../../DateUtils";
|
||||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||||
import {ALL_RULE_TYPES} from "../../../mjolnir/BanList";
|
import {ALL_RULE_TYPES} from "../../../mjolnir/BanList";
|
||||||
import * as ObjectUtils from "../../../ObjectUtils";
|
|
||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
import {E2E_STATE} from "./E2EIcon";
|
import {E2E_STATE} from "./E2EIcon";
|
||||||
import {toRem} from "../../../utils/units";
|
import {toRem} from "../../../utils/units";
|
||||||
import {WidgetType} from "../../../widgets/WidgetType";
|
import {WidgetType} from "../../../widgets/WidgetType";
|
||||||
import RoomAvatar from "../avatars/RoomAvatar";
|
import RoomAvatar from "../avatars/RoomAvatar";
|
||||||
import {WIDGET_LAYOUT_EVENT_TYPE} from "../../../stores/widgets/WidgetLayoutStore";
|
import {WIDGET_LAYOUT_EVENT_TYPE} from "../../../stores/widgets/WidgetLayoutStore";
|
||||||
|
import {objectHasDiff} from "../../../utils/objects";
|
||||||
|
|
||||||
const eventTileTypes = {
|
const eventTileTypes = {
|
||||||
'm.room.message': 'messages.MessageEvent',
|
'm.room.message': 'messages.MessageEvent',
|
||||||
|
@ -294,7 +294,7 @@ export default class EventTile extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
if (!ObjectUtils.shallowEqual(this.state, nextState)) {
|
if (objectHasDiff(this.state, nextState)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1933,7 +1933,6 @@
|
||||||
"Please provide a room address": "Please provide a room address",
|
"Please provide a room address": "Please provide a room address",
|
||||||
"This address is available to use": "This address is available to use",
|
"This address is available to use": "This address is available to use",
|
||||||
"This address is already in use": "This address is already in use",
|
"This address is already in use": "This address is already in use",
|
||||||
"Room directory": "Room directory",
|
|
||||||
"Server Options": "Server Options",
|
"Server Options": "Server Options",
|
||||||
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.": "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.",
|
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.": "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Element with an existing Matrix account on a different homeserver.",
|
||||||
"Join millions for free on the largest public server": "Join millions for free on the largest public server",
|
"Join millions for free on the largest public server": "Join millions for free on the largest public server",
|
||||||
|
|
|
@ -211,7 +211,7 @@ export class Algorithm extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we do have a room though, we expect to be able to find it
|
// When we do have a room though, we expect to be able to find it
|
||||||
let tag = this.roomIdsToTags[val.roomId][0];
|
let tag = this.roomIdsToTags[val.roomId]?.[0];
|
||||||
if (!tag) throw new Error(`${val.roomId} does not belong to a tag and cannot be sticky`);
|
if (!tag) throw new Error(`${val.roomId} does not belong to a tag and cannot be sticky`);
|
||||||
|
|
||||||
// We specifically do NOT use the ordered rooms set as it contains the sticky room, which
|
// We specifically do NOT use the ordered rooms set as it contains the sticky room, which
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { arrayDiff, arrayHasDiff, arrayMerge, arrayUnion } from "./arrays";
|
import { arrayDiff, arrayMerge, arrayUnion } from "./arrays";
|
||||||
|
|
||||||
type ObjectExcluding<O extends {}, P extends (keyof O)[]> = {[k in Exclude<keyof O, P[number]>]: O[k]};
|
type ObjectExcluding<O extends {}, P extends (keyof O)[]> = {[k in Exclude<keyof O, P[number]>]: O[k]};
|
||||||
|
|
||||||
|
@ -86,11 +86,13 @@ export function objectShallowClone<O extends {}>(a: O, propertyCloner?: (k: keyo
|
||||||
* @returns True if there's a difference between the objects, false otherwise
|
* @returns True if there's a difference between the objects, false otherwise
|
||||||
*/
|
*/
|
||||||
export function objectHasDiff<O extends {}>(a: O, b: O): boolean {
|
export function objectHasDiff<O extends {}>(a: O, b: O): boolean {
|
||||||
|
if (a === b) return false;
|
||||||
const aKeys = Object.keys(a);
|
const aKeys = Object.keys(a);
|
||||||
const bKeys = Object.keys(b);
|
const bKeys = Object.keys(b);
|
||||||
if (arrayHasDiff(aKeys, bKeys)) return true;
|
|
||||||
|
|
||||||
const possibleChanges = arrayUnion(aKeys, bKeys);
|
const possibleChanges = arrayUnion(aKeys, bKeys);
|
||||||
|
// if the amalgamation of both sets of keys has the a different length to the inputs then there must be a change
|
||||||
|
if (possibleChanges.length !== aKeys.length) return true;
|
||||||
|
|
||||||
return possibleChanges.some(k => a[k] !== b[k]);
|
return possibleChanges.some(k => a[k] !== b[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2018 New Vector Ltd
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {phasedRollOutExpiredForUser} from '../src/PhasedRollOut';
|
|
||||||
|
|
||||||
const OFFSET = 6000000;
|
|
||||||
// phasedRollOutExpiredForUser enables users in bucks of 1 minute
|
|
||||||
const MS_IN_MINUTE = 60 * 1000;
|
|
||||||
|
|
||||||
describe('PhasedRollOut', function() {
|
|
||||||
it('should return true if phased rollout is not configured', function() {
|
|
||||||
expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", 0, null)).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true if phased rollout feature is not configured', function() {
|
|
||||||
expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", 0, {
|
|
||||||
"feature_other": {offset: 0, period: 0},
|
|
||||||
})).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false if phased rollout for feature is misconfigured', function() {
|
|
||||||
expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", 0, {
|
|
||||||
"feature_test": {},
|
|
||||||
})).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should return false if phased rollout hasn't started yet", function() {
|
|
||||||
expect(phasedRollOutExpiredForUser("@user:hs", "feature_test", 5000000, {
|
|
||||||
"feature_test": {offset: OFFSET, period: MS_IN_MINUTE},
|
|
||||||
})).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should start to return true in bucket 2/10 for '@user:hs'", function() {
|
|
||||||
expect(phasedRollOutExpiredForUser("@user:hs", "feature_test",
|
|
||||||
OFFSET + (MS_IN_MINUTE * 2) - 1, {
|
|
||||||
"feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10},
|
|
||||||
})).toBeFalsy();
|
|
||||||
expect(phasedRollOutExpiredForUser("@user:hs", "feature_test",
|
|
||||||
OFFSET + (MS_IN_MINUTE * 2), {
|
|
||||||
"feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10},
|
|
||||||
})).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should start to return true in bucket 4/10 for 'alice@other-hs'", function() {
|
|
||||||
expect(phasedRollOutExpiredForUser("alice@other-hs", "feature_test",
|
|
||||||
OFFSET + (MS_IN_MINUTE * 4) - 1, {
|
|
||||||
"feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10},
|
|
||||||
})).toBeFalsy();
|
|
||||||
expect(phasedRollOutExpiredForUser("alice@other-hs", "feature_test",
|
|
||||||
OFFSET + (MS_IN_MINUTE * 4), {
|
|
||||||
"feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10},
|
|
||||||
})).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should return true after complete rollout period'", function() {
|
|
||||||
expect(phasedRollOutExpiredForUser("user:hs", "feature_test",
|
|
||||||
OFFSET + (MS_IN_MINUTE * 20), {
|
|
||||||
"feature_test": {offset: OFFSET, period: MS_IN_MINUTE * 10},
|
|
||||||
})).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Add table
Add a link
Reference in a new issue