Subscription file cards are now replaced with unified file cards
GetAllFiles can now filter by sub_id Improved API models and added request body docs for GetAllFilespull/657/head
parent
0dd617b438
commit
b5ee0d365c
@ -0,0 +1,9 @@
|
|||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
export enum FileTypeFilter {
|
||||||
|
AUDIO_ONLY = 'audio_only',
|
||||||
|
VIDEO_ONLY = 'video_only',
|
||||||
|
BOTH = 'both',
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
import type { FileTypeFilter } from './FileTypeFilter';
|
||||||
|
import type { Sort } from './Sort';
|
||||||
|
|
||||||
|
export type GetAllFilesRequest = {
|
||||||
|
sort?: Sort;
|
||||||
|
range?: Array<number>;
|
||||||
|
/**
|
||||||
|
* Filter files by title
|
||||||
|
*/
|
||||||
|
text_search?: string;
|
||||||
|
file_type_filter?: FileTypeFilter;
|
||||||
|
/**
|
||||||
|
* Include if you want to filter by subscription
|
||||||
|
*/
|
||||||
|
sub_id?: string;
|
||||||
|
};
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
export type Sort = {
|
||||||
|
/**
|
||||||
|
* Property to sort by
|
||||||
|
*/
|
||||||
|
by?: string;
|
||||||
|
/**
|
||||||
|
* 1 for ascending, -1 for descending
|
||||||
|
*/
|
||||||
|
order?: number;
|
||||||
|
};
|
||||||
@ -1,20 +0,0 @@
|
|||||||
<div style="position: relative; width: fit-content;">
|
|
||||||
<div class="duration-time">
|
|
||||||
<ng-container i18n="Video duration label">Length:</ng-container> {{formattedDuration}}
|
|
||||||
</div>
|
|
||||||
<button [matMenuTriggerFor]="action_menu" class="menuButton" mat-icon-button><mat-icon>more_vert</mat-icon></button>
|
|
||||||
<mat-menu #action_menu="matMenu">
|
|
||||||
<button (click)="openSubscriptionInfoDialog()" mat-menu-item><mat-icon>info</mat-icon><ng-container i18n="Subscription video info button">Info</ng-container></button>
|
|
||||||
<button (click)="deleteAndRedownload()" mat-menu-item><mat-icon>restore</mat-icon><ng-container i18n="Delete and redownload subscription video button">Delete and redownload</ng-container></button>
|
|
||||||
<button (click)="deleteForever()" mat-menu-item *ngIf="sub.archive && use_youtubedl_archive"><mat-icon>delete_forever</mat-icon><ng-container i18n="Delete forever subscription video button">Delete forever</ng-container></button>
|
|
||||||
</mat-menu>
|
|
||||||
<mat-card (click)="goToFile()" 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>
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.duration-time {
|
|
||||||
position: absolute;
|
|
||||||
left: 5px;
|
|
||||||
top: 5px;
|
|
||||||
z-index: 99999;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 576px){
|
|
||||||
|
|
||||||
.example-card {
|
|
||||||
width: 175px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image {
|
|
||||||
width: 175px;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { SubscriptionFileCardComponent } from './subscription-file-card.component';
|
|
||||||
|
|
||||||
describe('SubscriptionFileCardComponent', () => {
|
|
||||||
let component: SubscriptionFileCardComponent;
|
|
||||||
let fixture: ComponentFixture<SubscriptionFileCardComponent>;
|
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
declarations: [ SubscriptionFileCardComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(SubscriptionFileCardComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,98 +0,0 @@
|
|||||||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
|
||||||
import { Observable, Subject } from 'rxjs';
|
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
import { PostsService } from 'app/posts.services';
|
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
|
||||||
import { VideoInfoDialogComponent } from 'app/dialogs/video-info-dialog/video-info-dialog.component';
|
|
||||||
|
|
||||||
@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;
|
|
||||||
|
|
||||||
formattedDuration = null;
|
|
||||||
|
|
||||||
@Input() file;
|
|
||||||
@Input() sub;
|
|
||||||
@Input() use_youtubedl_archive = false;
|
|
||||||
|
|
||||||
@Output() goToFileEmit = new EventEmitter<any>();
|
|
||||||
@Output() reloadSubscription = new EventEmitter<boolean>();
|
|
||||||
|
|
||||||
constructor(private snackBar: MatSnackBar, private postsService: PostsService, private dialog: MatDialog) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
if (this.file.duration) {
|
|
||||||
this.formattedDuration = fancyTimeFormat(this.file.duration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onImgError(event) {
|
|
||||||
this.image_errored = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
imageLoaded(loaded) {
|
|
||||||
this.image_loaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
goToFile() {
|
|
||||||
const emit_obj = {
|
|
||||||
uid: this.file.uid,
|
|
||||||
url: this.file.requested_formats ? this.file.requested_formats[0].url : this.file.url
|
|
||||||
}
|
|
||||||
this.goToFileEmit.emit(emit_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
openSubscriptionInfoDialog() {
|
|
||||||
const dialogRef = this.dialog.open(VideoInfoDialogComponent, {
|
|
||||||
data: {
|
|
||||||
file: this.file,
|
|
||||||
},
|
|
||||||
minWidth: '50vw'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteAndRedownload() {
|
|
||||||
this.postsService.deleteSubscriptionFile(this.sub, this.file.id, false, this.file.uid).subscribe(res => {
|
|
||||||
this.reloadSubscription.emit(true);
|
|
||||||
this.openSnackBar(`Successfully deleted file: '${this.file.id}'`, 'Dismiss.');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteForever() {
|
|
||||||
this.postsService.deleteSubscriptionFile(this.sub, this.file.id, true, this.file.uid).subscribe(res => {
|
|
||||||
this.reloadSubscription.emit(true);
|
|
||||||
this.openSnackBar(`Successfully deleted file: '${this.file.id}'`, 'Dismiss.');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public openSnackBar(message: string, action: string) {
|
|
||||||
this.snackBar.open(message, action, {
|
|
||||||
duration: 2000,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function fancyTimeFormat(time) {
|
|
||||||
// Hours, minutes and seconds
|
|
||||||
const hrs = ~~(time / 3600);
|
|
||||||
const mins = ~~((time % 3600) / 60);
|
|
||||||
const secs = ~~time % 60;
|
|
||||||
|
|
||||||
// Output like "1:01" or "4:03:59" or "123:03:59"
|
|
||||||
let ret = '';
|
|
||||||
|
|
||||||
if (hrs > 0) {
|
|
||||||
ret += '' + hrs + ':' + (mins < 10 ? '0' : '');
|
|
||||||
}
|
|
||||||
|
|
||||||
ret += '' + mins + ':' + (secs < 10 ? '0' : '');
|
|
||||||
ret += '' + secs;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue