Skip to content

Commit

Permalink
Merge pull request #322 from ReadAlongs/dev.ap/navbar
Browse files Browse the repository at this point in the history
feat: add navbar navigation
  • Loading branch information
roedoejet authored Jul 23, 2024
2 parents c894678 + e276125 commit 7422e31
Show file tree
Hide file tree
Showing 23 changed files with 660 additions and 432 deletions.
33 changes: 32 additions & 1 deletion packages/studio-web/src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,2 +1,33 @@
<mat-toolbar>
<span i18n="Welcome message for app" id="welcome-header">
ReadAlong Studio
</span>
<span class="nav-spacer"></span>
<div class="nav__buttons">
<button
class="nav__button"
mat-button
[color]="currentURL === '/' ? 'accent' : ''"
[routerLink]="''"
>
Studio
</button>
<button
class="nav__button"
mat-button
[color]="currentURL === '/editor' ? 'accent' : ''"
[routerLink]="'editor'"
>
<mat-icon>edit</mat-icon>
Editor
</button>
<button class="nav__button" mat-button (click)="openPrivacyDialog()">
<mat-icon>policy</mat-icon>
Privacy
</button>
</div>
</mat-toolbar>
<router-outlet></router-outlet>
<div class="version">&#64;readalongs/studio-web version: {{ version }}</div>
<div class="footer">
<div class="version">&#64;readalongs/studio-web version: {{ version }}</div>
</div>
6 changes: 6 additions & 0 deletions packages/studio-web/src/app/app.component.sass
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@
align-items: center
justify-content: space-between
align-content:space-around

.nav__button
align-items: right

.nav-spacer
flex: 1 1 auto
50 changes: 46 additions & 4 deletions packages/studio-web/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Subject } from "rxjs";

