Improve storing of the state on change rather than periodically
Signed-off-by: trivernis <trivernis@protonmail.com>pull/4/head
parent
f652785ccf
commit
08632080cb
@ -1,27 +1,48 @@
|
|||||||
import {TabState} from "./TabState.rs";
|
import {TabState} from "./TabState.rs";
|
||||||
import {FileService} from "../services/file/file.service";
|
import {FileService} from "../services/file/file.service";
|
||||||
|
import {BehaviorSubject} from "rxjs";
|
||||||
|
import {TabCategory} from "./TabCategory";
|
||||||
|
|
||||||
export class AppState {
|
export class AppState {
|
||||||
|
|
||||||
public tabs: TabState[] = [];
|
private tabIdCounter = 0;
|
||||||
|
public tabs = new BehaviorSubject<TabState[]>([]);
|
||||||
|
|
||||||
constructor() {
|
private readonly fileService: FileService
|
||||||
|
|
||||||
|
constructor(fileService: FileService) {
|
||||||
|
this.fileService = fileService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addTab(category: TabCategory): TabState {
|
||||||
|
const state = new TabState(this.tabIdCounter++, category, this.fileService);
|
||||||
|
this.tabs.next([...this.tabs.value, state]);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async closeTab(uuid: number) {
|
||||||
|
const index = this.tabs.value.findIndex(t => t.uuid === uuid);
|
||||||
|
const tabs = this.tabs.value;
|
||||||
|
tabs.splice(index, 1)
|
||||||
|
this.tabs.next(tabs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static deserializeJson(stateString: string, fileService: FileService): AppState {
|
public static deserializeJson(stateString: string, fileService: FileService): AppState {
|
||||||
let state = JSON.parse(stateString);
|
let state = JSON.parse(stateString);
|
||||||
let appState = new AppState();
|
let appState = new AppState(fileService);
|
||||||
for (let tab of state.tabs) {
|
const tabs = state.tabs.map((tab: any) => TabState.fromDTO(tab, fileService));
|
||||||
appState.tabs.push(TabState.fromDTO(tab, fileService));
|
appState.tabs.next(tabs);
|
||||||
}
|
|
||||||
|
appState.tabIdCounter = state.tabIdCounter;
|
||||||
|
|
||||||
return appState
|
return appState
|
||||||
}
|
}
|
||||||
|
|
||||||
public serializeJson(): string {
|
public serializeJson(): string {
|
||||||
const tabDTOs = this.tabs.map(tab => tab.getDTO());
|
const tabDTOs = this.tabs.value.map(tab => tab.getDTO());
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
tabs: tabDTOs
|
tabs: tabDTOs,
|
||||||
|
tabIdCounter: this.tabIdCounter,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
import {TestBed} from "@angular/core/testing";
|
||||||
|
|
||||||
|
import {StateService} from "./state.service";
|
||||||
|
|
||||||
|
describe("StateServiceService", () => {
|
||||||
|
let service: StateService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(StateService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should be created", () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,76 @@
|
|||||||
|
import {Injectable} from "@angular/core";
|
||||||
|
import {BehaviorSubject, Subscription} from "rxjs";
|
||||||
|
import {AppState} from "../../models/AppState";
|
||||||
|
import {invoke} from "@tauri-apps/api/tauri";
|
||||||
|
import {FileService} from "../file/file.service";
|
||||||
|
import {RepositoryService} from "../repository/repository.service";
|
||||||
|
import {TabState} from "../../models/TabState.rs";
|
||||||
|
import {debounceTime} from "rxjs/operators";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: "root"
|
||||||
|
})
|
||||||
|
export class StateService {
|
||||||
|
|
||||||
|
public state: BehaviorSubject<AppState>;
|
||||||
|
|
||||||
|
private tabSubscriptions: Subscription[] = [];
|
||||||
|
|
||||||
|
private stateChange = new BehaviorSubject<void>(undefined);
|
||||||
|
|
||||||
|
constructor(private fileService: FileService, private repoService: RepositoryService) {
|
||||||
|
this.state = new BehaviorSubject(new AppState(fileService));
|
||||||
|
this.repoService.selectedRepository.subscribe(async (repo) => {
|
||||||
|
if (repo) {
|
||||||
|
await this.loadState();
|
||||||
|
} else {
|
||||||
|
const state = new AppState(this.fileService);
|
||||||
|
this.subscribeToState(state);
|
||||||
|
this.state.next(state);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.stateChange.pipe(debounceTime(1000)).subscribe(async () => this.saveState());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the state of the frontend
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
public async loadState() {
|
||||||
|
let stateString = await invoke<string | undefined>(
|
||||||
|
"plugin:mediarepo|get_frontend_state");
|
||||||
|
let state;
|
||||||
|
|
||||||
|
if (stateString) {
|
||||||
|
state = AppState.deserializeJson(stateString, this.fileService)
|
||||||
|
} else {
|
||||||
|
state = new AppState(this.fileService);
|
||||||
|
}
|
||||||
|
this.subscribeToState(state);
|
||||||
|
this.state.next(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
private subscribeToState(state: AppState) {
|
||||||
|
state.tabs.subscribe(async tabs => {
|
||||||
|
this.tabSubscriptions.forEach(s => s.unsubscribe());
|
||||||
|
tabs.forEach((tab) => this.subscribeToTab(tab));
|
||||||
|
this.stateChange.next();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private subscribeToTab(tab: TabState) {
|
||||||
|
this.tabSubscriptions.push(tab.filters
|
||||||
|
.subscribe(() => this.stateChange.next()));
|
||||||
|
this.tabSubscriptions.push(tab.sortKeys
|
||||||
|
.subscribe(() => this.stateChange.next()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the state of the frontend
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
public async saveState(): Promise<void> {
|
||||||
|
await invoke("plugin:mediarepo|set_frontend_state",
|
||||||
|
{state: this.state.value.serializeJson()})
|
||||||
|
}
|
||||||
|
}
|
@ -1,55 +1,17 @@
|
|||||||
import {Injectable} from "@angular/core";
|
import {Injectable} from "@angular/core";
|
||||||
import {BehaviorSubject} from "rxjs";
|
import {BehaviorSubject} from "rxjs";
|
||||||
import {TabState} from "../../models/TabState.rs";
|
|
||||||
import {TabCategory} from "../../models/TabCategory";
|
|
||||||
import {FileService} from "../file/file.service";
|
|
||||||
import {AppState} from "../../models/AppState";
|
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: "root"
|
providedIn: "root"
|
||||||
})
|
})
|
||||||
export class TabService {
|
export class TabService {
|
||||||
|
|
||||||
private tabIdCounter = 0;
|
|
||||||
public selectedTab = new BehaviorSubject<number>(0);
|
public selectedTab = new BehaviorSubject<number>(0);
|
||||||
public tabs = new BehaviorSubject<TabState[]>([]);
|
|
||||||
private appState?: AppState;
|
|
||||||
|
|
||||||
constructor(private fileService: FileService) {
|
constructor() {
|
||||||
}
|
|
||||||
|
|
||||||
public restoreFromState(appState: AppState) {
|
|
||||||
this.tabs.next(appState.tabs);
|
|
||||||
this.appState = appState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public setSelectedTab(index: number) {
|
public setSelectedTab(index: number) {
|
||||||
this.selectedTab.next(index);
|
this.selectedTab.next(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public addTab(category: TabCategory): TabState {
|
|
||||||
const state = new TabState(this.tabIdCounter++, category, this.fileService);
|
|
||||||
this.tabs.next([...this.tabs.value, state]);
|
|
||||||
this.saveState();
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public closeTab(uuid: number) {
|
|
||||||
const index = this.tabs.value.findIndex(t => t.uuid === uuid);
|
|
||||||
const tabs = this.tabs.value;
|
|
||||||
tabs.splice(index, 1)
|
|
||||||
this.saveState();
|
|
||||||
this.tabs.next(tabs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public closeAllTabs() {
|
|
||||||
this.tabs.next([]);
|
|
||||||
this.saveState();
|
|
||||||
}
|
|
||||||
|
|
||||||
private saveState() {
|
|
||||||
if (this.appState) {
|
|
||||||
this.appState.tabs = this.tabs.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Loading…
Reference in New Issue