Improved UI for download only mode

Updated API model for DatabaseFile
pull/657/head
Isaac Abadi 3 years ago
parent bec158f65d
commit 6d3f5e6c94

@ -2421,6 +2421,10 @@ components:
type: number type: number
local_view_count: local_view_count:
type: number type: number
sub_id:
type: string
registered:
type: number
Playlist: Playlist:
required: required:
- uids - uids

@ -30,4 +30,6 @@ export type DatabaseFile = {
category?: Category; category?: Category;
view_count?: number; view_count?: number;
local_view_count?: number; local_view_count?: number;
sub_id?: string;
registered?: number;
}; };

@ -32,8 +32,9 @@
<div *ngIf="!selectMode" class="container" style="margin-bottom: 16px"> <div *ngIf="!selectMode" class="container" style="margin-bottom: 16px">
<div class="row justify-content-center"> <div class="row justify-content-center">
<ng-container *ngIf="normal_files_received && paged_data"> <ng-container *ngIf="normal_files_received && paged_data">
<div *ngFor="let file of paged_data; let i = index" class="mb-2 mt-2 d-flex justify-content-center" [ngClass]="[ postsService.card_size === 'small' ? 'col-2 small-col' : '', postsService.card_size === 'medium' ? 'col-6 col-lg-4 medium-col' : '', postsService.card_size === 'large' ? 'col-12 large-col' : '' ]"> <div style="display: flex; align-items: center;" *ngFor="let file of paged_data; let i = index" class="mb-2 mt-2 d-flex justify-content-center" [ngClass]="[ postsService.card_size === 'small' ? 'col-2 small-col' : '', postsService.card_size === 'medium' ? 'col-6 col-lg-4 medium-col' : '', postsService.card_size === 'large' ? 'col-12 large-col' : '' ]">
<app-unified-file-card [index]="i" [card_size]="postsService.card_size" [locale]="postsService.locale" (goToFile)="goToFile($event)" (goToSubscription)="goToSubscription($event)" [file_obj]="file" [use_youtubedl_archive]="postsService.config['Downloader']['use_youtubedl_archive']" [availablePlaylists]="playlists" (addFileToPlaylist)="addFileToPlaylist($event)" [loading]="false" (deleteFile)="deleteFile($event)" [baseStreamPath]="postsService.path" [jwtString]="postsService.isLoggedIn ? this.postsService.token : ''"></app-unified-file-card> <app-unified-file-card [ngClass]="downloading_content[file.uid] ? 'blurred' : ''" [index]="i" [card_size]="postsService.card_size" [locale]="postsService.locale" (goToFile)="goToFile($event)" (goToSubscription)="goToSubscription($event)" [file_obj]="file" [use_youtubedl_archive]="postsService.config['Downloader']['use_youtubedl_archive']" [availablePlaylists]="playlists" (addFileToPlaylist)="addFileToPlaylist($event)" [loading]="false" (deleteFile)="deleteFile($event)" [baseStreamPath]="postsService.path" [jwtString]="postsService.isLoggedIn ? this.postsService.token : ''"></app-unified-file-card>
<mat-spinner *ngIf="downloading_content[file.uid]" class="downloading-spinner" [diameter]="32"></mat-spinner>
</div> </div>
<div *ngIf="paged_data.length === 0"> <div *ngIf="paged_data.length === 0">
<ng-container i18n="No files found">No files found.</ng-container> <ng-container i18n="No files found">No files found.</ng-container>

@ -109,4 +109,13 @@
text-overflow: ellipsis; text-overflow: ellipsis;
max-width: 70%; max-width: 70%;
margin: 0 auto; margin: 0 auto;
}
.blurred {
filter: blur(2px);
}
.downloading-spinner {
align-self: center;
position: absolute;
} }

