Replace ObjectUtils.js with objects.ts
							parent
							
								
									8fc244452c
								
							
						
					
					
						commit
						3ca5632f6a
					
				|  | @ -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; | ||||
| } | ||||
|  | @ -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<IProps, IState> { | |||
|     } | ||||
| 
 | ||||
|     shouldComponentUpdate(nextProps, nextState) { | ||||
|         return (!ObjectUtils.shallowEqual(this.props, nextProps) || | ||||
|                 !ObjectUtils.shallowEqual(this.state, nextState)); | ||||
|         return (objectHasDiff(this.props, nextProps) || objectHasDiff(this.state, nextState)); | ||||
|     } | ||||
| 
 | ||||
|     componentDidUpdate() { | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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<IProps, IState> { | |||
|     } | ||||
| 
 | ||||
|     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) { | ||||
|  |  | |||
|  | @ -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; | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -86,6 +86,7 @@ export function objectShallowClone<O extends {}>(a: O, propertyCloner?: (k: keyo | |||
|  * @returns True if there's a difference between the objects, false otherwise | ||||
|  */ | ||||
| export function objectHasDiff<O extends {}>(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; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Michael Telatynski
						Michael Telatynski