mirror of https://github.com/Chocobozzz/PeerTube
Add option to download subtitles in download modal
parent
9b7668f527
commit
8ba9c205ba
|
@ -1,6 +1,17 @@
|
||||||
<ng-template #modal let-hide="close">
|
<ng-template #modal let-hide="close">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h4 i18n class="modal-title">Download video</h4>
|
<h4 i18n class="modal-title">Download
|
||||||
|
<span *ngIf="!videoCaptions" i18n>video</span>
|
||||||
|
<div *ngIf="videoCaptions" ngbDropdown class="d-inline-block">
|
||||||
|
<span id="dropdownDownloadType" ngbDropdownToggle i18n>
|
||||||
|
{{ type }}
|
||||||
|
</span>
|
||||||
|
<div ngbDropdownMenu aria-labelledby="dropdownDownloadType">
|
||||||
|
<button *ngIf="type === 'video'" (click)="switchToType('subtitles')" ngbDropdownItem i18n>subtitles</button>
|
||||||
|
<button *ngIf="type === 'subtitles'" (click)="switchToType('video')" ngbDropdownItem i18n>video</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</h4>
|
||||||
<my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
|
<my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -8,9 +19,12 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="input-group input-group-sm">
|
<div class="input-group input-group-sm">
|
||||||
<div class="input-group-prepend peertube-select-container">
|
<div class="input-group-prepend peertube-select-container">
|
||||||
<select [(ngModel)]="resolutionId">
|
<select *ngIf="type === 'video'" [(ngModel)]="resolutionId">
|
||||||
<option *ngFor="let file of getVideoFiles()" [value]="file.resolution.id">{{ file.resolution.label }}</option>
|
<option *ngFor="let file of getVideoFiles()" [value]="file.resolution.id">{{ file.resolution.label }}</option>
|
||||||
</select>
|
</select>
|
||||||
|
<select *ngIf="type === 'subtitles'" [(ngModel)]="subtitleLanguageId">
|
||||||
|
<option *ngFor="let caption of videoCaptions" [value]="caption.language.id">{{ caption.language.label }}</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<input #urlInput (click)="urlInput.select()" type="text" class="form-control input-sm readonly" readonly [value]="getLink()" />
|
<input #urlInput (click)="urlInput.select()" type="text" class="form-control input-sm readonly" readonly [value]="getLink()" />
|
||||||
<div class="input-group-append">
|
<div class="input-group-append">
|
||||||
|
@ -21,7 +35,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="download-type">
|
<div class="download-type" *ngIf="type === 'video'">
|
||||||
<div class="peertube-radio-container">
|
<div class="peertube-radio-container">
|
||||||
<input type="radio" name="download" id="download-direct" [(ngModel)]="downloadType" value="direct">
|
<input type="radio" name="download" id="download-direct" [(ngModel)]="downloadType" value="direct">
|
||||||
<label i18n for="download-direct">Direct download</label>
|
<label i18n for="download-direct">Direct download</label>
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#dropdownDownloadType {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.download-type {
|
.download-type {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@ import { VideoDetails } from '../../../shared/video/video-details.model'
|
||||||
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
import { AuthService, Notifier } from '@app/core'
|
import { AuthService, Notifier } from '@app/core'
|
||||||
import { VideoPrivacy } from '@shared/models'
|
import { VideoPrivacy, VideoCaption } from '@shared/models'
|
||||||
|
|
||||||
|
type DownloadType = 'video' | 'subtitles'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-video-download',
|
selector: 'my-video-download',
|
||||||
|
@ -15,10 +17,14 @@ export class VideoDownloadComponent {
|
||||||
|
|
||||||
downloadType: 'direct' | 'torrent' = 'torrent'
|
downloadType: 'direct' | 'torrent' = 'torrent'
|
||||||
resolutionId: number | string = -1
|
resolutionId: number | string = -1
|
||||||
|
subtitleLanguageId: string
|
||||||
|
|
||||||
video: VideoDetails
|
video: VideoDetails
|
||||||
|
videoCaptions: VideoCaption[]
|
||||||
activeModal: NgbActiveModal
|
activeModal: NgbActiveModal
|
||||||
|
|
||||||
|
type: DownloadType = 'video'
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private notifier: Notifier,
|
private notifier: Notifier,
|
||||||
private modalService: NgbModal,
|
private modalService: NgbModal,
|
||||||
|
@ -26,22 +32,31 @@ export class VideoDownloadComponent {
|
||||||
private i18n: I18n
|
private i18n: I18n
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
get typeText () {
|
||||||
|
return this.type === 'video'
|
||||||
|
? this.i18n('video')
|
||||||
|
: this.i18n('subtitles')
|
||||||
|
}
|
||||||
|
|
||||||
getVideoFiles () {
|
getVideoFiles () {
|
||||||
if (!this.video) return []
|
if (!this.video) return []
|
||||||
|
|
||||||
return this.video.getFiles()
|
return this.video.getFiles()
|
||||||
}
|
}
|
||||||
|
|
||||||
show (video: VideoDetails) {
|
show (video: VideoDetails, videoCaptions?: VideoCaption[]) {
|
||||||
this.video = video
|
this.video = video
|
||||||
|
this.videoCaptions = videoCaptions && videoCaptions.length ? videoCaptions : undefined
|
||||||
|
|
||||||
this.activeModal = this.modalService.open(this.modal)
|
this.activeModal = this.modalService.open(this.modal)
|
||||||
|
|
||||||
this.resolutionId = this.getVideoFiles()[0].resolution.id
|
this.resolutionId = this.getVideoFiles()[0].resolution.id
|
||||||
|
if (this.videoCaptions) this.subtitleLanguageId = this.videoCaptions[0].language.id
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose () {
|
onClose () {
|
||||||
this.video = undefined
|
this.video = undefined
|
||||||
|
this.videoCaptions = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
download () {
|
download () {
|
||||||
|
@ -50,6 +65,12 @@ export class VideoDownloadComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
getLink () {
|
getLink () {
|
||||||
|
return this.type === 'subtitles' && this.videoCaptions
|
||||||
|
? this.getSubtitlesLink()
|
||||||
|
: this.getVideoLink()
|
||||||
|
}
|
||||||
|
|
||||||
|
getVideoLink () {
|
||||||
// HTML select send us a string, so convert it to a number
|
// HTML select send us a string, so convert it to a number
|
||||||
this.resolutionId = parseInt(this.resolutionId.toString(), 10)
|
this.resolutionId = parseInt(this.resolutionId.toString(), 10)
|
||||||
|
|
||||||
|
@ -72,7 +93,15 @@ export class VideoDownloadComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSubtitlesLink () {
|
||||||
|
return window.location.origin + this.videoCaptions.find(caption => caption.language.id === this.subtitleLanguageId).captionPath
|
||||||
|
}
|
||||||
|
|
||||||
activateCopiedMessage () {
|
activateCopiedMessage () {
|
||||||
this.notifier.success(this.i18n('Copied'))
|
this.notifier.success(this.i18n('Copied'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switchToType (type: DownloadType) {
|
||||||
|
this.type = type
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { VideoReportComponent } from '@app/shared/video/modals/video-report.comp
|
||||||
import { VideoBlacklistComponent } from '@app/shared/video/modals/video-blacklist.component'
|
import { VideoBlacklistComponent } from '@app/shared/video/modals/video-blacklist.component'
|
||||||
import { VideoBlacklistService } from '@app/shared/video-blacklist'
|
import { VideoBlacklistService } from '@app/shared/video-blacklist'
|
||||||
import { ScreenService } from '@app/shared/misc/screen.service'
|
import { ScreenService } from '@app/shared/misc/screen.service'
|
||||||
|
import { VideoCaption } from '@shared/models'
|
||||||
|
|
||||||
export type VideoActionsDisplayType = {
|
export type VideoActionsDisplayType = {
|
||||||
playlist?: boolean
|
playlist?: boolean
|
||||||
|
@ -37,6 +38,7 @@ export class VideoActionsDropdownComponent implements OnChanges {
|
||||||
@ViewChild('videoBlacklistModal', { static: false }) videoBlacklistModal: VideoBlacklistComponent
|
@ViewChild('videoBlacklistModal', { static: false }) videoBlacklistModal: VideoBlacklistComponent
|
||||||
|
|
||||||
@Input() video: Video | VideoDetails
|
@Input() video: Video | VideoDetails
|
||||||
|
@Input() videoCaptions: VideoCaption[] = []
|
||||||
|
|
||||||
@Input() displayOptions: VideoActionsDisplayType = {
|
@Input() displayOptions: VideoActionsDisplayType = {
|
||||||
playlist: false,
|
playlist: false,
|
||||||
|
@ -105,7 +107,7 @@ export class VideoActionsDropdownComponent implements OnChanges {
|
||||||
showDownloadModal () {
|
showDownloadModal () {
|
||||||
this.modalOpened.emit()
|
this.modalOpened.emit()
|
||||||
|
|
||||||
this.videoDownloadModal.show(this.video as VideoDetails)
|
this.videoDownloadModal.show(this.video as VideoDetails, this.videoCaptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
showReportModal () {
|
showReportModal () {
|
||||||
|
|
|
@ -109,7 +109,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<my-video-actions-dropdown
|
<my-video-actions-dropdown
|
||||||
placement="bottom auto" buttonDirection="horizontal" [buttonStyled]="true" [video]="video"
|
placement="bottom auto" buttonDirection="horizontal" [buttonStyled]="true" [video]="video" [videoCaptions]="videoCaptions"
|
||||||
(videoRemoved)="onVideoRemoved()" (modalOpened)="onModalOpened()"
|
(videoRemoved)="onVideoRemoved()" (modalOpened)="onModalOpened()"
|
||||||
></my-video-actions-dropdown>
|
></my-video-actions-dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue