diff --git a/src/app/app.component.html b/src/app/app.component.html index 76660a0..d2f5e49 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,12 +1,14 @@
- Click me for color picker!
-
+
+
+ Click me for color picker! +
diff --git a/src/app/app.component.scss b/src/app/app.component.scss index 6eed0fa..eb2147f 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -4,6 +4,12 @@ plan-display { } :host { - width: 100%; - height: 100%; + display: flex; + max-height: 100vh; + max-width: 100vw; +} + +.editor { + max-height: 100%; + overflow-y: hidden; } \ No newline at end of file diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ec4e1dc..56f7d31 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -10,7 +10,6 @@ import { ConfigService } from "./services/config.service"; import { ColorPickerComponent } from './color-picker/color-picker.component'; import { MatButtonModule } from "@angular/material/button"; import { EditorComponent } from "./editor/editor.component"; -import { initFuzzr } from "./fuzzr/fuzzr"; export function initializeApp(configService: ConfigService) { return (): Promise => { diff --git a/src/app/editor/editor.component.html b/src/app/editor/editor.component.html index f7e32bd..3ae31fe 100644 --- a/src/app/editor/editor.component.html +++ b/src/app/editor/editor.component.html @@ -1,33 +1,39 @@
- -

Campaign zones

- -
-
- Name: {{item.name}}
in act {{item.act}} + + CHOSEN FILTER ACT {{filterAct.name}} + +

Campaign zones

+
+
+
{{item.name}}
+
Act {{item.act}}
-
+
-
- -

Plan

-
-
-
{{areasMap?.get(item.area_key)?.name}}
-
#{{index}}
-
+
+ Auto scroll to end on add to end + Reverse display: + + +

Plan

+
+
+
+
{{areasMap?.get(item.area_key)?.name}}
+
Act {{areasMap?.get(item.area_key)?.act}}
+
+
#{{planIndexOf(item)}}
+
+ Place at end of list +
- \ No newline at end of file +
\ No newline at end of file diff --git a/src/app/editor/editor.component.scss b/src/app/editor/editor.component.scss index 7388d2b..ee2cdc4 100644 --- a/src/app/editor/editor.component.scss +++ b/src/app/editor/editor.component.scss @@ -1,41 +1,54 @@ -:host { - height: 100%; -} +:host {} .container { width: 400px; max-width: 100%; margin: 0 25px 25px 0; - display: inline-block; - vertical-align: top; - flex-grow: 1 1 auto; + display: flex; + flex-direction: column; + max-height: 100%; + overflow: hidden; } .list { - border: solid 1px #ccc; - min-height: 60px; background: white; - border-radius: 4px; + border: solid 1px #ccc; display: block; - padding-bottom: 50px; + border-radius: 4px; + min-height: 60px; + max-height: 100%; + max-width: 100%; overflow: auto; +} + +.innerList { + position: relative; + min-height: 60px; max-height: 100%; + max-width: 100%; + width: 100%; } .box { - padding: 10px 5px; + position: relative; border-bottom: solid 1px #ccc; color: rgba(0, 0, 0, 0.87); display: flex; - flex-direction: row; align-items: center; justify-content: space-between; box-sizing: border-box; cursor: move; - background: white; + background-color: white; font-size: 14px; + padding: 20px 20px 20px 5px; + width: 100%; + + &:hover { + background-color: rgba(0, 0, 0, 0.1); + } } + .cdk-drag-preview { box-sizing: border-box; border-radius: 4px; @@ -60,9 +73,10 @@ transition: transform 125ms cubic-bezier(0, 0, 0.2, 1); } - .editor-container { display: flex; flex-direction: row; + box-sizing: border-box; height: 100%; + overflow: hidden; } \ No newline at end of file diff --git a/src/app/editor/editor.component.ts b/src/app/editor/editor.component.ts index 4bce600..546bbbb 100644 --- a/src/app/editor/editor.component.ts +++ b/src/app/editor/editor.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { CdkDrag, @@ -15,6 +15,11 @@ import { WorldAreaService } from '../services/world-area.service'; import { FormsModule } from '@angular/forms'; import { Fuzzr } from '../fuzzr/fuzzr'; +interface Act { + value: number; + name: string; +} + @Component({ selector: 'plan-editor', templateUrl: './editor.component.html', @@ -36,13 +41,22 @@ export class EditorComponent implements OnInit { areaSearchString: string = ""; planSearchString: string = ""; planFuzzer: Fuzzr; + filterAct: Act; + planFilterAct: Act; + acts: Act[]; + @ViewChild('planList') planListElement!: ElementRef; + autoScrollToEnd: boolean; + reverseDisplay: boolean; - constructor(public worldAreaService: WorldAreaService) { + + constructor(public worldAreaService: WorldAreaService, private cdr: ChangeDetectorRef) { this.plan = { plan: [], current: 0, } + this.autoScrollToEnd = false; + this.planFuzzer = new Fuzzr(this.plan.plan, { toString: (e: PlanElement) => { return this.areasMap?.get(e.area_key)?.name; @@ -50,6 +64,20 @@ export class EditorComponent implements OnInit { }); this.planAreas = []; + + this.reverseDisplay = false; + + this.acts = []; + for (let i = 0; i <= 10; i++) { + if (i == 0) { + this.acts.push({ value: i, name: "All" }); + } else { + this.acts.push({ value: i, name: "Act " + i.toString() }); + } + } + + this.filterAct = this.acts[0]; + this.planFilterAct = this.acts[0]; } ngOnInit(): void { @@ -60,14 +88,26 @@ export class EditorComponent implements OnInit { } dropHandler(event: CdkDragDrop | CdkDragDrop) { - if (event.previousContainer === event.container) { - moveItemInArray(this.plan.plan, event.previousIndex, event.currentIndex); + if (event.previousContainer === event.container && !isWorldAreaEvent(event)) { + const realCurrent = this.plan.plan.indexOf(event.previousContainer.data[event.currentIndex]); + const realPrev = this.plan.plan.indexOf(event.previousContainer.data[event.previousIndex]); + moveItemInArray(this.plan.plan, realPrev, realCurrent); } else - if (this.plan && this.areas) { - this.plan.plan.splice(event.currentIndex, 0, this.planItemFromArea(this.areas[event.previousIndex])); + if (this.plan && this.areas && isWorldAreaEvent(event)) { + this.plan.plan.splice(event.currentIndex, 0, this.planItemFromArea(event.previousContainer.data[event.previousIndex])); } } + dropEndHandler(event: CdkDragDrop | CdkDragDrop) { + if (isWorldAreaEvent(event) && this.areas) { + this.plan.plan.splice(this.plan.plan.length, 0, this.planItemFromArea(event.previousContainer.data[event.previousIndex])); + this.scrollToEnd(); + } else { + moveItemInArray(this.plan.plan, event.previousIndex, this.plan.plan.length); + this.scrollToEnd(); + } + } + planItemFromArea(area: WorldArea): PlanElement { return { area_key: area.named_id, @@ -75,22 +115,59 @@ export class EditorComponent implements OnInit { }; } - filterAreas(searchString: string) { - if (searchString !== "") { - - return this.worldAreaService.matcher?.search(searchString).map(({ item }) => { + filterAreas() { + if (this.areaSearchString !== "" || this.filterAct.value != 0) { + return this.worldAreaService.matcher!.search(this.areaSearchString).map(({ item }) => { return item[1]; - }); + }).filter(item => item.act == this.filterAct.value || this.filterAct.value == 0); } else { - return this.areas; + return this.areas!; } } - filterPlanElements(searchString: string) { - if (searchString !== "") { - return this.planFuzzer.search(searchString).map(({item}) => item); + scrollToEnd() { + 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.plan.plan.splice(this.plan.plan.length, 0, this.planItemFromArea(item)); + this.scrollToEnd(); + } + + filterPlanElements() { + const value = (): any[] => { + if (this.planSearchString !== "" || this.planFilterAct.value != 0) { + return this.planFuzzer.search(this.planSearchString).map(({ item }) => item).filter(item => { + return this.areasMap?.get(item.area_key)?.act == this.planFilterAct.value || this.planFilterAct.value == 0; + }); + } else { + return this.plan.plan; + } + } + + if (this.reverseDisplay) { + return value().slice().reverse(); } else { - return this.plan.plan; + return value(); } } + + planIndexOf(planElement: PlanElement) { + const index = this.plan.plan.indexOf(planElement); + console.log("plan element", planElement, "index", index); + return index; + } } + + +function isWorldAreaEvent(event: any): event is CdkDragDrop { + return (event.previousContainer.data.length > 0 && 'connections_world_areas_keys' in event.previousContainer.data[0]); +} \ No newline at end of file diff --git a/src/app/models/plan.ts b/src/app/models/plan.ts index 4775501..78f7373 100644 --- a/src/app/models/plan.ts +++ b/src/app/models/plan.ts @@ -8,5 +8,4 @@ export interface Plan { export interface PlanElement { area_key: string; notes?: string; - index?: number; } \ No newline at end of file diff --git a/src/app/services/world-area.service.ts b/src/app/services/world-area.service.ts index 070de32..2cb9328 100644 --- a/src/app/services/world-area.service.ts +++ b/src/app/services/world-area.service.ts @@ -16,7 +16,7 @@ export class WorldAreaService { constructor(private zone: NgZone) { from(invoke>('load_world_areas')).subscribe((data) => { - const entries = Object.entries(data).sort((a, b) => naturalCompare(a[1].named_id, b[1].named_id)); + const entries = Object.entries(data).sort((a, b) => a[1].key_id - b[1].key_id); this.worldAreas = new Map(entries); this.zone.run(() => this.worldAreasSubject.next(this.worldAreas!)); this.matcher = new Fuzzr(this.worldAreas, { diff --git a/src/styles.scss b/src/styles.scss index 7c68bdb..528df57 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -28,9 +28,10 @@ $my-theme: mat.define-dark-theme(( html, body { height: 100vh; -} - -body { + width: 100vw; + background-color: rgba(#ff00ff, 0.05); + margin: 0; + padding: 0; overflow: hidden; }