fix bug where the wrong left panel tile is removed when accepting invite

because when comparing a tile to itself it wasn't returned 0
This commit is contained in:
Bruno Windels 2022-02-10 16:27:32 +01:00
parent b0d790543a
commit 30c8ea29b2
5 changed files with 71 additions and 7 deletions

View file

@ -18,7 +18,7 @@ limitations under the License.
import {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from "../../avatar.js"; import {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from "../../avatar.js";
import {ViewModel} from "../../ViewModel.js"; import {ViewModel} from "../../ViewModel.js";
const KIND_ORDER = ["invite", "room"]; const KIND_ORDER = ["roomBeingCreated", "invite", "room"];
export class BaseTileViewModel extends ViewModel { export class BaseTileViewModel extends ViewModel {
constructor(options) { constructor(options) {

View file

@ -1,5 +1,4 @@
/* /*
Copyright 2020 Bruno Windels <bruno@windels.cloud>
Copyright 2020, 2021 The Matrix.org Foundation C.I.C. Copyright 2020, 2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -16,6 +15,7 @@ limitations under the License.
*/ */
import {BaseTileViewModel} from "./BaseTileViewModel.js"; import {BaseTileViewModel} from "./BaseTileViewModel.js";
import {comparePrimitive} from "./common";
export class InviteTileViewModel extends BaseTileViewModel { export class InviteTileViewModel extends BaseTileViewModel {
constructor(options) { constructor(options) {
@ -34,6 +34,9 @@ export class InviteTileViewModel extends BaseTileViewModel {
get badgeCount() { return this.i18n`!`; } get badgeCount() { return this.i18n`!`; }
get _avatarSource() { return this._invite; } get _avatarSource() { return this._invite; }
/** very important that sorting order is stable and that comparing
* to itself always returns 0, otherwise SortedMapList will
* remove the wrong children, etc ... */
compare(other) { compare(other) {
const parentComparison = super.compare(other); const parentComparison = super.compare(other);
if (parentComparison !== 0) { if (parentComparison !== 0) {
@ -43,6 +46,19 @@ export class InviteTileViewModel extends BaseTileViewModel {
if (timeDiff !== 0) { if (timeDiff !== 0) {
return timeDiff; return timeDiff;
} }
return this._invite.id < other._invite.id ? -1 : 1; return comparePrimitive(this._invite.id, other._invite.id);
}
}
export function tests() {
return {
"test compare with timestamp": assert => {
const urlCreator = {openRoomActionUrl() { return "";}}
const vm1 = new InviteTileViewModel({invite: {timestamp: 500, id: "1"}, urlCreator});
const vm2 = new InviteTileViewModel({invite: {timestamp: 250, id: "2"}, urlCreator});
assert(vm1.compare(vm2) < 0);
assert(vm2.compare(vm1) > 0);
assert.equal(vm1.compare(vm1), 0);
},
} }
} }

View file

@ -16,6 +16,7 @@ limitations under the License.
*/ */
import {BaseTileViewModel} from "./BaseTileViewModel.js"; import {BaseTileViewModel} from "./BaseTileViewModel.js";
import {comparePrimitive} from "./common";
export class RoomBeingCreatedTileViewModel extends BaseTileViewModel { export class RoomBeingCreatedTileViewModel extends BaseTileViewModel {
constructor(options) { constructor(options) {
@ -33,12 +34,20 @@ export class RoomBeingCreatedTileViewModel extends BaseTileViewModel {
get name() { return this._roomBeingCreated.name; } get name() { return this._roomBeingCreated.name; }
get _avatarSource() { return this._roomBeingCreated; } get _avatarSource() { return this._roomBeingCreated; }
/** very important that sorting order is stable and that comparing
* to itself always returns 0, otherwise SortedMapList will
* remove the wrong children, etc ... */
compare(other) { compare(other) {
const parentComparison = super.compare(other); const parentCmp = super.compare(other);
if (parentComparison !== 0) { if (parentCmp !== 0) {
return parentComparison; return parentCmp;
}
const nameCmp = comparePrimitive(this.name, other.name);
if (nameCmp === 0) {
return comparePrimitive(this._roomBeingCreated.id, other._roomBeingCreated.id);
} else {
return nameCmp;
} }
return other._roomBeingCreated.name.localeCompare(this._roomBeingCreated.name);
} }
avatarUrl(size) { avatarUrl(size) {
@ -46,3 +55,16 @@ export class RoomBeingCreatedTileViewModel extends BaseTileViewModel {
return this._roomBeingCreated.avatarBlobUrl ?? super.avatarUrl(size); return this._roomBeingCreated.avatarBlobUrl ?? super.avatarUrl(size);
} }
} }
export function tests() {
return {
"test compare with names": assert => {
const urlCreator = {openRoomActionUrl() { return "";}}
const vm1 = new RoomBeingCreatedTileViewModel({roomBeingCreated: {name: "A", id: "1"}, urlCreator});
const vm2 = new RoomBeingCreatedTileViewModel({roomBeingCreated: {name: "B", id: "2"}, urlCreator});
assert(vm1.compare(vm2) < 0);
assert(vm2.compare(vm1) > 0);
assert.equal(vm1.compare(vm1), 0);
},
}
}

View file

@ -33,6 +33,9 @@ export class RoomTileViewModel extends BaseTileViewModel {
return this._url; return this._url;
} }
/** very important that sorting order is stable and that comparing
* to itself always returns 0, otherwise SortedMapList will
* remove the wrong children, etc ... */
compare(other) { compare(other) {
const parentComparison = super.compare(other); const parentComparison = super.compare(other);
if (parentComparison !== 0) { if (parentComparison !== 0) {

View file

@ -0,0 +1,23 @@
/*
Copyright 2020, 2021 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.
*/
export function comparePrimitive(a, b) {
if (a === b) {
return 0;
} else {
return a < b ? -1 : 1;
}
}