import { Subject, takeUntil } from "rxjs";
import { MatDialogRef, MatDialog } from "@angular/material/dialog";
import { Component, OnDestroy, OnInit } from "@angular/core";
import { environment } from "../environments/environment";
import { Router } from "@angular/router";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
Expand All @@ -10,8 +11,26 @@ import { environment } from "../environments/environment";
export class AppComponent implements OnDestroy, OnInit {
unsubscribe$ = new Subject<void>();
version = environment.packageJson.singleFileBundleVersion;
constructor() {}
ngOnInit(): void {}
currentURL = "/";
constructor(
private dialog: MatDialog,
public router: Router,
) {}
ngOnInit(): void {
this.router.events.pipe(takeUntil(this.unsubscribe$)).subscribe((event) => {
if (event.type === 1) {
this.currentURL = event.url;
}
});
}

openPrivacyDialog(): void {
this.dialog.open(PrivacyDialog, {
width: "50vw",
maxWidth: "50vw", // maxWidth is required to force material to use justify-content: flex-start
minWidth: "50vw",
});
}

ngOnDestroy(): void {
this.unsubscribe$.next();
Expand All @@ -20,3 +39,26 @@ export class AppComponent implements OnDestroy, OnInit {

ngAfterViewInit() {}
}

@Component({
selector: "privacy-dialog",
templateUrl: "privacy-dialog.html",
})
export class PrivacyDialog {
analyticsExcluded =
window.localStorage.getItem("plausible_ignore") === "true";
constructor(public dialogRef: MatDialogRef<PrivacyDialog>) {}
ngOnInit() {
this.dialogRef.updateSize("100%");
}

toggleAnalytics() {
if (this.analyticsExcluded) {
window.localStorage.removeItem("plausible_ignore");
} else {
window.localStorage.setItem("plausible_ignore", "true");
}
this.analyticsExcluded =
window.localStorage.getItem("plausible_ignore") === "true";
}
}
3 changes: 2 additions & 1 deletion packages/studio-web/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import { UploadComponent } from "./upload/upload.component";
import { TextFormatDialogComponent } from "./text-format-dialog/text-format-dialog.component";
import { NgxRAWebComponentModule } from "@readalongs/ngx-web-component";
import { defineCustomElements } from "@readalongs/web-component/loader";
import { StudioComponent, PrivacyDialog } from "./studio/studio.component";
import { StudioComponent } from "./studio/studio.component";
import { PrivacyDialog } from "./app.component";
import { ErrorPageComponent } from "./error-page/error-page.component";
import { EditorComponent } from "./editor/editor.component";
import { SharedModule } from "./shared/shared.module";
Expand Down
79 changes: 41 additions & 38 deletions packages/studio-web/src/app/demo/demo.component.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<section>
<!-- <ng-template *ngIf="b64Inputs$ | async as b64Inputs"> -->
<div class="container">
<div class="container" *ngIf="studioService.render$ | async">
<div class="row">
<div class="col-9">
<h2
Expand All @@ -11,50 +10,54 @@
Congratulations! Here's your ReadAlong!
</h2>
</div>
<div class="col-3" *ngIf="b64Inputs">
<div class="col-3">
<ras-shared-download
[slots]="slots"
[b64Audio]="b64Inputs[0]"
[rasXML]="b64Inputs[1]"
[readalong]="readalong"
(downloadButtonClicked)="download($event)"
></ras-shared-download>
</div>
</div>

<div class="row"></div>

<div class="row" *ngIf="b64Inputs">
<read-along
id="readalong"
[language]="language"
#readalong
*ngIf="render$ | async"
mode="EDIT"
href="data:application/readalong+xml;base64,{{
b64Service.xmlToB64(b64Inputs[1])
}}"
audio="{{ b64Inputs[0] }}"
class="hydrated"
>
<input
#title
[(ngModel)]="slots.title"
[ngStyle]="{ 'width.ch': slots.title.length, 'min-width.ch': 20 }"
style="border: none"
placeholder="Enter your title here"
slot="read-along-header"
/>
<input
#subtitle
[(ngModel)]="slots.subtitle"
[ngStyle]="{ 'width.ch': slots.subtitle.length, 'min-width.ch': 20 }"
style="border: none"
placeholder="Enter your subtitle here"
slot="read-along-subheader"
/>
</read-along>
<div class="row" *ngIf="studioService.b64Inputs$ | async as b64Inputs">
<div *ngIf="b64Inputs[0] && b64Inputs[1]">
<read-along
id="readalong"
[language]="language"
#readalong
*ngIf="studioService.render$ | async"
mode="EDIT"
href="data:application/readalong+xml;base64,{{
b64Service.xmlToB64(b64Inputs[1])
}}"
audio="{{ b64Inputs[0] }}"
class="hydrated"
>
<input
#title
[(ngModel)]="studioService.slots.title"
[ngStyle]="{
'width.ch': studioService.slots.title.length,
'min-width.ch': 20
}"
style="border: none"
placeholder="Enter your title here"
slot="read-along-header"
/>
<input
#subtitle
[(ngModel)]="studioService.slots.subtitle"
[ngStyle]="{
'width.ch': studioService.slots.subtitle.length,
'min-width.ch': 20
}"
style="border: none"
placeholder="Enter your subtitle here"
slot="read-along-subheader"
/>
</read-along>
</div>
</div>
<div class="row"></div>
</div>
<!-- </ng-template> -->
</section>
4 changes: 2 additions & 2 deletions packages/studio-web/src/app/demo/demo.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ describe("DemoComponent", () => {
});

it(`should have as title 'Title'`, () => {
expect(component.slots.title).toEqual("Title");
expect(component.studioService.slots.title).toEqual("Title");
});

it(`should have as subtitle 'SubTitle'`, () => {
expect(component.slots.subtitle).toEqual("Subtitle");
expect(component.studioService.slots.subtitle).toEqual("Subtitle");
});
});
58 changes: 46 additions & 12 deletions packages/studio-web/src/app/demo/demo.component.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
import { Observable, Subject } from "rxjs";
import { Subject } from "rxjs";

import { Component, Input, OnDestroy, OnInit, ViewChild } from "@angular/core";
import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core";
import { Components } from "@readalongs/web-component/loader";

import { B64Service } from "../b64.service";
import { ReadAlongSlots } from "../ras.service";
import { StudioService } from "../studio/studio.service";
import { DownloadService } from "../shared/download/download.service";
import { SupportedOutputs } from "../ras.service";
import { ToastrService } from "ngx-toastr";

