From 2873a53efd8913b6b5fbf305320f88731cd07771 Mon Sep 17 00:00:00 2001 From: lutangar Date: Tue, 30 Aug 2022 17:13:26 +0200 Subject: Set scroll position at top of the textarea when opening the subtitle editor. ## Description This set the position of the scrollbar at the top of the textarea when opening the __subtitle editor__. Previously the textarea scroll position was at the bottom of the textarea which doesn't make much sense when you want to edit a subtitle : you most likely want to edit the beginning of the subtitle first. This also set the caret position on the first character. ## Design decision I had to use a *component approach* instead of an `` for the edition modal because the `@viewChild` directive doesn't work for elements __inside__ an ``. I needed the `viewChild` directive to get an `ElementRef` of the `textarea`. > See the following issue and its workaround : > - https://github.com/valor-software/ngx-bootstrap/issues/3825 > - https://stackblitz.com/edit/angular-t5dfp7 > - https://medium.com/@izzatnadiri/how-to-pass-data-to-and-receive-from-ng-bootstrap-modals-916f2ad5d66e ## Related issues Closes [peertube-plugin-transcription/#39](https://gitlab.com/apps_education/peertube/plugin-transcription/-/issues/39) --- ...video-caption-edit-modal-content.component.html | 34 ++++++++ ...video-caption-edit-modal-content.component.scss | 4 + .../video-caption-edit-modal-content.component.ts | 91 ++++++++++++++++++++++ .../video-caption-edit-modal.component.html | 36 --------- .../video-caption-edit-modal.component.scss | 4 - .../video-caption-edit-modal.component.ts | 83 -------------------- .../+video-edit/shared/video-edit.component.html | 9 +-- .../+video-edit/shared/video-edit.component.ts | 14 +++- .../+video-edit/shared/video-edit.module.ts | 4 +- 9 files changed, 143 insertions(+), 136 deletions(-) create mode 100644 client/src/app/+videos/+video-edit/shared/video-caption-edit-modal-content/video-caption-edit-modal-content.component.html create mode 100644 client/src/app/+videos/+video-edit/shared/video-caption-edit-modal-content/video-caption-edit-modal-content.component.scss create mode 100644 client/src/app/+videos/+video-edit/shared/video-caption-edit-modal-content/video-caption-edit-modal-content.component.ts delete mode 100644 client/src/app/+videos/+video-edit/shared/video-caption-edit-modal/video-caption-edit-modal.component.html delete mode 100644 client/src/app/+videos/+video-edit/shared/video-caption-edit-modal/video-caption-edit-modal.component.scss delete mode 100644 client/src/app/+videos/+video-edit/shared/video-caption-edit-modal/video-caption-edit-modal.component.ts (limited to 'client/src/app') diff --git a/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal-content/video-caption-edit-modal-content.component.html b/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal-content/video-caption-edit-modal-content.component.html new file mode 100644 index 000000000..e8079c74e --- /dev/null +++ b/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal-content/video-caption-edit-modal-content.component.html @@ -0,0 +1,34 @@ + + + + + + + diff --git a/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal-content/video-caption-edit-modal-content.component.scss b/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal-content/video-caption-edit-modal-content.component.scss new file mode 100644 index 000000000..bd96f2b7a --- /dev/null +++ b/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal-content/video-caption-edit-modal-content.component.scss @@ -0,0 +1,4 @@ +.caption-textarea { + min-height: 600px; +} + diff --git a/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal-content/video-caption-edit-modal-content.component.ts b/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal-content/video-caption-edit-modal-content.component.ts new file mode 100644 index 000000000..f33353d36 --- /dev/null +++ b/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal-content/video-caption-edit-modal-content.component.ts @@ -0,0 +1,91 @@ +import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' +import { VIDEO_CAPTION_FILE_CONTENT_VALIDATOR } from '@app/shared/form-validators/video-captions-validators' +import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' +import { VideoCaptionEdit, VideoCaptionService, VideoCaptionWithPathEdit } from '@app/shared/shared-main' +import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap' +import { HTMLServerConfig, VideoConstant } from '@shared/models' +import { ServerService } from '../../../../core' + +/** + * https://github.com/valor-software/ngx-bootstrap/issues/3825 + * https://stackblitz.com/edit/angular-t5dfp7 + * https://medium.com/@izzatnadiri/how-to-pass-data-to-and-receive-from-ng-bootstrap-modals-916f2ad5d66e + */ +@Component({ + selector: 'my-video-caption-edit-modal-content', + styleUrls: [ './video-caption-edit-modal-content.component.scss' ], + templateUrl: './video-caption-edit-modal-content.component.html' +}) + +export class VideoCaptionEditModalContentComponent extends FormReactive implements OnInit { + @Input() videoCaption: VideoCaptionWithPathEdit + @Input() serverConfig: HTMLServerConfig + + @Output() captionEdited = new EventEmitter() + + @ViewChild('textarea', { static: true }) textarea!: ElementRef + + videoCaptionLanguages: VideoConstant[] = [] + + constructor ( + protected openedModal: NgbActiveModal, + protected formValidatorService: FormValidatorService, + private modalService: NgbModal, + private videoCaptionService: VideoCaptionService, + private serverService: ServerService + ) { + super() + } + + ngOnInit () { + this.serverService.getVideoLanguages().subscribe(languages => this.videoCaptionLanguages = languages) + + this.buildForm({ captionFileContent: VIDEO_CAPTION_FILE_CONTENT_VALIDATOR }) + + this.loadCaptionContent() + } + + loadCaptionContent () { + const { captionPath } = this.videoCaption + if (!captionPath) return + + this.videoCaptionService.getCaptionContent({ captionPath }) + .subscribe(res => { + this.form.patchValue({ + captionFileContent: res + }) + this.resetTextarea() + }) + } + + resetTextarea () { + this.textarea.nativeElement.scrollTop = 0 + this.textarea.nativeElement.selectionStart = 0 + this.textarea.nativeElement.selectionEnd = 0 + } + + hide () { + this.openedModal.close() + } + + cancel () { + this.hide() + } + + updateCaption () { + const format = 'vtt' + const languageId = this.videoCaption.language.id + const languageObject = this.videoCaptionLanguages.find(l => l.id === languageId) + + this.captionEdited.emit({ + language: languageObject, + captionfile: new File([ this.form.value['captionFileContent'] ], `${languageId}.${format}`, { + type: 'text/vtt', + lastModified: Date.now() + }), + action: 'UPDATE' + }) + + this.hide() + } +} diff --git a/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal/video-caption-edit-modal.component.html b/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal/video-caption-edit-modal.component.html deleted file mode 100644 index be6f676c2..000000000 --- a/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal/video-caption-edit-modal.component.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - diff --git a/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal/video-caption-edit-modal.component.scss b/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal/video-caption-edit-modal.component.scss deleted file mode 100644 index bd96f2b7a..000000000 --- a/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal/video-caption-edit-modal.component.scss +++ /dev/null @@ -1,4 +0,0 @@ -.caption-textarea { - min-height: 600px; -} - diff --git a/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal/video-caption-edit-modal.component.ts b/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal/video-caption-edit-modal.component.ts deleted file mode 100644 index f74f3c5ea..000000000 --- a/client/src/app/+videos/+video-edit/shared/video-caption-edit-modal/video-caption-edit-modal.component.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' -import { VIDEO_CAPTION_FILE_CONTENT_VALIDATOR } from '@app/shared/form-validators/video-captions-validators' -import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' -import { VideoCaptionEdit, VideoCaptionService, VideoCaptionWithPathEdit } from '@app/shared/shared-main' -import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap' -import { HTMLServerConfig, VideoConstant } from '@shared/models' -import { ServerService } from '../../../../core' - -@Component({ - selector: 'my-video-caption-edit-modal', - styleUrls: [ './video-caption-edit-modal.component.scss' ], - templateUrl: './video-caption-edit-modal.component.html' -}) - -export class VideoCaptionEditModalComponent extends FormReactive implements OnInit { - @Input() videoCaption: VideoCaptionWithPathEdit - @Input() serverConfig: HTMLServerConfig - - @Output() captionEdited = new EventEmitter() - - @ViewChild('modal', { static: true }) modal: ElementRef - - videoCaptionLanguages: VideoConstant[] = [] - private openedModal: NgbModalRef - - constructor ( - protected formValidatorService: FormValidatorService, - private modalService: NgbModal, - private videoCaptionService: VideoCaptionService, - private serverService: ServerService - ) { - super() - } - - ngOnInit () { - this.serverService.getVideoLanguages().subscribe(languages => this.videoCaptionLanguages = languages) - - this.buildForm({ captionFileContent: VIDEO_CAPTION_FILE_CONTENT_VALIDATOR }) - - this.loadCaptionContent() - } - - loadCaptionContent () { - const { captionPath } = this.videoCaption - if (!captionPath) return - - this.videoCaptionService.getCaptionContent({ captionPath }) - .subscribe(res => { - this.form.patchValue({ - captionFileContent: res - }) - }) - } - - show () { - this.openedModal = this.modalService.open(this.modal, { centered: true, keyboard: false }) - } - - hide () { - this.openedModal.close() - } - - cancel () { - this.hide() - } - - updateCaption () { - const format = 'vtt' - const languageId = this.videoCaption.language.id - const languageObject = this.videoCaptionLanguages.find(l => l.id === languageId) - - this.captionEdited.emit({ - language: languageObject, - captionfile: new File([ this.form.value['captionFileContent'] ], `${languageId}.${format}`, { - type: 'text/vtt', - lastModified: Date.now() - }), - action: 'UPDATE' - }) - - this.hide() - } -} diff --git a/client/src/app/+videos/+video-edit/shared/video-edit.component.html b/client/src/app/+videos/+video-edit/shared/video-edit.component.html index de126bdf7..7be5a3736 100644 --- a/client/src/app/+videos/+video-edit/shared/video-edit.component.html +++ b/client/src/app/+videos/+video-edit/shared/video-edit.component.html @@ -185,7 +185,7 @@
Already uploaded on {{ videoCaption.updatedAt | date }} ✔
- Edit + Edit Delete @@ -212,13 +212,6 @@ Cancel deletion - - diff --git a/client/src/app/+videos/+video-edit/shared/video-edit.component.ts b/client/src/app/+videos/+video-edit/shared/video-edit.component.ts index 99f8c9034..0275f66f5 100644 --- a/client/src/app/+videos/+video-edit/shared/video-edit.component.ts +++ b/client/src/app/+videos/+video-edit/shared/video-edit.component.ts @@ -35,10 +35,11 @@ import { } from '@shared/models' import { I18nPrimengCalendarService } from './i18n-primeng-calendar.service' import { VideoCaptionAddModalComponent } from './video-caption-add-modal.component' -import { VideoCaptionEditModalComponent } from './video-caption-edit-modal/video-caption-edit-modal.component' +import { VideoCaptionEditModalContentComponent } from './video-caption-edit-modal-content/video-caption-edit-modal-content.component' import { VideoEditType } from './video-edit.type' import { VideoSource } from '@shared/models/videos/video-source' import { logger } from '@root-helpers/logger' +import { NgbModal } from '@ng-bootstrap/ng-bootstrap' type VideoLanguages = VideoConstant & { group?: string } type PluginField = { @@ -70,7 +71,6 @@ export class VideoEditComponent implements OnInit, OnDestroy { @Input() liveVideo: LiveVideo @ViewChild('videoCaptionAddModal', { static: true }) videoCaptionAddModal: VideoCaptionAddModalComponent - @ViewChild('videoCaptionEditModal', { static: true }) editCaptionModal: VideoCaptionEditModalComponent @Output() formBuilt = new EventEmitter() @Output() pluginFieldsAdded = new EventEmitter() @@ -128,7 +128,8 @@ export class VideoEditComponent implements OnInit, OnDestroy { private i18nPrimengCalendarService: I18nPrimengCalendarService, private ngZone: NgZone, private hooks: HooksService, - private cd: ChangeDetectorRef + private cd: ChangeDetectorRef, + private modalService: NgbModal ) { this.calendarTimezone = this.i18nPrimengCalendarService.getTimezone() this.calendarDateFormat = this.i18nPrimengCalendarService.getDateFormat() @@ -286,6 +287,13 @@ export class VideoEditComponent implements OnInit, OnDestroy { this.videoCaptionAddModal.show() } + openEditCaptionModal (videoCaption: VideoCaptionWithPathEdit) { + const modalRef = this.modalService.open(VideoCaptionEditModalContentComponent, { centered: true, keyboard: false }) + modalRef.componentInstance.videoCaption = videoCaption + modalRef.componentInstance.serverConfig = this.serverConfig + modalRef.componentInstance.captionEdited.subscribe(this.onCaptionEdited.bind(this)) + } + isSaveReplayEnabled () { return this.serverConfig.live.allowReplay } diff --git a/client/src/app/+videos/+video-edit/shared/video-edit.module.ts b/client/src/app/+videos/+video-edit/shared/video-edit.module.ts index 4e8767364..d463bf633 100644 --- a/client/src/app/+videos/+video-edit/shared/video-edit.module.ts +++ b/client/src/app/+videos/+video-edit/shared/video-edit.module.ts @@ -6,7 +6,7 @@ import { SharedMainModule } from '@app/shared/shared-main' import { SharedVideoLiveModule } from '@app/shared/shared-video-live' import { I18nPrimengCalendarService } from './i18n-primeng-calendar.service' import { VideoCaptionAddModalComponent } from './video-caption-add-modal.component' -import { VideoCaptionEditModalComponent } from './video-caption-edit-modal/video-caption-edit-modal.component' +import { VideoCaptionEditModalContentComponent } from './video-caption-edit-modal-content/video-caption-edit-modal-content.component' import { VideoEditComponent } from './video-edit.component' @NgModule({ @@ -22,7 +22,7 @@ import { VideoEditComponent } from './video-edit.component' declarations: [ VideoEditComponent, VideoCaptionAddModalComponent, - VideoCaptionEditModalComponent + VideoCaptionEditModalContentComponent ], exports: [ -- cgit v1.2.3