added basic subscriptions support for playlists and channels

update youtube-dl binary on windows

updated favicon to the new icon
This commit is contained in:
Isaac Grynsztein
2020-03-05 20:14:36 -05:00
parent a755b0b281
commit a70abb3945
38 changed files with 1200 additions and 32 deletions

View File

@@ -0,0 +1,17 @@
<div style="position: relative; width: fit-content;">
<button [matMenuTriggerFor]="action_menu" class="menuButton" mat-icon-button><mat-icon>more_vert</mat-icon></button>
<mat-menu #action_menu="matMenu">
<button mat-menu-item><mat-icon>info</mat-icon>Info</button>
<button mat-menu-item><mat-icon>restore</mat-icon>Delete and redownload</button>
<button mat-menu-item><mat-icon>delete_forever</mat-icon>Delete forever</button>
</mat-menu>
<mat-card (click)="goToFile(file.name)" matRipple class="example-card mat-elevation-z6">
<div style="padding:5px">
<div *ngIf="!image_errored && file.thumbnailURL" class="img-div">
<img class="image" (error)="onImgError($event)" [src]="file.thumbnailURL" alt="Thumbnail">
</div>
<span class="max-two-lines"><strong>{{file.title}}</strong></span>
</div>
</mat-card>
</div>

View File

@@ -0,0 +1,69 @@
.example-card {
width: 200px;
height: 200px;
padding: 0px;
cursor: pointer;
}
.menuButton {
right: 0px;
top: -1px;
position: absolute;
z-index: 999;
}
/* Coerce the <span> icon container away from display:inline */
.mat-icon-button .mat-button-wrapper {
display: flex;
justify-content: center;
}
.image {
width: 200px;
height: 112.5px;
object-fit: cover;
}
.example-full-width-height {
width: 100%;
height: 100%
}
.centered {
margin: 0 auto;
top: 50%;
left: 50%;
}
.img-div {
max-height: 80px;
padding: 0px;
margin: 32px 0px 0px -5px;
width: calc(100% + 5px + 5px);
}
.max-two-lines {
display: -webkit-box;
display: -moz-box;
max-height: 2.4em;
line-height: 1.2em;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
bottom: 5px;
position: absolute;
}
@media (max-width: 576px){
.example-card {
width: 175px !important;
}
.image {
width: 175px;
}
}

View File

@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SubscriptionFileCardComponent } from './subscription-file-card.component';
describe('SubscriptionFileCardComponent', () => {
let component: SubscriptionFileCardComponent;
let fixture: ComponentFixture<SubscriptionFileCardComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SubscriptionFileCardComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SubscriptionFileCardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,56 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { MatSnackBar } from '@angular/material';
import { Router } from '@angular/router';
@Component({
selector: 'app-subscription-file-card',
templateUrl: './subscription-file-card.component.html',
styleUrls: ['./subscription-file-card.component.scss']
})
export class SubscriptionFileCardComponent implements OnInit {
image_errored = false;
image_loaded = false;
scrollSubject;
scrollAndLoad;
@Input() file;
@Output() goToFileEmit = new EventEmitter<any>();
constructor(private snackBar: MatSnackBar) {
this.scrollSubject = new Subject();
this.scrollAndLoad = Observable.merge(
Observable.fromEvent(window, 'scroll'),
this.scrollSubject
);
}
ngOnInit() {
}
onImgError(event) {
this.image_errored = true;
}
onHoverResponse() {
this.scrollSubject.next();
}
imageLoaded(loaded) {
this.image_loaded = true;
}
goToFile() {
this.goToFileEmit.emit(this.file.title);
}
public openSnackBar(message: string, action: string) {
this.snackBar.open(message, action, {
duration: 2000,
});
}
}

View File

@@ -0,0 +1,20 @@
<br/>
<button class="back-button" (click)="goBack()" mat-icon-button><mat-icon>arrow_back</mat-icon></button>
<div style="margin-bottom: 15px;">
<h2 style="text-align: center;" *ngIf="subscription">
{{subscription.name}}
</h2>
</div>
<mat-divider style="width: 80%; margin: 0 auto"></mat-divider>
<br/>
<div *ngIf="subscription">
<h4 style="text-align: center; margin-bottom: 20px;">Videos</h4>
<div class="container">
<div class="row">
<div *ngFor="let file of files" class="col mb-4 sub-file-col">
<app-subscription-file-card (goToFileEmit)="goToFile($event)" [file]="file"></app-subscription-file-card>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,9 @@
.sub-file-col {
max-width: 240px;
}
.back-button {
float: left;
position: absolute;
left: 15px;
}

View File

@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SubscriptionComponent } from './subscription.component';
describe('SubscriptionComponent', () => {
let component: SubscriptionComponent;
let fixture: ComponentFixture<SubscriptionComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SubscriptionComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SubscriptionComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,44 @@
import { Component, OnInit } from '@angular/core';
import { PostsService } from 'app/posts.services';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'app-subscription',
templateUrl: './subscription.component.html',
styleUrls: ['./subscription.component.scss']
})
export class SubscriptionComponent implements OnInit {
id = null;
subscription = null;
files: any[] = null;
constructor(private postsService: PostsService, private route: ActivatedRoute, private router: Router) { }
ngOnInit() {
if (this.route.snapshot.paramMap.get('id')) {
this.id = this.route.snapshot.paramMap.get('id');
this.getSubscription();
}
}
goBack() {
this.router.navigate(['/subscriptions']);
}
getSubscription() {
this.postsService.getSubscription(this.id).subscribe(res => {
this.subscription = res['subscription'];
console.log(res['files']);
this.files = res['files'];
});
}
goToFile(name) {
localStorage.setItem('player_navigator', this.router.url);
this.router.navigate(['/player', {fileNames: name, type: 'subscription', subscriptionName: this.subscription.name,
subPlaylist: this.subscription.isPlaylist}]);
}
}