Support drag and drop for video upload and torrent file import

This commit is contained in:
Rigel Kent 2020-04-03 00:22:04 +02:00
parent b515c98c6b
commit c9ff8a08a0
No known key found for this signature in database
GPG Key ID: 5E53E96A494E452F
9 changed files with 64 additions and 17 deletions

View File

@ -9,7 +9,7 @@
<div class="modal-body"> <div class="modal-body">
<label i18n for="language">Language</label> <label i18n for="language">Language</label>
<div class="peertube-select-container"> <div class="peertube-select-container">
<select id="language" formControlName="language"> <select id="language" formControlName="language" class="form-control">
<option></option> <option></option>
<option *ngFor="let language of videoCaptionLanguages" [value]="language.id">{{ language.label }}</option> <option *ngFor="let language of videoCaptionLanguages" [value]="language.id">{{ language.label }}</option>
</select> </select>

View File

@ -0,0 +1,30 @@
import { Directive, Output, EventEmitter, HostBinding, HostListener } from '@angular/core'
@Directive({
selector: '[dragDrop]'
})
export class DragDropDirective {
@Output() onFileDropped = new EventEmitter<FileList>()
@HostBinding('class.dragover') dragover = false
@HostListener('dragover', ['$event']) onDragOver(e: Event) {
e.preventDefault()
e.stopPropagation()
this.dragover = true
}
@HostListener('dragleave', ['$event']) public onDragLeave(e: Event) {
e.preventDefault()
e.stopPropagation()
this.dragover = false
}
@HostListener('drop', ['$event']) public ondrop(e: DragEvent) {
e.preventDefault()
e.stopPropagation()
this.dragover = false
let files = e.dataTransfer.files
if (files.length > 0) this.onFileDropped.emit(files)
}
}

View File

@ -1,14 +1,13 @@
<div *ngIf="!hasImportedVideo" class="upload-video-container"> <div *ngIf="!hasImportedVideo" class="upload-video-container" dragDrop (onFileDropped)="setTorrentFile($event)">
<div class="first-step-block"> <div class="first-step-block">
<my-global-icon class="upload-icon" iconName="upload"></my-global-icon> <my-global-icon class="upload-icon" iconName="upload"></my-global-icon>
<div class="button-file"> <div class="button-file form-control" [ngbTooltip]="'(extensions: .torrent)'">
<span i18n>Select the torrent to import</span> <span i18n>Select the torrent to import</span>
<input #torrentfileInput type="file" name="torrentfile" id="torrentfile" accept=".torrent" (change)="fileChange()" /> <input #torrentfileInput type="file" name="torrentfile" id="torrentfile" accept=".torrent" (change)="fileChange()" />
</div> </div>
<span class="button-file-extension">(.torrent)</span>
<div class="torrent-or-magnet" i18n>Or</div> <div class="torrent-or-magnet" i18n-data-content data-content="OR"></div>
<div class="form-group form-group-magnet-uri"> <div class="form-group form-group-magnet-uri">
<label i18n for="magnetUri">Paste magnet URI</label> <label i18n for="magnetUri">Paste magnet URI</label>
@ -21,13 +20,13 @@
</ng-template> </ng-template>
</my-help> </my-help>
<input type="text" id="magnetUri" [(ngModel)]="magnetUri" /> <input type="text" id="magnetUri" [(ngModel)]="magnetUri" class="form-control" />
</div> </div>
<div class="form-group"> <div class="form-group">
<label i18n for="first-step-channel">Channel</label> <label i18n for="first-step-channel">Channel</label>
<div class="peertube-select-container"> <div class="peertube-select-container">
<select id="first-step-channel" [(ngModel)]="firstStepChannelId"> <select id="first-step-channel" [(ngModel)]="firstStepChannelId" class="form-control">
<option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option> <option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
</select> </select>
</div> </div>
@ -36,7 +35,7 @@
<div class="form-group"> <div class="form-group">
<label i18n for="first-step-privacy">Privacy</label> <label i18n for="first-step-privacy">Privacy</label>
<div class="peertube-select-container"> <div class="peertube-select-container">
<select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId"> <select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId" class="form-control">
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option> <option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
</select> </select>
</div> </div>

View File

