Moved loading of subscribers to constructors; improved subscriber destruction pattern; code quality improvements

This commit is contained in:
2025-08-23 14:07:19 -05:00
parent 60289953ec
commit d44e7d4e51
10 changed files with 119 additions and 117 deletions

View File

@@ -1,7 +1,11 @@
import { Component, inject } from "@angular/core";
import {
Component,
DestroyRef,
inject
} from "@angular/core";
import { CommonModule } from "@angular/common";
import { Subject, takeUntil } from 'rxjs';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import * as bootstrap from "bootstrap";
@@ -25,17 +29,18 @@ import 'ace-diff/dist/ace-diff-dark.min.css';
}
})
export class DiffModalComponent {
readonly #destroyRef: DestroyRef = inject(DestroyRef);
diffModal!: bootstrap.Modal;
constructor() {
this.loadSubscribers();
}
private ngAfterViewInit(): void {
this.loadDiffView();
this.loadSubscribers();
}
private loadDiffView() {

View File

@@ -8,7 +8,7 @@ import * as ace from "ace-builds/src-min-noconflict/ace";
providedIn: 'root'
})
export class ColorTokenizerService {
Rules = {
readonly #RULES = {
start: [
{ token: "hex3", regex: "#[A-Fa-f0-9]{3}(?![A-Fa-f0-9])" },
{ token: "hex6", regex: "#[A-Fa-f0-9]{6}(?![A-Fa-f0-9])" },
@@ -28,11 +28,12 @@ export class ColorTokenizerService {
cssLines: {} = {};
public init() {
constructor() {
const Tokenizer = ace.require("ace/tokenizer").Tokenizer;
this.tokenizer = new Tokenizer(this.Rules);
this.tokenizer = new Tokenizer(this.#RULES);
}
public async parse(data: string) {
const lines = data.split("\n");
for (let i = 0; i < lines.length; i++) {

View File

@@ -20,12 +20,7 @@ export class FilesService {
private tabsService: TabsService = inject(TabsService);
files: Map<string, NewtonFile>;
constructor() {
this.files = new Map<string, NewtonFile>();
}
files: Map<string, NewtonFile> = new Map();
public get(path: string): NewtonFile {
@@ -117,7 +112,6 @@ export class FilesService {
joinWorkspaceURI: false
}
file.session["colorTokenizer"] = new ColorTokenizerService();
file.session["colorTokenizer"].init();
file.session["colorTokenizer"].parse(data);
this.files.set(file.path, file);

View File

@@ -1,4 +1,10 @@
import { Directive, ElementRef, Input, ViewChild, inject } from '@angular/core';
import {
Directive,
ElementRef,
Input,
ViewChild,
inject
} from '@angular/core';
import * as uuid from 'uuid';
import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.service';
@@ -50,10 +56,6 @@ export class CodeViewBase {
public showContextMenu: boolean = false;
constructor() {
}
public selectLeftEditor() {
let message = new ServiceMessage();
message.action = "select-left-editor";

View File

@@ -1,5 +1,5 @@
import { Component, inject } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import { Component, DestroyRef, inject } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { EditorsService } from '../common/services/editor/editors.service';
import { TabsService } from '../common/services/editor/tabs/tabs.service';
@@ -29,7 +29,7 @@ import { ServiceMessage } from '../common/types/service-message.type';
}
})
export class EditorsComponent {
private unsubscribe: Subject<void> = new Subject();
readonly #destroyRef: DestroyRef = inject(DestroyRef);
private editorsService: EditorsService = inject(EditorsService);
private tabsService: TabsService = inject(TabsService);
@@ -37,23 +37,14 @@ export class EditorsComponent {
constructor() {
}
private ngAfterViewInit(): void {
this.loadSubscribers();
this.loadMainSubscribers();
}
private ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
private loadSubscribers() {
this.editorsService.getMessage$().pipe(
takeUntil(this.unsubscribe)
takeUntilDestroyed(this.#destroyRef)
).subscribe((message: ServiceMessage) => {
switch ( message.action ) {
case "select-left-editor":

View File

@@ -1,5 +1,5 @@
import { Component, inject } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import { Component, DestroyRef, inject } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.service';
@@ -17,7 +17,7 @@ import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.s
}
})
export class InfoBarComponent {
private unsubscribe: Subject<void> = new Subject();
readonly #destroyRef: DestroyRef = inject(DestroyRef);
private infoBarService: InfoBarService = inject(InfoBarService);
@@ -28,18 +28,14 @@ export class InfoBarComponent {
ftype: string = "";
constructor() {}
private ngAfterViewInit(): void {
constructor() {
this.loadSubscribers();
}
private loadSubscribers() {
this.infoBarService.updateInfoBarFPath$().pipe(
takeUntil(this.unsubscribe)
takeUntilDestroyed(this.#destroyRef)
).subscribe((fpath: string) => {
this.fpath = fpath;
let _path = fpath;
@@ -52,19 +48,19 @@ export class InfoBarComponent {
});
this.infoBarService.updateInfoBarCursorPos$().pipe(
takeUntil(this.unsubscribe)
takeUntilDestroyed(this.#destroyRef)
).subscribe((cursorPos: any) => {
this.cursorPos = `${cursorPos.row + 1}:${cursorPos.column}`;
});
this.infoBarService.updateInfoBarEncodeing$().pipe(
takeUntil(this.unsubscribe)
takeUntilDestroyed(this.#destroyRef)
).subscribe((encodeing: string) => {
this.encodeing = encodeing;
});
this.infoBarService.updateInfoBarFType$().pipe(
takeUntil(this.unsubscribe)
takeUntilDestroyed(this.#destroyRef)
).subscribe((ftype: string) => {
let mode = ftype.split("/");
this.ftype = mode[ mode.length - 1 ];

View File

@@ -1,5 +1,12 @@
import { Component, ChangeDetectorRef, ElementRef, HostBinding, ViewChild, inject } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import {
Component,
ChangeDetectorRef,
DestroyRef,
ElementRef,
HostBinding,
ViewChild,
inject } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { LspManagerService } from '../../common/services/editor/lsp-manager/lsp-manager.service';
@@ -23,8 +30,8 @@ import { ServiceMessage } from '../../common/types/service-message.type';
}
})
export class LspManagerComponent {
private unsubscribe: Subject<void> = new Subject();
private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);
readonly #destroyRef = inject(DestroyRef);
private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);
lspManagerService: LspManagerService = inject(LspManagerService);
@@ -38,17 +45,11 @@ export class LspManagerComponent {
constructor() {
}
private ngAfterViewInit(): void {
this.mapEditorsAndLoadConfig();
this.loadSubscribers();
}
private ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
private ngAfterViewInit(): void {
this.mapEditorsAndLoadConfig();
}
private mapEditorsAndLoadConfig() {
@@ -68,7 +69,7 @@ export class LspManagerComponent {
private loadSubscribers() {
this.lspManagerService.getMessage$().pipe(
takeUntil(this.unsubscribe)
takeUntilDestroyed(this.#destroyRef)
).subscribe((message: ServiceMessage) => {
if (message.action === "toggle-lsp-manager") {
this.toggleLspManager(message);
@@ -141,8 +142,10 @@ export class LspManagerComponent {
}
private editorUpdate(message: ServiceMessage) {
if (!this.editor) return;
if (!message.rawData.activeFile) return;
if (
!this.editor ||
!message.rawData.activeFile
) return;
this.editor.setSession(message.rawData.editor.getSession())
this.activeFile = message.rawData.activeFile;

View File

@@ -1,5 +1,10 @@
import { Component, HostBinding, inject } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import {
Component,
DestroyRef,
HostBinding,
inject
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { MarkdownPreviewService } from '../../common/services/editor/markdown-preview/markdown-preview.service';
@@ -19,7 +24,7 @@ import { ServiceMessage } from '../../common/types/service-message.type';
}
})
export class MarkdownPreviewComponent {
private unsubscribe: Subject<void> = new Subject();
readonly #destroyRef: DestroyRef = inject(DestroyRef);
private markdownPreviewService: MarkdownPreviewService = inject(MarkdownPreviewService);
@@ -32,26 +37,22 @@ export class MarkdownPreviewComponent {
constructor() {
}
private ngAfterViewInit(): void {
this.loadSubscribers();
}
private ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
private loadSubscribers() {
this.markdownPreviewService.getMessage$().pipe(
takeUntil(this.unsubscribe)
takeUntilDestroyed(this.#destroyRef)
).subscribe((message: ServiceMessage) => {
if (message.action === "toggle-markdown-preview") {
this.toggleMarkdownPreview(message);
} else if (message.action === "set-active-editor") {
this.setActiveEditor(message);
switch ( message.action ) {
case "toggle-markdown-preview":
this.toggleMarkdownPreview(message);
break;
case "set-active-editor":
this.setActiveEditor(message);
break;
default:
break;
}
});
}

View File

@@ -1,5 +1,13 @@
import { Component, ElementRef, HostBinding, Input, ViewChild, inject } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import {
Component,
DestroyRef,
ElementRef,
HostBinding,
Input,
ViewChild,
inject
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { SearchReplaceService } from '../../common/services/editor/search-replace/search-replace.service';
@@ -20,7 +28,7 @@ import { ServiceMessage } from '../../common/types/service-message.type';
}
})
export class SearchReplaceComponent {
private unsubscribe: Subject<void> = new Subject();
readonly #destroyRef: DestroyRef = inject(DestroyRef);
private searchReplaceService: SearchReplaceService = inject(SearchReplaceService);
@@ -45,26 +53,22 @@ export class SearchReplaceComponent {
constructor() {
}
private ngAfterViewInit(): void {
this.loadSubscribers();
}
private ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
private loadSubscribers() {
this.searchReplaceService.getMessage$().pipe(
takeUntil(this.unsubscribe)
takeUntilDestroyed(this.#destroyRef)
).subscribe((message: ServiceMessage) => {
if (message.action === "toggle-search-replace") {
this.toggleSearchReplace(message);
} else if (message.action === "set-active-editor") {
this.setActiveEditor(message);
switch ( message.action ) {
case "toggle-search-replace":
this.toggleSearchReplace(message);
break;
case "set-active-editor":
this.setActiveEditor(message);
break;
default:
break;
}
});
}

View File

@@ -1,7 +1,12 @@
import { Component, ChangeDetectorRef, inject } from '@angular/core';
import {
Component,
ChangeDetectorRef,
DestroyRef,
inject
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { CdkDrag, CdkDragDrop, CdkDropList } from '@angular/cdk/drag-drop';
import { Subject, takeUntil } from 'rxjs';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { TabsService } from '../../common/services/editor/tabs/tabs.service';
@@ -24,7 +29,7 @@ import { ServiceMessage } from '../../common/types/service-message.type';
}
})
export class TabsComponent {
private unsubscribe: Subject<void> = new Subject();
readonly #destroyRef = inject(DestroyRef);
private tabsService: TabsService = inject(TabsService);
private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);
@@ -33,36 +38,36 @@ export class TabsComponent {
constructor() {
}
private ngAfterViewInit(): void {
this.loadSubscribers();
}
private ngOnDestroy(): void {
this.unsubscribe.next();
this.unsubscribe.complete();
}
private loadSubscribers() {
this.tabsService.getMessage$().pipe(
takeUntil(this.unsubscribe)
takeUntilDestroyed(this.#destroyRef)
).subscribe((message: ServiceMessage) => {
if (message.action === "create-tab") {
this.createTab(message.fileName, message.fileUUID, message.filePath);
} else if (message.action === "file-changed") {
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1];
elm.classList.add("file-changed");
elm.classList.remove("file-deleted");
} else if (message.action === "file-deleted") {
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1];
elm.classList.add("file-deleted");
elm.classList.remove("file-changed");
} else if (message.action === "file-saved") {
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1];
elm.classList.remove("file-deleted");
elm.classList.remove("file-changed");
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1];
switch ( message.action ) {
case "create-tab":
this.createTab(message.fileName, message.fileUUID, message.filePath);
break;
case "file-changed":
elm.classList.add("file-changed");
elm.classList.remove("file-deleted");
break;
case "file-deleted":
elm.classList.add("file-deleted");
elm.classList.remove("file-changed");
break;
case "file-saved":
elm.classList.remove("file-deleted");
elm.classList.remove("file-changed");
break;
default:
break;
}
});
}