diff --git a/apps/octra/src/app/core/component/transcr-editor/config/te.config.ts b/apps/octra/src/app/core/component/transcr-editor/config/te.config.ts index c5189153a..76f473321 100644 --- a/apps/octra/src/app/core/component/transcr-editor/config/te.config.ts +++ b/apps/octra/src/app/core/component/transcr-editor/config/te.config.ts @@ -19,4 +19,10 @@ export class TranscrEditorConfig { boundary: false, }; public highlightingEnabled = false; + + constructor(partial?: Partial) { + if (partial) { + Object.assign(partial); + } + } } diff --git a/apps/octra/src/app/core/component/transcr-editor/transcr-editor.component.ts b/apps/octra/src/app/core/component/transcr-editor/transcr-editor.component.ts index afe7d1118..46e87cee5 100644 --- a/apps/octra/src/app/core/component/transcr-editor/transcr-editor.component.ts +++ b/apps/octra/src/app/core/component/transcr-editor/transcr-editor.component.ts @@ -8,6 +8,7 @@ import { HostListener, Input, OnChanges, + OnDestroy, OnInit, Output, Renderer2, @@ -57,12 +58,12 @@ declare let document: any; selector: 'octra-transcr-editor', templateUrl: './transcr-editor.component.html', styleUrls: ['./transcr-editor.component.scss'], - providers: [TranscrEditorConfig], + providers: [], changeDetection: ChangeDetectionStrategy.OnPush, }) export class TranscrEditorComponent extends DefaultComponent - implements OnChanges, AfterViewInit, OnInit + implements OnChanges, AfterViewInit, OnInit, OnDestroy { @Output() loaded: EventEmitter = new EventEmitter(); @Output() onkeyup: EventEmitter = new EventEmitter(); @@ -654,10 +655,10 @@ export class TranscrEditorComponent this.subscriptionManager.removeByTag('typing_change'); this.subscribe( this.internalTyping, - (status) => { + async (status) => { if (status === 'stopped') { - this.validate(); - this.initPopover(); + await this.validate(); + await this.initPopover(); } this.typing.emit(status); @@ -667,6 +668,7 @@ export class TranscrEditorComponent } ngOnInit() { + this.subscriptionManager.removeByTag('afterInit'); this.subscribe(this.annotationStoreService.guidelines$, { next: (guidelines) => { this.guidelines = guidelines?.selected?.json; @@ -674,6 +676,10 @@ export class TranscrEditorComponent }); } + override ngOnDestroy() { + super.ngOnDestroy(); + } + async ngOnChanges(obj: SimpleChanges) { let renew = false; if ( @@ -705,7 +711,7 @@ export class TranscrEditorComponent obj['transcript'].currentValue !== undefined && !obj['transcript'].firstChange ) { - await this.setTranscript(obj['transcript'].currentValue); + //await this.setTranscript(obj['transcript'].currentValue); } if ( @@ -1134,8 +1140,8 @@ export class TranscrEditorComponent let code = this._rawText; // insert selection placeholders if (!focusAtEnd) { - const startMarker = '[[[sel-start]]][[[/sel-start]]]'; - const endMarker = '[[[sel-end]]][[[/sel-end]]]'; + const startMarker = '[[[sel-start/]]]'; + const endMarker = '[[[sel-end/]]]'; code = this.lastCursorPosition!.endMarker !== undefined && this._textSelection.end >= this._textSelection.start @@ -1148,23 +1154,21 @@ export class TranscrEditorComponent code = insertString(code, this._textSelection.start, startMarker); } - code = this.annotationStoreService.underlineTextRed( - code, - this.annotationStoreService.validate(code) - ); + const validation = this.annotationStoreService.validate(code); + code = this.annotationStoreService.underlineTextRed(code, validation); code = await this.annotationStoreService.rawToHTML(code); if (!focusAtEnd) { code = code.replace( - /([\s ]+)(<\/sel-start><\/sel-end><\/p>)?$/g, + /([\s ]+)(<\/p>)?$/g, ' $2' ); code = code.replace( - /<\/sel-start>/g, + //g, this.lastCursorPosition!.startMarker ); code = code.replace( - /<\/sel-end>/g, + //g, this.lastCursorPosition!.endMarker ? this.lastCursorPosition!.endMarker : '' @@ -1435,8 +1439,12 @@ export class TranscrEditorComponent this.joditComponent.jodit.value = await this.annotationStoreService.rawToHTML(rawText); - this.validate(); - this.initPopover(); + this.subscribe(timer(500), { + next: async () => { + await this.validate(); + await this.initPopover(); + }, + }); this.asr = { status: 'inactive', @@ -1726,7 +1734,6 @@ export class TranscrEditorComponent } onAfterInit = () => { - this.subscriptionManager.removeByTag('afterInit'); this.subscribe( timer(200), () => { diff --git a/apps/octra/src/app/core/component/transcr-editor/validation-popover/validation-popover.component.scss b/apps/octra/src/app/core/component/transcr-editor/validation-popover/validation-popover.component.scss index 6fd388aa2..d7cc278fb 100644 --- a/apps/octra/src/app/core/component/transcr-editor/validation-popover/validation-popover.component.scss +++ b/apps/octra/src/app/core/component/transcr-editor/validation-popover/validation-popover.component.scss @@ -4,6 +4,7 @@ position: absolute; z-index: 100; display: none; + font-size: 0.85rem; } .card { diff --git a/apps/octra/src/app/core/component/transcr-overview/transcr-overview.component.html b/apps/octra/src/app/core/component/transcr-overview/transcr-overview.component.html index 4a6a92e23..a338502d1 100644 --- a/apps/octra/src/app/core/component/transcr-overview/transcr-overview.component.html +++ b/apps/octra/src/app/core/component/transcr-overview/transcr-overview.component.html @@ -156,13 +156,16 @@

{{ 'g.transcript' | transloco }}

any; @@ -51,6 +51,13 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { return this._textEditor; } + editorConfig: TranscrEditorConfig = new TranscrEditorConfig({ + btnPopover: false + }); + + @ViewChild('transcrEditor', { static: false }) + transcrEditor?: TranscrEditorComponent; + public selectedError: any = ''; public shownSegments: { transcription: { @@ -58,6 +65,7 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { text: string; }; }[] = []; + public transcript = ""; @Input() currentLevel?: OctraAnnotationAnyLevel< OctraAnnotationSegment @@ -69,9 +77,6 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { @Output() segmentclicked: EventEmitter = new EventEmitter(); - @ViewChild('transcrEditor', { static: false }) - transcrEditor?: TranscrEditorComponent; - private subscrmanager: SubscriptionManager; public playAllState: { @@ -150,9 +155,8 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { let resultStr = ''; for (let i = 0; i < this.shownSegments.length; i++) { resultStr += this.shownSegments[i].transcription.html; + found += (this.shownSegments[i].transcription.html.match(/ 0 @@ -544,7 +530,6 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { this.playAllState.icon = 'bi bi-play-fill'; this.cd.markForCheck(); - this.cd.detectChanges(); } else { console.log(`playAll failed`); } @@ -556,7 +541,6 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { ? 'bi bi-stop-fill' : 'bi bi-play-fill'; this.cd.markForCheck(); - this.cd.detectChanges(); const playpos = this.audio.audioManager.createSampleUnit(0); @@ -593,7 +577,6 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { 'bi bi-play-fill'; this.cd.markForCheck(); - this.cd.detectChanges(); this.uiService.addElementFromEvent( 'mouseclick', @@ -629,7 +612,6 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { this.playStateSegments[segmentNumber].state = 'started'; this.playStateSegments[segmentNumber].icon = 'bi bi-stop-fill'; this.cd.markForCheck(); - this.cd.detectChanges(); const startSample = segmentNumber > 0 ? level.items[segmentNumber - 1].time.samples : 0; @@ -637,7 +619,6 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { this.playAllState.currentSegment = segmentNumber; this.cd.markForCheck(); - this.cd.detectChanges(); this.audio.audiomanagers[0].playPosition = this.audio.audiomanagers[0].createSampleUnit(startSample); this.audio.audiomanagers[0] @@ -654,13 +635,11 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { this.playStateSegments[segmentNumber].icon = 'bi bi-play-fill'; this.playAllState.currentSegment = -1; this.cd.markForCheck(); - this.cd.detectChanges(); this.subscrmanager.add( timer(100).subscribe({ next: () => { this.cd.markForCheck(); - this.cd.detectChanges(); resolve(); }, @@ -680,7 +659,6 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { this.playAllState.currentSegment = -1; this.cd.markForCheck(); - this.cd.detectChanges(); resolve(); }) @@ -701,7 +679,6 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { this.stopPlayback() .then(() => { this.cd.markForCheck(); - this.cd.detectChanges(); const startSample = segmentNumber > 0 @@ -735,7 +712,6 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { this.playSegment(segmentNumber) .then(() => { this.cd.markForCheck(); - this.cd.detectChanges(); }) .catch((error) => { console.error(error); @@ -779,7 +755,6 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { this.playAllState.icon = 'bi bi-play-fill'; this.playAllState.currentSegment = -1; this.cd.markForCheck(); - this.cd.detectChanges(); this.playAllState.currentSegment = -1; }) .catch((error) => { @@ -796,7 +771,6 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { this.annotationStoreService.validateAll(); await this.updateSegments(); this.cd.markForCheck(); - this.cd.detectChanges(); } toggleSkipCheckbox() { @@ -811,7 +785,6 @@ export class TranscrOverviewComponent implements OnInit, OnDestroy, OnChanges { this.playStateSegments[this.playAllState.currentSegment].icon = 'bi bi-play-fill'; this.cd.markForCheck(); - this.cd.detectChanges(); } this.audio.audiomanagers[0].stopPlayback().then(resolve).catch(reject); }); diff --git a/apps/octra/src/app/core/store/login-mode/annotation/annotation.store.service.ts b/apps/octra/src/app/core/store/login-mode/annotation/annotation.store.service.ts index 3e8f3567b..8624920c1 100644 --- a/apps/octra/src/app/core/store/login-mode/annotation/annotation.store.service.ts +++ b/apps/octra/src/app/core/store/login-mode/annotation/annotation.store.service.ts @@ -649,82 +649,92 @@ export class AnnotationStoreService { public underlineTextRed(rawtext: string, validation: any[]) { let result = rawtext; - interface Pos { - start: number; - puffer: string; - } + try { + const sPos = rawtext.indexOf('[[[sel-start/]]]'); + const sLen = '[[[sel-start/]]]'.length; - const markerPositions = this.getMarkerPositions(rawtext, this.guidelines); + interface Pos { + start: number; + puffer: string; + } - let insertions: Pos[] = []; + const markerPositions = this.getMarkerPositions(rawtext, this.guidelines); - if (validation.length > 0) { - // prepare insertions - for (const validationElement of validation) { - const foundMarker = markerPositions.find((a) => { - return ( - validationElement.start > a.start && - validationElement.start + validationElement.length < a.end - ); - }); + let insertions: Pos[] = []; - if (foundMarker === undefined) { - let insertStart = insertions.find((val) => { - return val.start === validationElement.start; + if (validation.length > 0) { + // prepare insertions + for (const validationElement of validation) { + const foundMarker = markerPositions.find((a) => { + return ( + validationElement.start > a.start && + validationElement.start + validationElement.length < a.end + ); }); - if (insertStart === undefined) { - insertStart = { - start: validationElement.start, - puffer: + if (foundMarker === undefined) { + let insertStart = insertions.find((val) => { + return val.start === validationElement.start; + }); + + if (insertStart === undefined) { + insertStart = { + start: + sPos < 0 || validationElement.start < sPos + ? validationElement.start + : sPos + sLen + validationElement.start, + puffer: + "[[[span class='val-error' data-errorcode='" + + validationElement.code + + "']]]", + }; + insertions.push(insertStart); + } else { + insertStart.puffer += "[[[span class='val-error' data-errorcode='" + validationElement.code + - "']]]", - }; - insertions.push(insertStart); - } else { - insertStart.puffer += - "[[[span class='val-error' data-errorcode='" + - validationElement.code + - "']]]"; - } + "']]]"; + } - let insertEnd = insertions.find((val) => { - return ( - val.start === validationElement.start + validationElement.length - ); - }); + let insertEnd = insertions.find((val) => { + return ( + val.start === validationElement.start + validationElement.length + ); + }); - if (insertEnd === undefined) { - insertEnd = { - start: insertStart.start + validationElement.length, - puffer: '', - }; - insertEnd.puffer = '[[[/span]]]'; - insertions.push(insertEnd); - } else { - insertEnd.puffer = '[[[/span]]]' + insertEnd.puffer; + if (insertEnd === undefined) { + insertEnd = { + start: insertStart.start + validationElement.length, + puffer: '', + }; + insertEnd.puffer = '[[[/span]]]'; + insertions.push(insertEnd); + } else { + insertEnd.puffer = '[[[/span]]]' + insertEnd.puffer; + } } } - } - insertions = insertions.sort((a: Pos, b: Pos) => { - if (a.start === b.start) { - return 0; - } else if (a.start < b.start) { - return -1; - } - return 1; - }); + insertions = insertions.sort((a: Pos, b: Pos) => { + if (a.start === b.start) { + return 0; + } else if (a.start < b.start) { + return -1; + } + return 1; + }); - let puffer = ''; - for (const insertion of insertions) { - const offset = puffer.length; - const pos = insertion.start; + let puffer = ''; + for (const insertion of insertions) { + const offset = puffer.length; + const pos = insertion.start; - result = insertString(result, pos + offset, insertion.puffer); - puffer += insertion.puffer; + result = insertString(result, pos + offset, insertion.puffer); + puffer += insertion.puffer; + } } + } catch (e) { + console.error(e); } return result; } diff --git a/libs/web-media/src/lib/shortcut-manager.ts b/libs/web-media/src/lib/shortcut-manager.ts index 4bfe96e5b..019bd1461 100644 --- a/libs/web-media/src/lib/shortcut-manager.ts +++ b/libs/web-media/src/lib/shortcut-manager.ts @@ -1,5 +1,5 @@ -import {BrowserInfo} from './browser-info'; -import {HotkeysEvent} from "hotkeys-js"; +import { HotkeysEvent } from 'hotkeys-js'; +import { BrowserInfo } from './browser-info'; /** * wrapper containing KeyboardEvent information with additional data @@ -175,9 +175,9 @@ export class ShortcutManager { } public unregisterItemFromGroup(groupName: string, itemName: string) { - this._shortcuts = this._shortcuts.map(a => { - if(a.name === groupName) { - a.items = a.items.filter(b => b.name !== itemName); + this._shortcuts = this._shortcuts.map((a) => { + if (a.name === groupName) { + a.items = a.items.filter((b) => b.name !== itemName); } return a; }); @@ -314,10 +314,10 @@ export class ShortcutManager { public getShorcutCombination(event: KeyboardEvent) { const keyCode = this.getKeyCode(event); - const alt = this._pressedKeys.alt; - const ctrl = this._pressedKeys.ctrl; + const alt = event.altKey; + const ctrl = event.ctrlKey; const cmd = this._pressedKeys.cmd; - const shift = this._pressedKeys.shift; + const shift = event.shiftKey; let name = this.getNameByEvent(event); if (name === '' && keyCode > -1) {