Skip to content

Commit

Permalink
drag and drop re-ordering for parsers
Browse files Browse the repository at this point in the history
  • Loading branch information
cbartondock committed Oct 25, 2024
1 parent 8fb0c81 commit fdb791c
Show file tree
Hide file tree
Showing 12 changed files with 267 additions and 202 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

All notable changes to this project will be documented in this file.

## 2.5.28

### Added

- Ability to drag/drop to re-arrange parsers in Classic and Deck themes.

### Fixed

- Executables on Mac OS should be allowed to be directories (.app folders).

## 2.5.27

### Added
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"@electron/remote": "^2.1.2",
"@node-steam/vdf": "^2.2.0",
"ajv": "^8.17.1",
"angular-draggable-droppable": "^8.0.0",
"async": "^3.2.6",
"bcp-47": "^2.1.0",
"better-sqlite3": "^11.3.0",
Expand Down
4 changes: 2 additions & 2 deletions src/lang/en-US/langStrings.json
Original file line number Diff line number Diff line change
Expand Up @@ -448,8 +448,8 @@
"component": {
"buttons": {
"save": "Save",
"copy": "Copy",
"testParser": "Test parser",
"copy": "Clone",
"testParser": "Test",
"delete": "Delete",
"moveUp": "Move up",
"moveDown": "Move down",
Expand Down
2 changes: 2 additions & 0 deletions src/renderer/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import * as Directives from "./directives";
import * as Pipes from "./pipes";
import * as Guards from "./guards";
import { AppRoutes } from "./app.routing";
import { DragAndDropModule } from "angular-draggable-droppable";

// Unfortunately not usable for declarations right now, as the strictly typed compiler can't evaluate statically
// Ideally one would have declarations: [...ngObjectsToArray<Components(Components), etc]
Expand All @@ -34,6 +35,7 @@ function ngObjectsToArray<T>(importObject: T) {
FormsModule,
ReactiveFormsModule,
ColorPickerModule,
DragAndDropModule
],
declarations: [
Components.AboutComponent,
Expand Down
131 changes: 73 additions & 58 deletions src/renderer/components/nav-parsers.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { UserConfiguration, AppSettings } from "../../models";
import { Subscription } from "rxjs";
import { APP } from "../../variables";
import { Router } from "@angular/router";

@Component({
selector: "nav-parsers",
Expand All @@ -30,12 +31,15 @@ export class NavParsersComponent implements OnDestroy {
navForm: FormGroup;
imageMap: { [k: string]: any } = {};
private subscriptions: Subscription = new Subscription();
private appSettings: AppSettings;
appSettings: AppSettings;
dragStartIndex: number = -1;
currentId: string = "";

constructor(
private parsersService: ParsersService,
private languageService: LanguageService,
private exceptionsService: UserExceptionsService,
private router: Router,
private settingsService: SettingsService,
private changeRef: ChangeDetectorRef,
private formBuilder: FormBuilder,
Expand All @@ -50,35 +54,8 @@ export class NavParsersComponent implements OnDestroy {
this.parsersService
.getUserConfigurations()
.subscribe((userConfigurations) => {
for (let userConfiguration of userConfigurations) {
let separatedValues: string[] =
userConfiguration.saved.configTitle.split(" - ");
let separatedValuesImg = separatedValues.length
? separatedValues[0].replaceAll(/[\/\-\(\)\.\s]/g, "")
: "";
separatedValuesImg = separatedValuesImg
.replaceAll("3do", "p3do")
.toLowerCase();
let imgValue = "";
let alternativeValue = false;
let detailsValue = "";
try {
imgValue = require(
`../../assets/systems/${separatedValuesImg}.svg`,
);
detailsValue = userConfiguration.saved.configTitle
.split(" - ")
.slice(1)
.join(" - ");
} catch (e) {
alternativeValue = true;
detailsValue = userConfiguration.saved.configTitle;
}
this.imageMap[userConfiguration.saved.parserId] = {
alternative: alternativeValue,
details: detailsValue,
img: imgValue,
};
if(this.appSettings.theme == "EmuDeck") {
this.initializeImageMap(userConfigurations)
}
this.userConfigurations = userConfigurations;

Expand All @@ -89,20 +66,12 @@ export class NavParsersComponent implements OnDestroy {
: false;
this.navForm = this.formBuilder.group({
selectAll: someOn,
parserStatuses: this.formBuilder.array(
this.userConfigurations.map(
(config: {
saved: UserConfiguration;
current: UserConfiguration;
}) => {
let singleton: { [k: string]: boolean } = {};
singleton[config.saved.parserId] = !config.saved.disabled;
return this.formBuilder.group(singleton);
},
),
),
parserStatuses: this.formBuilder.group(
Object.fromEntries(this.userConfigurations.map((config: {saved: UserConfiguration, current: UserConfiguration}) => {
return [config.saved.parserId, !config.saved.disabled]
}))
)
});

this.navForm
.get("selectAll")
.valueChanges.subscribe((val: boolean) => {
Expand All @@ -115,17 +84,13 @@ export class NavParsersComponent implements OnDestroy {
this.parsersService.changeEnabledStatusAll(val);
}
});

this.getParserControls().forEach((control: FormGroup) => {
control.valueChanges.subscribe(
(val: { [parserId: string]: boolean }) => {
this.parsersService.changeEnabledStatus(
Object.keys(val)[0],
Object.values(val)[0],
);
},
);
});
const parserControls = this.getParserControls();
for(let userConfiguration of this.userConfigurations) {
let parserId = userConfiguration.saved.parserId;
parserControls[parserId].valueChanges.subscribe((val: boolean)=>{
this.parsersService.changeEnabledStatus(parserId, val);
})
}

this.changeRef.detectChanges();
}),
Expand All @@ -150,16 +115,66 @@ export class NavParsersComponent implements OnDestroy {
}

getParserControls() {
return (this.navForm.get("parserStatuses") as FormArray)
.controls as FormGroup[];
return (this.navForm.get("parserStatuses") as FormGroup).controls;
}

emuClick(control: FormControl) {
if (this.appSettings.theme == "EmuDeck") {
control.setValue(!control.value);
control.setValue(!control.value);
}

onClick(index: number, parserId: string) {
this.router.navigate(["/parsers", index]);
this.currentId = parserId;
}

dragStart(event: Event) {
this.dragStartIndex = parseInt(this.router.url.split("/")[2]);
}

handleDrop(fromIndex: number, toIndex:number) {
this.parsersService.injectIndex(fromIndex, toIndex);
if(fromIndex < this.dragStartIndex && this.dragStartIndex <= toIndex) {
this.router.navigate(["/parsers", this.dragStartIndex - 1])
} else if(toIndex <= this.dragStartIndex && this.dragStartIndex < fromIndex) {
this.router.navigate(["/parsers", this.dragStartIndex + 1])
} else if(this.dragStartIndex==fromIndex) {
this.router.navigate(["/parsers", toIndex])
}
}

initializeImageMap(userConfigurations: {current: UserConfiguration, saved: UserConfiguration}[]) {
for (let userConfiguration of userConfigurations) {
let separatedValues: string[] =
userConfiguration.saved.configTitle.split(" - ");
let separatedValuesImg = separatedValues.length
? separatedValues[0].replaceAll(/[\/\-\(\)\.\s]/g, "")
: "";
separatedValuesImg = separatedValuesImg
.replaceAll("3do", "p3do")
.toLowerCase();
let imgValue = "";
let alternativeValue = false;
let detailsValue = "";
try {
imgValue = require(
`../../assets/systems/${separatedValuesImg}.svg`,
);
detailsValue = userConfiguration.saved.configTitle
.split(" - ")
.slice(1)
.join(" - ");
} catch (e) {
alternativeValue = true;
detailsValue = userConfiguration.saved.configTitle;
}
this.imageMap[userConfiguration.saved.parserId] = {
alternative: alternativeValue,
details: detailsValue,
img: imgValue,
};
}
}

ngOnDestroy() {
this.subscriptions.unsubscribe();
}
Expand Down
29 changes: 23 additions & 6 deletions src/renderer/services/parsers.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,31 @@ export class ParsersService {
this.saveUserConfigurations();
}

swapIndex(currentIndex: number, newIndex: number) {
let userConfigurations = this.userConfigurations.getValue();
swapIndex(fromIndex: number, toIndex: number) {
if(fromIndex == toIndex){return;}
const configs = this.userConfigurations.getValue();
if (fromIndex >= configs.length || toIndex >= configs.length) {
throw 'Index out of bounds';
}
const from = configs[fromIndex];
configs[fromIndex] = configs[toIndex];
configs[toIndex] = from;
this.userConfigurations.next(configs);
this.saveUserConfigurations();
}

let temp = userConfigurations[currentIndex];
userConfigurations[currentIndex] = userConfigurations[newIndex];
userConfigurations[newIndex] = temp;
this.userConfigurations.next(userConfigurations);
injectIndex(fromIndex: number, toIndex: number) {
if (fromIndex == toIndex) {return;}
const configs = this.userConfigurations.getValue();
if (fromIndex >= configs.length || toIndex >= configs.length) {
throw 'Index out of bounds';
}
const from = configs[fromIndex];
const withoutFrom = configs.filter((_,i) => i!==fromIndex);
const newConfigs = withoutFrom.slice(0,toIndex).concat(from).concat(withoutFrom.slice(toIndex))
this.userConfigurations.next(newConfigs);
this.saveUserConfigurations();

}

changeEnabledStatus(parserId: string, enabled: boolean): Promise<void> {
Expand Down
Loading

0 comments on commit fdb791c

Please sign in to comment.