diff --git a/src/observable/BaseObservable.ts b/src/observable/BaseObservable.ts index 16bd3b81..1d774797 100644 --- a/src/observable/BaseObservable.ts +++ b/src/observable/BaseObservable.ts @@ -14,6 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ +// we return undefined so you can reassign any member +// that uses `member?: T` syntax in one statement. +export type SubscriptionHandle = () => undefined; + export abstract class BaseObservable { protected _handlers: Set = new Set(); @@ -25,7 +29,7 @@ export abstract class BaseObservable { } - subscribe(handler: T): () => void { + subscribe(handler: T): SubscriptionHandle { this._handlers.add(handler); if (this._handlers.size === 1) { this.onSubscribeFirst(); @@ -35,15 +39,14 @@ export abstract class BaseObservable { }; } - unsubscribe(handler: T | null): null { + unsubscribe(handler?: T): undefined { if (handler) { this._handlers.delete(handler); if (this._handlers.size === 0) { this.onUnsubscribeLast(); } - handler = null; } - return null; + return undefined; } unsubscribeAll(): void { diff --git a/src/platform/web/ui/general/ListView.ts b/src/platform/web/ui/general/ListView.ts index e6d15755..f76bd961 100644 --- a/src/platform/web/ui/general/ListView.ts +++ b/src/platform/web/ui/general/ListView.ts @@ -16,6 +16,7 @@ limitations under the License. import {el} from "./html"; import {mountView, insertAt} from "./utils"; +import {SubscriptionHandle} from "../../../../observable/BaseObservable"; import {BaseObservableList as ObservableList} from "../../../../observable/list/BaseObservableList"; import {IView, IMountArgs} from "./types"; @@ -27,8 +28,6 @@ interface IOptions { parentProvidesUpdates?: boolean } -type SubscriptionHandle = () => void; - export class ListView implements IView { private _onItemClick?: (childView: V, evt: UIEvent) => void; @@ -115,8 +114,7 @@ export class ListView implements IView { } private _unloadList() { - this._subscription!() - this._subscription = undefined; + this._subscription = this._subscription!(); for (let child of this._childInstances!) { child.unmount(); } diff --git a/src/sdk.ts b/src/sdk.ts new file mode 100644 index 00000000..0754b2ab --- /dev/null +++ b/src/sdk.ts @@ -0,0 +1,58 @@ +/* +Copyright 2020 Bruno Windels +Copyright 2020 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. +*/ + +// import {RecordRequester, ReplayRequester} from "./matrix/net/request/replay.js"; +import {SessionContainer} from "./matrix/SessionContainer.js"; +import {RootViewModel} from "./domain/RootViewModel.js"; +import {createNavigation, createRouter} from "./domain/navigation/index.js"; +// Don't use a default export here, as we use multiple entries during legacy build, +// which does not support default exports, +// see https://github.com/rollup/plugins/tree/master/packages/multi-entry +export async function main(platform) { + try { + // to replay: + // const fetchLog = await (await fetch("/fetchlogs/constrainterror.json")).json(); + // const replay = new ReplayRequester(fetchLog, {delay: false}); + // const request = replay.request; + + // to record: + // const recorder = new RecordRequester(createFetchRequest(clock.createTimeout)); + // const request = recorder.request; + // window.getBrawlFetchLog = () => recorder.log(); + const navigation = createNavigation(); + platform.setNavigation(navigation); + const urlRouter = createRouter({navigation, history: platform.history}); + urlRouter.attach(); + const olmPromise = platform.loadOlm(); + const workerPromise = platform.loadOlmWorker(); + + const vm = new RootViewModel({ + createSessionContainer: () => { + return new SessionContainer({platform, olmPromise, workerPromise}); + }, + platform, + // the only public interface of the router is to create urls, + // so we call it that in the view models + urlCreator: urlRouter, + navigation, + }); + await vm.load(); + platform.createAndMountRootView(vm); + } catch(err) { + console.error(`${err.message}:\n${err.stack}`); + } +}