mirror of
https://github.com/Tzahi12345/YoutubeDL-Material.git
synced 2026-03-20 11:41:00 +03:00
Subscription downloads already queued are now not requeued on the next check Headers in download queue table are now sortable Added button to clear all finished downloads in the downloads manager
215 lines
7.1 KiB
TypeScript
215 lines
7.1 KiB
TypeScript
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
|
|
import { PostsService } from 'app/posts.services';
|
|
import { trigger, transition, animateChild, stagger, query, style, animate } from '@angular/animations';
|
|
import { Router } from '@angular/router';
|
|
import { MatPaginator } from '@angular/material/paginator';
|
|
import { MatTableDataSource } from '@angular/material/table';
|
|
import { MatDialog } from '@angular/material/dialog';
|
|
import { ConfirmDialogComponent } from 'app/dialogs/confirm-dialog/confirm-dialog.component';
|
|
import { MatSort } from '@angular/material/sort';
|
|
|
|
@Component({
|
|
selector: 'app-downloads',
|
|
templateUrl: './downloads.component.html',
|
|
styleUrls: ['./downloads.component.scss'],
|
|
animations: [
|
|
// nice stagger effect when showing existing elements
|
|
trigger('list', [
|
|
transition(':enter', [
|
|
// child animation selector + stagger
|
|
query('@items',
|
|
stagger(100, animateChild()), { optional: true }
|
|
)
|
|
]),
|
|
]),
|
|
trigger('items', [
|
|
// cubic-bezier for a tiny bouncing feel
|
|
transition(':enter', [
|
|
style({ transform: 'scale(0.5)', opacity: 0 }),
|
|
animate('500ms cubic-bezier(.8,-0.6,0.2,1.5)',
|
|
style({ transform: 'scale(1)', opacity: 1 }))
|
|
]),
|
|
transition(':leave', [
|
|
style({ transform: 'scale(1)', opacity: 1, height: '*' }),
|
|
animate('1s cubic-bezier(.8,-0.6,0.2,1.5)',
|
|
style({ transform: 'scale(0.5)', opacity: 0, height: '0px', margin: '0px' }))
|
|
]),
|
|
])
|
|
],
|
|
})
|
|
export class DownloadsComponent implements OnInit, OnDestroy {
|
|
|
|
downloads_check_interval = 1000;
|
|
downloads = [];
|
|
finished_downloads = [];
|
|
interval_id = null;
|
|
|
|
keys = Object.keys;
|
|
|
|
valid_sessions_length = 0;
|
|
|
|
STEP_INDEX_TO_LABEL = {
|
|
0: 'Creating download',
|
|
1: 'Getting info',
|
|
2: 'Downloading file',
|
|
3: 'Complete'
|
|
}
|
|
|
|
displayedColumns: string[] = ['date', 'title', 'stage', 'subscription', 'progress', 'actions'];
|
|
dataSource = null; // new MatTableDataSource<Download>();
|
|
downloads_retrieved = false;
|
|
|
|
@ViewChild(MatPaginator) paginator: MatPaginator;
|
|
@ViewChild(MatSort) sort: MatSort;
|
|
|
|
sort_downloads = (a, b) => {
|
|
const result = b.timestamp_start - a.timestamp_start;
|
|
return result;
|
|
}
|
|
|
|
constructor(public postsService: PostsService, private router: Router, private dialog: MatDialog) { }
|
|
|
|
ngOnInit(): void {
|
|
if (this.postsService.initialized) {
|
|
this.getCurrentDownloadsRecurring();
|
|
} else {
|
|
this.postsService.service_initialized.subscribe(init => {
|
|
if (init) {
|
|
this.getCurrentDownloadsRecurring();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
getCurrentDownloadsRecurring() {
|
|
if (!this.postsService.config['Extra']['enable_downloads_manager']) {
|
|
this.router.navigate(['/home']);
|
|
return;
|
|
}
|
|
this.getCurrentDownloads();
|
|
this.interval_id = setInterval(() => {
|
|
this.getCurrentDownloads();
|
|
}, this.downloads_check_interval);
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
if (this.interval_id) { clearInterval(this.interval_id) }
|
|
}
|
|
|
|
getCurrentDownloads(): void {
|
|
this.postsService.getCurrentDownloads().subscribe(res => {
|
|
this.downloads_retrieved = true;
|
|
if (res['downloads'] !== null
|
|
&& res['downloads'] !== undefined
|
|
&& JSON.stringify(this.downloads) !== JSON.stringify(res['downloads'])) {
|
|
this.downloads = this.combineDownloads(this.downloads, res['downloads']);
|
|
// this.downloads = res['downloads'];
|
|
this.downloads.sort(this.sort_downloads);
|
|
this.dataSource = new MatTableDataSource<Download>(this.downloads);
|
|
this.dataSource.paginator = this.paginator;
|
|
this.dataSource.sort = this.sort;
|
|
} else {
|
|
// failed to get downloads
|
|
}
|
|
});
|
|
}
|
|
|
|
clearFinishedDownloads(): void {
|
|
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
|
|
data: {
|
|
dialogTitle: $localize`Clear finished downloads`,
|
|
dialogText: $localize`Would you like to clear your finished downloads?`,
|
|
submitText: $localize`Clear`,
|
|
warnSubmitColor: true
|
|
}
|
|
});
|
|
dialogRef.afterClosed().subscribe(confirmed => {
|
|
if (confirmed) {
|
|
this.postsService.clearFinishedDownloads().subscribe(res => {
|
|
if (!res['success']) {
|
|
this.postsService.openSnackBar('Failed to clear finished downloads!');
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
pauseDownload(download_uid: string): void {
|
|
this.postsService.pauseDownload(download_uid).subscribe(res => {
|
|
if (!res['success']) {
|
|
this.postsService.openSnackBar('Failed to pause download! See server logs for more info.');
|
|
}
|
|
});
|
|
}
|
|
|
|
resumeDownload(download_uid: string): void {
|
|
this.postsService.resumeDownload(download_uid).subscribe(res => {
|
|
if (!res['success']) {
|
|
this.postsService.openSnackBar('Failed to resume download! See server logs for more info.');
|
|
}
|
|
});
|
|
}
|
|
|
|
restartDownload(download_uid: string): void {
|
|
this.postsService.restartDownload(download_uid).subscribe(res => {
|
|
if (!res['success']) {
|
|
this.postsService.openSnackBar('Failed to restart download! See server logs for more info.');
|
|
}
|
|
});
|
|
}
|
|
|
|
cancelDownload(download_uid: string): void {
|
|
this.postsService.cancelDownload(download_uid).subscribe(res => {
|
|
if (!res['success']) {
|
|
this.postsService.openSnackBar('Failed to cancel download! See server logs for more info.');
|
|
}
|
|
});
|
|
}
|
|
|
|
clearDownload(download_uid: string): void {
|
|
this.postsService.clearDownload(download_uid).subscribe(res => {
|
|
if (!res['success']) {
|
|
this.postsService.openSnackBar('Failed to pause download! See server logs for more info.');
|
|
}
|
|
});
|
|
}
|
|
|
|
watchContent(download): void {
|
|
const container = download['container'];
|
|
localStorage.setItem('player_navigator', this.router.url.split(';')[0]);
|
|
const is_playlist = container['uids']; // hacky, TODO: fix
|
|
if (is_playlist) {
|
|
this.router.navigate(['/player', {playlist_id: container['id'], type: download['type']}]);
|
|
} else {
|
|
this.router.navigate(['/player', {type: download['type'], uid: container['uid']}]);
|
|
}
|
|
}
|
|
|
|
combineDownloads(downloads_old, downloads_new) {
|
|
// only keeps downloads that exist in the new set
|
|
downloads_old = downloads_old.filter(download_old => downloads_new.some(download_new => download_new.uid === download_old.uid));
|
|
|
|
// add downloads from the new set that the old one doesn't have
|
|
const downloads_to_add = downloads_new.filter(download_new => !downloads_old.some(download_old => download_new.uid === download_old.uid));
|
|
downloads_old.push(...downloads_to_add);
|
|
downloads_old.forEach(download_old => {
|
|
const download_new = downloads_new.find(download_to_check => download_old.uid === download_to_check.uid);
|
|
Object.keys(download_new).forEach(key => {
|
|
download_old[key] = download_new[key];
|
|
});
|
|
|
|
Object.keys(download_old).forEach(key => {
|
|
if (!download_new[key]) delete download_old[key];
|
|
});
|
|
});
|
|
|
|
return downloads_old;
|
|
}
|
|
}
|
|
|
|
export interface Download {
|
|
timestamp_start: number;
|
|
title: string;
|
|
step_index: number;
|
|
progress: string;
|
|
} |