1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { faTrashAlt, faCheckCircle, faTimesCircle } from '@fortawesome/free-regular-svg-icons';
import { faRedoAlt } from '@fortawesome/free-solid-svg-icons';
import { CookieService } from 'ngx-cookie-service';
import { DownloadsService, Status } from './downloads.service';
import { MasterCheckboxComponent } from './master-checkbox.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.sass']
})
export class AppComponent implements AfterViewInit {
addUrl: string;
qualities: Array<Object> = [
{id: "best", text: "Best"},
{id: "1440p", text: "1440p"},
{id: "1080p", text: "1080p"},
{id: "720p", text: "720p"},
{id: "480p", text: "480p"},
{id: "audio", text: "Audio only"}
];
quality: string;
formats: Array<Object> = [
{id: "any", text: "Any"},
{id: "mp4", text: "MP4"}
];
format: string;
addInProgress = false;
@ViewChild('queueMasterCheckbox') queueMasterCheckbox: MasterCheckboxComponent;
@ViewChild('queueDelSelected') queueDelSelected: ElementRef;
@ViewChild('doneMasterCheckbox') doneMasterCheckbox: MasterCheckboxComponent;
@ViewChild('doneDelSelected') doneDelSelected: ElementRef;
@ViewChild('doneClearCompleted') doneClearCompleted: ElementRef;
@ViewChild('doneClearFailed') doneClearFailed: ElementRef;
faTrashAlt = faTrashAlt;
faCheckCircle = faCheckCircle;
faTimesCircle = faTimesCircle;
faRedoAlt = faRedoAlt;
constructor(public downloads: DownloadsService, private cookieService: CookieService) {
this.quality = cookieService.get('metube_quality') || 'best';
this.format = cookieService.get('metube_format') || 'any';
}
ngAfterViewInit() {
this.downloads.queueChanged.subscribe(() => {
this.queueMasterCheckbox.selectionChanged();
});
this.downloads.doneChanged.subscribe(() => {
this.doneMasterCheckbox.selectionChanged();
let completed: number = 0, failed: number = 0;
this.downloads.done.forEach(dl => {
if (dl.status === 'finished')
completed++;
else if (dl.status === 'error')
failed++;
});
this.doneClearCompleted.nativeElement.disabled = completed === 0;
this.doneClearFailed.nativeElement.disabled = failed === 0;
});
}
// workaround to allow fetching of Map values in the order they were inserted
// https://github.com/angular/angular/issues/31420
asIsOrder(a, b) {
return 1;
}
qualityChanged() {
this.cookieService.set('metube_quality', this.quality, { expires: 3650 });
}
formatChanged() {
this.cookieService.set('metube_format', this.format, { expires: 3650 });
}
queueSelectionChanged(checked: number) {
this.queueDelSelected.nativeElement.disabled = checked == 0;
}
doneSelectionChanged(checked: number) {
this.doneDelSelected.nativeElement.disabled = checked == 0;
}
addDownload(url?: string, quality?: string, format?: string) {
url = url ?? this.addUrl
quality = quality ?? this.quality
format = format ?? this.format
this.addInProgress = true;
this.downloads.add(url, quality, format).subscribe((status: Status) => {
if (status.status === 'error') {
alert(`Error adding URL: ${status.msg}`);
} else {
this.addUrl = '';
}
this.addInProgress = false;
});
}
retryDownload(key: string, quality: string, format: string) {
this.addDownload(key, quality, format);
this.downloads.delById('done', [key]).subscribe();
}
delDownload(where: string, id: string) {
this.downloads.delById(where, [id]).subscribe();
}
delSelectedDownloads(where: string) {
this.downloads.delByFilter(where, dl => dl.checked).subscribe();
}
clearCompletedDownloads() {
this.downloads.delByFilter('done', dl => dl.status === 'finished').subscribe();
}
clearFailedDownloads() {
this.downloads.delByFilter('done', dl => dl.status === 'error').subscribe();
}
}
|