|
|
|
@ -1,4 +1,4 @@
|
|
|
|
|
import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
|
|
|
|
import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, OnChanges, OnInit, QueryList, SimpleChanges, ViewChild, ViewChildren } from '@angular/core';
|
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
CdkDrag,
|
|
|
|
@ -14,7 +14,7 @@ import { Plan, PlanElement } from '../_models/plan';
|
|
|
|
|
import { WorldAreaService } from '../_services/world-area.service';
|
|
|
|
|
import { FormsModule } from '@angular/forms';
|
|
|
|
|
import { Fuzzr } from '../fuzzr/fuzzr';
|
|
|
|
|
import { from } from 'rxjs';
|
|
|
|
|
import { BehaviorSubject, first, from, skip } from 'rxjs';
|
|
|
|
|
import { save } from '@tauri-apps/api/dialog';
|
|
|
|
|
import { PlanService } from '../_services/plan.service';
|
|
|
|
|
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
|
|
|
@ -47,12 +47,11 @@ interface Act {
|
|
|
|
|
MatInputModule,
|
|
|
|
|
MatSelectModule,
|
|
|
|
|
MatButtonModule,
|
|
|
|
|
MatSlideToggleModule
|
|
|
|
|
MatSlideToggleModule,
|
|
|
|
|
],
|
|
|
|
|
providers: []
|
|
|
|
|
})
|
|
|
|
|
export class EditorComponent implements OnInit {
|
|
|
|
|
planInEditing: Plan;
|
|
|
|
|
|
|
|
|
|
areas?: WorldArea[];
|
|
|
|
|
planAreas: WorldArea[];
|
|
|
|
|
areasMap?: Map<String, WorldArea>;
|
|
|
|
@ -62,22 +61,22 @@ export class EditorComponent implements OnInit {
|
|
|
|
|
filterAct: Act;
|
|
|
|
|
planFilterAct: Act;
|
|
|
|
|
acts: Act[];
|
|
|
|
|
@ViewChild('planList') planListElement!: ElementRef;
|
|
|
|
|
@ViewChild('planListElement') planListElement!: ElementRef;
|
|
|
|
|
autoScrollToEnd: boolean;
|
|
|
|
|
reverseDisplay: boolean;
|
|
|
|
|
disabledPlanDD: boolean;
|
|
|
|
|
original: PlanElement[] = [];
|
|
|
|
|
|
|
|
|
|
latestList: BehaviorSubject<PlanElement[]> = new BehaviorSubject<PlanElement[]>([]);
|
|
|
|
|
|
|
|
|
|
constructor(public worldAreaService: WorldAreaService, private cdr: ChangeDetectorRef, private planService: PlanService, public dialog: MatDialog) {
|
|
|
|
|
this.planInEditing = new Plan({
|
|
|
|
|
plan: [],
|
|
|
|
|
current: 0
|
|
|
|
|
});
|
|
|
|
|
this.disabledPlanDD = false;
|
|
|
|
|
|
|
|
|
|
this.autoScrollToEnd = false;
|
|
|
|
|
|
|
|
|
|
this.planFuzzer = new Fuzzr(this.planInEditing.plan, {
|
|
|
|
|
this.latestList = new BehaviorSubject<any[]>([]);
|
|
|
|
|
|
|
|
|
|
this.planFuzzer = new Fuzzr(this.original, {
|
|
|
|
|
toString: (e: PlanElement) => {
|
|
|
|
|
return this.areasMap?.get(e.area_key)?.name;
|
|
|
|
|
}
|
|
|
|
@ -100,6 +99,19 @@ export class EditorComponent implements OnInit {
|
|
|
|
|
this.planFilterAct = this.acts[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
planSearchStringChange(value: string) {
|
|
|
|
|
this.planSearchString = value;
|
|
|
|
|
this.filterPlanElements();
|
|
|
|
|
}
|
|
|
|
|
planFilterActChange(value: Act) {
|
|
|
|
|
this.planFilterAct = value;
|
|
|
|
|
this.filterPlanElements();
|
|
|
|
|
}
|
|
|
|
|
reverseDisplayChange(value: boolean) {
|
|
|
|
|
this.reverseDisplay = value;
|
|
|
|
|
this.filterPlanElements();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ngOnInit(): void {
|
|
|
|
|
this.worldAreaService.getWorldAreas().subscribe(worldAreas => {
|
|
|
|
|
this.areas = [...worldAreas.values()];
|
|
|
|
@ -113,32 +125,45 @@ export class EditorComponent implements OnInit {
|
|
|
|
|
|
|
|
|
|
dropHandler(event: CdkDragDrop<WorldArea[]> | CdkDragDrop<PlanElement[]>) {
|
|
|
|
|
if (event.previousContainer === event.container && !isWorldAreaEvent(event)) {
|
|
|
|
|
const realCurrent = this.planInEditing.plan.indexOf(event.previousContainer.data[event.currentIndex]);
|
|
|
|
|
const realPrev = this.planInEditing.plan.indexOf(event.previousContainer.data[event.previousIndex]);
|
|
|
|
|
moveItemInArray(this.planInEditing.plan, realPrev, realCurrent);
|
|
|
|
|
} else
|
|
|
|
|
if (this.planInEditing && this.areas && isWorldAreaEvent(event)) {
|
|
|
|
|
const realCurrent = this.original.indexOf(event.previousContainer.data[event.currentIndex]);
|
|
|
|
|
const realPrev = this.original.indexOf(event.previousContainer.data[event.previousIndex]);
|
|
|
|
|
moveItemInArray(this.original, realPrev, realCurrent);
|
|
|
|
|
} else {
|
|
|
|
|
if (this.areas && isWorldAreaEvent(event)) {
|
|
|
|
|
if (event.container.data.length > 0 && 'connections_world_areas_keys' in event.container.data[0]) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bounds = this.planElemFilterBounds();
|
|
|
|
|
let index = event.currentIndex;
|
|
|
|
|
let index = event.item.data;
|
|
|
|
|
if (bounds) {
|
|
|
|
|
index += bounds[0];
|
|
|
|
|
}
|
|
|
|
|
this.planInEditing.plan.splice(index, 0, this.planItemFromArea(event.previousContainer.data[event.previousIndex]));
|
|
|
|
|
this.original.splice(index, 0, this.planItemFromArea(event.previousContainer.data[event.previousIndex]));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dropEndHandler(event: CdkDragDrop<WorldArea[]> | CdkDragDrop<PlanElement[]>) {
|
|
|
|
|
this.latestList.pipe(skip(1)).pipe(first()).subscribe(() => {
|
|
|
|
|
this.scrollToEnd();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.filterPlanElements();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dropEndHandler(event: CdkDragDrop<WorldArea[]> | CdkDragDrop<PlanElement[]> | null) {
|
|
|
|
|
if (event == null) return;
|
|
|
|
|
|
|
|
|
|
if (isWorldAreaEvent(event) && this.areas) {
|
|
|
|
|
this.planInEditing.plan.splice(this.getEnd(), 0, this.planItemFromArea(event.previousContainer.data[event.previousIndex]));
|
|
|
|
|
this.original.splice(this.getEnd(), 0, this.planItemFromArea(event.previousContainer.data[event.previousIndex]));
|
|
|
|
|
} else {
|
|
|
|
|
moveItemInArray(this.planInEditing.plan, event.previousIndex, this.getEnd());
|
|
|
|
|
moveItemInArray(this.original, event.previousIndex, this.getEnd());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.latestList.pipe(skip(1)).pipe(first()).subscribe(() => {
|
|
|
|
|
this.scrollToEnd();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.filterPlanElements();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getEnd() {
|
|
|
|
@ -146,12 +171,14 @@ export class EditorComponent implements OnInit {
|
|
|
|
|
if (bounds) {
|
|
|
|
|
return bounds[1];
|
|
|
|
|
} else {
|
|
|
|
|
return this.planInEditing.plan.length;
|
|
|
|
|
return this.original.length;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
remove(item: PlanElement) {
|
|
|
|
|
this.planInEditing.plan.splice(this.planIndexOf(item), 1);
|
|
|
|
|
this.original.splice(this.planIndexOf(item), 1);
|
|
|
|
|
|
|
|
|
|
this.filterPlanElements();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
canDrop = () => {
|
|
|
|
@ -181,28 +208,36 @@ export class EditorComponent implements OnInit {
|
|
|
|
|
if (!this.autoScrollToEnd) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.cdr.detectChanges();
|
|
|
|
|
|
|
|
|
|
if (!this.reverseDisplay) {
|
|
|
|
|
this.planListElement.nativeElement.scrollTop = this.planListElement.nativeElement.scrollHeight;
|
|
|
|
|
} else {
|
|
|
|
|
this.planListElement.nativeElement.scrollTop = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
doubleClickArea(item: WorldArea) {
|
|
|
|
|
this.planInEditing.plan.splice(this.planInEditing.plan.length, 0, this.planItemFromArea(item));
|
|
|
|
|
this.original.splice(this.original.length, 0, this.planItemFromArea(item));
|
|
|
|
|
|
|
|
|
|
this.latestList.pipe(skip(1)).pipe(first()).subscribe((_) => {
|
|
|
|
|
this.scrollToEnd();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.filterPlanElements();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
planElemFilterBounds() {
|
|
|
|
|
if (this.planFilterAct.value !== 0) {
|
|
|
|
|
let bounds = this.planInEditing.plan.filter(item => item.anchor_act === this.planFilterAct.value || this.planFilterAct.value + 1 === item.anchor_act).map((value) => this.planIndexOf(value));
|
|
|
|
|
let bounds = this.original.filter(item => item.anchor_act === this.planFilterAct.value || this.planFilterAct.value + 1 === item.anchor_act).map((value) => this.planIndexOf(value));
|
|
|
|
|
if (bounds.length == 2) {
|
|
|
|
|
return bounds;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bounds.length == 1 && this.planFilterAct.value == 10) {
|
|
|
|
|
bounds[1] = this.planInEditing.plan.length;
|
|
|
|
|
bounds[1] = this.original.length;
|
|
|
|
|
return bounds;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -218,7 +253,6 @@ export class EditorComponent implements OnInit {
|
|
|
|
|
this.disabledPlanDD = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this.planSearchString !== "" || this.planFilterAct.value != 0) {
|
|
|
|
|
let bounds = this.planElemFilterBounds();
|
|
|
|
|
|
|
|
|
@ -237,24 +271,22 @@ export class EditorComponent implements OnInit {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
return this.planInEditing.plan;
|
|
|
|
|
return this.original;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.reverseDisplay) {
|
|
|
|
|
return value().slice().reverse();
|
|
|
|
|
} else {
|
|
|
|
|
return value();
|
|
|
|
|
}
|
|
|
|
|
this.latestList.next([... (this.reverseDisplay ? value().slice().reverse() : value())]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
planIndexOf(planElement: PlanElement) {
|
|
|
|
|
const index = this.planInEditing.plan.indexOf(planElement);
|
|
|
|
|
return index;
|
|
|
|
|
return this.original.indexOf(planElement);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clearPlan() {
|
|
|
|
|
this.planInEditing.plan.length = 0;
|
|
|
|
|
while (this.original.length > 0) {
|
|
|
|
|
this.original.pop();
|
|
|
|
|
}
|
|
|
|
|
this.filterPlanElements();
|
|
|
|
|
this.cdr.detectChanges();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -266,7 +298,9 @@ export class EditorComponent implements OnInit {
|
|
|
|
|
}]
|
|
|
|
|
})).subscribe(file => {
|
|
|
|
|
if (file) {
|
|
|
|
|
this.planService.savePlanAtPath(file, this.planInEditing).subscribe();
|
|
|
|
|
const plan = new Plan();
|
|
|
|
|
plan.plan = [...this.original];
|
|
|
|
|
this.planService.savePlanAtPath(file, plan).subscribe();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
@ -284,8 +318,8 @@ export class EditorComponent implements OnInit {
|
|
|
|
|
if (file) {
|
|
|
|
|
// We disallow multiple but interface still says it can be multiple, thus the cast.
|
|
|
|
|
this.planService.loadPlanFromPath(file as string, false).subscribe(plan => {
|
|
|
|
|
this.planInEditing.plan.length = 0;
|
|
|
|
|
plan.plan.forEach(p => this.planInEditing.plan.push(p));
|
|
|
|
|
plan.plan.forEach(item => this.original.push(item));
|
|
|
|
|
this.filterPlanElements();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
@ -293,8 +327,8 @@ export class EditorComponent implements OnInit {
|
|
|
|
|
|
|
|
|
|
loadBasePlan() {
|
|
|
|
|
this.planService.getBasePlan().subscribe(plan => {
|
|
|
|
|
this.planInEditing.plan.length = 0;
|
|
|
|
|
plan.plan.forEach(p => this.planInEditing.plan.push(p));
|
|
|
|
|
plan.plan.forEach(item => this.original.push(item));
|
|
|
|
|
this.filterPlanElements();
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|