mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-23 11:35:04 +01:00
port SessionPickerViewModel to SessionContainer
This commit is contained in:
parent
a5965ad378
commit
f4983b5ba6
@ -1,6 +1,7 @@
|
|||||||
import {SortedArray} from "../observable/index.js";
|
import {SortedArray} from "../observable/index.js";
|
||||||
import {EventEmitter} from "../utils/EventEmitter.js";
|
import {EventEmitter} from "../utils/EventEmitter.js";
|
||||||
import {createNewSessionId} from "./BrawlViewModel.js"
|
import {LoadStatus} from "../matrix/SessionContainer.js";
|
||||||
|
import {SyncStatus} from "../matrix/Sync.js";
|
||||||
|
|
||||||
class SessionItemViewModel extends EventEmitter {
|
class SessionItemViewModel extends EventEmitter {
|
||||||
constructor(sessionInfo, pickerVM) {
|
constructor(sessionInfo, pickerVM) {
|
||||||
@ -99,22 +100,58 @@ class SessionItemViewModel extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class SessionPickerViewModel {
|
export class SessionPickerViewModel {
|
||||||
constructor({storageFactory, sessionInfoStorage, sessionCallback}) {
|
constructor({storageFactory, sessionInfoStorage, sessionCallback, createSessionContainer}) {
|
||||||
this._storageFactory = storageFactory;
|
this._storageFactory = storageFactory;
|
||||||
this._sessionInfoStorage = sessionInfoStorage;
|
this._sessionInfoStorage = sessionInfoStorage;
|
||||||
this._sessionCallback = sessionCallback;
|
this._sessionCallback = sessionCallback;
|
||||||
|
this._createSessionContainer = createSessionContainer;
|
||||||
this._sessions = new SortedArray((s1, s2) => s1.id.localeCompare(s2.id));
|
this._sessions = new SortedArray((s1, s2) => s1.id.localeCompare(s2.id));
|
||||||
|
this._loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this loads all the sessions
|
||||||
async load() {
|
async load() {
|
||||||
const sessions = await this._sessionInfoStorage.getAll();
|
const sessions = await this._sessionInfoStorage.getAll();
|
||||||
this._sessions.setManyUnsorted(sessions.map(s => new SessionItemViewModel(s, this)));
|
this._sessions.setManyUnsorted(sessions.map(s => new SessionItemViewModel(s, this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pick(id) {
|
// this is the loading of a single picked session
|
||||||
|
get loading() {
|
||||||
|
return this._loading;
|
||||||
|
}
|
||||||
|
|
||||||
|
get loadStatus() {
|
||||||
|
return this._sessionContainer && this._sessionContainer.loadStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
get loadError() {
|
||||||
|
if (this._sessionContainer) {
|
||||||
|
const error = this._sessionContainer.loadError;
|
||||||
|
if (error) {
|
||||||
|
return error.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async pick(id) {
|
||||||
const sessionVM = this._sessions.array.find(s => s.id === id);
|
const sessionVM = this._sessions.array.find(s => s.id === id);
|
||||||
if (sessionVM) {
|
if (sessionVM) {
|
||||||
this._sessionCallback(sessionVM.sessionInfo);
|
this._loading = true;
|
||||||
|
this.emit("change", "loading");
|
||||||
|
this._sessionContainer = this._createSessionContainer();
|
||||||
|
this._sessionContainer.startWithExistingSession(sessionVM.sessionInfo.id);
|
||||||
|
// TODO: allow to cancel here
|
||||||
|
const waitHandle = this._sessionContainer.loadStatus.waitFor(s => {
|
||||||
|
this.emit("change", "loadStatus");
|
||||||
|
// wait for initial sync, but not catchup sync
|
||||||
|
return (
|
||||||
|
s === LoadStatus.FirstSync &&
|
||||||
|
this._sessionContainer.sync.status === SyncStatus.CatchupSync
|
||||||
|
) || s === LoadStatus.Ready;
|
||||||
|
});
|
||||||
|
await waitHandle.promise;
|
||||||
|
this._sessionCallback(this._sessionContainer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +166,7 @@ export class SessionPickerViewModel {
|
|||||||
const data = JSON.parse(json);
|
const data = JSON.parse(json);
|
||||||
const {sessionInfo} = data;
|
const {sessionInfo} = data;
|
||||||
sessionInfo.comment = `Imported on ${new Date().toLocaleString()} from id ${sessionInfo.id}.`;
|
sessionInfo.comment = `Imported on ${new Date().toLocaleString()} from id ${sessionInfo.id}.`;
|
||||||
sessionInfo.id = createNewSessionId();
|
sessionInfo.id = this._createSessionContainer().createNewSessionId();
|
||||||
await this._storageFactory.import(sessionInfo.id, data.stores);
|
await this._storageFactory.import(sessionInfo.id, data.stores);
|
||||||
await this._sessionInfoStorage.add(sessionInfo);
|
await this._sessionInfoStorage.add(sessionInfo);
|
||||||
this._sessions.set(new SessionItemViewModel(sessionInfo, this));
|
this._sessions.set(new SessionItemViewModel(sessionInfo, this));
|
||||||
|
@ -23,19 +23,21 @@ export default async function main(container) {
|
|||||||
const request = fetchRequest;
|
const request = fetchRequest;
|
||||||
const sessionInfoStorage = new SessionInfoStorage("brawl_sessions_v1");
|
const sessionInfoStorage = new SessionInfoStorage("brawl_sessions_v1");
|
||||||
const clock = new Clock();
|
const clock = new Clock();
|
||||||
|
const storageFactory = new StorageFactory();
|
||||||
|
|
||||||
const vm = new BrawlViewModel({
|
const vm = new BrawlViewModel({
|
||||||
createSessionContainer: () => {
|
createSessionContainer: () => {
|
||||||
return new SessionContainer({
|
return new SessionContainer({
|
||||||
random: Math.random,
|
random: Math.random,
|
||||||
onlineStatus: new OnlineStatus(),
|
onlineStatus: new OnlineStatus(),
|
||||||
storageFactory: new StorageFactory(),
|
storageFactory,
|
||||||
sessionInfoStorage,
|
sessionInfoStorage,
|
||||||
request,
|
request,
|
||||||
clock,
|
clock,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
sessionInfoStorage,
|
sessionInfoStorage,
|
||||||
|
storageFactory,
|
||||||
clock,
|
clock,
|
||||||
});
|
});
|
||||||
await vm.load();
|
await vm.load();
|
||||||
|
@ -43,7 +43,7 @@ export class SessionContainer {
|
|||||||
this._storage = null;
|
this._storage = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_createNewSessionId() {
|
createNewSessionId() {
|
||||||
return (Math.floor(this._random() * Number.MAX_SAFE_INTEGER)).toString();
|
return (Math.floor(this._random() * Number.MAX_SAFE_INTEGER)).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +54,9 @@ export class SessionContainer {
|
|||||||
this._status.set(LoadStatus.Loading);
|
this._status.set(LoadStatus.Loading);
|
||||||
try {
|
try {
|
||||||
const sessionInfo = await this._sessionInfoStorage.get(sessionId);
|
const sessionInfo = await this._sessionInfoStorage.get(sessionId);
|
||||||
|
if (!sessionInfo) {
|
||||||
|
throw new Error("Invalid session id: " + sessionId);
|
||||||
|
}
|
||||||
await this._loadSessionInfo(sessionInfo);
|
await this._loadSessionInfo(sessionInfo);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._error = err;
|
this._error = err;
|
||||||
@ -70,7 +73,7 @@ export class SessionContainer {
|
|||||||
try {
|
try {
|
||||||
const hsApi = new HomeServerApi({homeServer, request: this._request});
|
const hsApi = new HomeServerApi({homeServer, request: this._request});
|
||||||
const loginData = await hsApi.passwordLogin(username, password).response();
|
const loginData = await hsApi.passwordLogin(username, password).response();
|
||||||
const sessionId = this._createNewSessionId();
|
const sessionId = this.createNewSessionId();
|
||||||
sessionInfo = {
|
sessionInfo = {
|
||||||
id: sessionId,
|
id: sessionId,
|
||||||
deviceId: loginData.device_id,
|
deviceId: loginData.device_id,
|
||||||
@ -211,6 +214,7 @@ export class SessionContainer {
|
|||||||
}
|
}
|
||||||
if (this._storage) {
|
if (this._storage) {
|
||||||
this._storage.close();
|
this._storage.close();
|
||||||
|
this._storage = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,42 +230,3 @@ export class SessionContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
function main() {
|
|
||||||
// these are only required for external classes,
|
|
||||||
// SessionFactory has it's defaults for internal classes
|
|
||||||
const sessionFactory = new SessionFactory({
|
|
||||||
Clock: DOMClock,
|
|
||||||
OnlineState: DOMOnlineState,
|
|
||||||
SessionInfoStorage: LocalStorageSessionStore, // should be called SessionInfoStore?
|
|
||||||
StorageFactory: window.indexedDB ? IDBStorageFactory : MemoryStorageFactory, // should be called StorageManager?
|
|
||||||
// should be moved to StorageFactory as `KeyBounds`?: minStorageKey, middleStorageKey, maxStorageKey
|
|
||||||
// would need to pass it into EventKey though
|
|
||||||
request,
|
|
||||||
});
|
|
||||||
|
|
||||||
// lets not do this in a first cut
|
|
||||||
// internally in the matrix lib
|
|
||||||
const room = new creator.ctor("Room", Room)({});
|
|
||||||
|
|
||||||
// or short
|
|
||||||
const sessionFactory = new SessionFactory(WebFactory);
|
|
||||||
// sessionFactory.sessionInfoStore
|
|
||||||
|
|
||||||
// registration
|
|
||||||
// const registration = sessionFactory.registerUser();
|
|
||||||
// registration.stage
|
|
||||||
|
|
||||||
|
|
||||||
const container = sessionFactory.startWithRegistration(registration);
|
|
||||||
const container = sessionFactory.startWithLogin(server, username, password);
|
|
||||||
const container = sessionFactory.startWithExistingSession(sessionId);
|
|
||||||
// container.loadStatus is an ObservableValue<LoadStatus>
|
|
||||||
await container.loadStatus.waitFor(s => s === LoadStatus.FirstSync && container.sync.status === SyncStatus.CatchupSync || s === LoadStatus.Ready);
|
|
||||||
|
|
||||||
// loader isn't needed anymore from now on
|
|
||||||
const {session, sync, reconnector} = container;
|
|
||||||
container.stop();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
Loading…
Reference in New Issue
Block a user