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

View File

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

View File

@@ -20,12 +20,7 @@ export class FilesService {
private tabsService: TabsService = inject(TabsService); private tabsService: TabsService = inject(TabsService);
files: Map<string, NewtonFile>; files: Map<string, NewtonFile> = new Map();
constructor() {
this.files = new Map<string, NewtonFile>();
}
public get(path: string): NewtonFile { public get(path: string): NewtonFile {
@@ -117,7 +112,6 @@ export class FilesService {
joinWorkspaceURI: false joinWorkspaceURI: false
} }
file.session["colorTokenizer"] = new ColorTokenizerService(); file.session["colorTokenizer"] = new ColorTokenizerService();
file.session["colorTokenizer"].init();
file.session["colorTokenizer"].parse(data); file.session["colorTokenizer"].parse(data);
this.files.set(file.path, file); 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 * as uuid from 'uuid';
import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.service'; import { InfoBarService } from '../../common/services/editor/info-bar/info-bar.service';
@@ -50,10 +56,6 @@ export class CodeViewBase {
public showContextMenu: boolean = false; public showContextMenu: boolean = false;
constructor() {
}
public selectLeftEditor() { public selectLeftEditor() {
let message = new ServiceMessage(); let message = new ServiceMessage();
message.action = "select-left-editor"; message.action = "select-left-editor";

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,10 @@
import { Component, HostBinding, inject } from '@angular/core'; import {
import { Subject, takeUntil } from 'rxjs'; 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'; 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 { export class MarkdownPreviewComponent {
private unsubscribe: Subject<void> = new Subject(); readonly #destroyRef: DestroyRef = inject(DestroyRef);
private markdownPreviewService: MarkdownPreviewService = inject(MarkdownPreviewService); private markdownPreviewService: MarkdownPreviewService = inject(MarkdownPreviewService);
@@ -32,26 +37,22 @@ export class MarkdownPreviewComponent {
constructor() { constructor() {
}
private ngAfterViewInit(): void {
this.loadSubscribers(); this.loadSubscribers();
} }
private ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
private loadSubscribers() { private loadSubscribers() {
this.markdownPreviewService.getMessage$().pipe( this.markdownPreviewService.getMessage$().pipe(
takeUntil(this.unsubscribe) takeUntilDestroyed(this.#destroyRef)
).subscribe((message: ServiceMessage) => { ).subscribe((message: ServiceMessage) => {
if (message.action === "toggle-markdown-preview") { switch ( message.action ) {
this.toggleMarkdownPreview(message); case "toggle-markdown-preview":
} else if (message.action === "set-active-editor") { this.toggleMarkdownPreview(message);
this.setActiveEditor(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 {
import { Subject, takeUntil } from 'rxjs'; 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'; 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 { export class SearchReplaceComponent {
private unsubscribe: Subject<void> = new Subject(); readonly #destroyRef: DestroyRef = inject(DestroyRef);
private searchReplaceService: SearchReplaceService = inject(SearchReplaceService); private searchReplaceService: SearchReplaceService = inject(SearchReplaceService);
@@ -45,26 +53,22 @@ export class SearchReplaceComponent {
constructor() { constructor() {
}
private ngAfterViewInit(): void {
this.loadSubscribers(); this.loadSubscribers();
} }
private ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
private loadSubscribers() { private loadSubscribers() {
this.searchReplaceService.getMessage$().pipe( this.searchReplaceService.getMessage$().pipe(
takeUntil(this.unsubscribe) takeUntilDestroyed(this.#destroyRef)
).subscribe((message: ServiceMessage) => { ).subscribe((message: ServiceMessage) => {
if (message.action === "toggle-search-replace") { switch ( message.action ) {
this.toggleSearchReplace(message); case "toggle-search-replace":
} else if (message.action === "set-active-editor") { this.toggleSearchReplace(message);
this.setActiveEditor(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 { CommonModule } from '@angular/common';
import { CdkDrag, CdkDragDrop, CdkDropList } from '@angular/cdk/drag-drop'; 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'; import { TabsService } from '../../common/services/editor/tabs/tabs.service';
@@ -24,7 +29,7 @@ import { ServiceMessage } from '../../common/types/service-message.type';
} }
}) })
export class TabsComponent { export class TabsComponent {
private unsubscribe: Subject<void> = new Subject(); readonly #destroyRef = inject(DestroyRef);
private tabsService: TabsService = inject(TabsService); private tabsService: TabsService = inject(TabsService);
private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef); private changeDetectorRef: ChangeDetectorRef = inject(ChangeDetectorRef);
@@ -33,36 +38,36 @@ export class TabsComponent {
constructor() { constructor() {
}
private ngAfterViewInit(): void {
this.loadSubscribers(); this.loadSubscribers();
} }
private ngOnDestroy(): void {
this.unsubscribe.next();
this.unsubscribe.complete();
}
private loadSubscribers() { private loadSubscribers() {
this.tabsService.getMessage$().pipe( this.tabsService.getMessage$().pipe(
takeUntil(this.unsubscribe) takeUntilDestroyed(this.#destroyRef)
).subscribe((message: ServiceMessage) => { ).subscribe((message: ServiceMessage) => {
if (message.action === "create-tab") { let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1];
this.createTab(message.fileName, message.fileUUID, message.filePath);
} else if (message.action === "file-changed") { switch ( message.action ) {
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1]; case "create-tab":
elm.classList.add("file-changed"); this.createTab(message.fileName, message.fileUUID, message.filePath);
elm.classList.remove("file-deleted"); break;
} else if (message.action === "file-deleted") { case "file-changed":
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1]; elm.classList.add("file-changed");
elm.classList.add("file-deleted"); elm.classList.remove("file-deleted");
elm.classList.remove("file-changed"); break;
} else if (message.action === "file-saved") { case "file-deleted":
let elm = document.querySelectorAll(`[title="${message.filePath}"]`)[1]; elm.classList.add("file-deleted");
elm.classList.remove("file-deleted"); elm.classList.remove("file-changed");
elm.classList.remove("file-changed"); break;
case "file-saved":
elm.classList.remove("file-deleted");
elm.classList.remove("file-changed");
break;
default:
break;
} }
}); });
} }