2025-06-21 04:52:22 +00:00
|
|
|
import { Component, ViewChild, ViewContainerRef, inject } from '@angular/core';
|
2025-05-28 02:10:45 +00:00
|
|
|
import { Subject, takeUntil } from 'rxjs';
|
|
|
|
|
2025-06-13 01:31:08 +00:00
|
|
|
import { NewtonEditorComponent } from "./newton-editor/newton-editor.component";
|
2025-06-15 05:43:33 +00:00
|
|
|
import { FilesModalComponent } from "./modals/files-modal.component";
|
2025-05-28 02:10:45 +00:00
|
|
|
import { EditorsService } from '../common/services/editor/editors.service';
|
2025-06-20 05:50:43 +00:00
|
|
|
import { TabsService } from '../common/services/editor/tabs/tabs.service';
|
2025-06-14 18:03:00 +00:00
|
|
|
import { FilesService } from '../common/services/editor/files.service';
|
2025-05-28 02:10:45 +00:00
|
|
|
|
|
|
|
import { DndDirective } from '../common/directives/dnd.directive';
|
|
|
|
import { NewtonFile } from '../common/types/file.type';
|
|
|
|
import { ServiceMessage } from '../common/types/service-message.type';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'editors',
|
|
|
|
standalone: true,
|
|
|
|
imports: [
|
2025-06-15 05:43:33 +00:00
|
|
|
DndDirective,
|
|
|
|
FilesModalComponent
|
2025-05-28 02:10:45 +00:00
|
|
|
],
|
|
|
|
templateUrl: './editors.component.html',
|
|
|
|
styleUrl: './editors.component.css',
|
|
|
|
host: {
|
|
|
|
'class': 'row'
|
|
|
|
}
|
|
|
|
})
|
|
|
|
export class EditorsComponent {
|
2025-06-21 04:52:22 +00:00
|
|
|
private unsubscribe: Subject<void> = new Subject();
|
|
|
|
|
|
|
|
private editorsService: EditorsService = inject(EditorsService);
|
|
|
|
private tabsService: TabsService = inject(TabsService);
|
|
|
|
private filesService: FilesService = inject(FilesService);
|
2025-05-28 02:10:45 +00:00
|
|
|
|
|
|
|
@ViewChild('containerRef', {read: ViewContainerRef}) containerRef!: ViewContainerRef;
|
|
|
|
activeEditor!: string;
|
|
|
|
|
|
|
|
|
2025-06-21 04:52:22 +00:00
|
|
|
constructor() {
|
2025-05-28 02:10:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ngAfterViewInit(): void {
|
2025-05-30 05:30:54 +00:00
|
|
|
this.loadSubscribers();
|
2025-06-01 05:49:30 +00:00
|
|
|
this.loadMainSubscribers();
|
2025-05-30 05:30:54 +00:00
|
|
|
|
2025-06-14 03:36:01 +00:00
|
|
|
let leftEditor = this.createEditor();
|
|
|
|
let rightEditor = this.createEditor();
|
2025-06-12 04:02:45 +00:00
|
|
|
|
2025-06-14 03:36:01 +00:00
|
|
|
this.activeEditor = leftEditor.instance.uuid;
|
|
|
|
leftEditor.instance.isDefault = true;
|
|
|
|
leftEditor.instance.rightSiblingUUID = rightEditor.instance.uuid;
|
|
|
|
rightEditor.instance.leftSiblingUUID = leftEditor.instance.uuid;
|
2025-05-30 05:30:54 +00:00
|
|
|
}
|
|
|
|
|
2025-06-21 00:51:03 +00:00
|
|
|
ngOnDestroy() {
|
|
|
|
this.unsubscribe.next();
|
|
|
|
this.unsubscribe.complete();
|
|
|
|
}
|
|
|
|
|
2025-05-30 05:30:54 +00:00
|
|
|
loadSubscribers() {
|
2025-06-14 03:36:01 +00:00
|
|
|
|
2025-06-19 03:35:28 +00:00
|
|
|
this.editorsService.getMessage$().pipe(
|
2025-06-14 03:36:01 +00:00
|
|
|
takeUntil(this.unsubscribe)
|
2025-06-19 03:35:28 +00:00
|
|
|
).subscribe((message: ServiceMessage) => {
|
2025-06-20 05:50:43 +00:00
|
|
|
if (message.action === "select-left-editor") {
|
2025-06-19 03:35:28 +00:00
|
|
|
let editorComponent = this.editorsService.get(message.editorUUID);
|
|
|
|
if (!editorComponent.leftSiblingUUID) return;
|
|
|
|
let siblingComponent = this.editorsService.get(editorComponent.leftSiblingUUID);
|
|
|
|
siblingComponent.editor.focus()
|
2025-06-20 05:50:43 +00:00
|
|
|
} else if (message.action === "select-right-editor") {
|
2025-06-19 03:35:28 +00:00
|
|
|
let editorComponent = this.editorsService.get(message.editorUUID);
|
|
|
|
if (!editorComponent.rightSiblingUUID) return;
|
|
|
|
let siblingComponent = this.editorsService.get(editorComponent.rightSiblingUUID);
|
|
|
|
siblingComponent.editor.focus()
|
2025-06-20 05:50:43 +00:00
|
|
|
} else if (message.action === "move-session-left") {
|
2025-06-19 03:35:28 +00:00
|
|
|
let editorComponent = this.editorsService.get(message.editorUUID);
|
|
|
|
if (!editorComponent.leftSiblingUUID) return;
|
2025-06-21 00:51:03 +00:00
|
|
|
|
2025-06-19 03:35:28 +00:00
|
|
|
let siblingComponent = this.editorsService.get(editorComponent.leftSiblingUUID);
|
|
|
|
let session = editorComponent.editor.getSession();
|
|
|
|
let siblingSession = siblingComponent.editor.getSession();
|
|
|
|
|
|
|
|
if (session == siblingSession) return;
|
2025-06-21 00:51:03 +00:00
|
|
|
|
2025-06-19 03:35:28 +00:00
|
|
|
siblingComponent.editor.setSession(session);
|
2025-06-21 00:51:03 +00:00
|
|
|
siblingComponent.activeFile = editorComponent.activeFile;
|
|
|
|
|
2025-06-21 21:28:41 +00:00
|
|
|
editorComponent.newSession();
|
2025-06-19 03:35:28 +00:00
|
|
|
siblingComponent.editor.focus()
|
2025-06-20 05:50:43 +00:00
|
|
|
} else if (message.action === "move-session-right") {
|
2025-06-19 03:35:28 +00:00
|
|
|
let editorComponent = this.editorsService.get(message.editorUUID);
|
|
|
|
if (!editorComponent.rightSiblingUUID) return;
|
2025-06-21 00:51:03 +00:00
|
|
|
|
2025-06-19 03:35:28 +00:00
|
|
|
let siblingComponent = this.editorsService.get(editorComponent.rightSiblingUUID);
|
|
|
|
let session = editorComponent.editor.getSession();
|
|
|
|
let siblingSession = siblingComponent.editor.getSession();
|
|
|
|
|
|
|
|
if (session == siblingSession) return;
|
2025-06-21 00:51:03 +00:00
|
|
|
|
2025-06-19 03:35:28 +00:00
|
|
|
siblingComponent.editor.setSession(session);
|
2025-06-21 00:51:03 +00:00
|
|
|
siblingComponent.activeFile = editorComponent.activeFile;
|
|
|
|
|
2025-06-21 21:28:41 +00:00
|
|
|
editorComponent.newSession();
|
2025-06-19 03:35:28 +00:00
|
|
|
siblingComponent.editor.focus()
|
2025-06-20 05:50:43 +00:00
|
|
|
} else if (message.action === "set-active-editor") {
|
2025-06-19 03:35:28 +00:00
|
|
|
this.editorsService.get(this.activeEditor).removeActiveStyling();
|
|
|
|
this.activeEditor = message.editorUUID;
|
|
|
|
this.editorsService.get(this.activeEditor).addActiveStyling();
|
2025-06-20 05:50:43 +00:00
|
|
|
} else if (message.action === "set-tab-to-editor") {
|
2025-06-19 03:35:28 +00:00
|
|
|
let file = this.filesService.get(message.filePath);
|
|
|
|
let editorComponent = this.getActiveEditorComponent();
|
|
|
|
let editor = editorComponent.editor;
|
|
|
|
|
|
|
|
editorComponent.activeFile = file;
|
|
|
|
editor.setSession(file.session);
|
2025-06-20 05:50:43 +00:00
|
|
|
} else if (message.action === "close-tab") {
|
2025-06-19 03:35:28 +00:00
|
|
|
let file = this.filesService.get(message.filePath);
|
|
|
|
let editors = this.editorsService.getEditorsAsArray();
|
|
|
|
|
|
|
|
for (let i = 0; i < editors.length; i++) {
|
|
|
|
let editorComponent = editors[i].instance;
|
|
|
|
if (editorComponent.editor.session == file.session) {
|
2025-06-21 21:28:41 +00:00
|
|
|
editorComponent.newSession();
|
2025-06-19 03:35:28 +00:00
|
|
|
}
|
2025-06-02 05:10:56 +00:00
|
|
|
}
|
2025-06-19 03:35:28 +00:00
|
|
|
|
|
|
|
this.filesService.delete(file);
|
2025-06-02 05:10:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
});
|
2025-06-14 03:36:01 +00:00
|
|
|
|
2025-05-28 02:10:45 +00:00
|
|
|
}
|
|
|
|
|
2025-06-01 05:49:30 +00:00
|
|
|
loadMainSubscribers() {
|
|
|
|
window.fs.onLoadFiles(async (paths: []) => {
|
|
|
|
for (let i = 0; i < paths.length; i++) {
|
|
|
|
let file = new File([], "") as NewtonFile;
|
|
|
|
|
2025-06-15 23:15:39 +00:00
|
|
|
if ( this.filesService.get(paths[i]) ) continue;
|
|
|
|
|
2025-06-14 18:03:00 +00:00
|
|
|
await this.filesService.addFile(paths[i], file);
|
|
|
|
this.filesService.addTab(file);
|
2025-06-01 05:49:30 +00:00
|
|
|
}
|
|
|
|
|
2025-06-14 18:03:00 +00:00
|
|
|
let path = paths[ paths.length - 1 ];
|
|
|
|
let file = this.filesService.get(path);
|
2025-06-01 18:49:18 +00:00
|
|
|
this.setSession(file);
|
2025-06-01 05:49:30 +00:00
|
|
|
});
|
|
|
|
|
2025-06-20 01:03:02 +00:00
|
|
|
window.fs.onChangedFile(async (path: string) => {
|
2025-06-20 05:50:43 +00:00
|
|
|
let message = new ServiceMessage();
|
|
|
|
message.action = "file-changed";
|
|
|
|
message.filePath = path;
|
|
|
|
this.tabsService.sendMessage(message);
|
2025-06-20 01:03:02 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
window.fs.onDeletedFile(async (path: string) => {
|
2025-06-20 05:50:43 +00:00
|
|
|
let message = new ServiceMessage();
|
|
|
|
message.action = "file-deleted";
|
|
|
|
message.filePath = path;
|
|
|
|
|
|
|
|
this.tabsService.sendMessage(message);
|
|
|
|
this.filesService.sendMessage(message);
|
|
|
|
});
|
|
|
|
|
|
|
|
window.fs.onSavedFile(async (path: string) => {
|
|
|
|
let message = new ServiceMessage();
|
|
|
|
message.action = "file-saved";
|
|
|
|
message.filePath = path;
|
|
|
|
|
|
|
|
this.tabsService.sendMessage(message);
|
|
|
|
});
|
|
|
|
|
|
|
|
window.fs.onUpdateFilePath(async (path: string) => {
|
2025-06-20 01:03:02 +00:00
|
|
|
console.log(path);
|
2025-06-20 05:50:43 +00:00
|
|
|
// this.tabsService.sendMessage(message);
|
|
|
|
// this.filesService.sendMessage(message);
|
2025-06-20 01:03:02 +00:00
|
|
|
});
|
|
|
|
|
2025-06-01 05:49:30 +00:00
|
|
|
window.main.onMenuActions(async (action: string) => {
|
|
|
|
let editorComponent = this.getActiveEditorComponent();
|
|
|
|
let editor = editorComponent.editor;
|
|
|
|
|
|
|
|
switch ( action ) {
|
|
|
|
case "new-file":
|
|
|
|
break;
|
2025-06-01 18:49:18 +00:00
|
|
|
case "open-files":
|
|
|
|
editorComponent.openFiles();
|
|
|
|
break;
|
2025-06-01 05:49:30 +00:00
|
|
|
case "save-file":
|
|
|
|
editorComponent.saveFile();
|
|
|
|
break;
|
|
|
|
case "save-file-as":
|
|
|
|
editorComponent.saveFileAs();
|
|
|
|
break;
|
|
|
|
case "cut":
|
|
|
|
editorComponent.cutText();
|
|
|
|
break;
|
|
|
|
case "copy":
|
|
|
|
editorComponent.copyText();
|
|
|
|
break;
|
|
|
|
case "paste":
|
|
|
|
editorComponent.pasteText();
|
|
|
|
break;
|
|
|
|
case "zoom-in":
|
|
|
|
editorComponent.zoomIn()
|
|
|
|
break;
|
|
|
|
case "zoom-out":
|
|
|
|
editorComponent.zoomOut()
|
|
|
|
break;
|
2025-06-13 01:31:08 +00:00
|
|
|
case "open-settings":
|
|
|
|
editor.showSettingsMenu();
|
2025-06-01 05:49:30 +00:00
|
|
|
case "show-about":
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
editor.execCommand(action);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2025-06-14 21:50:46 +00:00
|
|
|
// Note: Only really works with 2 editors and very brittle logic.
|
|
|
|
protected setEditorSize(event: any) {
|
|
|
|
let lEditorComponent = null;
|
|
|
|
let rEditorComponent = null;
|
|
|
|
let lSize = 6;
|
|
|
|
let rSize = 6;
|
|
|
|
|
|
|
|
if (
|
|
|
|
event.target.parentElement.classList.contains("editor-left-size")
|
|
|
|
) {
|
|
|
|
lSize = parseInt(
|
|
|
|
event.target.classList[1].split("-")[1]
|
|
|
|
);
|
|
|
|
rSize = 12 - lSize;
|
|
|
|
|
|
|
|
lEditorComponent = this.editorsService.get(this.activeEditor);
|
|
|
|
if (lEditorComponent.leftSiblingUUID) {
|
|
|
|
rEditorComponent = lEditorComponent;
|
|
|
|
lEditorComponent = this.editorsService.get(lEditorComponent.leftSiblingUUID);
|
|
|
|
} else {
|
|
|
|
rEditorComponent = this.editorsService.get(lEditorComponent.rightSiblingUUID);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
rSize = parseInt(
|
|
|
|
event.target.classList[1].split("-")[1]
|
|
|
|
);
|
|
|
|
lSize = 12 - rSize;
|
|
|
|
rEditorComponent = this.editorsService.get(this.activeEditor);
|
|
|
|
if (rEditorComponent.rightSiblingUUID) {
|
|
|
|
lEditorComponent = rEditorComponent;
|
|
|
|
rEditorComponent = this.editorsService.get(rEditorComponent.rightSiblingUUID);
|
|
|
|
} else {
|
|
|
|
lEditorComponent = this.editorsService.get(rEditorComponent.leftSiblingUUID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-06-21 00:51:03 +00:00
|
|
|
this.resizeAndFocus(lEditorComponent, lSize, rEditorComponent, rSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
private resizeAndFocus(lEditorComponent: any, lSize: number, rEditorComponent: any, rSize: number) {
|
2025-06-14 21:50:46 +00:00
|
|
|
let lElm = lEditorComponent.editorElm.nativeElement.parentElement;
|
|
|
|
let rElm = rEditorComponent.editorElm.nativeElement.parentElement;
|
|
|
|
|
|
|
|
lElm.setAttribute(
|
|
|
|
'class',
|
|
|
|
(lSize == 0) ? "hidden" : `col col-${lSize}`
|
|
|
|
);
|
|
|
|
|
|
|
|
rElm.setAttribute(
|
|
|
|
'class',
|
|
|
|
(rSize == 0) ? "hidden" : `col col-${rSize}`
|
|
|
|
);
|
|
|
|
|
|
|
|
if (lSize == 0) rEditorComponent.editor.focus();
|
|
|
|
if (rSize == 0) lEditorComponent.editor.focus();
|
|
|
|
}
|
|
|
|
|
2025-05-28 02:10:45 +00:00
|
|
|
private createEditor() {
|
2025-06-13 01:31:08 +00:00
|
|
|
const component = this.containerRef.createComponent(NewtonEditorComponent);
|
2025-06-14 18:32:07 +00:00
|
|
|
component.instance.editorSettings = this.editorsService.editorSettings;
|
|
|
|
this.editorsService.set(component.instance.uuid, component)
|
2025-05-28 02:10:45 +00:00
|
|
|
|
|
|
|
return component;
|
|
|
|
}
|
|
|
|
|
2025-06-01 05:49:30 +00:00
|
|
|
protected onFileDropped(files: any) {
|
2025-06-14 18:03:00 +00:00
|
|
|
this.filesService.loadFilesList(files).then((file: NewtonFile | undefined | null) => {
|
2025-06-01 18:49:18 +00:00
|
|
|
this.setSession(file);
|
2025-05-28 02:10:45 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2025-06-01 18:49:18 +00:00
|
|
|
private async setSession(file: NewtonFile | undefined | null) {
|
|
|
|
if ( !file ) return;
|
|
|
|
let editorComponent = this.getActiveEditorComponent();
|
|
|
|
let editor = editorComponent.editor;
|
2025-06-01 05:49:30 +00:00
|
|
|
|
2025-06-01 18:49:18 +00:00
|
|
|
editorComponent.activeFile = file;
|
|
|
|
editor.setSession(file.session);
|
2025-06-01 05:49:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private getSession() {
|
2025-06-14 18:32:07 +00:00
|
|
|
let editorComponent = this.editorsService.get(this.activeEditor);
|
2025-06-01 05:49:30 +00:00
|
|
|
let editor = editorComponent.editor;
|
|
|
|
|
2025-06-01 18:49:18 +00:00
|
|
|
return editor.getSession();
|
2025-06-01 05:49:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private getActiveEditorComponent(): any {
|
2025-06-14 18:32:07 +00:00
|
|
|
return this.editorsService.get(this.activeEditor);
|
2025-06-01 05:49:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private getActiveEditor(): any {
|
2025-06-14 18:32:07 +00:00
|
|
|
let editorComponent = this.editorsService.get(this.activeEditor);
|
2025-06-01 05:49:30 +00:00
|
|
|
let editor = editorComponent.editor;
|
|
|
|
return editor;
|
|
|
|
}
|
|
|
|
|
2025-05-28 02:10:45 +00:00
|
|
|
}
|