UNPKG

globular-mvc

Version:

Generic template to create web-application that made use of globular as backend and materialize as css (wrap in web-component's)

280 lines (232 loc) 10 kB
import { generatePeerToken, Model } from "./Model"; import { ApplicationView } from "./ApplicationView"; import { Account } from "./Account" import * as resource from "globular-web-client/resource/resource_pb"; import { Globular } from "globular-web-client"; import { GetSubjectAvailableSpaceRqst, SubjectType } from "globular-web-client/rbac/rbac_pb"; /** * The session object will keep information about the * the account. */ export enum SessionState { Online, Offline, Away } export class Session extends Model { // private members. private _id: string; private account: Account; private state_: SessionState; private lastStateTime_: Date; // Keep track ot the last session state. private domain_: string; // where the session is... public get domain(): string { return this.domain_ } public get lastStateTime(): Date { return this.lastStateTime_; } public set lastStateTime(value: Date) { this.lastStateTime_ = value; } public get state(): SessionState { return this.state_; } // Set the session state. public set state(value: SessionState) { this.state_ = value; this.lastStateTime = new Date(); } // The link to the account. constructor(account: Account, state: number = 1, lastStateTime?: number) { super(); this.account = account; this._id = this.account.id; if (state == 0) { this.state = SessionState.Online; } else if (state == 1) { this.state = SessionState.Offline; } else if (state == 2) { this.state = SessionState.Away; } if (lastStateTime != undefined) { this.lastStateTime = new Date(lastStateTime * 1000) } } // Retreive the most recent session on all peers getSession(callback: (session: resource.Session, domain: string) => void, errorCallback: (err: any) => void) { let globules = Model.getGlobules() // Keep the most recent session... let lastSession: resource.Session let lastDomain: string let _getSession_ = (globule: Globular) => { // In that case I will get the values from the database... let rqst = new resource.GetSessionRequest rqst.setAccountid(this._id) // call persist data globule.resourceService .getSession(rqst, { token: localStorage.getItem("user_token"), application: Model.application, domain: Model.domain, address: Model.address }) .then((rsp: resource.GetSessionResponse) => { // get the response let obj = rsp.getSession() if (lastSession != null) { if (obj.getExpireAt() > lastSession.getExpireAt()) { lastSession = obj lastDomain = globule.domain } } else { lastSession = obj lastDomain = globule.domain } if (globules.length > 0) { _getSession_(globules.pop()) return } // end here... callback(lastSession, lastDomain) }).catch(err => { if (globules.length > 0) { _getSession_(globules.pop()) return } if (lastSession != null) { callback(lastSession, lastDomain) } else { errorCallback(err) } return }) } _getSession_(globules.pop()) } initData(initCallback: () => void, errorCallback: (err: any) => void) { let accountId = this.account.id + "@" + this.account.domain this._id = accountId; this.getSession((session: resource.Session, domain: string) => { this.state_ = session.getState().valueOf(); this.lastStateTime = new Date(session.getLastStateTime() * 1000); this.domain_ = domain; let globule = Model.getGlobule(this.account.domain) let rqst = new GetSubjectAvailableSpaceRqst rqst.setSubject(accountId) rqst.setType(SubjectType.ACCOUNT) let token = localStorage.getItem("user_token") // load available space for the account on the globule... globule.rbacService .getSubjectAvailableSpace(rqst, { token: token, application: Model.application, domain: Model.domain }) .then((rsp) => { console.log(rsp) }) .catch((err) => { console.log(err) }); // So here I will lisen on session change event and keep this object with it. globule.eventHub.subscribe(`session_state_${this.account.id + "@" + this.account.domain}_change_event`, (uuid: string) => { /** nothing special here... */ }, (evt: string) => { let obj = JSON.parse(evt) // update the session state from the network. this.state_ = obj.state; this.lastStateTime = new Date(obj.lastStateTime * 1000); // a number to date }, false, this) Model.eventHub.subscribe(`__session_state_${this.account.id + "@" + this.account.domain}_change_event__`, (uuid: string) => { /** nothing special here... */ }, (obj: any) => { // Set the object state from the object and save it... this.state_ = obj.state; this.lastStateTime = obj.lastStateTime; // already a date this.save(() => { /* nothing here*/ }, (err: any) => { ApplicationView.displayMessage(err, 3000) }) }, true, this) Account.getAccount(this._id, (account: Account) => { // Here I will connect local event to react with interface element... this.account = account; initCallback() }, errorCallback) }, (err: any) => { // In that case I will save defaut session values... this.save(() => { initCallback() }, errorCallback) }) } toString(): string { // return the basic infomration to be store in the database. let lastTime = 0 if (this.lastStateTime) { lastTime = Math.floor(this.lastStateTime.getTime() / 1000) } return `{"_id":"${this._id}", "state":${this.state.toString()}, "lastStateTime":"${lastTime}"}` } // Init from the db... fromObject(obj: any) { this._id = obj._id; Account.getAccount(this._id, (account: Account) => { this.account = account }, (err: any) => { console.log(err) }) if (obj.state == 0) { this.state = SessionState.Online; } else if (obj.state == 1) { this.state = SessionState.Offline; } else if (obj.state == 2) { this.state = SessionState.Away; } this.lastStateTime = new Date(obj.lastStateTime * 1000); } // Save session state in the databese. save(onSave: () => void, onError: (err: any) => void) { let rqst = new resource.UpdateSessionRequest; let session = new resource.Session; // save the actual session informations. session.setAccountid(this.account.id + "@" + this.account.domain) let lastStateTime = 0 if (this.lastStateTime) { lastStateTime = Math.floor(this.lastStateTime.getTime() / 1000) } session.setLastStateTime(lastStateTime) if (this.state == SessionState.Away) { session.setState(resource.SessionState.AWAY) } else if (this.state == SessionState.Online) { session.setState(resource.SessionState.ONLINE) } else if (this.state == SessionState.Offline) { session.setState(resource.SessionState.OFFLINE) } session.setExpireAt(parseInt(localStorage.getItem("token_expired"))) rqst.setSession(session) // TEST if session must be on the user globule or the actual session store. let globule = Model.getGlobule(this.account.domain) generatePeerToken(globule, token => { // call persist data globule.resourceService .updateSession(rqst, { token: token, application: Model.application, domain: this.account.domain, address: Model.address }) .then((rsp: resource.UpdateSessionResponse) => { // Here I will return the value with it Model.getGlobule(this.account.domain).eventHub.publish(`session_state_${this._id}_change_event`, this.toString(), false) onSave(); }) .catch((err: any) => { onError(err); }); }, err => console.log(err)) } }