@ -72,6 +72,11 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca
this.importVideo(torrentfile) this.importVideo(torrentfile)
} }
setTorrentFile (files: FileList) {
this.torrentfileInput.nativeElement.files = files
this.fileChange()
}
importVideo (torrentfile?: Blob) { importVideo (torrentfile?: Blob) {
this.isImportingVideo = true this.isImportingVideo = true

View File

@ -15,13 +15,13 @@
</ng-template> </ng-template>
</my-help> </my-help>
<input type="text" id="targetUrl" [(ngModel)]="targetUrl" /> <input type="text" id="targetUrl" [(ngModel)]="targetUrl" class="form-control" />
</div> </div>
<div class="form-group"> <div class="form-group">
<label i18n for="first-step-channel">Channel</label> <label i18n for="first-step-channel">Channel</label>
<div class="peertube-select-container"> <div class="peertube-select-container">
<select id="first-step-channel" [(ngModel)]="firstStepChannelId"> <select id="first-step-channel" [(ngModel)]="firstStepChannelId" class="form-control">
<option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option> <option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
</select> </select>
</div> </div>
@ -30,7 +30,7 @@
<div class="form-group"> <div class="form-group">
<label i18n for="first-step-privacy">Privacy</label> <label i18n for="first-step-privacy">Privacy</label>
<div class="peertube-select-container"> <div class="peertube-select-container">
<select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId"> <select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId" class="form-control">
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option> <option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
</select> </select>
</div> </div>

View File

@ -1,8 +1,8 @@
<div *ngIf="!isUploadingVideo" class="upload-video-container"> <div *ngIf="!isUploadingVideo" class="upload-video-container" dragDrop (onFileDropped)="setVideoFile($event)">
<div class="first-step-block"> <div class="first-step-block">
<my-global-icon class="upload-icon" iconName="upload"></my-global-icon> <my-global-icon class="upload-icon" iconName="upload"></my-global-icon>
<div class="button-file form-control" [ngbTooltip]="'(extensions: ' + videoExtensions + ')'" container="body"> <div class="button-file form-control" [ngbTooltip]="'(extensions: ' + videoExtensions + ')'">
<span i18n>Select the file to upload</span> <span i18n>Select the file to upload</span>
<input #videofileInput type="file" name="videofile" id="videofile" [accept]="videoExtensions" (change)="fileChange()" autofocus /> <input #videofileInput type="file" name="videofile" id="videofile" [accept]="videoExtensions" (change)="fileChange()" autofocus />
</div> </div>

View File

@ -108,6 +108,11 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
return this.videofileInput.nativeElement.files[0] return this.videofileInput.nativeElement.files[0]
} }
setVideoFile (files: FileList) {
this.videofileInput.nativeElement.files = files
this.fileChange()
}
getAudioUploadLabel () { getAudioUploadLabel () {
const videofile = this.getVideoFile() const videofile = this.getVideoFile()
if (!videofile) return this.i18n('Upload') if (!videofile) return this.i18n('Upload')

View File

@ -40,14 +40,19 @@ $border-color: #EAEAEA;
::ng-deep .upload-video-container { ::ng-deep .upload-video-container {
border: $border-width $border-type $border-color; border: $border-width $border-type $border-color;
border-top: none; border-top: transparent;
background-color: var(--submenuColor); background-color: var(--submenuColor);
border-radius: 3px; border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
width: 100%; width: 100%;
min-height: 440px; min-height: 440px;
padding-bottom: 20px; padding-bottom: 20px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
&.dragover {
border: 3px dashed var(--mainColor);
}
} }

View File

@ -3,6 +3,7 @@ import { SharedModule } from '../../shared'
import { VideoEditModule } from './shared/video-edit.module' import { VideoEditModule } from './shared/video-edit.module'
import { VideoAddRoutingModule } from './video-add-routing.module' import { VideoAddRoutingModule } from './video-add-routing.module'
import { VideoAddComponent } from './video-add.component' import { VideoAddComponent } from './video-add.component'
import { DragDropDirective } from './video-add-components/drag-drop.directive'
import { CanDeactivateGuard } from '../../shared/guards/can-deactivate-guard.service' import { CanDeactivateGuard } from '../../shared/guards/can-deactivate-guard.service'
import { VideoUploadComponent } from '@app/videos/+video-edit/video-add-components/video-upload.component' import { VideoUploadComponent } from '@app/videos/+video-edit/video-add-components/video-upload.component'
import { VideoImportUrlComponent } from '@app/videos/+video-edit/video-add-components/video-import-url.component' import { VideoImportUrlComponent } from '@app/videos/+video-edit/video-add-components/video-import-url.component'
@ -18,10 +19,12 @@ import { VideoImportTorrentComponent } from '@app/videos/+video-edit/video-add-c
VideoAddComponent, VideoAddComponent,
VideoUploadComponent, VideoUploadComponent,
VideoImportUrlComponent, VideoImportUrlComponent,
VideoImportTorrentComponent VideoImportTorrentComponent,
DragDropDirective
], ],
exports: [ exports: [
VideoAddComponent VideoAddComponent,
DragDropDirective
], ],
providers: [ providers: [
CanDeactivateGuard CanDeactivateGuard