Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/end-to-end-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ jobs:
run: npx nx e2e studio-web

- name: Upload HTML report
if: always()
uses: actions/upload-artifact@v6
with:
name: playwright-report--attempt-${{ github.run_attempt }}
Expand Down
6 changes: 6 additions & 0 deletions packages/studio-web/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@
"update-browserslist": {
"command": "npx -y update-browserslist-db@latest"
},
"just-serve": {
"executor": "@angular-builders/custom-webpack:dev-server",
"options": {
"buildTarget": "studio-web:build:development,en"
}
},
"serve": {
"executor": "@angular-builders/custom-webpack:dev-server",
"dependsOn": ["update-browserslist"],
Expand Down
11 changes: 6 additions & 5 deletions packages/studio-web/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,21 @@ export class AppComponent implements OnInit {
})
export class PrivacyDialog {
private dialogRef = inject(MatDialogRef<PrivacyDialog>);
protected analyticsExcluded =
window.localStorage.getItem("plausible_ignore") === "true";
protected analyticsExcluded = signal(
window.localStorage.getItem("plausible_ignore") === "true",
);

ngOnInit() {
this.dialogRef.updateSize("100%");
}

toggleAnalytics() {
if (this.analyticsExcluded) {
if (this.analyticsExcluded()) {
window.localStorage.removeItem("plausible_ignore");
this.analyticsExcluded = false;
this.analyticsExcluded.set(false);
} else {
window.localStorage.setItem("plausible_ignore", "true");
this.analyticsExcluded = true;
this.analyticsExcluded.set(true);
}
}
}
6 changes: 3 additions & 3 deletions packages/studio-web/src/app/editor/editor.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ <h1 i18n="Welcome message for app editor" id="welcome-header">
</button>
</div>
</div>
@if (editorService.uploadFormGroup.valid) {
@if (editorService.uploadFormValid()) {
<div class="col-4">
<ras-shared-download
(downloadButtonClicked)="download($event)"
Expand Down Expand Up @@ -60,8 +60,8 @@ <h2 i18n="Title for upload box" class="title">
>
<div id="readalongContainer" #readalongContainer></div>
<div
[class.d-none]="!rasFileIsLoaded"
[class.d-lg-flex]="rasFileIsLoaded"
[class.d-none]="!rasFileIsLoaded()"
[class.d-lg-flex]="rasFileIsLoaded()"
class="flex-row"
>
<div
Expand Down
9 changes: 5 additions & 4 deletions packages/studio-web/src/app/editor/editor.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ElementRef,
inject,
OnDestroy,
signal,
ViewChild,
} from "@angular/core";
import SegmentsPlugin from "./segments";
Expand Down Expand Up @@ -57,7 +58,7 @@ export class EditorComponent implements OnDestroy, AfterViewInit {
// a comma separated list of file extensions or mime types.
protected htmlUploadAccepts = ".html";
private destroyRef$ = inject(DestroyRef);
protected rasFileIsLoaded = false;
protected rasFileIsLoaded = signal(false);

private beforeUnload: (e: Event) => void;

Expand Down Expand Up @@ -99,7 +100,7 @@ export class EditorComponent implements OnDestroy, AfterViewInit {
private formIsDirty(): boolean {
return (
(this.rasFileUpload && this.rasFileUpload.nativeElement.value !== "") ||
this.rasFileIsLoaded
this.rasFileIsLoaded()
);
}

Expand Down Expand Up @@ -217,7 +218,7 @@ export class EditorComponent implements OnDestroy, AfterViewInit {
this.wcStylingService,
);
}
this.rasFileIsLoaded = false;
this.rasFileIsLoaded.set(false);

window.removeEventListener("beforeunload", this.beforeUnload);
}
Expand Down Expand Up @@ -304,7 +305,7 @@ export class EditorComponent implements OnDestroy, AfterViewInit {
const readalong = await this.parseReadalong(text);
this.loadAudioIntoWavesurferElement();
this.renderReadalong(readalong);
this.rasFileIsLoaded = true;
this.rasFileIsLoaded.set(true);
}

async renderReadalong(readalongBody: string | undefined) {
Expand Down
11 changes: 11 additions & 0 deletions packages/studio-web/src/app/editor/editor.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Injectable } from "@angular/core";
import { FormControl, FormGroup, Validators } from "@angular/forms";
import { toSignal } from "@angular/core/rxjs-interop";
import { map, startWith } from "rxjs";
import { ReadAlongSlots } from "../ras.service";

@Injectable({
Expand Down Expand Up @@ -27,5 +29,14 @@ export class EditorService {
ras: this.rasControl$,
audioB64: this.audioB64Control$,
});
public uploadFormValid = toSignal(
this.uploadFormGroup.statusChanges.pipe(
startWith(this.uploadFormGroup.status),
map(() => this.uploadFormGroup.valid),
),
{
initialValue: this.uploadFormGroup.valid,
},
);
temporaryBlob: Blob | undefined = undefined;
}
2 changes: 1 addition & 1 deletion packages/studio-web/src/app/privacy-dialog.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ <h1 i18n="Title for privacy dialog" mat-dialog-title>Privacy Policy</h1>
style="display: flex; justify-content: space-evenly; margin-top: 1em"
>
<div>
@if(analyticsExcluded) {
@if(analyticsExcluded()) {
<button
color="accent"
(click)="toggleAnalytics()"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ <h1 class="title pt-2">
(change)="toggleStyleInput($event)"
name="inputMethod"
aria-label="Input Method"
[value]="inputType"
[value]="inputType()"
>
<mat-button-toggle i18n="Label for style Write toggle" value="edit"
>Write</mat-button-toggle
Expand All @@ -85,7 +85,7 @@ <h1 class="title pt-2">

@if (!(collapsed$ | async)) {
<div>
@if (inputType === "upload") {
@if (inputType() === "upload") {
<div>
<div class="row">
<div class="mt-4 mb-3">
Expand All @@ -111,7 +111,7 @@ <h1 class="title pt-2">
</div>
}

@if (inputType === "edit") {
@if (inputType() === "edit") {
<div>
<div
class="d-flex flex-column flex-md-row justify-content-between p-0 styling-toolbar"
Expand Down Expand Up @@ -143,7 +143,7 @@ <h1 class="title pt-2">
</button>
</span>
</div>
@if (canUseClipBoard) {
@if (canUseClipBoard()) {
<div class="row">
<div class="col d-flex justify-content-center">
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ElementRef,
inject,
OnInit,
signal,
ViewChild,
} from "@angular/core";
import { ToastrService } from "@openng/ngx-toastr";
Expand All @@ -27,12 +28,12 @@ import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
export class WcStylingComponent implements OnInit {
protected styleText$ = new BehaviorSubject<string>("");
private fontDeclaration$ = new BehaviorSubject<string>("");
protected inputType: "edit" | "upload" = "edit";
protected inputType = signal<"edit" | "upload">("edit");
public collapsed$ = new BehaviorSubject<boolean>(true);
@ViewChild("styleInputElement") private styleInputElement: ElementRef;
@ViewChild("fontInputElement") private fontInputElement: ElementRef;
@ViewChild("styleSection") public styleSection: ElementRef;
protected canUseClipBoard = false;
protected canUseClipBoard = signal(false);
private toastr = inject(ToastrService);
private wcStylingService = inject(WcStylingService);
private dialog = inject(MatDialog);
Expand All @@ -58,14 +59,14 @@ export class WcStylingComponent implements OnInit {
.query({ name: "clipboard-write" as PermissionName })
.then((result) => {
if (result.state === "granted" || result.state === "prompt") {
this.canUseClipBoard = true;
this.canUseClipBoard.set(true);
} else {
this.canUseClipBoard = false;
this.canUseClipBoard.set(false);
}
})
.catch((err) => {
console.error("Failed to query clipboard permissions", err);
this.canUseClipBoard = false;
this.canUseClipBoard.set(false);
});
}
onFontSelected(event: any) {
Expand Down Expand Up @@ -125,7 +126,7 @@ export class WcStylingComponent implements OnInit {
this.styleText$.next(val);

this.wcStylingService.$wcStyleInput.next(val);
this.inputType = "edit";
this.inputType.set("edit");
this.toastr.success(
$localize`File ` +
file.name +
Expand Down Expand Up @@ -195,7 +196,7 @@ span.theme--dark.sentence__text {
}
}
toggleStyleInput(event: any) {
this.inputType = event.value;
this.inputType.set(event.value);
}
async ngOnInit() {
this.wcStylingService.$wcStyleInput
Expand All @@ -219,13 +220,13 @@ span.theme--dark.sentence__text {
this.collapsed$.next(!this.collapsed$.getValue());
}
pasteStyle() {
if (this.canUseClipBoard) {
if (this.canUseClipBoard()) {
navigator.clipboard
.readText()
.then((text) => {
this.styleText$.next(text);
this.wcStylingService.$wcStyleInput.next(text);
this.inputType = "edit";
this.inputType.set("edit");
this.toastr.success(
$localize`Style sheet pasted from clipboard.`,
undefined,
Expand All @@ -246,7 +247,7 @@ span.theme--dark.sentence__text {
}

copyStyle() {
if (this.canUseClipBoard) {
if (this.canUseClipBoard()) {
navigator.clipboard
.writeText(this.styleText$.getValue())
.then(() => {
Expand Down
32 changes: 12 additions & 20 deletions packages/studio-web/src/app/upload/upload.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -193,25 +193,25 @@ <h2 i18n="Title for record box" class="subtitle">
class="audioControl"
mat-button
(click)="startRecording()"
[color]="recording ? 'warn' : 'primary'"
[color]="recording() ? 'warn' : 'primary'"
aria-label="Record button"
[disabled]="starting_to_record"
[disabled]="starting_to_record()"
data-test-id="ras-audio-recording-btn"
>
<mat-icon class="mat-icon-lg">mic</mat-icon>
@if (studioService.audioControl$.value !== null && !recording) {
@if (has_audio() && !recording()) {
<span i18n="Audio re-record button"
>Delete and re-record</span
>
}
@if (studioService.audioControl$.value === null && !recording) {
@if (!has_audio() && !recording()) {
<span i18n="Audio record button">Record</span>
}
@if (recording) {
@if (recording()) {
<span i18n="Audio recording button">Recording</span>
}
</button>
@if (recording) {
@if (recording()) {
<button
i18n="Audio stop button"
class="audioControl"
Expand All @@ -229,11 +229,7 @@ <h2 i18n="Title for record box" class="subtitle">
}
<div class="row">
<div class="col-12 col-xl-4">
@if (
!recording &&
studioService.audioControl$.value !== null &&
!playing
) {
@if (!recording() && has_audio() && !playing()) {
<button
i18n="Audio play button"
class="audioControl"
Expand All @@ -246,11 +242,7 @@ <h2 i18n="Title for record box" class="subtitle">
Play
</button>
}
@if (
!recording &&
studioService.audioControl$.value !== null &&
playing
) {
@if (!recording() && has_audio() && playing()) {
<button
i18n="Audio stop button"
class="audioControl"
Expand All @@ -265,7 +257,7 @@ <h2 i18n="Title for record box" class="subtitle">
}
</div>
<div class="col-12 col-xl-4">
@if (!recording && studioService.audioControl$.value !== null) {
@if (!recording() && has_audio()) {
<button
i18n="Audio download button"
class="audioControl"
Expand All @@ -281,7 +273,7 @@ <h2 i18n="Title for record box" class="subtitle">
}
</div>
<div class="col-12 col-xl-4">
@if (!recording && studioService.audioControl$.value !== null) {
@if (!recording() && has_audio()) {
<button
i18n="Audio delete button"
class="audioControl"
Expand Down Expand Up @@ -392,7 +384,7 @@ <h1 i18n="Title for language box" class="title">
i18n="Next button"
id="next-step"
class="mt-4 plausible-event-name=CreateReadalong"
[disabled]="loading || !isLoaded"
[disabled]="loading() || !isLoaded()"
mat-raised-button
color="primary"
type="submit"
Expand All @@ -401,7 +393,7 @@ <h1 i18n="Title for language box" class="title">
>
Go to the next step!
</button>
@if (loading) {
@if (loading()) {
<mat-progress-bar
[mode]="progressMode"
[value]="progressValue"
Expand Down
Loading
Loading