From f7b4fb4e47e8266320977de38adccaaf5fe70593 Mon Sep 17 00:00:00 2001 From: DavidMockler Date: Tue, 13 Aug 2024 15:24:57 +0100 Subject: [PATCH] work on sentence segmentation preview screen --- .../src/app/core/services/dr-story.service.ts | 3 + .../digital-reader.component.html | 30 ++++ .../digital-reader.component.scss | 32 +++++ .../digital-reader.component.ts | 132 ++++++++++++++---- ngapp/src/app/nav-bar/nav-bar.module.ts | 6 +- 5 files changed, 177 insertions(+), 26 deletions(-) diff --git a/ngapp/src/app/core/services/dr-story.service.ts b/ngapp/src/app/core/services/dr-story.service.ts index d4e4b41cf..20fe0cd55 100644 --- a/ngapp/src/app/core/services/dr-story.service.ts +++ b/ngapp/src/app/core/services/dr-story.service.ts @@ -19,6 +19,8 @@ import { AudioEncoding } from './synthesis.service'; }) export class DigitalReaderStoryService { + public segmentedSentences:Array; + constructor( private http: HttpClient, private router: Router, @@ -137,6 +139,7 @@ export class DigitalReaderStoryService { // reformat sentence segmenter output for use with the segmentation API const sentences:Array = this.reformatExtractedSentences(sentenceTextChunks) + this.segmentedSentences = sentences; const words:Array = await this.tagSentences(sentenceTextChunks) diff --git a/ngapp/src/app/nav-bar/digital-reader/digital-reader.component.html b/ngapp/src/app/nav-bar/digital-reader/digital-reader.component.html index 29852f703..aa0d16e52 100644 --- a/ngapp/src/app/nav-bar/digital-reader/digital-reader.component.html +++ b/ngapp/src/app/nav-bar/digital-reader/digital-reader.component.html @@ -108,6 +108,36 @@ +
+
+
+ {{ i }} {{sent.text}} + +
+ + + + + + +
+
diff --git a/ngapp/src/app/nav-bar/digital-reader/digital-reader.component.scss b/ngapp/src/app/nav-bar/digital-reader/digital-reader.component.scss index 24863d862..ecac4fe2c 100644 --- a/ngapp/src/app/nav-bar/digital-reader/digital-reader.component.scss +++ b/ngapp/src/app/nav-bar/digital-reader/digital-reader.component.scss @@ -146,6 +146,38 @@ input[type="file"] { }*/ +.sentContainer { + margin:auto; + width: 70%; + display:flex; + flex-direction: column; + height: 300px; + overflow-y: scroll; + text-align: left; +} + +/*.sentencePreview { + //min-height: 20px; + min-height: fit-content; +}*/ + +/*.sentencePreview:hover { + background-color: var(--scealai-light-green); +}*/ + +.sentencePreview:focus { + background-color: var(--scealai-cream); + outline: none +} + +.sentenceMerger:hover { + background-color: var(--scealai-light-green); +} + +/*.sentContainer > input[type="text"] { + width:100%; +}*/ + .footerLARA { display: flex; flex-direction: column; diff --git a/ngapp/src/app/nav-bar/digital-reader/digital-reader.component.ts b/ngapp/src/app/nav-bar/digital-reader/digital-reader.component.ts index f04de3875..e358c1bd4 100644 --- a/ngapp/src/app/nav-bar/digital-reader/digital-reader.component.ts +++ b/ngapp/src/app/nav-bar/digital-reader/digital-reader.component.ts @@ -1,8 +1,9 @@ -import { Component, OnInit, Output, EventEmitter } from '@angular/core'; +import { Component, OnInit, Output, EventEmitter, NgZone, ViewChild, ViewEncapsulation } from '@angular/core'; +import { CdkTextareaAutosize} from '@angular/cdk/text-field'; import { TranslationService } from 'app/core/services/translation.service'; import { AuthenticationService } from 'app/core/services/authentication.service'; -import { firstValueFrom, from } from "rxjs"; +import { firstValueFrom, from, take } from "rxjs"; import { User } from "app/core/models/user"; import { UserService } from "app/core/services/user.service"; //import { createClient } from "@supabase/supabase-js" @@ -28,7 +29,8 @@ import { SynthesisService, Voice, voices } from 'app/core/services/synthesis.ser @Component({ selector: 'app-digital-reader', templateUrl: './digital-reader.component.html', - styleUrls: ['./digital-reader.component.scss'] + styleUrls: ['./digital-reader.component.scss'], + encapsulation: ViewEncapsulation.None }) export class DigitalReaderComponent implements OnInit { @@ -54,7 +56,8 @@ export class DigitalReaderComponent implements OnInit { public drStoryService: DigitalReaderStoryService, public http: HttpClient, private dialog: MatDialog, - private synth: SynthesisService,) { + private synth: SynthesisService, + private _ngZone: NgZone,) { this.dialectOptions = [this.ts.l.connacht, this.ts.l.munster, this.ts.l.ulster] //console.log(adminStoryCollectionOpts) @@ -79,6 +82,98 @@ export class DigitalReaderComponent implements OnInit { ]*/ } + updateSentenceNumbers(targetContainer:Element, startNumber:number) { + let tmp = targetContainer; + let number = startNumber; + while (tmp) { + tmp.setAttribute('sentNumber', number.toString()); + (tmp.querySelector('b') as Element).textContent = number.toString() + ' ' // setting the number element + number++; + tmp = tmp.nextElementSibling; + } + } + + test() { + console.log('input event fires anyway!') + } + + splitSentence(event:InputEvent) { + console.log(event) + const target:HTMLInputElement = event.target as HTMLInputElement; + + if (event.inputType==="insertLineBreak") { + event.preventDefault(); + const breakIndex:number = getSelection()?.anchorOffset; + const fullTextContent:string = target.textContent; + if (breakIndex > 0 && breakIndex < fullTextContent.length) { + const textPreSplit:string = fullTextContent?.slice(0, breakIndex); + const textPostSplit:string = fullTextContent?.slice(breakIndex, fullTextContent.length); + + console.log(textPreSplit); + console.log(textPostSplit); + + const localContainer = target.parentElement as Element; + const parentContainer = localContainer.parentElement as Element; + + target.textContent = textPostSplit; + + const newSentenceContainer = document.createElement('div'); + + const mergeButton = document.createElement('button'); + mergeButton.className="sentenceMerger" + mergeButton.textContent="merge" // TODO : change to use translation service + + const newNumberEl = document.createElement('b'); + const sentNumber = localContainer.getAttribute('sentNumber'); + newNumberEl.textContent = sentNumber + ' '; + + const newSentencePreview = document.createElement('span'); + newSentencePreview.textContent = textPreSplit; + newSentencePreview.className = 'sentencePreview'; + newSentencePreview.contentEditable = "plaintext-only" + newSentencePreview.spellcheck = false; + //newSentencePreview.onbeforeinput = this.splitSentence; + + newSentencePreview.addEventListener('beforeinput', (event) => { + this.splitSentence(event); + }) + + newSentenceContainer.setAttribute('sentNumber', sentNumber.toString()) + newSentenceContainer.append(mergeButton); + newSentenceContainer.append(document.createElement('br')) + newSentenceContainer.append(newNumberEl); + newSentenceContainer.append(newSentencePreview); + + //parentContainer.insertBefore(newSentencePreview, target); + parentContainer.insertBefore(newSentenceContainer, localContainer); + + console.log(localContainer); + console.log(sentNumber); + console.log(parseInt(sentNumber)); + this.updateSentenceNumbers(localContainer, parseInt(sentNumber)+1); + + // below was its own function, however was getting some weird errors + /*let tmp = localContainer; + let number = parseInt(sentNumber)+1; + while (tmp) { + tmp.setAttribute('sentNumber', number.toString()); + (tmp.firstChild as Element).textContent = number.toString() + ' ' // setting the number element + number++; + tmp = tmp.nextElementSibling; + }*/ + + } + } else { + console.log('disallowed!') + event.preventDefault(); + } + } + + /*test2(target:HTMLInputElement) { + //(input)="this.style.height = ''; this.style.height = this.scrollHeight +'px'; console.log(this.style)" + target.style.height = target.scrollHeight +'px'; + }*/ + async ngOnInit() { const user = this.auth.getUserDetails(); if (!user) return; @@ -107,6 +202,7 @@ export class DigitalReaderComponent implements OnInit { } + // TODO : Migrate to use queuing API async synthesiseStory(htmlBody:Document, storyId:string) { //const parser = new DOMParser; @@ -168,22 +264,8 @@ export class DigitalReaderComponent implements OnInit { if (res) { if (res.title) { - console.log(res) - - /*let dialects:Array = []; - console.log(res.dialects) - for (const key in res.dialects) { - console.log(key) - console.log(res.dialects[key]) - if (res.dialects[key] === true) - - dialects.push(key) - }*/ - - /*console.log(Array.isArray(dialects) && dialects.length!==0) - console.log(dialects) - console.log(Array.isArray(dialects)) - console.log(dialects.length)*/ + console.log(res) + let collections = [] for (let key in res.collections) { if (res.collections[key] === true) { @@ -215,7 +297,7 @@ export class DigitalReaderComponent implements OnInit { this.storyState = '' return; } - + /* Temporarily commented out for testing if (this.convertedHTMLDoc) { //console.log(this.convertedHTMLDoc) const story = constructJSON(this.convertedHTMLDoc.body) @@ -236,11 +318,11 @@ export class DigitalReaderComponent implements OnInit { this.storyState = '' }, }); - } - /*} else { + }*/ + //} else { //alert(this.ts.l.dialect_required) - this.storyState = '' - }*/ + //this.storyState = '' + //} } else { alert(this.ts.l.title_required); this.storyState = '' diff --git a/ngapp/src/app/nav-bar/nav-bar.module.ts b/ngapp/src/app/nav-bar/nav-bar.module.ts index f05ace30e..5e2596839 100644 --- a/ngapp/src/app/nav-bar/nav-bar.module.ts +++ b/ngapp/src/app/nav-bar/nav-bar.module.ts @@ -10,6 +10,8 @@ import { MatTabsModule } from '@angular/material/tabs'; import { MatButtonModule } from '@angular/material/button'; import { MatDividerModule } from '@angular/material/divider'; import { FormsModule } from '@angular/forms'; +import { MatInputModule } from '@angular/material/input'; +import { MatFormFieldModule } from '@angular/material/form-field'; import { NavBarRoutingModule } from './nav-bar-routing.module'; import { NavBarComponent } from './nav-bar/nav-bar.component'; @@ -64,7 +66,9 @@ import { FiosComponent } from './fios/fios.component'; MatTabsModule, MatButtonModule, MatDividerModule, - FormsModule + FormsModule, + MatInputModule, + MatFormFieldModule ] }) export class NavBarModule { }