11import WaveSurfer from "wavesurfer.js" ;
22
3- import { takeUntil , Subject , take } from "rxjs" ;
3+ import { takeUntil , Subject , take , fromEvent , debounceTime } from "rxjs" ;
44import {
55 AfterViewInit ,
66 Component ,
@@ -31,6 +31,8 @@ import { DownloadService } from "../shared/download/download.service";
3131import { SupportedOutputs } from "../ras.service" ;
3232import { ToastrService } from "ngx-toastr" ;
3333import { validateFileType } from "../utils/utils" ;
34+ import { WcStylingService } from "../shared/wc-styling/wc-styling.service" ;
35+ import { WcStylingComponent } from "../shared/wc-styling/wc-styling.component" ;
3436@Component ( {
3537 selector : "app-editor" ,
3638 templateUrl : "./editor.component.html" ,
@@ -41,7 +43,8 @@ export class EditorComponent implements OnDestroy, OnInit, AfterViewInit {
4143 @ViewChild ( "wavesurferContainer" ) wavesurferContainer ! : ElementRef ;
4244 wavesurfer : WaveSurfer ;
4345 @ViewChild ( "readalongContainer" ) readalongContainerElement : ElementRef ;
44-
46+ @ViewChild ( "handle" ) handleElement ! : ElementRef ;
47+ @ViewChild ( "styleWindow" ) styleElement ! : WcStylingComponent ;
4548 readalong : Components . ReadAlong ;
4649
4750 language : "eng" | "fra" | "spa" = "eng" ;
@@ -51,14 +54,31 @@ export class EditorComponent implements OnDestroy, OnInit, AfterViewInit {
5154 htmlUploadAccepts = ".html" ;
5255
5356 unsubscribe$ = new Subject < void > ( ) ;
57+ rasFileIsLoaded = false ;
5458 constructor (
5559 public b64Service : B64Service ,
5660 private fileService : FileService ,
5761 public shepherdService : ShepherdService ,
5862 public editorService : EditorService ,
5963 private toastr : ToastrService ,
6064 private downloadService : DownloadService ,
61- ) { }
65+ private wcStylingService : WcStylingService ,
66+ ) {
67+ this . wcStylingService . $wcStyleInput . subscribe ( ( css ) =>
68+ this . updateWCStyle ( css ) ,
69+ ) ;
70+ this . wcStylingService . $wcStyleFonts . subscribe ( ( font ) =>
71+ this . addWCCustomFont ( font ) ,
72+ ) ;
73+ fromEvent ( window , "resize" )
74+ . pipe ( debounceTime ( 100 ) , takeUntil ( this . unsubscribe$ ) ) // wait for 1 second after the last resize event
75+ . subscribe ( ( ) => {
76+ // When the window is resized, we want to reset the style window size
77+ // so that it does not get squeezed too small
78+ console . log ( "[DEBUG] window resized" ) ;
79+ this . resetStyleWindowSize ( ) ;
80+ } ) ;
81+ }
6282
6383 async ngAfterViewInit ( ) : Promise < void > {
6484 this . wavesurfer = WaveSurfer . create ( {
@@ -121,6 +141,40 @@ export class EditorComponent implements OnDestroy, OnInit, AfterViewInit {
121141 if ( window . location . hash . endsWith ( "startTour=yes" ) ) {
122142 this . startTour ( ) ;
123143 }
144+ if ( this . handleElement ) {
145+ fromEvent ( this . handleElement . nativeElement , "dragend" )
146+ . pipe ( takeUntil ( this . unsubscribe$ ) )
147+ . subscribe ( ( event ) => {
148+ const ev = event as DragEvent ;
149+ console . log ( "[DEBUG] dragged" ) ;
150+ if ( this . styleElement . collapsed$ . getValue ( ) ) {
151+ this . resetStyleWindowSize ( ) ;
152+ return ;
153+ }
154+ if ( ev . x < 600 ) {
155+ return ;
156+ } // do not let the read along be squeezed past 600px width
157+ if ( window . innerWidth - ev . x < 400 ) return ; // do not let the style window be squeezed past 600px width)
158+ // When the handle is dragged, we want to resize the readalong and style containers
159+ const styleEle = this . styleElement ?. styleSection
160+ . nativeElement as HTMLElement ;
161+ const readAlong = this . readalongContainerElement
162+ ?. nativeElement as HTMLElement ;
163+ if ( styleEle ?. style ) {
164+ styleEle . style . width = `calc(100vw - ${ ev . x + 50 } px)` ;
165+ }
166+
167+ if ( readAlong ?. style ) {
168+ readAlong . style . width = `${ ev . x } px` ;
169+ }
170+ } ) ;
171+ } else {
172+ this . resetStyleWindowSize ( ) ;
173+ }
174+ this . styleElement . collapsed$ . subscribe ( ( collapsed ) => {
175+ // When the style element is collapsed, we want to reset the style window size
176+ this . resetStyleWindowSize ( ) ;
177+ } ) ;
124178 }
125179
126180 ngOnInit ( ) : void { }
@@ -138,8 +192,10 @@ export class EditorComponent implements OnDestroy, OnInit, AfterViewInit {
138192 this . readalong ,
139193 this . editorService . slots ,
140194 this . editorService . audioB64Control$ . value ,
195+ this . wcStylingService ,
141196 ) ;
142197 }
198+ this . rasFileIsLoaded = false ;
143199 }
144200
145201 download ( download_type : SupportedOutputs ) {
@@ -154,6 +210,7 @@ export class EditorComponent implements OnDestroy, OnInit, AfterViewInit {
154210 this . editorService . slots ,
155211 this . readalong ,
156212 "Editor" , //from
213+ this . wcStylingService ,
157214 ) ;
158215 } else {
159216 this . toastr . error ( $localize `Download failed.` , $localize `Sorry!` , {
@@ -216,10 +273,14 @@ export class EditorComponent implements OnDestroy, OnInit, AfterViewInit {
216273 }
217274
218275 async loadRasFile ( file : File | Blob ) {
276+ //reset css
277+ this . wcStylingService . $wcStyleInput . next ( "" ) ;
278+ this . wcStylingService . $wcStyleFonts . next ( "" ) ;
219279 const text = await file . text ( ) ;
220280 const readalong = await this . parseReadalong ( text ) ;
221281 this . loadAudioIntoWavesurferElement ( ) ;
222282 this . renderReadalong ( readalong ) ;
283+ this . rasFileIsLoaded = true ;
223284 }
224285
225286 async renderReadalong ( readalongBody : string | undefined ) {
@@ -259,6 +320,12 @@ export class EditorComponent implements OnDestroy, OnInit, AfterViewInit {
259320 // Make Editable
260321 rasElement . setAttribute ( "mode" , "EDIT" ) ;
261322 this . readalong = rasElement ;
323+ //set custom fonts
324+ if ( this . wcStylingService . $wcStyleFonts . getValue ( ) . length ) {
325+ this . readalong . addCustomFont (
326+ this . wcStylingService . $wcStyleFonts . getValue ( ) ,
327+ ) ;
328+ }
262329 const currentWord$ = await this . readalong . getCurrentWord ( ) ;
263330 const alignments = await this . readalong . getAlignments ( ) ;
264331 // Subscribe to the current word of the readalong and center the wavesurfer element on it
@@ -359,6 +426,34 @@ export class EditorComponent implements OnDestroy, OnInit, AfterViewInit {
359426 this . createSegments ( this . editorService . rasControl$ . value ) ;
360427 }
361428
429+ // stylesheet linked
430+
431+ const css = element . getAttribute ( "css-url" ) ;
432+
433+ if ( css !== null && css . length > 0 ) {
434+ if ( css . startsWith ( "data:text/css;base64," ) ) {
435+ this . wcStylingService . $wcStyleInput . next (
436+ this . b64Service . b64_to_utf8 ( css . substring ( css . indexOf ( "," ) + 1 ) ) ,
437+ ) ;
438+ } else {
439+ const reply = await fetch ( css ) ;
440+ // Did that work? Great!
441+ if ( reply . ok ) {
442+ reply . text ( ) . then ( ( cssText ) => {
443+ this . wcStylingService . $wcStyleInput . next ( cssText ) ;
444+ } ) ;
445+ }
446+ }
447+ } else {
448+ this . wcStylingService . $wcStyleInput . next ( "" ) ;
449+ }
450+ //check for custom fonts
451+ const customFont = readalong . querySelector ( "#ra-wc-custom-font" ) ;
452+ if ( customFont !== null ) {
453+ this . wcStylingService . $wcStyleFonts . next ( customFont . innerHTML ) ;
454+ } else {
455+ this . wcStylingService . $wcStyleFonts . next ( "" ) ;
456+ }
362457 return readalong . querySelector ( "body" ) ?. innerHTML ;
363458 }
364459
@@ -460,4 +555,28 @@ export class EditorComponent implements OnDestroy, OnInit, AfterViewInit {
460555 ] ) ;
461556 this . shepherdService . start ( ) ;
462557 }
558+ async updateWCStyle ( $event : string ) {
559+ this . readalong ?. setCss (
560+ `data:text/css;base64,${ this . b64Service . utf8_to_b64 ( $event ?? "" ) } ` ,
561+ ) ;
562+ }
563+ async addWCCustomFont ( $font : string ) {
564+ this . readalong ?. addCustomFont ( $font ) ;
565+ }
566+ resetStyleWindowSize ( ) {
567+ const styleEle = this . styleElement ?. styleSection
568+ . nativeElement as HTMLElement ;
569+ const readAlong = this . readalongContainerElement
570+ ?. nativeElement as HTMLElement ;
571+
572+ if ( window . innerWidth > 1199 ) {
573+ styleEle . style . width = this . styleElement . collapsed$ . value
574+ ? `65vh`
575+ : "calc(30vw - 50px)" ;
576+ readAlong . style . width = `70vw` ;
577+ } else {
578+ styleEle . style . width = `95vw` ;
579+ readAlong . style . width = `95vw` ;
580+ }
581+ }
463582}
0 commit comments