@ -41,7 +41,7 @@ export class RecentVideosComponent implements OnInit {
subscription_files_received = false; subscription_files_received = false;
file_count = 10; file_count = 10;
searchChangedSubject: Subject<string> = new Subject<string>(); searchChangedSubject: Subject<string> = new Subject<string>();
downloading_content = {'video': {}, 'audio': {}}; downloading_content = {};
search_mode = false; search_mode = false;
search_text = ''; search_text = '';
searchIsFocused = false; searchIsFocused = false;
@ -148,7 +148,7 @@ export class RecentVideosComponent implements OnInit {
}); });
} }
getAllPlaylists() { getAllPlaylists(): void {
this.postsService.getPlaylists().subscribe(res => { this.postsService.getPlaylists().subscribe(res => {
this.playlists = res['playlists']; this.playlists = res['playlists'];
}); });
@ -156,22 +156,22 @@ export class RecentVideosComponent implements OnInit {
// search // search
onSearchInputChanged(newvalue) { onSearchInputChanged(newvalue: string): void {
this.normal_files_received = false; this.normal_files_received = false;
this.searchChangedSubject.next(newvalue); this.searchChangedSubject.next(newvalue);
} }
filterOptionChanged(value) { filterOptionChanged(value: string): void {
localStorage.setItem('filter_property', value['key']); localStorage.setItem('filter_property', value['key']);
this.getAllFiles(); this.getAllFiles();
} }
fileTypeFilterChanged(value) { fileTypeFilterChanged(value: string): void {
localStorage.setItem('file_type_filter', value); localStorage.setItem('file_type_filter', value);
this.getAllFiles(); this.getAllFiles();
} }
toggleModeChange() { toggleModeChange(): void {
this.descendingMode = !this.descendingMode; this.descendingMode = !this.descendingMode;
localStorage.setItem('recent_videos_sort_order', this.descendingMode ? 'descending' : 'ascending'); localStorage.setItem('recent_videos_sort_order', this.descendingMode ? 'descending' : 'ascending');
this.getAllFiles(); this.getAllFiles();
@ -179,7 +179,7 @@ export class RecentVideosComponent implements OnInit {
// get files // get files
getAllFiles(cache_mode = false) { getAllFiles(cache_mode = false): void {
this.normal_files_received = cache_mode; this.normal_files_received = cache_mode;
const current_file_index = (this.paginator?.pageIndex ? this.paginator.pageIndex : 0)*this.pageSize; const current_file_index = (this.paginator?.pageIndex ? this.paginator.pageIndex : 0)*this.pageSize;
const sort = {by: this.filterProperty['property'], order: this.descendingMode ? -1 : 1}; const sort = {by: this.filterProperty['property'], order: this.descendingMode ? -1 : 1};
@ -212,7 +212,7 @@ export class RecentVideosComponent implements OnInit {
} }
} }
navigateToFile(file, new_tab) { navigateToFile(file: DatabaseFile, new_tab: boolean): void {
localStorage.setItem('player_navigator', this.router.url); localStorage.setItem('player_navigator', this.router.url);
if (file.sub_id) { if (file.sub_id) {
const sub = this.postsService.getSubscriptionByID(file.sub_id); const sub = this.postsService.getSubscriptionByID(file.sub_id);
@ -234,46 +234,26 @@ export class RecentVideosComponent implements OnInit {
} }
} }
goToSubscription(file) { goToSubscription(file: DatabaseFile): void {
this.router.navigate(['/subscription', {id: file.sub_id}]); this.router.navigate(['/subscription', {id: file.sub_id}]);
} }
// downloading // downloading
downloadFile(file) { downloadFile(file: DatabaseFile): void {
if (file.sub_id) {
this.downloadSubscriptionFile(file);
} else {
this.downloadNormalFile(file);
}
}
downloadSubscriptionFile(file) {
const type = (file.isAudio ? 'audio' : 'video') as FileType;
const ext = type === 'audio' ? '.mp3' : '.mp4'
const sub = this.postsService.getSubscriptionByID(file.sub_id);
this.postsService.downloadFileFromServer(file.uid).subscribe(res => {
const blob: Blob = res;
saveAs(blob, file.id + ext);
}, err => {
console.log(err);
});
}
downloadNormalFile(file) {
const type = (file.isAudio ? 'audio' : 'video') as FileType; const type = (file.isAudio ? 'audio' : 'video') as FileType;
const ext = type === 'audio' ? '.mp3' : '.mp4' const ext = type === 'audio' ? '.mp3' : '.mp4'
const name = file.id; const name = file.id;
this.downloading_content[type][name] = true; this.downloading_content[file.uid] = true;
this.postsService.downloadFileFromServer(file.uid).subscribe(res => { this.postsService.downloadFileFromServer(file.uid).subscribe(res => {
this.downloading_content[type][name] = false; this.downloading_content[file.uid] = false;
const blob: Blob = res; const blob: Blob = res;
saveAs(blob, decodeURIComponent(name) + ext); saveAs(blob, decodeURIComponent(name) + ext);
if (!this.postsService.config.Extra.file_manager_enabled) { if (!this.postsService.config.Extra.file_manager_enabled && !file.sub_id) {
// tell server to delete the file once downloaded // tell server to delete the file once downloaded
this.postsService.deleteFile(file.uid).subscribe(delRes => { this.postsService.deleteFile(file.uid).subscribe(() => {
// reload mp4s // reload files
this.getAllFiles(); this.getAllFiles();
}); });
} }
@ -284,7 +264,6 @@ export class RecentVideosComponent implements OnInit {
deleteFile(args) { deleteFile(args) {
const file = args.file; const file = args.file;
const index = args.index;
const blacklistMode = args.blacklistMode; const blacklistMode = args.blacklistMode;
if (file.sub_id) { if (file.sub_id) {
@ -294,7 +273,7 @@ export class RecentVideosComponent implements OnInit {
} }
} }
deleteNormalFile(file, blacklistMode = false) { deleteNormalFile(file: DatabaseFile, blacklistMode = false): void {
this.postsService.deleteFile(file.uid, blacklistMode).subscribe(result => { this.postsService.deleteFile(file.uid, blacklistMode).subscribe(result => {
if (result) { if (result) {
this.postsService.openSnackBar($localize`Delete success!', 'OK.`); this.postsService.openSnackBar($localize`Delete success!', 'OK.`);
@ -302,12 +281,12 @@ export class RecentVideosComponent implements OnInit {
} else { } else {
this.postsService.openSnackBar($localize`Delete failed!', 'OK.`); this.postsService.openSnackBar($localize`Delete failed!', 'OK.`);
} }
}, err => { }, () => {
this.postsService.openSnackBar($localize`Delete failed!', 'OK.`); this.postsService.openSnackBar($localize`Delete failed!', 'OK.`);
}); });
} }
deleteSubscriptionFile(file, blacklistMode = false) { deleteSubscriptionFile(file: DatabaseFile, blacklistMode = false): void {
if (blacklistMode) { if (blacklistMode) {
this.deleteForever(file); this.deleteForever(file);
} else { } else {
@ -315,23 +294,23 @@ export class RecentVideosComponent implements OnInit {
} }
} }
deleteAndRedownload(file) { deleteAndRedownload(file: DatabaseFile): void {
const sub = this.postsService.getSubscriptionByID(file.sub_id); const sub = this.postsService.getSubscriptionByID(file.sub_id);
this.postsService.deleteSubscriptionFile(sub, file.id, false, file.uid).subscribe(res => { this.postsService.deleteSubscriptionFile(sub, file.id, false, file.uid).subscribe(() => {
this.postsService.openSnackBar(`Successfully deleted file: '${file.id}'`); this.postsService.openSnackBar(`Successfully deleted file: '${file.id}'`);
this.removeFileCard(file); this.removeFileCard(file);
}); });
} }
deleteForever(file) { deleteForever(file: DatabaseFile): void {
const sub = this.postsService.getSubscriptionByID(file.sub_id); const sub = this.postsService.getSubscriptionByID(file.sub_id);
this.postsService.deleteSubscriptionFile(sub, file.id, true, file.uid).subscribe(res => { this.postsService.deleteSubscriptionFile(sub, file.id, true, file.uid).subscribe(() => {
this.postsService.openSnackBar(`Successfully deleted file: '${file.id}'`); this.postsService.openSnackBar(`Successfully deleted file: '${file.id}'`);
this.removeFileCard(file); this.removeFileCard(file);
}); });
} }
removeFileCard(file_to_remove) { removeFileCard(file_to_remove: DatabaseFile): void {
const index = this.paged_data.map(e => e.uid).indexOf(file_to_remove.uid); const index = this.paged_data.map(e => e.uid).indexOf(file_to_remove.uid);
this.paged_data.splice(index, 1); this.paged_data.splice(index, 1);
this.getAllFiles(true); this.getAllFiles(true);
@ -356,13 +335,13 @@ export class RecentVideosComponent implements OnInit {
// sorting and filtering // sorting and filtering
sortFiles(a, b) { sortFiles(a: DatabaseFile, b: DatabaseFile): number {
// uses the 'registered' flag as the timestamp // uses the 'registered' flag as the timestamp
const result = b.registered - a.registered; const result = b.registered - a.registered;
return result; return result;
} }
durationStringToNumber(dur_str) { durationStringToNumber(dur_str: string): number {
let num_sum = 0; let num_sum = 0;
const dur_str_parts = dur_str.split(':'); const dur_str_parts = dur_str.split(':');
for (let i = dur_str_parts.length - 1; i >= 0; i--) { for (let i = dur_str_parts.length - 1; i >= 0; i--) {

Loading…
Cancel
Save