Optimize caption edit modal
This commit is contained in:
parent
6e2f86e1b3
commit
857507dd1d
|
@ -42,72 +42,78 @@
|
|||
</div>
|
||||
|
||||
<div class="text-start segments pe-2 ps-2" [hidden]="rawEdition">
|
||||
<div class="pt-1 pb-1 mb-3" *ngFor="let segment of segments">
|
||||
@if (segmentToUpdate === segment) {
|
||||
<div role="form">
|
||||
<div class="d-flex flex-wrap ">
|
||||
<div>
|
||||
<label class="visually-hidden" i18n for="segmentStart">Segment start timestamp</label>
|
||||
@for (segment of segments; track segment.id) {
|
||||
<div class="pt-1 pb-1 mb-3">
|
||||
@if (segmentToUpdate === segment) {
|
||||
<div role="form">
|
||||
<div class="d-flex flex-wrap ">
|
||||
<div>
|
||||
<label class="visually-hidden" i18n for="segmentStart">Segment start timestamp</label>
|
||||
|
||||
<my-timestamp-input
|
||||
class="me-1"
|
||||
inputName="segmentStart" [disableBorder]="false" [maxTimestamp]="publishedVideo.duration * 1000" mask="99:99:99.999"
|
||||
[(ngModel)]="segment.startMs" [parser]="timestampParser" [formatter]="timestampFormatter"
|
||||
></my-timestamp-input>
|
||||
<my-timestamp-input
|
||||
class="me-1"
|
||||
inputName="segmentStart" [disableBorder]="false" [maxTimestamp]="publishedVideo.duration * 1000" mask="99:99:99.999"
|
||||
[(ngModel)]="segment.startMs" [parser]="timestampParser" [formatter]="timestampFormatter"
|
||||
></my-timestamp-input>
|
||||
|
||||
<my-button *ngIf="publishedVideo" icon="clock-arrow-down" i18n-title title="Use video current time as start time" (click)="videoTimeForSegmentStart(segment)">
|
||||
</my-button>
|
||||
<my-button *ngIf="publishedVideo" icon="clock-arrow-down" i18n-title title="Use video current time as start time" (click)="videoTimeForSegmentStart(segment)">
|
||||
</my-button>
|
||||
</div>
|
||||
|
||||
<my-global-icon class="d-inline-block ms-2 me-2" iconName="move-right"></my-global-icon>
|
||||
|
||||
<div>
|
||||
<label class="visually-hidden" i18n for="segmentEnd">Segment end timestamp</label>
|
||||
|
||||
<my-timestamp-input
|
||||
class="me-1"
|
||||
inputName="segmentEnd" [disableBorder]="false" [maxTimestamp]="publishedVideo.duration * 1000" mask="99:99:99.999"
|
||||
[(ngModel)]="segment.endMs" [parser]="timestampParser" [formatter]="timestampFormatter"
|
||||
></my-timestamp-input>
|
||||
|
||||
<my-button *ngIf="publishedVideo" icon="clock-arrow-down" i18n-title title="Use video current time as end time" (click)="videoTimeForSegmentEnd(segment)">
|
||||
</my-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<my-global-icon class="d-inline-block ms-2 me-2" iconName="move-right"></my-global-icon>
|
||||
<div class="d-flex mt-2">
|
||||
<div class="form-group w-100">
|
||||
<label class="visually-hidden" i18n for="segment-edition">Segment end timestamp</label>
|
||||
|
||||
<div>
|
||||
<label class="visually-hidden" i18n for="segmentEnd">Segment end timestamp</label>
|
||||
<textarea id="segment-edition" name="segment-edition" class="form-control fs-7" [(ngModel)]="segment.text"></textarea>
|
||||
|
||||
<my-timestamp-input
|
||||
class="me-1"
|
||||
inputName="segmentEnd" [disableBorder]="false" [maxTimestamp]="publishedVideo.duration * 1000" mask="99:99:99.999"
|
||||
[(ngModel)]="segment.endMs" [parser]="timestampParser" [formatter]="timestampFormatter"
|
||||
></my-timestamp-input>
|
||||
<div *ngIf="segmentEditionError" class="form-error" role="alert">{{ segmentEditionError }}</div>
|
||||
</div>
|
||||
|
||||
<my-button *ngIf="publishedVideo" icon="clock-arrow-down" i18n-title title="Use video current time as end time" (click)="videoTimeForSegmentEnd(segment)">
|
||||
</my-button>
|
||||
<div class="d-flex flex-column ms-3">
|
||||
<my-button i18n-title title="Save" icon="tick" (click)="onEditionSaved(segment)"></my-button>
|
||||
<my-button class="mt-3" i18n-title title="Revert" icon="undo" (click)="onEditionCanceled(segment)"></my-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex mt-2">
|
||||
<div class="form-group w-100">
|
||||
<label class="visually-hidden" i18n for="segment-edition">Segment end timestamp</label>
|
||||
|
||||
<textarea id="segment-edition" name="segment-edition" class="form-control fs-7" [(ngModel)]="segment.text"></textarea>
|
||||
|
||||
<div *ngIf="segmentEditionError" class="form-error" role="alert">{{ segmentEditionError }}</div>
|
||||
} @else {
|
||||
<div class="d-flex">
|
||||
<div
|
||||
class="flex-grow-1 segment-text ps-1 pe-1" role="button" tabindex="0" i18n-title title="Jump to this segment"
|
||||
(keyup.enter)="onSegmentClick($event, segment)" (click)="onSegmentClick($event, segment)"
|
||||
[ngClass]="{ active: segment === activeSegment }"
|
||||
>
|
||||
<strong class="segment-start me-2 d-block">{{ segment.startFormatted }} -> {{ segment.endFormatted }}</strong>
|
||||
<span class="segment-text fs-7">{{ segment.text }}</span>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-column ms-3">
|
||||
<my-button i18n-title title="Save" icon="tick" (click)="onEditionSaved(segment)"></my-button>
|
||||
<my-button class="mt-3" i18n-title title="Revert" icon="undo" (click)="onEditionCanceled(segment)"></my-button>
|
||||
</div>
|
||||
<div class="d-flex flex-column ms-3" [ngClass]="{ 'opacity-0': !!segmentToUpdate }">
|
||||
@defer (on viewport) {
|
||||
<my-edit-button i18n-title title="Edit this segment" (click)="updateSegment(segment)"></my-edit-button>
|
||||
<my-delete-button class="mt-1" i18n-title title="Delete this segment" (click)="deleteSegment(segment)"></my-delete-button>
|
||||
} @placeholder {
|
||||
<div style="height: 100%; width: 40px"></div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="d-flex">
|
||||
<div
|
||||
class="flex-grow-1 segment-text ps-1 pe-1" role="button" tabindex="0" i18n-title title="Jump to this segment"
|
||||
(keyup.enter)="onSegmentClick($event, segment)" (click)="onSegmentClick($event, segment)"
|
||||
[ngClass]="getSegmentClasses(segment)"
|
||||
>
|
||||
<strong class="segment-start me-2 d-block">{{ segment.startFormatted }} -> {{ segment.endFormatted }}</strong>
|
||||
<span class="segment-text fs-7" [innerHTML]="segment.text | nl2br"></span>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-column ms-3" [ngClass]="{ 'opacity-0': !!segmentToUpdate }">
|
||||
<my-edit-button i18n-title title="Edit this segment" (click)="updateSegment(segment)"></my-edit-button>
|
||||
<my-delete-button class="mt-1" i18n-title title="Delete this segment" (click)="deleteSegment(segment)"></my-delete-button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
}
|
||||
|
||||
.segment-text {
|
||||
white-space: pre-wrap;
|
||||
|
||||
&.active,
|
||||
&:hover {
|
||||
background: pvar(--mainBackgroundHoverColor);
|
||||
|
|
|
@ -330,13 +330,9 @@ export class VideoCaptionEditModalContentComponent extends FormReactive implemen
|
|||
this.openedModal.close()
|
||||
}
|
||||
|
||||
getSegmentClasses (segment: Segment) {
|
||||
return { active: this.activeSegment === segment, ['segment-' + segment.id]: true }
|
||||
}
|
||||
|
||||
private scrollToSegment (segment: Segment) {
|
||||
setTimeout(() => {
|
||||
const element = document.querySelector<HTMLElement>('.segment-' + segment.id)
|
||||
const element = document.querySelector<HTMLElement>(`.segments > div:nth-child(${parseInt(segment.id) + 1})`)
|
||||
if (!element) return
|
||||
|
||||
element.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, booleanAttribute } from '@angular/core'
|
||||
import { NgClass, NgIf, NgTemplateOutlet } from '@angular/common'
|
||||
import { ChangeDetectionStrategy, Component, Input, OnChanges, booleanAttribute } from '@angular/core'
|
||||
import { RouterLink } from '@angular/router'
|
||||
import { GlobalIconName } from '@app/shared/shared-icons/global-icon.component'
|
||||
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { GlobalIconComponent } from '../../shared-icons/global-icon.component'
|
||||
import { LoaderComponent } from '../common/loader.component'
|
||||
import { RouterLink } from '@angular/router'
|
||||
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { NgIf, NgClass, NgTemplateOutlet } from '@angular/common'
|
||||
|
||||
@Component({
|
||||
selector: 'my-button',
|
||||
|
@ -15,7 +15,7 @@ import { NgIf, NgClass, NgTemplateOutlet } from '@angular/common'
|
|||
imports: [ NgIf, NgClass, NgbTooltip, NgTemplateOutlet, RouterLink, LoaderComponent, GlobalIconComponent ]
|
||||
})
|
||||
|
||||
export class ButtonComponent implements OnInit, OnChanges {
|
||||
export class ButtonComponent implements OnChanges {
|
||||
@Input() label = ''
|
||||
@Input() theme: 'orange' | 'grey' = 'grey'
|
||||
@Input() icon: GlobalIconName
|
||||
|
@ -27,15 +27,13 @@ export class ButtonComponent implements OnInit, OnChanges {
|
|||
|
||||
classes: { [id: string]: boolean } = {}
|
||||
|
||||
ngOnInit () {
|
||||
this.buildClasses()
|
||||
}
|
||||
|
||||
ngOnChanges () {
|
||||
this.buildClasses()
|
||||
}
|
||||
|
||||
private buildClasses () {
|
||||
console.log('build classes')
|
||||
|
||||
this.classes = {
|
||||
'peertube-button': !this.ptRouterLink,
|
||||
'peertube-button-link': !!this.ptRouterLink,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, Input, OnInit } from '@angular/core'
|
||||
import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core'
|
||||
import { ButtonComponent } from './button.component'
|
||||
|
||||
@Component({
|
||||
|
@ -11,15 +11,16 @@ import { ButtonComponent } from './button.component'
|
|||
></my-button>
|
||||
`,
|
||||
standalone: true,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [ ButtonComponent ]
|
||||
})
|
||||
export class DeleteButtonComponent implements OnInit {
|
||||
export class DeleteButtonComponent implements OnChanges {
|
||||
@Input() label: string
|
||||
@Input() title: string
|
||||
@Input() responsiveLabel = false
|
||||
@Input() disabled: boolean
|
||||
|
||||
ngOnInit () {
|
||||
ngOnChanges () {
|
||||
if (this.label === undefined && !this.title) {
|
||||
this.title = $localize`Delete`
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, Input, OnInit } from '@angular/core'
|
||||
import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core'
|
||||
import { ButtonComponent } from './button.component'
|
||||
|
||||
@Component({
|
||||
|
@ -10,15 +10,16 @@ import { ButtonComponent } from './button.component'
|
|||
></my-button>
|
||||
`,
|
||||
standalone: true,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [ ButtonComponent ]
|
||||
})
|
||||
export class EditButtonComponent implements OnInit {
|
||||
export class EditButtonComponent implements OnChanges {
|
||||
@Input() label: string
|
||||
@Input() title: string
|
||||
@Input() ptRouterLink: string[] | string = []
|
||||
@Input() responsiveLabel = false
|
||||
|
||||
ngOnInit () {
|
||||
ngOnChanges () {
|
||||
// <my-edit-button /> No label
|
||||
if (this.label === undefined && !this.title) {
|
||||
this.title = $localize`Update`
|
||||
|
|
Loading…
Reference in New Issue