Start refactoring state management

This commit is contained in:
schmelczerandras 2019-08-31 21:21:21 +02:00
commit a9ad628488

View file

@ -1,93 +1,69 @@
import { Injectable } from '@angular/core';
import { StoreService } from './store.service';
import { Page } from '../model/page';
const USER_DATA_KEY = 'life-towers.user-data.v.1';
import { Root } from '../storage/root';
import { Serializable } from '../model/serializable';
import { Tower } from '../model/tower';
import { Block } from '../model/block';
import { IPage } from '../interfaces/persistance/page';
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
import { Observable } from 'rxjs/internal/Observable';
@Injectable({
providedIn: 'root'
})
export class DataService {
get active(): Page {
return this._active;
export class DataService extends Root<Page> {
get pages(): Array<Page> {
return this.children;
}
get pageNames(): string[] {
return this.data.map(p => p.name);
}
private readonly _safeChildren: BehaviorSubject<Array<Page>> = new BehaviorSubject(null);
readonly safeChildren$: Observable<Array<Page>> = this._safeChildren.asObservable();
private subscribers: (() => void)[] = [];
private _active: Page = null;
private data: Page[];
private hasLoaded = new Promise(resolve => (this.afterLoadFinished = resolve));
private afterLoadFinished: () => void;
constructor(private storeService: StoreService) {
this.init();
}
push(value: Page) {
value.subscribe(() => this.save());
this.data.push(value);
this._active = value;
this.save();
}
remove() {
this.data = this.data.filter(p => p !== this.active);
this._active = this.data.length > 0 ? this.data[0] : null;
this.save();
}
subscribe(func: () => void) {
this.subscribers.push(func);
}
async changeActiveByName(name: string): Promise<void> {
await this.hasLoaded;
this._active = this.data.filter(p => p.name === name)[0];
this.saveActiveIndex(this.data.indexOf(this.active));
this.update();
}
async changeActiveByIndex(index: number): Promise<void> {
await this.hasLoaded;
this._active = this.data[index];
this.saveActiveIndex(index);
this.update();
constructor(private storeService: StoreService<Array<IPage>>) {
super();
this.init().catch();
}
private async init() {
this.data = await this.storeService.load();
this.data.map(p => p.subscribe(() => this.save()));
this._active = this.data.length > 0 ? this.data[0] : null;
this.loadActiveIndex();
this.afterLoadFinished();
}
private save() {
this.storeService.save(this.data);
this.update();
}
private update() {
this.subscribers.map(f => f());
}
private loadActiveIndex() {
const userData = JSON.parse(window.localStorage.getItem(USER_DATA_KEY));
if (userData === null) {
return;
const pages = await this.storeService.load();
Serializable.childrenMap = {
Page: {
childrenListName: 'towers',
childrenConstructor: Tower
},
Tower: {
childrenListName: 'blocks',
childrenConstructor: Block
},
Block: {
childrenListName: null,
childrenConstructor: null
}
};
for (let page of pages) {
new Page(this, page);
}
this._active = this.data[userData.index];
this.children$.subscribe(value => {
this.log();
this._safeChildren.next(value);
this.storeService.scheduleSave(this.pages);
});
}
private saveActiveIndex(index: number) {
window.localStorage.setItem(
USER_DATA_KEY,
JSON.stringify({
index
})
);
addPage(name: string) {
new Page(this, {
name,
userData: {},
type: 'Page',
towers: []
});
}
removePage(page: Page) {
this.changeValue({
oldValue: this.children,
newValue: this.children.filter(c => c !== page)
});
}
}