diff --git a/src/domain/session/leftpanel/LeftPanelViewModel.js b/src/domain/session/leftpanel/LeftPanelViewModel.js index 9e37a05e..04d8c2a5 100644 --- a/src/domain/session/leftpanel/LeftPanelViewModel.js +++ b/src/domain/session/leftpanel/LeftPanelViewModel.js @@ -43,7 +43,7 @@ export class LeftPanelViewModel extends ViewModel { } _mapTileViewModels(list) { - return new MappedList(list, (roomOrInvite, emitChange) => { + const mapper = (roomOrInvite, emitChange) => { let vm; if (roomOrInvite === null) { vm = new PlaceholderRoomTileViewModel(this.childOptions({room: null, emitChange})); @@ -64,7 +64,11 @@ export class LeftPanelViewModel extends ViewModel { } } return vm; - }); + }; + const updater = (tileViewModel, noIdea, roomOrInvite) => { + return mapper(roomOrInvite); + } + return new MappedList(list, mapper, updater); } _updateCurrentVM(vm) { diff --git a/src/matrix/Sync3ObservableList.ts b/src/matrix/Sync3ObservableList.ts index 70028a08..25921597 100644 --- a/src/matrix/Sync3ObservableList.ts +++ b/src/matrix/Sync3ObservableList.ts @@ -17,12 +17,14 @@ limitations under the License. import * as assert from "assert"; import { BaseObservableList } from "../observable/list/BaseObservableList"; import { ObservableMap } from "../observable/map/ObservableMap.js"; +import { SubscriptionHandle } from "../observable/BaseObservable"; import { Room } from "./room/Room.js"; // subset of Sync3 functions used in this list; interfaced out for testing interface ISync { count(): number; roomAtIndex(i: number): string + indexOfRoom(roomId: string): number } /** @@ -31,6 +33,7 @@ interface ISync { export class Sync3ObservableList extends BaseObservableList { sync: ISync; rooms: ObservableMap; + subscription: SubscriptionHandle | null; /** * Construct an observable list that produces Rooms within the sliding window of Sync3 responses @@ -41,9 +44,40 @@ export class Sync3ObservableList extends BaseObservableList { constructor(sync3: ISync, rooms: ObservableMap) { super(); this.sync = sync3; + this.subscription = null; this.rooms = rooms; } + onSubscribeFirst() { + this.subscription = this.rooms.subscribe(this); + } + + onUnsubscribeLast() { + if (!this.subscription) { + return; + } + this.subscription(); + this.subscription = null; + } + + onAdd(index, entry) { + let i = this.sync.indexOfRoom(entry.id); + this.emitUpdate(i, entry); // we always emit updates as we have num_joined_rooms entries (placeholders) + } + + onUpdate(index, entry, params) { + let i = this.sync.indexOfRoom(entry.id); + if (i === -1) { + return; + } + this.emitUpdate(i, entry); // we always emit updates as we have num_joined_rooms entries (placeholders) + } + + onRemove(index, entry) { + let i = this.sync.indexOfRoom(entry.id); + this.emitUpdate(i, entry); // we always emit updates as we have num_joined_rooms entries (placeholders) + } + get length(): number { return this.sync.count(); } @@ -120,6 +154,15 @@ export function tests() { roomAtIndex: (i: number): string => { return indexToRoomId[i]; }, + indexOfRoom(roomId: string): number { + for (let i of Object.keys(indexToRoomId)) { + let r = indexToRoomId[i]; + if (r === roomId) { + return Number(i); + } + } + return -1; + } }; makeRooms(100).forEach((r) => { diff --git a/src/observable/list/BaseMappedList.ts b/src/observable/list/BaseMappedList.ts index 4e3d05e0..6794d1a7 100644 --- a/src/observable/list/BaseMappedList.ts +++ b/src/observable/list/BaseMappedList.ts @@ -15,21 +15,21 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {BaseObservableList} from "./BaseObservableList"; -import {findAndUpdateInArray} from "./common"; +import { BaseObservableList } from "./BaseObservableList"; +import { findAndUpdateInArray } from "./common"; -export type Mapper = (value: F) => T -export type Updater = (mappedValue: T, params: any, value: F) => void; +export type Mapper = (value: F) => T +export type Updater = (mappedValue: T, params: any, value: F) => void; -export class BaseMappedList extends BaseObservableList { +export class BaseMappedList extends BaseObservableList { protected _sourceList: BaseObservableList; protected _sourceUnsubscribe: (() => void) | null = null; - _mapper: Mapper; - _updater?: Updater; + _mapper: Mapper; + _updater?: Updater; _removeCallback?: (value: T) => void; _mappedValues: T[] | null = null; - constructor(sourceList: BaseObservableList, mapper: Mapper, updater?: Updater, removeCallback?: (value: T) => void) { + constructor(sourceList: BaseObservableList, mapper: Mapper, updater?: Updater, removeCallback?: (value: T) => void) { super(); this._sourceList = sourceList; this._mapper = mapper; @@ -50,12 +50,12 @@ export class BaseMappedList extends BaseObservableList { } } -export function runAdd(list: BaseMappedList, index: number, mappedValue: T): void { +export function runAdd(list: BaseMappedList, index: number, mappedValue: T): void { list._mappedValues!.splice(index, 0, mappedValue); list.emitAdd(index, mappedValue); } -export function runUpdate(list: BaseMappedList, index: number, value: F, params: any): void { +export function runUpdate(list: BaseMappedList, index: number, value: F, params: any): void { const mappedValue = list._mappedValues![index]; if (list._updater) { list._updater(mappedValue, params, value); @@ -63,7 +63,7 @@ export function runUpdate(list: BaseMappedList, index: number, val list.emitUpdate(index, mappedValue, params); } -export function runRemove(list: BaseMappedList, index: number): void { +export function runRemove(list: BaseMappedList, index: number): void { const mappedValue = list._mappedValues![index]; list._mappedValues!.splice(index, 1); if (list._removeCallback) { @@ -72,14 +72,14 @@ export function runRemove(list: BaseMappedList, index: number): vo list.emitRemove(index, mappedValue); } -export function runMove(list: BaseMappedList, fromIdx: number, toIdx: number): void { +export function runMove(list: BaseMappedList, fromIdx: number, toIdx: number): void { const mappedValue = list._mappedValues![fromIdx]; list._mappedValues!.splice(fromIdx, 1); list._mappedValues!.splice(toIdx, 0, mappedValue); list.emitMove(fromIdx, toIdx, mappedValue); } -export function runReset(list: BaseMappedList): void { +export function runReset(list: BaseMappedList): void { list._mappedValues = []; list.emitReset(); } diff --git a/src/observable/list/ConcatList.ts b/src/observable/list/ConcatList.ts index 5822468a..7d9676c9 100644 --- a/src/observable/list/ConcatList.ts +++ b/src/observable/list/ConcatList.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {BaseObservableList, IListObserver} from "./BaseObservableList"; +import { BaseObservableList, IListObserver } from "./BaseObservableList"; export class ConcatList extends BaseObservableList implements IListObserver { protected _sourceLists: BaseObservableList[]; @@ -50,7 +50,7 @@ export class ConcatList extends BaseObservableList implements IListObserve // reset, and this.emitReset(); let idx = 0; - for(const item of this) { + for (const item of this) { this.emitAdd(idx, item); idx += 1; } @@ -106,8 +106,8 @@ export class ConcatList extends BaseObservableList implements IListObserve } } -import {ObservableArray} from "./ObservableArray"; -import {defaultObserverWith} from "./BaseObservableList"; +import { ObservableArray } from "./ObservableArray"; +import { defaultObserverWith } from "./BaseObservableList"; export async function tests() { return { test_length(assert) {