diff --git a/mediarepo-ui/src/app/components/core/core.component.html b/mediarepo-ui/src/app/components/core/core.component.html
index 5cbb8c5..def7489 100644
--- a/mediarepo-ui/src/app/components/core/core.component.html
+++ b/mediarepo-ui/src/app/components/core/core.component.html
@@ -14,8 +14,8 @@
-
-
+
+
diff --git a/mediarepo-ui/src/app/components/core/core.component.ts b/mediarepo-ui/src/app/components/core/core.component.ts
index b6ade5c..edf3026 100644
--- a/mediarepo-ui/src/app/components/core/core.component.ts
+++ b/mediarepo-ui/src/app/components/core/core.component.ts
@@ -4,10 +4,10 @@ import {RepositoryService} from "../../services/repository/repository.service";
import {MatTabChangeEvent, MatTabGroup} from "@angular/material/tabs";
import {TagService} from "../../services/tag/tag.service";
import {TabService} from "../../services/tab/tab.service";
-import {TabCategory} from "../../models/TabCategory";
-import {TabState} from "../../models/TabState";
-import {AppState} from "../../models/AppState";
+import {TabCategory} from "../../models/state/TabCategory";
+import {AppState} from "../../models/state/AppState";
import {StateService} from "../../services/state/state.service";
+import {TabState} from "../../models/state/TabState";
@Component({
selector: "app-core",
diff --git a/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.ts b/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.ts
index 831bd11..fd9fa5f 100644
--- a/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.ts
+++ b/mediarepo-ui/src/app/components/core/empty-tab/empty-tab.component.ts
@@ -1,5 +1,5 @@
import {ChangeDetectionStrategy, Component, EventEmitter, Output} from "@angular/core";
-import {TabCategory} from "../../../models/TabCategory";
+import {TabCategory} from "../../../models/state/TabCategory";
type TabCategoryName = "files" | "import";
diff --git a/mediarepo-ui/src/app/components/core/files-tab/files-tab-sidebar/files-tab-sidebar.component.ts b/mediarepo-ui/src/app/components/core/files-tab/files-tab-sidebar/files-tab-sidebar.component.ts
index 311bce8..e9d3d5f 100644
--- a/mediarepo-ui/src/app/components/core/files-tab/files-tab-sidebar/files-tab-sidebar.component.ts
+++ b/mediarepo-ui/src/app/components/core/files-tab/files-tab-sidebar/files-tab-sidebar.component.ts
@@ -5,7 +5,7 @@ import {File} from "../../../../../api/models/File";
import {FileSearchComponent} from "../../../shared/sidebar/file-search/file-search.component";
import {RepositoryService} from "../../../../services/repository/repository.service";
import {TagEditComponent} from "../../../shared/sidebar/tag-edit/tag-edit.component";
-import {TabState} from "../../../../models/TabState";
+import {FilesTabState} from "../../../../models/state/FilesTabState";
@Component({
selector: "app-files-tab-sidebar",
@@ -14,7 +14,7 @@ import {TabState} from "../../../../models/TabState";
})
export class FilesTabSidebarComponent implements OnInit, OnChanges {
- @Input() state!: TabState;
+ @Input() state!: FilesTabState;
@Input() selectedFiles: File[] = [];
@Output() searchStartEvent = new EventEmitter();
@Output() searchEndEvent = new EventEmitter();
diff --git a/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.ts b/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.ts
index 706866f..8233c6c 100644
--- a/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.ts
+++ b/mediarepo-ui/src/app/components/core/files-tab/files-tab.component.ts
@@ -1,9 +1,9 @@
import {Component, Input, OnInit} from "@angular/core";
import {File} from "../../../../api/models/File";
-import {TabState} from "../../../models/TabState";
+import {FilesTabState} from "../../../models/state/FilesTabState";
import {RepositoryMetadata} from "../../../../api/api-types/repo";
import {RepositoryService} from "../../../services/repository/repository.service";
-import {TabCategory} from "../../../models/TabCategory";
+import {TabCategory} from "../../../models/state/TabCategory";
@Component({
selector: "app-files-tab",
@@ -12,7 +12,7 @@ import {TabCategory} from "../../../models/TabCategory";
})
export class FilesTabComponent implements OnInit {
- @Input() state!: TabState;
+ @Input() state!: FilesTabState;
files: File[] = [];
contentLoading = false;
diff --git a/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.ts b/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.ts
index ba47f1e..857f3b9 100644
--- a/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.ts
+++ b/mediarepo-ui/src/app/components/core/import-tab/import-tab.component.ts
@@ -1,6 +1,6 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit} from "@angular/core";
import {File} from "../../../../api/models/File";
-import {TabState} from "../../../models/TabState";
+import {ImportTabState} from "../../../models/state/ImportTabState";
@Component({
selector: "app-import-tab",
@@ -10,7 +10,7 @@ import {TabState} from "../../../models/TabState";
})
export class ImportTabComponent implements OnInit {
- @Input() state!: TabState;
+ @Input() state!: ImportTabState;
public files: File[] = [];
public selectedFiles: File[] = [];
diff --git a/mediarepo-ui/src/app/components/shared/file/file-multiview/file-multiview.component.ts b/mediarepo-ui/src/app/components/shared/file/file-multiview/file-multiview.component.ts
index 37f4fed..8a69d99 100644
--- a/mediarepo-ui/src/app/components/shared/file/file-multiview/file-multiview.component.ts
+++ b/mediarepo-ui/src/app/components/shared/file/file-multiview/file-multiview.component.ts
@@ -6,7 +6,7 @@ import {FileActionBaseComponent} from "../../app-base/file-action-base/file-acti
import {MatDialog} from "@angular/material/dialog";
import {LoggingService} from "../../../../services/logging/logging.service";
import {FileService} from "../../../../services/file/file.service";
-import {TabState} from "../../../../models/TabState";
+import {FilesTabState} from "../../../../models/state/FilesTabState";
@Component({
selector: "app-file-multiview",
@@ -17,7 +17,7 @@ export class FileMultiviewComponent extends FileActionBaseComponent implements A
@Input() files!: File[];
@Input() mode: "grid" | "gallery" = "grid";
- @Input() tabState!: TabState;
+ @Input() tabState!: FilesTabState;
@Output() fileOpenEvent = new EventEmitter();
@Output() fileSelectEvent = new EventEmitter();
diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.ts b/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.ts
index 97d1c46..fe88675 100644
--- a/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.ts
+++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.ts
@@ -15,7 +15,7 @@ import {LoggingService} from "../../../../services/logging/logging.service";
import {FilterDialogComponent} from "./filter-dialog/filter-dialog.component";
import {Tag} from "../../../../../api/models/Tag";
import {clipboard} from "@tauri-apps/api";
-import {TabState} from "../../../../models/TabState";
+import {FilesTabState} from "../../../../models/state/FilesTabState";
import {FilterQueryBuilder} from "../../../../../api/models/FilterQueryBuilder";
import {SearchFilters} from "../../../../../api/models/SearchFilters";
import {FileStatus, FilterExpression,} from "../../../../../api/api-types/files";
@@ -37,7 +37,7 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
@Input() availableTags: Tag[] = [];
@Input() contextTags: Tag[] = [];
- @Input() state!: TabState;
+ @Input() state!: FilesTabState;
@Input() tagsLoading = false;
@Output() searchStartEvent = new EventEmitter();
diff --git a/mediarepo-ui/src/app/models/AppState.ts b/mediarepo-ui/src/app/models/AppState.ts
deleted file mode 100644
index 923e4c3..0000000
--- a/mediarepo-ui/src/app/models/AppState.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import {TabState} from "./TabState";
-import {FileService} from "../services/file/file.service";
-import {BehaviorSubject} from "rxjs";
-import {TabCategory} from "./TabCategory";
-
-export class AppState {
-
- public tabs = new BehaviorSubject([]);
- public selectedTab = new BehaviorSubject(undefined);
- public repoName: string | undefined;
- private tabIdCounter = 0;
- private readonly fileService: FileService;
-
- constructor(fileService: FileService) {
- this.fileService = fileService;
- }
-
- public static deserializeJson(stateString: string, fileService: FileService): AppState {
- let state = JSON.parse(stateString);
- let appState = new AppState(fileService);
- const tabs = state.tabs.map((tab: any) => TabState.fromDTO(tab, fileService));
- appState.tabs.next(tabs);
-
- appState.tabIdCounter = state.tabIdCounter;
- appState.selectedTab.next(state.selectedTab);
- appState.repoName = state.repoName;
-
- return appState;
- }
-
- 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 serializeJson(): string {
- const tabDTOs = this.tabs.value.map(tab => tab.getDTO());
- return JSON.stringify({
- repoName: this.repoName,
- tabs: tabDTOs,
- tabIdCounter: this.tabIdCounter,
- selectedTab: this.selectedTab.value,
- });
- }
-}
diff --git a/mediarepo-ui/src/app/models/TabState.ts b/mediarepo-ui/src/app/models/TabState.ts
deleted file mode 100644
index fc75b1b..0000000
--- a/mediarepo-ui/src/app/models/TabState.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-import {BehaviorSubject} from "rxjs";
-import {TabCategory} from "./TabCategory";
-import {FileService} from "../services/file/file.service";
-import {File} from "../../api/models/File";
-import {SortKey} from "../../api/models/SortKey";
-import {debounceTime} from "rxjs/operators";
-import {mapNew} from "../../api/models/adaptors";
-import {SearchFilters} from "../../api/models/SearchFilters";
-import {SortingPreset} from "../../api/models/SortingPreset";
-
-export class TabState {
- public uuid: number;
- public category: TabCategory;
- public mode = new BehaviorSubject<"grid" | "gallery">("grid");
- public selectedCD = new BehaviorSubject(undefined);
- public loading = new BehaviorSubject(false);
-
- public files = new BehaviorSubject([]);
- public filters = new BehaviorSubject(new SearchFilters([]));
- public sortingPreset = new BehaviorSubject(SortingPreset.fromValues(
- -1,
- [SortKey.fromValues(
- "FileImportedTime",
- "Ascending",
- undefined
- )]
- ));
-
- private fileService: FileService;
-
- constructor(
- uuid: number,
- category: TabCategory,
- fileService: FileService
- ) {
- this.category = category;
- this.uuid = uuid;
- this.fileService = fileService;
- if (this.category === TabCategory.Files) {
- this.filters.pipe(debounceTime(500))
- .subscribe(async () => await this.findFiles());
- this.sortingPreset.pipe(debounceTime(100))
- .subscribe(async () => await this.findFiles());
- }
- }
-
- public static fromDTO(
- dto: any,
- fileService: FileService
- ): TabState {
- const state = new TabState(
- dto.uuid,
- dto.category,
- fileService
- );
-
- state.filters.next(new SearchFilters(dto.filters ?? []));
- state.sortingPreset.next(new SortingPreset(dto.sortingPreset));
- state.mode.next(dto.mode ?? "grid");
- state.selectedCD.next(dto.selectedFileHash);
- state.files.next((dto.files ?? []).map(mapNew(File)));
-
- return state;
- }
-
- public async findFiles() {
- this.loading.next(true);
- const files = await this.fileService.findFiles(
- this.filters.value,
- this.sortingPreset.value.sortKeys
- );
- this.files.next(files);
- this.loading.next(false);
- }
-
- public setTagFilters(filters: SearchFilters) {
- this.filters.next(filters);
- }
-
- public setSortingPreset(preset: SortingPreset) {
- this.sortingPreset.next(preset);
- }
-
- public getDTO(): any {
- return {
- uuid: this.uuid,
- category: this.category,
- filters: this.filters.value.getFilters(),
- sortingPreset: this.sortingPreset.value.rawData,
- mode: this.mode.value,
- selectedFileHash: this.selectedCD.value,
- files: this.category === TabCategory.Import ? this.files.value.map(
- f => f.rawData) : [],
- };
- }
-}
diff --git a/mediarepo-ui/src/app/models/state/AppState.ts b/mediarepo-ui/src/app/models/state/AppState.ts
new file mode 100644
index 0000000..b1b5559
--- /dev/null
+++ b/mediarepo-ui/src/app/models/state/AppState.ts
@@ -0,0 +1,75 @@
+import {FilesTabSaveState, FilesTabState} from "./FilesTabState";
+import {BehaviorSubject} from "rxjs";
+import {TabCategory} from "./TabCategory";
+import {TabSaveState, TabState} from "./TabState";
+import {StateServices} from "./StateServices";
+import {ImportTabSaveState, ImportTabState} from "./ImportTabState";
+
+export class AppState {
+
+ public tabs = new BehaviorSubject([]);
+ public selectedTab = new BehaviorSubject(undefined);
+ public repoName: string | undefined;
+ private tabIdCounter = 0;
+ private readonly services: StateServices;
+
+ constructor(services: StateServices) {
+ this.services = services;
+ }
+
+ public static deserializeJson(stateString: string, services: StateServices): AppState {
+ let state = JSON.parse(stateString);
+ let appState = new AppState(services);
+
+ const tabs = state.tabs.map((saveState: TabSaveState) => {
+ let tab;
+
+ if (saveState.category === TabCategory.Files) {
+ tab = new FilesTabState(saveState.uuid, services);
+ tab.restoreSaveState(saveState as FilesTabSaveState);
+ } else if (saveState.category === TabCategory.Import) {
+ tab = new ImportTabState(saveState.uuid, services);
+ tab.restoreSaveState(saveState as ImportTabSaveState);
+ }
+
+ return tab;
+ });
+ appState.tabs.next(tabs);
+
+ appState.tabIdCounter = state.tabIdCounter;
+ appState.selectedTab.next(state.selectedTab);
+ appState.repoName = state.repoName;
+
+ return appState;
+ }
+
+ public addTab(category: TabCategory): TabState {
+ let state;
+
+ if (category == TabCategory.Files) {
+ state = new FilesTabState(this.tabIdCounter++, this.services);
+ } else {
+ state = new ImportTabState(this.tabIdCounter++, this.services);
+ }
+
+ 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 serializeJson(): string {
+ const tabDTOs = this.tabs.value.map(tab => tab.toSaveState());
+ return JSON.stringify({
+ repoName: this.repoName,
+ tabs: tabDTOs,
+ tabIdCounter: this.tabIdCounter,
+ selectedTab: this.selectedTab.value,
+ });
+ }
+}
diff --git a/mediarepo-ui/src/app/models/state/FilesTabState.ts b/mediarepo-ui/src/app/models/state/FilesTabState.ts
new file mode 100644
index 0000000..2bd5072
--- /dev/null
+++ b/mediarepo-ui/src/app/models/state/FilesTabState.ts
@@ -0,0 +1,97 @@
+import {BehaviorSubject} from "rxjs";
+import {TabCategory} from "./TabCategory";
+import {File} from "../../../api/models/File";
+import {SortKey} from "../../../api/models/SortKey";
+import {debounceTime} from "rxjs/operators";
+import {mapNew} from "../../../api/models/adaptors";
+import {SearchFilters} from "../../../api/models/SearchFilters";
+import {SortingPreset} from "../../../api/models/SortingPreset";
+import {TabSaveState, TabState} from "./TabState";
+import {StateServices} from "./StateServices";
+import {FileBasicData, FilterExpression} from "../../../api/api-types/files";
+import {SortingPresetData} from "../../../api/api-types/presets";
+import {SaveState} from "./SaveState";
+
+export type FilesTabSaveState = {
+ mode: "gallery" | "grid",
+ selectedCd: string | undefined,
+ files: FileBasicData[],
+ filters: FilterExpression[],
+ sortingPreset: SortingPresetData,
+} & TabSaveState;
+
+export class FilesTabState extends TabState implements SaveState {
+
+ public mode = new BehaviorSubject<"grid" | "gallery">("grid");
+ public selectedCD = new BehaviorSubject(undefined);
+ public loading = new BehaviorSubject(false);
+
+ public files = new BehaviorSubject([]);
+ public filters = new BehaviorSubject(new SearchFilters([]));
+ public sortingPreset = new BehaviorSubject(SortingPreset.fromValues(
+ -1,
+ [SortKey.fromValues(
+ "FileImportedTime",
+ "Ascending",
+ undefined
+ )]
+ ));
+
+ constructor(
+ uuid: number,
+ services: StateServices,
+ ) {
+ super(uuid, TabCategory.Files, services);
+ this.subscribe();
+ }
+
+ public restoreSaveState(
+ state: FilesTabSaveState,
+ ) {
+ super.restoreSaveState(state);
+ this.filters = new BehaviorSubject(new SearchFilters(state.filters ?? []));
+ this.sortingPreset = new BehaviorSubject(new SortingPreset(state.sortingPreset));
+ this.mode = new BehaviorSubject(state.mode ?? "grid");
+ this.selectedCD = new BehaviorSubject(state.selectedCd);
+ this.files = new BehaviorSubject((state.files ?? []).map(mapNew(File)));
+ this.subscribe();
+ }
+
+ public async findFiles() {
+ this.loading.next(true);
+ const files = await this.services.fileService.findFiles(
+ this.filters.value,
+ this.sortingPreset.value.sortKeys
+ );
+ this.files.next(files);
+ this.loading.next(false);
+ }
+
+ public setTagFilters(filters: SearchFilters) {
+ this.filters.next(filters);
+ }
+
+ public setSortingPreset(preset: SortingPreset) {
+ this.sortingPreset.next(preset);
+ }
+
+ public toSaveState(): FilesTabSaveState {
+ return {
+ uuid: this.uuid,
+ category: this.category,
+ filters: this.filters.value.getFilters(),
+ sortingPreset: this.sortingPreset.value.rawData,
+ mode: this.mode.value,
+ selectedCd: this.selectedCD.value,
+ files: this.category === TabCategory.Import ? this.files.value.map(
+ f => f.rawData) : [],
+ };
+ }
+
+ private subscribe() {
+ this.filters.pipe(debounceTime(500))
+ .subscribe(async () => await this.findFiles());
+ this.sortingPreset.pipe(debounceTime(100))
+ .subscribe(async () => await this.findFiles());
+ }
+}
diff --git a/mediarepo-ui/src/app/models/state/ImportTabState.ts b/mediarepo-ui/src/app/models/state/ImportTabState.ts
new file mode 100644
index 0000000..dcda802
--- /dev/null
+++ b/mediarepo-ui/src/app/models/state/ImportTabState.ts
@@ -0,0 +1,44 @@
+import {TabSaveState, TabState} from "./TabState";
+import {SaveState} from "./SaveState";
+import {StateServices} from "./StateServices";
+import {TabCategory} from "./TabCategory";
+import {BehaviorSubject} from "rxjs";
+import {File} from "../../../api/models/File";
+import {FileBasicData} from "../../../api/api-types/files";
+import {mapNew} from "../../../api/models/adaptors";
+
+export type ImportTabSaveState = {
+ selectedCd: string | undefined,
+ mode: "grid" | "gallery",
+ files: FileBasicData[],
+} & TabSaveState;
+
+export class ImportTabState extends TabState implements SaveState {
+
+ public mode = new BehaviorSubject<"grid" | "gallery">("grid");
+ public selectedCD = new BehaviorSubject(undefined);
+ public files = new BehaviorSubject([]);
+
+ constructor(uuid: number, services: StateServices) {
+ super(uuid, TabCategory.Import, services);
+ }
+
+ public restoreSaveState(state: ImportTabSaveState) {
+ super.restoreSaveState(state);
+ this.selectedCD = new BehaviorSubject(state.selectedCd);
+ this.files = new BehaviorSubject(state.files.map(mapNew(File)));
+ this.mode = new BehaviorSubject<"grid" | "gallery">(state.mode);
+
+ return self;
+ }
+
+ public toSaveState(): ImportTabSaveState {
+ return {
+ uuid: this.uuid,
+ category: this.category,
+ selectedCd: this.selectedCD.value,
+ files: this.files.value.map(f => f.rawData),
+ mode: this.mode.value
+ };
+ }
+}
diff --git a/mediarepo-ui/src/app/models/state/SaveState.ts b/mediarepo-ui/src/app/models/state/SaveState.ts
new file mode 100644
index 0000000..50906dd
--- /dev/null
+++ b/mediarepo-ui/src/app/models/state/SaveState.ts
@@ -0,0 +1,5 @@
+export interface SaveState {
+ restoreSaveState(state: State): void;
+
+ toSaveState(): State;
+}
diff --git a/mediarepo-ui/src/app/models/state/StateServices.ts b/mediarepo-ui/src/app/models/state/StateServices.ts
new file mode 100644
index 0000000..0cd930a
--- /dev/null
+++ b/mediarepo-ui/src/app/models/state/StateServices.ts
@@ -0,0 +1,6 @@
+import {FileService} from "../../services/file/file.service";
+
+export class StateServices {
+ constructor(public fileService: FileService) {
+ }
+}
diff --git a/mediarepo-ui/src/app/models/TabCategory.ts b/mediarepo-ui/src/app/models/state/TabCategory.ts
similarity index 100%
rename from mediarepo-ui/src/app/models/TabCategory.ts
rename to mediarepo-ui/src/app/models/state/TabCategory.ts
diff --git a/mediarepo-ui/src/app/models/state/TabState.ts b/mediarepo-ui/src/app/models/state/TabState.ts
new file mode 100644
index 0000000..da50cd4
--- /dev/null
+++ b/mediarepo-ui/src/app/models/state/TabState.ts
@@ -0,0 +1,49 @@
+import {TabCategory} from "./TabCategory";
+import {StateServices} from "./StateServices";
+import {SaveState} from "./SaveState";
+import {FilesTabState} from "./FilesTabState";
+import {ImportTabState} from "./ImportTabState";
+
+export type TabSaveState = {
+ uuid: number,
+ category: TabCategory,
+}
+
+export class TabState implements SaveState {
+ constructor(
+ public uuid: number,
+ public category: TabCategory,
+ protected services: StateServices
+ ) {
+ }
+
+ public toSaveState(): TabSaveState {
+ return {
+ uuid: this.uuid,
+ category: this.category
+ };
+ }
+
+ public restoreSaveState(state: TabSaveState): void {
+ this.uuid = state.uuid;
+ this.category = state.category;
+ }
+
+ /**
+ * Converts the state into a files tab state
+ * Warning: This should only be called when it's guaranteed that this tab is a files tab
+ * @returns {ImportTabState}
+ */
+ public filesTab(): FilesTabState {
+ return this as unknown as FilesTabState;
+ }
+
+ /**
+ * Converts the state into an import tab state
+ * Warning: This should only be called when it's guaranteed that this tab is an import tab
+ * @returns {ImportTabState}
+ */
+ public importTab(): ImportTabState {
+ return this as unknown as ImportTabState;
+ }
+}
diff --git a/mediarepo-ui/src/app/services/state/state.service.ts b/mediarepo-ui/src/app/services/state/state.service.ts
index 3d2a0f7..a11ae49 100644
--- a/mediarepo-ui/src/app/services/state/state.service.ts
+++ b/mediarepo-ui/src/app/services/state/state.service.ts
@@ -1,11 +1,15 @@
import {Injectable} from "@angular/core";
import {BehaviorSubject, Subscription} from "rxjs";
-import {AppState} from "../../models/AppState";
+import {AppState} from "../../models/state/AppState";
import {FileService} from "../file/file.service";
import {RepositoryService} from "../repository/repository.service";
-import {TabState} from "../../models/TabState";
+import {FilesTabState} from "../../models/state/FilesTabState";
import {debounceTime} from "rxjs/operators";
import {MediarepoApi} from "../../../api/Api";
+import {StateServices} from "../../models/state/StateServices";
+import {ImportTabState} from "../../models/state/ImportTabState";
+import {TabState} from "../../models/state/TabState";
+import {TabCategory} from "../../models/state/TabCategory";
@Injectable({
providedIn: "root"
@@ -19,12 +23,12 @@ export class StateService {
private stateChange = new BehaviorSubject(undefined);
constructor(private fileService: FileService, private repoService: RepositoryService) {
- this.state = new BehaviorSubject(new AppState(fileService));
+ this.state = new BehaviorSubject(new AppState(this.getServices()));
this.repoService.selectedRepository.subscribe(async (repo) => {
if (repo && (!this.state.value.repoName || this.state.value.repoName !== repo.name)) {
await this.loadState();
} else {
- const state = new AppState(this.fileService);
+ const state = new AppState(this.getServices());
this.subscribeToState(state);
this.state.next(state);
}
@@ -43,13 +47,13 @@ export class StateService {
if (stateString) {
try {
- state = AppState.deserializeJson(stateString, this.fileService);
+ state = AppState.deserializeJson(stateString, this.getServices());
} catch (err) {
console.error("could not deserialize malformed state: ", err);
- state = new AppState(this.fileService);
+ state = new AppState(this.getServices());
}
} else {
- state = new AppState(this.fileService);
+ state = new AppState(this.getServices());
}
let selectedRepo = this.repoService.selectedRepository.value;
if (selectedRepo) {
@@ -78,14 +82,34 @@ export class StateService {
}
private subscribeToTab(tab: TabState) {
+ if (tab.category === TabCategory.Files) {
+ this.subscribeToFilesTab(tab as FilesTabState);
+ } else if (tab.category === TabCategory.Import) {
+ this.subscribeToImportTab(tab as ImportTabState);
+ }
+ }
+
+ private subscribeToImportTab(tab: ImportTabState) {
+ this.tabSubscriptions.push(tab.mode
+ .subscribe(() => this.stateChange.next()));
+ }
+
+ private subscribeToFilesTab(tab: FilesTabState) {
this.tabSubscriptions.push(tab.filters
.subscribe(() => this.stateChange.next()));
+ this.tabSubscriptions.push(tab.files
+ .subscribe(() => this.stateChange.next()));
this.tabSubscriptions.push(tab.sortingPreset
.subscribe(() => this.stateChange.next()));
this.tabSubscriptions.push(
tab.selectedCD.subscribe(() => this.stateChange.next()));
this.tabSubscriptions.push(
tab.mode.subscribe(() => this.stateChange.next()));
- this.tabSubscriptions.push(tab.files.subscribe(() => this.stateChange.next()));
+ this.tabSubscriptions.push(tab.mode
+ .subscribe(() => this.stateChange.next()));
+ }
+
+ private getServices(): StateServices {
+ return new StateServices(this.fileService);
}
}