@Component({
selector: "app-demo",
templateUrl: "./demo.component.html",
styleUrls: ["./demo.component.sass"],
})
export class DemoComponent implements OnDestroy, OnInit {
@Input() b64Inputs: [string, Document];
@Input() render$: Observable<boolean>;
@ViewChild("readalong") readalong!: Components.ReadAlong;
slots: ReadAlongSlots = {
title: $localize`Title`,
subtitle: $localize`Subtitle`,
};
language: "eng" | "fra" | "spa" = "eng";
unsubscribe$ = new Subject<void>();

constructor(public b64Service: B64Service) {
constructor(
public b64Service: B64Service,
public studioService: StudioService,
private downloadService: DownloadService,
private toastr: ToastrService,
) {
// If we do more languages, this should be a lookup table
if ($localize.locale == "fr") {
this.language = "fra";
Expand All @@ -33,8 +34,41 @@ export class DemoComponent implements OnDestroy, OnInit {

ngOnInit(): void {}

ngOnDestroy(): void {
ngAfterViewInit(): void {}
download(download_type: SupportedOutputs) {
if (
this.studioService.b64Inputs$.value &&
this.studioService.b64Inputs$.value[1]
) {
this.downloadService.download(
download_type,
this.studioService.b64Inputs$.value[0],
this.studioService.b64Inputs$.value[1],
this.studioService.slots,
this.readalong,
);
} else {
this.toastr.error($localize`Download failed.`, $localize`Sorry!`, {
timeOut: 10000,
});
}
}

async ngOnDestroy() {
this.unsubscribe$.next();
this.unsubscribe$.complete();
// Save translations, images and all other edits to the studio service when we exit
if (this.studioService.b64Inputs$.value[1]) {
await this.downloadService.updateTranslations(
this.studioService.b64Inputs$.value[1],
this.readalong,
);
await this.downloadService.updateImages(
this.studioService.b64Inputs$.value[1],
true,
"image",
this.readalong,
);
}
}
}
43 changes: 19 additions & 24 deletions packages/studio-web/src/app/editor/editor.component.html
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
<section class="container mt-1">
<div class="row justify-content-center">
<button
i18n="Take the tour"
class="mb-4 col center text-center plausible-event-name=Tour"
mat-raised-button
color="primary"
(click)="startTour()"
>
Take the tour!
</button>
</div>
</section>
<section class="container mt-1"></section>
<section id="editor">
<div class="container mb-2 mt-5">
<div class="row justify-content-center mb-5">
<div class="col-6">
<h1 i18n="Welcome message for app editor" id="welcome-header">
Welcome to the ReadAlong Studio Editor
</h1>
<p>
This is a tool to help you edit your existing 'readalongs'. To get
started, click on the tour button below, and follow the steps.
</p>
<div class="row mt-5 justify-content-center">
<button
i18n="Take the tour"
class="mb-4 col center text-center plausible-event-name=Tour"
mat-raised-button
color="primary"
(click)="startTour()"
>
Take the tour!
</button>
</div>
</div>
<div
class="col-6"
*ngIf="
uploadFormGroup.valid && audioB64Control$.value && rasControl$.value
"
>
<div class="col-6" *ngIf="editorService.uploadFormGroup.valid">
<ras-shared-download
[slots]="slots"
[readalong]="readalong"
[b64Audio]="audioB64Control$.value"
[rasXML]="rasControl$.value"
(downloadButtonClicked)="download($event)"
></ras-shared-download>
</div>
</div>
Expand Down Expand Up @@ -67,7 +62,7 @@ <h2 i18n="Title for upload box" class="title">

<div class="row justify-content-center mt-5 mb-5">
<div class="col" id="audioToolbar">
<mat-toolbar *ngIf="audioControl$.valid">
<mat-toolbar *ngIf="editorService.audioControl$.valid">
<span i18n="Audio Toolbar">Audio Toolbar</span>
<span class="example-spacer"></span>
<span id="zoomControls">
Expand Down
Loading

0 comments on commit 7422e31

Please sign in to comment.