mirror of
https://github.com/Tzahi12345/YoutubeDL-Material.git
synced 2026-03-21 12:10:58 +03:00
images on file cards now load when the accordion is hovered over to increase responsiveness. images are loading maybe a second before clicking so hopefully they're done by the time the expansion finishes
added the ability to create playlists in the gui through a new dialog reloading mp3s/mp4s doesn't cause an image refresh anymore when the list is unchanged fixed loading spinner of available formats so it now only shows when it is loading the current url file card images now don't show when errored or thumbnailurl doesn't exist
This commit is contained in:
@@ -24,8 +24,15 @@ import {VgControlsModule} from 'videogular2/compiled/controls';
|
||||
import {VgOverlayPlayModule} from 'videogular2/compiled/overlay-play';
|
||||
import {VgBufferingModule} from 'videogular2/compiled/buffering';
|
||||
import { InputDialogComponent } from './input-dialog/input-dialog.component';
|
||||
import { LazyLoadImageModule } from 'ng-lazyload-image';
|
||||
import { LazyLoadImageModule, IsVisibleProps } from 'ng-lazyload-image';
|
||||
import { NgxContentLoadingModule } from 'ngx-content-loading';
|
||||
import { audioFilesMouseHovering, videoFilesMouseHovering } from './main/main.component';
|
||||
import { Observable } from 'rxjs';
|
||||
import { CreatePlaylistComponent } from './create-playlist/create-playlist.component';
|
||||
|
||||
function isVisible({ event, element, scrollContainer, offset }: IsVisibleProps<any>) {
|
||||
return (element.id === 'video' ? videoFilesMouseHovering : audioFilesMouseHovering);
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -33,7 +40,8 @@ import { NgxContentLoadingModule } from 'ngx-content-loading';
|
||||
FileCardComponent,
|
||||
MainComponent,
|
||||
PlayerComponent,
|
||||
InputDialogComponent
|
||||
InputDialogComponent,
|
||||
CreatePlaylistComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@@ -64,13 +72,14 @@ import { NgxContentLoadingModule } from 'ngx-content-loading';
|
||||
VgControlsModule,
|
||||
VgOverlayPlayModule,
|
||||
VgBufferingModule,
|
||||
LazyLoadImageModule,
|
||||
LazyLoadImageModule.forRoot({ isVisible }),
|
||||
NgxContentLoadingModule,
|
||||
RouterModule,
|
||||
AppRoutingModule,
|
||||
],
|
||||
entryComponents: [
|
||||
InputDialogComponent
|
||||
InputDialogComponent,
|
||||
CreatePlaylistComponent
|
||||
],
|
||||
providers: [PostsService],
|
||||
bootstrap: [AppComponent]
|
||||
|
||||
19
src/app/create-playlist/create-playlist.component.html
Normal file
19
src/app/create-playlist/create-playlist.component.html
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
<form>
|
||||
<div>
|
||||
<mat-form-field color="accent">
|
||||
<input [(ngModel)]="name" matInput placeholder="Name" type="text" required aria-required [ngModelOptions]="{standalone: true}">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field color="accent">
|
||||
<mat-label>{{(type === 'audio') ? 'Audio files' : 'Videos'}}</mat-label>
|
||||
<mat-select [formControl]="filesSelect" multiple required aria-required>
|
||||
<mat-option *ngFor="let file of filesToSelectFrom" [value]="file.id">{{file.id}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div *ngIf="create_in_progress" style="float: left"><mat-spinner [diameter]="25"></mat-spinner></div>
|
||||
<button (click)="createPlaylist()" [disabled]="!name || !filesSelect.value || filesSelect.value.length === 0" color="primary" style="float: right" mat-flat-button>Create</button>
|
||||
25
src/app/create-playlist/create-playlist.component.spec.ts
Normal file
25
src/app/create-playlist/create-playlist.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CreatePlaylistComponent } from './create-playlist.component';
|
||||
|
||||
describe('CreatePlaylistComponent', () => {
|
||||
let component: CreatePlaylistComponent;
|
||||
let fixture: ComponentFixture<CreatePlaylistComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ CreatePlaylistComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CreatePlaylistComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
58
src/app/create-playlist/create-playlist.component.ts
Normal file
58
src/app/create-playlist/create-playlist.component.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { Component, OnInit, Inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { PostsService } from 'app/posts.services';
|
||||
|
||||
@Component({
|
||||
selector: 'app-create-playlist',
|
||||
templateUrl: './create-playlist.component.html',
|
||||
styleUrls: ['./create-playlist.component.scss']
|
||||
})
|
||||
export class CreatePlaylistComponent implements OnInit {
|
||||
// really "createPlaylistDialogComponent"
|
||||
|
||||
filesToSelectFrom = null;
|
||||
type = null;
|
||||
filesSelect = new FormControl();
|
||||
name = '';
|
||||
|
||||
create_in_progress = false;
|
||||
|
||||
constructor(@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private postsService: PostsService,
|
||||
public dialogRef: MatDialogRef<CreatePlaylistComponent>) { }
|
||||
|
||||
|
||||
ngOnInit() {
|
||||
if (this.data) {
|
||||
this.filesToSelectFrom = this.data.filesToSelectFrom;
|
||||
this.type = this.data.type;
|
||||
}
|
||||
}
|
||||
|
||||
createPlaylist() {
|
||||
const thumbnailURL = this.getThumbnailURL();
|
||||
this.create_in_progress = true;
|
||||
this.postsService.createPlaylist(this.name, this.filesSelect.value, this.type, thumbnailURL).subscribe(res => {
|
||||
this.create_in_progress = false;
|
||||
if (res['success']) {
|
||||
this.dialogRef.close(true);
|
||||
} else {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getThumbnailURL() {
|
||||
for (let i = 0; i < this.filesToSelectFrom.length; i++) {
|
||||
const file = this.filesToSelectFrom[i];
|
||||
if (file.id === this.filesSelect.value[0]) {
|
||||
// different services store the thumbnail in different places
|
||||
if (file.thumbnailURL) { return file.thumbnailURL };
|
||||
if (file.thumbnail) { return file.thumbnail };
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,8 +5,8 @@
|
||||
<br/>
|
||||
<span class="max-two-lines">ID: {{name}}</span>
|
||||
<div *ngIf="isPlaylist">Count: {{count}}</div>
|
||||
<div class="img-div">
|
||||
<img class="image" [lazyLoad]="thumbnailURL" (onLoad)="imageLoaded($event)" alt="Thumbnail">
|
||||
<div *ngIf="!image_errored && thumbnailURL" class="img-div">
|
||||
<img class="image" (error) ="onImgError($event)" [id]="type" [lazyLoad]="thumbnailURL" [customObservable]="scrollAndLoad" (onLoad)="imageLoaded($event)" alt="Thumbnail">
|
||||
<span *ngIf="!image_loaded">
|
||||
<ngx-content-loading [width]="500" [height]="360">
|
||||
<svg:g ngx-rect width="500" height="360" y="0" x="0" rx="4" ry="4"></svg:g>
|
||||
|
||||
@@ -3,6 +3,8 @@ import {PostsService} from '../posts.services';
|
||||
import {MatSnackBar} from '@angular/material';
|
||||
import {EventEmitter} from '@angular/core';
|
||||
import { MainComponent } from 'app/main/main.component';
|
||||
import { Subject, Observable } from 'rxjs';
|
||||
import 'rxjs/add/observable/merge';
|
||||
|
||||
@Component({
|
||||
selector: 'app-file-card',
|
||||
@@ -21,8 +23,18 @@ export class FileCardComponent implements OnInit {
|
||||
@Input() count = null;
|
||||
type;
|
||||
image_loaded = false;
|
||||
image_errored = false;
|
||||
|
||||
constructor(private postsService: PostsService, public snackBar: MatSnackBar, public mainComponent: MainComponent) { }
|
||||
scrollSubject;
|
||||
scrollAndLoad;
|
||||
|
||||
constructor(private postsService: PostsService, public snackBar: MatSnackBar, public mainComponent: MainComponent) {
|
||||
this.scrollSubject = new Subject();
|
||||
this.scrollAndLoad = Observable.merge(
|
||||
Observable.fromEvent(window, 'scroll'),
|
||||
this.scrollSubject
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.type = this.isAudio ? 'audio' : 'video';
|
||||
@@ -44,6 +56,14 @@ export class FileCardComponent implements OnInit {
|
||||
|
||||
}
|
||||
|
||||
onImgError(event) {
|
||||
this.image_errored = true;
|
||||
}
|
||||
|
||||
onHoverResponse() {
|
||||
this.scrollSubject.next();
|
||||
}
|
||||
|
||||
imageLoaded(loaded) {
|
||||
this.image_loaded = true;
|
||||
}
|
||||
|
||||
@@ -111,4 +111,8 @@ mat-form-field.mat-form-field {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.add-playlist-button {
|
||||
float: right;
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
<div class="row">
|
||||
<div [ngClass]="allowQualitySelect ? 'col-sm-9' : null" class="col-12">
|
||||
<mat-form-field color="accent" class="example-full-width">
|
||||
<input style="padding-right: 25px;" matInput (ngModelChange)="inputChanged($event)" [(ngModel)]="url" [placeholder]="'URL' + (youtubeSearchEnabled ? ' or search' : '')" type="url" name="url" [formControl]="urlForm" required #urlinput>
|
||||
<input style="padding-right: 25px;" matInput (ngModelChange)="inputChanged($event)" [(ngModel)]="url" [placeholder]="'URL' + (youtubeSearchEnabled ? ' or search' : '')" type="url" name="url" [formControl]="urlForm" required #urlinput>
|
||||
<mat-error *ngIf="urlError || urlForm.invalid">Please enter a valid URL!</mat-error>
|
||||
<button class="input-clear-button" mat-icon-button (click)="clearInput()"><mat-icon>clear</mat-icon></button>
|
||||
</mat-form-field>
|
||||
@@ -21,12 +21,12 @@
|
||||
<mat-label>Quality</mat-label>
|
||||
<mat-select [ngModelOptions]="{standalone: true}" [(ngModel)]="selectedQuality">
|
||||
<ng-container *ngFor="let option of qualityOptions[(audioOnly) ? 'audio' : 'video']">
|
||||
<mat-option *ngIf="option.value === '' || url && cachedAvailableFormats[url] && cachedAvailableFormats[url] && cachedAvailableFormats[url][(audioOnly) ? 'audio' : 'video'][option.value]" [value]="option.value">
|
||||
<mat-option *ngIf="option.value === '' || url && cachedAvailableFormats[url] && cachedAvailableFormats[url]['formats'] && cachedAvailableFormats[url]['formats'][(audioOnly) ? 'audio' : 'video'][option.value]" [value]="option.value">
|
||||
{{option.label}}
|
||||
</mat-option>
|
||||
</ng-container>
|
||||
</mat-select>
|
||||
<div class="spinner-div" *ngIf="formats_loading && !cachedAvailableFormats[url]">
|
||||
<div class="spinner-div" *ngIf="url !== '' && cachedAvailableFormats[url] && cachedAvailableFormats[url]['formats_loading']">
|
||||
<mat-spinner [diameter]="25"></mat-spinner>
|
||||
</div>
|
||||
</mat-form-field>
|
||||
@@ -80,7 +80,7 @@
|
||||
</ng-template>
|
||||
<div style="margin: 20px" *ngIf="fileManagerEnabled">
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel class="big">
|
||||
<mat-expansion-panel (mouseleave)="accordionLeft('audio')" (mouseenter)="accordionEntered('audio')" class="big">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Audio
|
||||
@@ -92,26 +92,30 @@
|
||||
<div *ngIf="mp3s.length > 0;else nomp3s">
|
||||
<mat-grid-list style="margin-bottom: 15px;" (window:resize)="onResize($event)" [cols]="files_cols" rowHeight="150px">
|
||||
<mat-grid-tile *ngFor="let file of mp3s; index as i;">
|
||||
<app-file-card (removeFile)="removeFromMp3($event)" [title]="file.title" [name]="file.id" [thumbnailURL]="file.thumbnailURL"
|
||||
<app-file-card #audiofilecard (removeFile)="removeFromMp3($event)" [title]="file.title" [name]="file.id" [thumbnailURL]="file.thumbnailURL"
|
||||
[length]="file.duration" [isAudio]="true"></app-file-card>
|
||||
<mat-progress-bar *ngIf="downloading_content['audio'][file.id]" class="download-progress-bar" mode="indeterminate"></mat-progress-bar>
|
||||
</mat-grid-tile>
|
||||
</mat-grid-list>
|
||||
<mat-divider *ngIf="playlists.audio.length > 0"></mat-divider>
|
||||
<div style="width: 100%; text-align: center; margin-top: 10px;" *ngIf="playlists.audio.length > 0">
|
||||
<mat-divider></mat-divider>
|
||||
<div style="width: 100%; text-align: center; margin-top: 10px;">
|
||||
<h6>Playlists</h6>
|
||||
</div>
|
||||
<mat-grid-list *ngIf="playlists.audio.length > 0" (window:resize)="onResize($event)" [cols]="files_cols" rowHeight="150px">
|
||||
<mat-grid-tile *ngFor="let playlist of playlists.audio; let i = index;">
|
||||
<app-file-card (removeFile)="removePlaylistMp3(playlist.id, i)" [title]="playlist.name" [name]="playlist.id" [thumbnailURL]="playlist_thumbnails[playlist.id]"
|
||||
<app-file-card #audiofilecard (removeFile)="removePlaylistMp3(playlist.id, i)" [title]="playlist.name" [name]="playlist.id" [thumbnailURL]="playlist_thumbnails[playlist.id]"
|
||||
[length]="null" [isAudio]="true" [isPlaylist]="true" [count]="playlist.fileNames.length"></app-file-card>
|
||||
<mat-progress-bar *ngIf="downloading_content['audio'][playlist.id]" class="download-progress-bar" mode="indeterminate"></mat-progress-bar>
|
||||
</mat-grid-tile>
|
||||
</mat-grid-list>
|
||||
<div class="add-playlist-button"><button (click)="openCreatePlaylistDialog('audio')" mat-fab><mat-icon>add</mat-icon></button></div>
|
||||
<div *ngIf="playlists.audio.length === 0">
|
||||
No playlists available. Create one from your downloading audio files by clicking the blue plus button.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</mat-expansion-panel>
|
||||
<mat-expansion-panel class="big">
|
||||
<mat-expansion-panel (mouseleave)="accordionLeft('video')" (mouseenter)="accordionEntered('video')" class="big">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Video
|
||||
@@ -123,23 +127,29 @@
|
||||
<div *ngIf="mp4s.length > 0;else nomp4s">
|
||||
<mat-grid-list style="margin-bottom: 15px;" (window:resize)="onResize($event)" [cols]="files_cols" rowHeight="150px">
|
||||
<mat-grid-tile *ngFor="let file of mp4s; index as i;">
|
||||
<app-file-card (removeFile)="removeFromMp4($event)" [title]="file.title" [name]="file.id" [thumbnailURL]="file.thumbnailURL"
|
||||
<app-file-card #videofilecard (removeFile)="removeFromMp4($event)" [title]="file.title" [name]="file.id" [thumbnailURL]="file.thumbnailURL"
|
||||
[length]="file.duration" [isAudio]="false"></app-file-card>
|
||||
<mat-progress-bar *ngIf="downloading_content['video'][file.id]" class="download-progress-bar" mode="indeterminate"></mat-progress-bar>
|
||||
</mat-grid-tile>
|
||||
</mat-grid-list>
|
||||
<mat-divider *ngIf="playlists.video.length > 0"></mat-divider>
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<div style="width: 100%; text-align: center; margin-top: 10px;" *ngIf="playlists.video.length > 0">
|
||||
<div style="width: 100%; text-align: center; margin-top: 10px;">
|
||||
<h6>Playlists</h6>
|
||||
</div>
|
||||
<mat-grid-list *ngIf="playlists.video.length > 0" (window:resize)="onResize($event)" [cols]="files_cols" rowHeight="150px">
|
||||
<mat-grid-tile *ngFor="let playlist of playlists.video; let i = index;">
|
||||
<app-file-card (removeFile)="removePlaylistMp4(playlist.id, i)" [title]="playlist.name" [name]="playlist.id" [thumbnailURL]="playlist_thumbnails[playlist.id]"
|
||||
<app-file-card #videofilecard (removeFile)="removePlaylistMp4(playlist.id, i)" [title]="playlist.name" [name]="playlist.id" [thumbnailURL]="playlist_thumbnails[playlist.id]"
|
||||
[length]="null" [isAudio]="false" [isPlaylist]="true" [count]="playlist.fileNames.length"></app-file-card>
|
||||
<mat-progress-bar *ngIf="downloading_content['video'][playlist.id]" class="download-progress-bar" mode="indeterminate"></mat-progress-bar>
|
||||
</mat-grid-tile>
|
||||
</mat-grid-list>
|
||||
|
||||
<!-- Add video playlist button -->
|
||||
<div class="add-playlist-button"><button (click)="openCreatePlaylistDialog('video')" mat-fab><mat-icon>add</mat-icon></button></div>
|
||||
<div *ngIf="playlists.video.length === 0">
|
||||
No playlists available. Create one from your downloading video files by clicking the blue plus button.
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Component, OnInit, ElementRef, ViewChild } from '@angular/core';
|
||||
import { Component, OnInit, ElementRef, ViewChild, ViewChildren, QueryList } from '@angular/core';
|
||||
import {PostsService} from '../posts.services';
|
||||
import {FileCardComponent} from '../file-card/file-card.component';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import {FormControl, Validators} from '@angular/forms';
|
||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {MatSnackBar} from '@angular/material';
|
||||
import {MatSnackBar, MatDialog} from '@angular/material';
|
||||
import { saveAs } from 'file-saver';
|
||||
import 'rxjs/add/observable/of';
|
||||
import 'rxjs/add/operator/mapTo';
|
||||
@@ -16,6 +16,10 @@ import 'rxjs/add/operator/do'
|
||||
import 'rxjs/add/operator/switch'
|
||||
import { YoutubeSearchService, Result } from '../youtube-search.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { CreatePlaylistComponent } from 'app/create-playlist/create-playlist.component';
|
||||
|
||||
export let audioFilesMouseHovering = false;
|
||||
export let videoFilesMouseHovering = false;
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -156,11 +160,13 @@ export class MainComponent implements OnInit {
|
||||
formats_loading = false;
|
||||
|
||||
@ViewChild('urlinput', { read: ElementRef, static: false }) urlInput: ElementRef;
|
||||
@ViewChildren('audiofilecard') audioFileCards: QueryList<FileCardComponent>;
|
||||
@ViewChildren('videofilecard') videoFileCards: QueryList<FileCardComponent>;
|
||||
last_valid_url = '';
|
||||
last_url_check = 0;
|
||||
|
||||
constructor(private postsService: PostsService, private youtubeSearch: YoutubeSearchService, public snackBar: MatSnackBar,
|
||||
private router: Router) {
|
||||
private router: Router, public dialog: MatDialog) {
|
||||
this.audioOnly = false;
|
||||
|
||||
|
||||
@@ -202,7 +208,8 @@ export class MainComponent implements OnInit {
|
||||
this.postsService.getMp3s().subscribe(result => {
|
||||
const mp3s = result['mp3s'];
|
||||
const playlists = result['playlists'];
|
||||
this.mp3s = mp3s;
|
||||
// if they are different
|
||||
if (JSON.stringify(this.mp3s) !== JSON.stringify(mp3s)) { this.mp3s = mp3s };
|
||||
this.playlists.audio = playlists;
|
||||
|
||||
// get thumbnail url by using first video. this is a temporary hack
|
||||
@@ -216,7 +223,7 @@ export class MainComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
this.playlist_thumbnails[playlist.id] = videoToExtractThumbnail.thumbnailURL;
|
||||
if (videoToExtractThumbnail) { this.playlist_thumbnails[playlist.id] = videoToExtractThumbnail.thumbnailURL; }
|
||||
}
|
||||
}, error => {
|
||||
console.log(error);
|
||||
@@ -227,7 +234,8 @@ export class MainComponent implements OnInit {
|
||||
this.postsService.getMp4s().subscribe(result => {
|
||||
const mp4s = result['mp4s'];
|
||||
const playlists = result['playlists'];
|
||||
this.mp4s = mp4s;
|
||||
// if they are different
|
||||
if (JSON.stringify(this.mp4s) !== JSON.stringify(mp4s)) { this.mp4s = mp4s };
|
||||
this.playlists.video = playlists;
|
||||
|
||||
// get thumbnail url by using first video. this is a temporary hack
|
||||
@@ -241,7 +249,7 @@ export class MainComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
this.playlist_thumbnails[playlist.id] = videoToExtractThumbnail.thumbnailURL;
|
||||
if (videoToExtractThumbnail) { this.playlist_thumbnails[playlist.id] = videoToExtractThumbnail.thumbnailURL; }
|
||||
}
|
||||
},
|
||||
error => {
|
||||
@@ -396,9 +404,9 @@ export class MainComponent implements OnInit {
|
||||
|
||||
let customQualityConfiguration = null;
|
||||
if (this.selectedQuality !== '') {
|
||||
const cachedFormatsExists = this.cachedAvailableFormats[this.url];
|
||||
const cachedFormatsExists = this.cachedAvailableFormats[this.url] && this.cachedAvailableFormats[this.url]['formats'];
|
||||
if (cachedFormatsExists) {
|
||||
const audio_formats = this.cachedAvailableFormats[this.url]['audio'];
|
||||
const audio_formats = this.cachedAvailableFormats[this.url]['formats']['audio'];
|
||||
customQualityConfiguration = audio_formats[this.selectedQuality]['format_id'];
|
||||
}
|
||||
}
|
||||
@@ -415,9 +423,9 @@ export class MainComponent implements OnInit {
|
||||
});
|
||||
} else {
|
||||
let customQualityConfiguration = null;
|
||||
const cachedFormatsExists = this.cachedAvailableFormats[this.url];
|
||||
const cachedFormatsExists = this.cachedAvailableFormats[this.url] && this.cachedAvailableFormats[this.url]['formats'];
|
||||
if (cachedFormatsExists) {
|
||||
const video_formats = this.cachedAvailableFormats[this.url]['video'];
|
||||
const video_formats = this.cachedAvailableFormats[this.url]['formats']['video'];
|
||||
if (video_formats['best_audio_format'] && this.selectedQuality !== '') {
|
||||
customQualityConfiguration = video_formats[this.selectedQuality]['format_id'] + '+' + video_formats['best_audio_format'];
|
||||
}
|
||||
@@ -524,7 +532,7 @@ export class MainComponent implements OnInit {
|
||||
// tslint:disable-next-line: max-line-length
|
||||
const youtubeStrRegex = /(?:http(?:s)?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)\/))([^\?&\"'<> #]+)/;
|
||||
const reYT = new RegExp(youtubeStrRegex);
|
||||
const ytValid = reYT.test(str);
|
||||
const ytValid = true || reYT.test(str);
|
||||
if (valid && ytValid && Date.now() - this.last_url_check > 1000) {
|
||||
if (str !== this.last_valid_url && this.allowQualitySelect) {
|
||||
// get info
|
||||
@@ -543,18 +551,33 @@ export class MainComponent implements OnInit {
|
||||
}
|
||||
|
||||
getURLInfo(url) {
|
||||
if (!(this.cachedAvailableFormats[url])) {
|
||||
this.formats_loading = true;
|
||||
if (!this.cachedAvailableFormats[url]) {
|
||||
this.cachedAvailableFormats[url] = {};
|
||||
}
|
||||
if (!(this.cachedAvailableFormats[url] && this.cachedAvailableFormats[url]['formats'])) {
|
||||
this.cachedAvailableFormats[url]['formats_loading'] = true;
|
||||
this.postsService.getFileInfo([url], 'irrelevant', true).subscribe(res => {
|
||||
if (url === this.url) { this.formats_loading = false; }
|
||||
this.cachedAvailableFormats[url]['formats_loading'] = false;
|
||||
const infos = res['result'];
|
||||
if (!infos || !infos.formats) {
|
||||
this.errorFormats(url);
|
||||
return;
|
||||
}
|
||||
const parsed_infos = this.getAudioAndVideoFormats(infos.formats);
|
||||
console.log(parsed_infos);
|
||||
const available_formats = {audio: parsed_infos[0], video: parsed_infos[1]};
|
||||
this.cachedAvailableFormats[url] = available_formats;
|
||||
this.cachedAvailableFormats[url]['formats'] = available_formats;
|
||||
}, err => {
|
||||
this.errorFormats(url);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
errorFormats(url) {
|
||||
this.cachedAvailableFormats[url]['formats_loading'] = false;
|
||||
console.error('Could not load formats for url ' + url);
|
||||
}
|
||||
|
||||
attachToInput() {
|
||||
Observable.fromEvent(this.urlInput.nativeElement, 'keyup')
|
||||
.map((e: any) => e.target.value) // extract the value of input
|
||||
@@ -653,5 +676,45 @@ export class MainComponent implements OnInit {
|
||||
}
|
||||
return best_audio_format_for_mp4;
|
||||
}
|
||||
}
|
||||
|
||||
accordionEntered(type) {
|
||||
if (type === 'audio') {
|
||||
audioFilesMouseHovering = true;
|
||||
this.audioFileCards.forEach(filecard => {
|
||||
filecard.onHoverResponse();
|
||||
});
|
||||
} else if (type === 'video') {
|
||||
videoFilesMouseHovering = true;
|
||||
this.videoFileCards.forEach(filecard => {
|
||||
filecard.onHoverResponse();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
accordionLeft(type) {
|
||||
if (type === 'audio') {
|
||||
audioFilesMouseHovering = false;
|
||||
} else if (type === 'video') {
|
||||
videoFilesMouseHovering = false;
|
||||
}
|
||||
}
|
||||
|
||||
// creating a playlist
|
||||
openCreatePlaylistDialog(type) {
|
||||
const dialogRef = this.dialog.open(CreatePlaylistComponent, {
|
||||
data: {
|
||||
filesToSelectFrom: (type === 'audio') ? this.mp3s : this.mp4s,
|
||||
type: type
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if (result) {
|
||||
if (type === 'audio') { this.getMp3s() };
|
||||
if (type === 'video') { this.getMp4s() };
|
||||
this.openSnackBar('Successfully created playlist!', '');
|
||||
} else if (result === false) {
|
||||
this.openSnackBar('ERROR: failed to create playlist!', '');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user