Skip to content

Commit 3cfebdb

Browse files
committed
refactor: replaced unsubscribe mechanism with DestroyRef
1 parent 973bfdd commit 3cfebdb

7 files changed

Lines changed: 67 additions & 72 deletions

File tree

packages/studio-web/src/app/app.component.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
import { Subject, takeUntil } from "rxjs";
21
import { MatDialogRef, MatDialog } from "@angular/material/dialog";
3-
import { Component, OnDestroy, OnInit, signal } from "@angular/core";
2+
import { Component, DestroyRef, inject, OnInit, signal } from "@angular/core";
43
import { environment } from "../environments/environment";
54
import { Router } from "@angular/router";
5+
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
6+
67
@Component({
78
selector: "app-root",
89
templateUrl: "./app.component.html",
910
styleUrls: ["./app.component.sass"],
1011
standalone: false,
1112
})
12-
export class AppComponent implements OnDestroy, OnInit {
13-
unsubscribe$ = new Subject<void>();
13+
export class AppComponent implements OnInit {
14+
private destroyRef$ = inject(DestroyRef);
1415
version = environment.packageJson.singleFileBundleVersion;
1516
currentURL = signal("/");
1617
languages: (typeof environment)["languages"];
@@ -26,11 +27,13 @@ export class AppComponent implements OnDestroy, OnInit {
2627
}
2728

2829
ngOnInit(): void {
29-
this.router.events.pipe(takeUntil(this.unsubscribe$)).subscribe((event) => {
30-
if (event.type === 1) {
31-
this.currentURL.set(event.url);
32-
}
33-
});
30+
this.router.events
31+
.pipe(takeUntilDestroyed(this.destroyRef$))
32+
.subscribe((event) => {
33+
if (event.type === 1) {
34+
this.currentURL.set(event.url);
35+
}
36+
});
3437
}
3538

3639
openPrivacyDialog(): void {
@@ -45,13 +48,6 @@ export class AppComponent implements OnDestroy, OnInit {
4548
switchLanguage(url: string) {
4649
window.open(url, "_blank");
4750
}
48-
49-
ngOnDestroy(): void {
50-
this.unsubscribe$.next();
51-
this.unsubscribe$.complete();
52-
}
53-
54-
ngAfterViewInit() {}
5551
}
5652

5753
@Component({

packages/studio-web/src/app/demo/demo.component.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { Subject } from "rxjs";
2-
31
import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core";
42
import { Components } from "@readalongs/web-component/loader";
53

@@ -8,7 +6,7 @@ import { StudioService } from "../studio/studio.service";
86
import { DownloadService } from "../shared/download/download.service";
97
import { SupportedOutputs } from "../ras.service";
108
import { ToastrService } from "ngx-toastr";
11-
import { WcStylingService } from "../shared/wc-styling/wc-styling.service";
9+
1210
@Component({
1311
selector: "app-demo",
1412
templateUrl: "./demo.component.html",
@@ -18,7 +16,7 @@ import { WcStylingService } from "../shared/wc-styling/wc-styling.service";
1816
export class DemoComponent implements OnDestroy, OnInit {
1917
@ViewChild("readalong") readalong!: Components.ReadAlong;
2018
language: "eng" | "fra" | "spa" = "eng";
21-
unsubscribe$ = new Subject<void>();
19+
2220
constructor(
2321
public b64Service: B64Service,
2422
public studioService: StudioService,
@@ -56,8 +54,6 @@ export class DemoComponent implements OnDestroy, OnInit {
5654
}
5755

5856
async ngOnDestroy() {
59-
this.unsubscribe$.next();
60-
this.unsubscribe$.complete();
6157
// Save translations, images and all other edits to the studio service when we exit
6258
if (this.studioService.b64Inputs$.value[1]) {
6359
await this.downloadService.updateTranslations(

packages/studio-web/src/app/editor/editor.component.ts

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import WaveSurfer from "wavesurfer.js";
22

3-
import { takeUntil, Subject, take, fromEvent, debounceTime } from "rxjs";
3+
import { take, fromEvent, debounceTime } from "rxjs";
44
import {
55
AfterViewInit,
66
Component,
7+
DestroyRef,
78
ElementRef,
9+
inject,
810
OnDestroy,
911
OnInit,
1012
ViewChild,
@@ -33,6 +35,8 @@ import { ToastrService } from "ngx-toastr";
3335
import { validateFileType } from "../utils/utils";
3436
import { WcStylingService } from "../shared/wc-styling/wc-styling.service";
3537
import { WcStylingComponent } from "../shared/wc-styling/wc-styling.component";
38+
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
39+
3640
@Component({
3741
selector: "app-editor",
3842
templateUrl: "./editor.component.html",
@@ -56,7 +60,7 @@ export class EditorComponent implements OnDestroy, AfterViewInit {
5660
// a comma separated list of file extensions or mime types.
5761
htmlUploadAccepts = ".html";
5862

59-
unsubscribe$ = new Subject<void>();
63+
private destroyRef$ = inject(DestroyRef);
6064
rasFileIsLoaded = false;
6165

6266
private beforeUnload: (e: Event) => void;
@@ -77,7 +81,7 @@ export class EditorComponent implements OnDestroy, AfterViewInit {
7781
this.addWCCustomFont(font),
7882
);
7983
fromEvent(window, "resize")
80-
.pipe(debounceTime(100), takeUntil(this.unsubscribe$)) // wait for 1 second after the last resize event
84+
.pipe(debounceTime(100), takeUntilDestroyed(this.destroyRef$)) // wait for 1 second after the last resize event
8185
.subscribe(() => {
8286
// When the window is resized, we want to reset the style window size
8387
// so that it does not get squeezed too small
@@ -166,7 +170,7 @@ export class EditorComponent implements OnDestroy, AfterViewInit {
166170
}
167171
if (this.handleElement) {
168172
fromEvent(this.handleElement.nativeElement, "dragend")
169-
.pipe(takeUntil(this.unsubscribe$))
173+
.pipe(takeUntilDestroyed(this.destroyRef$))
170174
.subscribe((event) => {
171175
const ev = event as DragEvent;
172176
console.log("[DEBUG] dragged");
@@ -353,13 +357,15 @@ export class EditorComponent implements OnDestroy, AfterViewInit {
353357
const currentWord$ = await this.readalong.getCurrentWord();
354358
const alignments = await this.readalong.getAlignments();
355359
// Subscribe to the current word of the readalong and center the wavesurfer element on it
356-
currentWord$.pipe(takeUntil(this.unsubscribe$)).subscribe((word) => {
357-
if (word) {
358-
this.wavesurfer.seekAndCenter(
359-
alignments[word][0] / 1000 / this.wavesurfer.getDuration(),
360-
);
361-
}
362-
});
360+
currentWord$
361+
.pipe(takeUntilDestroyed(this.destroyRef$))
362+
.subscribe((word) => {
363+
if (word) {
364+
this.wavesurfer.seekAndCenter(
365+
alignments[word][0] / 1000 / this.wavesurfer.getDuration(),
366+
);
367+
}
368+
});
363369
}
364370
}
365371

@@ -518,7 +524,7 @@ export class EditorComponent implements OnDestroy, AfterViewInit {
518524
readalong_editor_choose_file["buttons"][1]["action"] = () => {
519525
this.fileService
520526
.returnFileFromPath$("assets/hello-world.offline.html")
521-
.pipe(takeUntil(this.unsubscribe$))
527+
.pipe(takeUntilDestroyed(this.destroyRef$))
522528
.subscribe(async (indexFile) => {
523529
await this.loadRasFile(indexFile);
524530
this.shepherdService.next();

packages/studio-web/src/app/shared/download/download.service.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { Injectable } from "@angular/core";
1+
import { DestroyRef, inject, Injectable } from "@angular/core";
22
import { HttpErrorResponse } from "@angular/common/http";
3-
import { Observable, Subject, takeUntil } from "rxjs";
43
import { slugify } from "../../utils/utils";
54
import { UploadService } from "../../upload.service";
65
import { ToastrService } from "ngx-toastr";
@@ -18,6 +17,7 @@ import {
1817
} from "../../ras.service";
1918
import { Components } from "@readalongs/web-component/loader";
2019
import { WcStylingService } from "../wc-styling/wc-styling.service";
20+
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
2121

2222
interface Image {
2323
path: string;
@@ -28,7 +28,7 @@ interface Image {
2828
providedIn: "root",
2929
})
3030
export class DownloadService {
31-
unsubscribe$ = new Subject<void>();
31+
private destroyRef$ = inject(DestroyRef);
3232
xmlSerializer = new XMLSerializer();
3333
readmeFile = new Blob(
3434
[
@@ -483,7 +483,7 @@ Use the text editor to paste the snippet below in your WordPress page:
483483
},
484484
selectedOutputFormat,
485485
)
486-
.pipe(takeUntil(this.unsubscribe$))
486+
.pipe(takeUntilDestroyed(this.destroyRef$))
487487
.subscribe({
488488
next: (x: Blob) => saveAs(x, `${basename}.${selectedOutputFormat}`),
489489
error: (err: HttpErrorResponse) => this.reportRasError(err),

packages/studio-web/src/app/shared/wc-styling/wc-styling.component.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import {
22
Component,
3+
DestroyRef,
34
ElementRef,
4-
OnDestroy,
5+
inject,
56
OnInit,
67
ViewChild,
78
} from "@angular/core";
@@ -15,18 +16,19 @@ import {
1516
} from "@angular/material/dialog";
1617
import { B64Service } from "../../b64.service";
1718
import { MatButtonModule } from "@angular/material/button";
19+
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
1820

1921
@Component({
2022
selector: "app-wc-styling",
2123
templateUrl: "./wc-styling.component.html",
2224
styleUrl: "./wc-styling.component.sass",
2325
standalone: false,
2426
})
25-
export class WcStylingComponent implements OnDestroy, OnInit {
27+
export class WcStylingComponent implements OnInit {
2628
styleText$ = new BehaviorSubject<string>("");
2729
fontDeclaration$ = new BehaviorSubject<string>("");
2830
inputType = "edit";
29-
unsubscribe$ = new Subject<void>();
31+
private destroyRef$ = inject(DestroyRef);
3032
collapsed$ = new BehaviorSubject<boolean>(true);
3133
@ViewChild("styleInputElement") styleInputElement: ElementRef;
3234
@ViewChild("fontInputElement") fontInputElement: ElementRef;
@@ -198,7 +200,7 @@ span.theme--dark.sentence__text {
198200
}
199201
async ngOnInit() {
200202
this.wcStylingService.$wcStyleInput
201-
.pipe(takeUntil(this.unsubscribe$))
203+
.pipe(takeUntilDestroyed(this.destroyRef$))
202204
.subscribe((css) => {
203205
if (this.styleText$.getValue().length < 1) {
204206
this.styleText$.next(css);
@@ -207,10 +209,6 @@ span.theme--dark.sentence__text {
207209
});
208210
}
209211

210-
ngOnDestroy(): void {
211-
this.unsubscribe$.next();
212-
this.unsubscribe$.complete();
213-
}
214212
openHelpDialog(): void {
215213
this.dialog.open(WCStylingHelper, {
216214
width: "80vw",

packages/studio-web/src/app/studio/studio.component.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
import { ShepherdService } from "../shepherd.service";
2-
import { forkJoin, of, Subject, take, takeUntil } from "rxjs";
2+
import { forkJoin, of, take } from "rxjs";
33
import { Segment } from "soundswallower";
44

5-
import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core";
5+
import {
6+
Component,
7+
DestroyRef,
8+
inject,
9+
OnDestroy,
10+
OnInit,
11+
ViewChild,
12+
} from "@angular/core";
613
import { ActivatedRoute, Router } from "@angular/router";
714
import { Meta } from "@angular/platform-browser";
815
import { MatStepper } from "@angular/material/stepper";
916
import { Title } from "@angular/platform-browser";
17+
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
1018

1119
import {
1220
createAlignedXML,
@@ -52,9 +60,8 @@ export class StudioComponent implements OnDestroy, OnInit {
5260
@ViewChild("upload", { static: false }) upload?: UploadComponent;
5361
@ViewChild("demo", { static: false }) demo?: DemoComponent;
5462
@ViewChild("stepper") private stepper: MatStepper;
55-
unsubscribe$ = new Subject<void>();
56-
5763
private beforeUnload: (e: Event) => void;
64+
private destroyRef$ = inject(DestroyRef);
5865
private route: ActivatedRoute;
5966
constructor(
6067
private titleService: Title,
@@ -122,7 +129,7 @@ export class StudioComponent implements OnDestroy, OnInit {
122129
// Catch and report a catastrophic failure as soon as possible
123130
this.ssjsService
124131
.loadModule$()
125-
.pipe(takeUntil(this.unsubscribe$))
132+
.pipe(takeUntilDestroyed(this.destroyRef$))
126133
.subscribe({
127134
error: (err) => {
128135
this.router.navigate(["error"], {
@@ -138,8 +145,6 @@ export class StudioComponent implements OnDestroy, OnInit {
138145
async ngOnDestroy() {
139146
// step us back to the previously left step
140147
this.studioService.lastStepperIndex = this.stepper?.selectedIndex;
141-
this.unsubscribe$.next();
142-
this.unsubscribe$.complete();
143148

144149
window.removeEventListener("beforeunload", this.beforeUnload);
145150
}
@@ -226,7 +231,7 @@ export class StudioComponent implements OnDestroy, OnInit {
226231
step_one_final_step["buttons"][1]["action"] = () => {
227232
this.fileService
228233
.returnFileFromPath$("assets/hello-world.mp3")
229-
.pipe(takeUntil(this.unsubscribe$))
234+
.pipe(takeUntilDestroyed(this.destroyRef$))
230235
.subscribe((audioFile) => {
231236
if (!(audioFile instanceof HttpErrorResponse) && this.upload) {
232237
this.studioService.$textInput.next("Hello world!");
@@ -315,7 +320,7 @@ export class StudioComponent implements OnDestroy, OnInit {
315320
this.fileService.readFileAsData$(event[1]), // audio
316321
of(aligned_xml),
317322
])
318-
.pipe(takeUntil(this.unsubscribe$))
323+
.pipe(takeUntilDestroyed(this.destroyRef$))
319324
.subscribe((x: any) => {
320325
this.studioService.b64Inputs$.next(x);
321326
this.stepper.next();

0 commit comments

Comments
 (0)