Skip redundant tile wrapper updates

This commit is contained in:
Robin
2026-10-27 10:44:33 +01:00
parent 4441bb5e8c
commit 9fcba5a704
2 changed files with 57 additions and 10 deletions
+16
View File
@@ -49,6 +49,22 @@ test("layoutShallowEquals detects a missing key", () => {
).toBe(false);
});
test("layoutShallowEquals considers tile wrappers with equal contents to be equal", () =>
expect(
layoutShallowEquals(spotlightPortrait, {
...spotlightPortrait,
spotlight: { vm: spotlightTile },
}),
).toBe(true));
test("layoutShallowEquals detects tile wrappers with different contents", () =>
expect(
layoutShallowEquals(spotlightPortrait, {
...spotlightPortrait,
spotlight: { vm: {} as unknown as SpotlightTileViewModel },
}),
).toBe(false));
test("layoutShallowEquals considers grid arrays with equal contents to be equal", () =>
expect(
layoutShallowEquals(spotlightPortrait, {
+41 -10
View File
@@ -162,10 +162,17 @@ export type Layout =
| PipLayout;
/**
* Tests whether the top-level properties and array elements of layout `a` are
* equal to those of layout `b`. Useful for deduping redundant layout updates.
* Tests whether the top-level properties of object `a` are equal to those of
* object `b` by the given comparator.
*/
export function layoutShallowEquals(a: Layout, b: Layout): boolean {
function equals(
a: object,
b: object,
comparator: (aValue: unknown, bValue: unknown) => boolean = (
aValue,
bValue,
) => aValue === bValue,
): boolean {
// If a and b have the same number of keys and every key in a is also in b,
// then they have the same keys.
const aKeys = Object.keys(a);
@@ -176,14 +183,38 @@ export function layoutShallowEquals(a: Layout, b: Layout): boolean {
if (!(key in b)) return false;
// Now check that they have the same values.
const aValue = (a as any)[key];
const bValue = (b as any)[key];
if (Array.isArray(aValue) && Array.isArray(bValue)) {
// Special case for arrays so we can detect when the grid tiles arrays are
// essentially the same.
if (!arrayShallowEquals(aValue, bValue)) return false;
} else if (aValue !== bValue) return false;
const aValue: unknown = (a as any)[key];
const bValue: unknown = (b as any)[key];
if (!comparator(aValue, bValue)) return false;
}
return true;
}
/**
* Tests whether the top-level properties, tile wrapper properties, and array
* elements of layout `a` are equal to those of layout `b`. Useful for deduping
* redundant layout updates.
*/
export function layoutShallowEquals(a: Layout, b: Layout): boolean {
return equals(a, b, (aValue, bValue) => {
// Special case for tile wrapper objects so we can detect when the
// spotlight or PiP tile is essentially the same
if (
typeof aValue === "object" &&
aValue !== null &&
"vm" in aValue &&
typeof bValue === "object" &&
bValue !== null &&
"vm" in bValue
)
return equals(aValue, bValue);
// Special case for arrays so we can detect when the grid tile arrays are
// essentially the same
if (Array.isArray(aValue) && Array.isArray(bValue))
return arrayShallowEquals(aValue, bValue);
return aValue === bValue;
});
}