From 50252483c6ec479d7848a8f3a47769a774801824 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Thu, 18 Feb 2021 18:05:41 +0000
Subject: [PATCH 1/7] Remove stale unused components
---
.../views/elements/RoomDirectoryButton.js | 41 ------------
.../views/elements/StartChatButton.js | 40 ------------
.../views/elements/TintableSvgButton.js | 63 -------------------
3 files changed, 144 deletions(-)
delete mode 100644 src/components/views/elements/RoomDirectoryButton.js
delete mode 100644 src/components/views/elements/StartChatButton.js
delete mode 100644 src/components/views/elements/TintableSvgButton.js
diff --git a/src/components/views/elements/RoomDirectoryButton.js b/src/components/views/elements/RoomDirectoryButton.js
deleted file mode 100644
index e9de6f8d15..0000000000
--- a/src/components/views/elements/RoomDirectoryButton.js
+++ /dev/null
@@ -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 (
-
- );
-};
-
-RoomDirectoryButton.propTypes = {
- size: PropTypes.string,
- tooltip: PropTypes.bool,
-};
-
-export default RoomDirectoryButton;
diff --git a/src/components/views/elements/StartChatButton.js b/src/components/views/elements/StartChatButton.js
deleted file mode 100644
index f828f8ae4d..0000000000
--- a/src/components/views/elements/StartChatButton.js
+++ /dev/null
@@ -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 (
-
- );
-};
-
-StartChatButton.propTypes = {
- size: PropTypes.string,
- tooltip: PropTypes.bool,
-};
-
-export default StartChatButton;
diff --git a/src/components/views/elements/TintableSvgButton.js b/src/components/views/elements/TintableSvgButton.js
deleted file mode 100644
index a3f5b7db5d..0000000000
--- a/src/components/views/elements/TintableSvgButton.js
+++ /dev/null
@@ -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 (
-
-
-
-
- );
- }
-}
-
-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() {},
-};
From 8fc244452ce2f2d40643b2ddc1d22085d62bb9ea Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Thu, 18 Feb 2021 18:06:26 +0000
Subject: [PATCH 2/7] Prevent error being thrown so that we can throw our own
better one
---
src/stores/room-list/algorithms/Algorithm.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/stores/room-list/algorithms/Algorithm.ts b/src/stores/room-list/algorithms/Algorithm.ts
index 25059aabe7..f709fc3ccb 100644
--- a/src/stores/room-list/algorithms/Algorithm.ts
+++ b/src/stores/room-list/algorithms/Algorithm.ts
@@ -211,7 +211,7 @@ export class Algorithm extends EventEmitter {
}
// 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`);
// We specifically do NOT use the ordered rooms set as it contains the sticky room, which
From 3ca5632f6a68f0b57c8c642d9b374d4bea6cd788 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 19 Feb 2021 00:00:10 +0000
Subject: [PATCH 3/7] Replace ObjectUtils.js with objects.ts
---
src/ObjectUtils.js | 113 ---------------------
src/components/structures/RoomView.tsx | 5 +-
src/components/structures/TimelinePanel.js | 6 +-
src/components/views/rooms/AuxPanel.tsx | 5 +-
src/components/views/rooms/EventTile.js | 4 +-
src/utils/objects.ts | 1 +
6 files changed, 10 insertions(+), 124 deletions(-)
delete mode 100644 src/ObjectUtils.js
diff --git a/src/ObjectUtils.js b/src/ObjectUtils.js
deleted file mode 100644
index 24dfe61d68..0000000000
--- a/src/ObjectUtils.js
+++ /dev/null
@@ -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;
-}
diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx
index ee50686123..68ab3c6e0c 100644
--- a/src/components/structures/RoomView.tsx
+++ b/src/components/structures/RoomView.tsx
@@ -38,7 +38,6 @@ import CallHandler from '../../CallHandler';
import dis from '../../dispatcher/dispatcher';
import Tinter from '../../Tinter';
import rateLimitedFunc from '../../ratelimitedfunc';
-import * as ObjectUtils from '../../ObjectUtils';
import * as Rooms from '../../Rooms';
import eventSearch, { searchPagination } from '../../Searching';
import { isOnlyCtrlOrCmdIgnoreShiftKeyEvent, Key } from '../../Keyboard';
@@ -80,6 +79,7 @@ import Notifier from "../../Notifier";
import { showToast as showNotificationsToast } from "../../toasts/DesktopNotificationsToast";
import { RoomNotificationStateStore } from "../../stores/notifications/RoomNotificationStateStore";
import { Container, WidgetLayoutStore } from "../../stores/widgets/WidgetLayoutStore";
+import { objectHasDiff } from "../../utils/objects";
const DEBUG = false;
let debuglog = function(msg: string) {};
@@ -523,8 +523,7 @@ export default class RoomView extends React.Component {
}
shouldComponentUpdate(nextProps, nextState) {
- return (!ObjectUtils.shallowEqual(this.props, nextProps) ||
- !ObjectUtils.shallowEqual(this.state, nextState));
+ return (objectHasDiff(this.props, nextProps) || objectHasDiff(this.state, nextState));
}
componentDidUpdate() {
diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js
index e8da5c42d0..6bc1f70ba1 100644
--- a/src/components/structures/TimelinePanel.js
+++ b/src/components/structures/TimelinePanel.js
@@ -26,7 +26,6 @@ import {EventTimeline} from "matrix-js-sdk";
import * as Matrix from "matrix-js-sdk";
import { _t } from '../../languageHandler';
import {MatrixClientPeg} from "../../MatrixClientPeg";
-import * as ObjectUtils from "../../ObjectUtils";
import UserActivity from "../../UserActivity";
import Modal from "../../Modal";
import dis from "../../dispatcher/dispatcher";
@@ -37,6 +36,7 @@ import shouldHideEvent from '../../shouldHideEvent';
import EditorStateTransfer from '../../utils/EditorStateTransfer';
import {haveTileForEvent} from "../views/rooms/EventTile";
import {UIFeature} from "../../settings/UIFeature";
+import {objectHasDiff} from "../../utils/objects";
const PAGINATE_SIZE = 20;
const INITIAL_SIZE = 20;
@@ -261,7 +261,7 @@ class TimelinePanel extends React.Component {
}
shouldComponentUpdate(nextProps, nextState) {
- if (!ObjectUtils.shallowEqual(this.props, nextProps)) {
+ if (objectHasDiff(this.props, nextProps)) {
if (DEBUG) {
console.group("Timeline.shouldComponentUpdate: props change");
console.log("props before:", this.props);
@@ -271,7 +271,7 @@ class TimelinePanel extends React.Component {
return true;
}
- if (!ObjectUtils.shallowEqual(this.state, nextState)) {
+ if (objectHasDiff(this.state, nextState)) {
if (DEBUG) {
console.group("Timeline.shouldComponentUpdate: state change");
console.log("state before:", this.state);
diff --git a/src/components/views/rooms/AuxPanel.tsx b/src/components/views/rooms/AuxPanel.tsx
index 7966643084..4ce31be410 100644
--- a/src/components/views/rooms/AuxPanel.tsx
+++ b/src/components/views/rooms/AuxPanel.tsx
@@ -19,7 +19,6 @@ import {MatrixClientPeg} from "../../../MatrixClientPeg";
import { Room } from 'matrix-js-sdk/src/models/room'
import * as sdk from '../../../index';
import dis from "../../../dispatcher/dispatcher";
-import * as ObjectUtils from '../../../ObjectUtils';
import AppsDrawer from './AppsDrawer';
import { _t } from '../../../languageHandler';
import classNames from 'classnames';
@@ -29,6 +28,7 @@ import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
import {UIFeature} from "../../../settings/UIFeature";
import { ResizeNotifier } from "../../../utils/ResizeNotifier";
import CallViewForRoom from '../voip/CallViewForRoom';
+import {objectHasDiff} from "../../../utils/objects";
interface IProps {
// js-sdk room object
@@ -89,8 +89,7 @@ export default class AuxPanel extends React.Component {
}
shouldComponentUpdate(nextProps, nextState) {
- return (!ObjectUtils.shallowEqual(this.props, nextProps) ||
- !ObjectUtils.shallowEqual(this.state, nextState));
+ return objectHasDiff(this.props, nextProps) || objectHasDiff(this.state, nextState);
}
componentDidUpdate(prevProps, prevState) {
diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js
index c856919f5a..210f966d1e 100644
--- a/src/components/views/rooms/EventTile.js
+++ b/src/components/views/rooms/EventTile.js
@@ -32,13 +32,13 @@ import {EventStatus} from 'matrix-js-sdk';
import {formatTime} from "../../../DateUtils";
import {MatrixClientPeg} from '../../../MatrixClientPeg';
import {ALL_RULE_TYPES} from "../../../mjolnir/BanList";
-import * as ObjectUtils from "../../../ObjectUtils";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import {E2E_STATE} from "./E2EIcon";
import {toRem} from "../../../utils/units";
import {WidgetType} from "../../../widgets/WidgetType";
import RoomAvatar from "../avatars/RoomAvatar";
import {WIDGET_LAYOUT_EVENT_TYPE} from "../../../stores/widgets/WidgetLayoutStore";
+import {objectHasDiff} from "../../../utils/objects";
const eventTileTypes = {
'm.room.message': 'messages.MessageEvent',
@@ -294,7 +294,7 @@ export default class EventTile extends React.Component {
}
shouldComponentUpdate(nextProps, nextState) {
- if (!ObjectUtils.shallowEqual(this.state, nextState)) {
+ if (objectHasDiff(this.state, nextState)) {
return true;
}
diff --git a/src/utils/objects.ts b/src/utils/objects.ts
index bc74ab9ee0..fe010df2b9 100644
--- a/src/utils/objects.ts
+++ b/src/utils/objects.ts
@@ -86,6 +86,7 @@ export function objectShallowClone(a: O, propertyCloner?: (k: keyo
* @returns True if there's a difference between the objects, false otherwise
*/
export function objectHasDiff(a: O, b: O): boolean {
+ if (a === b) return false;
const aKeys = Object.keys(a);
const bKeys = Object.keys(b);
if (arrayHasDiff(aKeys, bKeys)) return true;
From 3c52446205e420689eab66af20e1f220c387dd5d Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 19 Feb 2021 00:01:07 +0000
Subject: [PATCH 4/7] Remove redundant PhasedRollOut
---
src/PhasedRollOut.js | 51 ---------------------------
test/PhasedRollOut-test.js | 71 --------------------------------------
2 files changed, 122 deletions(-)
delete mode 100644 src/PhasedRollOut.js
delete mode 100644 test/PhasedRollOut-test.js
diff --git a/src/PhasedRollOut.js b/src/PhasedRollOut.js
deleted file mode 100644
index b17ed37974..0000000000
--- a/src/PhasedRollOut.js
+++ /dev/null
@@ -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;
-}
diff --git a/test/PhasedRollOut-test.js b/test/PhasedRollOut-test.js
deleted file mode 100644
index f02411d78d..0000000000
--- a/test/PhasedRollOut-test.js
+++ /dev/null
@@ -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();
- });
-});
From d4df9e731d0053aa439f62d3e9dc0a67fa8128c4 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 19 Feb 2021 00:10:47 +0000
Subject: [PATCH 5/7] i18n
---
src/i18n/strings/en_EN.json | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 5bbbdf60b5..c3038fd9af 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -1933,7 +1933,6 @@
"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 already in use": "This address is already in use",
- "Room directory": "Room directory",
"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.",
"Join millions for free on the largest public server": "Join millions for free on the largest public server",
From 32cca0534c5ff7c7a86d854e6a00a4764652d20b Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 19 Feb 2021 00:15:00 +0000
Subject: [PATCH 6/7] improve algo by skipping an O(n) operation
---
src/utils/objects.ts | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/utils/objects.ts b/src/utils/objects.ts
index fe010df2b9..41e3f37d1b 100644
--- a/src/utils/objects.ts
+++ b/src/utils/objects.ts
@@ -89,9 +89,10 @@ export function objectHasDiff(a: O, b: O): boolean {
if (a === b) return false;
const aKeys = Object.keys(a);
const bKeys = Object.keys(b);
- if (arrayHasDiff(aKeys, bKeys)) return true;
-
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]);
}
From 49f511bbab5a458f8be7e155f17ca317173d4a8e Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Fri, 19 Feb 2021 00:26:52 +0000
Subject: [PATCH 7/7] delint
---
src/utils/objects.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/utils/objects.ts b/src/utils/objects.ts
index 41e3f37d1b..166c31c4c3 100644
--- a/src/utils/objects.ts
+++ b/src/utils/objects.ts
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import { arrayDiff, arrayHasDiff, arrayMerge, arrayUnion } from "./arrays";
+import { arrayDiff, arrayMerge, arrayUnion } from "./arrays";
type ObjectExcluding = {[k in Exclude]: O[k]};