Added ability to favorite a file

Moved file filter options above the list of files, and added option to filter for favorites
pull/809/head
Isaac Abadi 3 years ago
parent c45e0f04be
commit 665bcc04a7

@ -1746,6 +1746,9 @@ components:
description: Filter files by title description: Filter files by title
file_type_filter: file_type_filter:
$ref: '#/components/schemas/FileTypeFilter' $ref: '#/components/schemas/FileTypeFilter'
favorite_filter:
type: boolean
description: If set to true, only gets favorites
sub_id: sub_id:
type: string type: string
description: Include if you want to filter by subscription description: Include if you want to filter by subscription
@ -2383,6 +2386,7 @@ components:
- upload_date - upload_date
- uploader - uploader
- url - url
- favorite
type: object type: object
properties: properties:
id: id:
@ -2430,6 +2434,8 @@ components:
abr: abr:
type: number type: number
description: In Kbps description: In Kbps
favorite:
type: boolean
Playlist: Playlist:
required: required:
- uids - uids

@ -926,6 +926,7 @@ app.post('/api/getAllFiles', optionalJwt, async function (req, res) {
const range = req.body.range; const range = req.body.range;
const text_search = req.body.text_search; const text_search = req.body.text_search;
const file_type_filter = req.body.file_type_filter; const file_type_filter = req.body.file_type_filter;
const favorite_filter = req.body.favorite_filter;
const sub_id = req.body.sub_id; const sub_id = req.body.sub_id;
const uuid = req.isAuthenticated() ? req.user.uid : null; const uuid = req.isAuthenticated() ? req.user.uid : null;
@ -939,6 +940,10 @@ app.post('/api/getAllFiles', optionalJwt, async function (req, res) {
} }
} }
if (favorite_filter) {
filter_obj['favorite'] = true;
}
if (sub_id) { if (sub_id) {
filter_obj['sub_id'] = sub_id; filter_obj['sub_id'] = sub_id;
} }

@ -554,6 +554,7 @@ function File(id, title, thumbnailURL, isAudio, duration, url, uploader, size, p
this.view_count = view_count; this.view_count = view_count;
this.height = height; this.height = height;
this.abr = abr; this.abr = abr;
this.favorite = false;
} }
module.exports = { module.exports = {

@ -40,4 +40,5 @@ export type DatabaseFile = {
* In Kbps * In Kbps
*/ */
abr?: number; abr?: number;
favorite: boolean;
}; };

@ -13,6 +13,10 @@ export type GetAllFilesRequest = {
*/ */
text_search?: string; text_search?: string;
file_type_filter?: FileTypeFilter; file_type_filter?: FileTypeFilter;
/**
* If set to true, only gets favorites
*/
favorite_filter?: boolean;
/** /**
* Include if you want to filter by subscription * Include if you want to filter by subscription
*/ */

@ -1,12 +1,13 @@
<div class="container-fluid" style="max-width: 941px;"> <div class="container-fluid" style="max-width: 941px;">
<div class="row"> <div class="row">
<!-- Sorting -->
<div class="col-12 order-2 col-sm-4 order-sm-1 d-flex justify-content-center"> <div class="col-12 order-2 col-sm-4 order-sm-1 d-flex justify-content-center">
<div> <div>
<div style="display: inline-block;"> <div style="display: inline-block;">
<mat-form-field appearance="outline" style="width: 165px;"> <mat-form-field appearance="outline" style="width: 165px;">
<mat-select [(ngModel)]="this.filterProperty" (selectionChange)="filterOptionChanged($event.value)"> <mat-select [(ngModel)]="this.sortProperty" (selectionChange)="filterOptionChanged($event.value)">
<mat-option *ngFor="let filterOption of filterProperties | keyvalue" [value]="filterOption.value"> <mat-option *ngFor="let sortOption of sortProperties | keyvalue" [value]="sortOption.value">
{{filterOption['value']['label']}} {{sortOption['value']['label']}}
</mat-option> </mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
@ -16,10 +17,12 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Files title -->
<div class="col-12 order-1 col-sm-4 order-sm-2 d-flex justify-content-center"> <div class="col-12 order-1 col-sm-4 order-sm-2 d-flex justify-content-center">
<h4 *ngIf="!customHeader" class="my-videos-title" i18n="My files title">My files</h4> <h4 *ngIf="!customHeader" class="my-videos-title" i18n="My files title">My files</h4>
<h4 *ngIf="customHeader" class="my-videos-title">{{customHeader}}</h4> <h4 *ngIf="customHeader" class="my-videos-title">{{customHeader}}</h4>
</div> </div>
<!-- Search -->
<div class="col-12 order-3 col-sm-4 order-sm-3 d-flex justify-content-center"> <div class="col-12 order-3 col-sm-4 order-sm-3 d-flex justify-content-center">
<mat-form-field appearance="outline" [ngClass]="searchIsFocused ? 'search-bar-focused' : 'search-bar-unfocused'" class="search-bar" color="accent"> <mat-form-field appearance="outline" [ngClass]="searchIsFocused ? 'search-bar-focused' : 'search-bar-unfocused'" class="search-bar" color="accent">
<mat-label i18n="Search">Search</mat-label> <mat-label i18n="Search">Search</mat-label>
@ -28,21 +31,30 @@
</mat-form-field> </mat-form-field>
</div> </div>
</div> </div>
<!-- Filters -->
<div class="row justify-content-center">
<mat-chip-listbox class="filter-list" [value]="selectedFilters" [multiple]="true" (change)="selectedFiltersChanged($event)">
<mat-chip-option *ngFor="let filter of fileFilters | keyvalue: originalOrder" [value]="filter.key" [selected]="selectedFilters.includes(filter.key)" color="accent">{{filter.value.label}}</mat-chip-option>
</mat-chip-listbox>
</div>
</div> </div>
<div> <div>
<!-- Files -->
<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">
<!-- Real cards -->
<ng-container *ngIf="normal_files_received && paged_data"> <ng-container *ngIf="normal_files_received && paged_data">
<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' : '' ]"> <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 [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> <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)" (toggleFavorite)="toggleFavorite($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> <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>
</div> </div>
</ng-container> </ng-container>
<ng-container *ngIf="!normal_files_received && loading_files && loading_files.length > 0"> <!-- Fake cards -->
<div *ngFor="let file of loading_files; 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' : '' ]"> <ng-container>
<div *ngFor="let file of loading_files; let i = index" class="mb-2 mt-2 d-flex justify-content-center" [ngClass]="[normal_files_received ? 'hide' : '', 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" [loading]="true" [theme]="postsService.theme"></app-unified-file-card> <app-unified-file-card [index]="i" [card_size]="postsService.card_size" [locale]="postsService.locale" [loading]="true" [theme]="postsService.theme"></app-unified-file-card>
</div> </div>
</ng-container> </ng-container>
@ -50,6 +62,7 @@
</div> </div>
<div *ngIf="selectMode"> <div *ngIf="selectMode">
<!-- If selected files e.g. for creating a playlist -->
<mat-tab-group [(selectedIndex)]="selectedIndex"> <mat-tab-group [(selectedIndex)]="selectedIndex">
<mat-tab label="Order" i18n-label="Order"> <mat-tab label="Order" i18n-label="Order">
<div *ngIf="selected_data.length"> <div *ngIf="selected_data.length">
@ -97,16 +110,6 @@
</div> </div>
<div style="position: relative;" *ngIf="usePaginator && selectedIndex > 0"> <div style="position: relative;" *ngIf="usePaginator && selectedIndex > 0">
<div style="position: absolute; margin-left: 8px; margin-top: -2px; scale: 0.8">
<mat-form-field>
<mat-label><ng-container i18n="File type">File type</ng-container></mat-label>
<mat-select color="accent" [(ngModel)]="fileTypeFilter" (selectionChange)="fileTypeFilterChanged($event.value)">
<mat-option value="both"><ng-container i18n="Both">Both</ng-container></mat-option>
<mat-option value="video_only"><ng-container i18n="Video only">Video only</ng-container></mat-option>
<mat-option value="audio_only"><ng-container i18n="Audio only">Audio only</ng-container></mat-option>
</mat-select>
</mat-form-field>
</div>
<mat-paginator class="paginator" #paginator (page)="pageChangeEvent($event)" [length]="file_count" <mat-paginator class="paginator" #paginator (page)="pageChangeEvent($event)" [length]="file_count"
[pageSize]="pageSize" [pageSize]="pageSize"
[pageSizeOptions]="[5, 10, 25, 100, this.paged_data && this.paged_data.length > 100 ? this.paged_data.length : 250]"> [pageSizeOptions]="[5, 10, 25, 100, this.paged_data && this.paged_data.length > 100 ? this.paged_data.length : 250]">

@ -119,3 +119,11 @@
align-self: center; align-self: center;
position: absolute; position: absolute;
} }
.filter-list {
margin-bottom: 10px;
}
.hide {
display: none !important;
}

@ -6,6 +6,8 @@ import { MatPaginator } from '@angular/material/paginator';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators'; import { distinctUntilChanged } from 'rxjs/operators';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { MatChipListboxChange, MatChipOption } from '@angular/material/chips';
import { KeyValue } from '@angular/common';
@Component({ @Component({
selector: 'app-recent-videos', selector: 'app-recent-videos',
@ -46,35 +48,54 @@ export class RecentVideosComponent implements OnInit {
search_text = ''; search_text = '';
searchIsFocused = false; searchIsFocused = false;
descendingMode = true; descendingMode = true;
filterProperties = { sortProperties = {
'registered': { 'registered': {
'key': 'registered', 'key': 'registered',
'label': 'Download Date', 'label': $localize`Download Date`,
'property': 'registered' 'property': 'registered'
}, },
'upload_date': { 'upload_date': {
'key': 'upload_date', 'key': 'upload_date',
'label': 'Upload Date', 'label': $localize`Upload Date`,
'property': 'upload_date' 'property': 'upload_date'
}, },
'name': { 'name': {
'key': 'name', 'key': 'name',
'label': 'Name', 'label': $localize`Name`,
'property': 'title' 'property': 'title'
}, },
'file_size': { 'file_size': {
'key': 'file_size', 'key': 'file_size',
'label': 'File Size', 'label': $localize`File Size`,
'property': 'size' 'property': 'size'
}, },
'duration': { 'duration': {
'key': 'duration', 'key': 'duration',
'label': 'Duration', 'label': $localize`Duration`,
'property': 'duration' 'property': 'duration'
} }
}; };
filterProperty = this.filterProperties['upload_date'];
fileTypeFilter = 'both'; fileFilters = {
video_only: {
key: 'video_only',
label: $localize`Video only`,
incompatible: ['audio_only']
},
audio_only: {
key: 'audio_only',
label: $localize`Audio only`,
incompatible: ['video_only']
},
favorited: {
key: 'favorited',
label: $localize`Favorited`
},
};
selectedFilters = [];
sortProperty = this.sortProperties['upload_date'];
playlists = null; playlists = null;
@ -88,15 +109,17 @@ export class RecentVideosComponent implements OnInit {
} }
// set filter property to cached value // set filter property to cached value
const cached_filter_property = localStorage.getItem('filter_property'); const cached_sort_property = localStorage.getItem('sort_property');
if (cached_filter_property && this.filterProperties[cached_filter_property]) { if (cached_sort_property && this.sortProperties[cached_sort_property]) {
this.filterProperty = this.filterProperties[cached_filter_property]; this.sortProperty = this.sortProperties[cached_sort_property];
} }
// set file type filter to cached value // set file type filter to cached value
const cached_file_type_filter = localStorage.getItem('file_type_filter'); const cached_file_filter = localStorage.getItem('file_filter');
if (this.usePaginator && cached_file_type_filter) { if (this.usePaginator && cached_file_filter) {
this.fileTypeFilter = cached_file_type_filter; this.selectedFilters = JSON.parse(cached_file_filter)
} else {
this.selectedFilters = [];
} }
const sort_order = localStorage.getItem('recent_videos_sort_order'); const sort_order = localStorage.getItem('recent_videos_sort_order');
@ -107,6 +130,12 @@ export class RecentVideosComponent implements OnInit {
} }
ngOnInit(): void { ngOnInit(): void {
if (this.sub_id) {
// subscriptions can't download both audio and video (for now), so don't let users filter for these
delete this.fileFilters['audio_only'];
delete this.fileFilters['video_only'];
}
if (this.postsService.initialized) { if (this.postsService.initialized) {
this.getAllFiles(); this.getAllFiles();
this.getAllPlaylists(); this.getAllPlaylists();
@ -166,9 +195,37 @@ export class RecentVideosComponent implements OnInit {
this.getAllFiles(); this.getAllFiles();
} }
fileTypeFilterChanged(value: string): void { filterChanged(value: string): void {
localStorage.setItem('file_type_filter', value); localStorage.setItem('file_filter', value);
this.getAllFiles(); // wait a bit for the animation to finish
setTimeout(() => this.getAllFiles(), 150);
}
selectedFiltersChanged(event: MatChipListboxChange): void {
// in some cases this function will fire even if the selected filters haven't changed
if (event.value.length === this.selectedFilters.length) return;
if (event.value.length > this.selectedFilters.length) {
const filter_key = event.value.filter(possible_new_key => !this.selectedFilters.includes(possible_new_key))[0];
this.selectedFilters = this.selectedFilters.filter(existing_filter => !this.fileFilters[existing_filter].incompatible || !this.fileFilters[existing_filter].incompatible.includes(filter_key));
this.selectedFilters.push(filter_key);
} else {
this.selectedFilters = event.value;
}
this.filterChanged(JSON.stringify(this.selectedFilters));
}
getFileTypeFilter(): string {
if (this.selectedFilters.includes('audio_only')) {
return 'audio_only';
} else if (this.selectedFilters.includes('video_only')) {
return 'video_only';
} else {
return 'both';
}
}
getFavoriteFilter(): boolean {
return this.selectedFilters.includes('favorited');
} }
toggleModeChange(): void { toggleModeChange(): void {
@ -182,9 +239,11 @@ export class RecentVideosComponent implements OnInit {
getAllFiles(cache_mode = false): void { 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.sortProperty['property'], order: this.descendingMode ? -1 : 1};
const range = [current_file_index, current_file_index + this.pageSize]; const range = [current_file_index, current_file_index + this.pageSize];
this.postsService.getAllFiles(sort, range, this.search_mode ? this.search_text : null, this.fileTypeFilter as FileTypeFilter, this.sub_id).subscribe(res => { const fileTypeFilter = this.getFileTypeFilter();
const favoriteFilter = this.getFavoriteFilter();
this.postsService.getAllFiles(sort, range, this.search_mode ? this.search_text : null, fileTypeFilter as FileTypeFilter, favoriteFilter, this.sub_id).subscribe(res => {
this.file_count = res['file_count']; this.file_count = res['file_count'];
this.paged_data = res['files']; this.paged_data = res['files'];
for (let i = 0; i < this.paged_data.length; i++) { for (let i = 0; i < this.paged_data.length; i++) {
@ -385,4 +444,13 @@ export class RecentVideosComponent implements OnInit {
this.selected_data_objs.splice(index, 1); this.selected_data_objs.splice(index, 1);
this.fileSelectionEmitter.emit({new_selection: this.selected_data, thumbnailURL: this.selected_data_objs[0].thumbnailURL}); this.fileSelectionEmitter.emit({new_selection: this.selected_data, thumbnailURL: this.selected_data_objs[0].thumbnailURL});
} }
originalOrder = (): number => {
return 0;
}
toggleFavorite(file_obj): void {
file_obj.favorite = !file_obj.favorite;
this.postsService.updateFile(file_obj.uid, {favorite: file_obj.favorite}).subscribe(res => {});
}
} }

@ -21,6 +21,11 @@
</mat-menu> </mat-menu>
<mat-menu #action_menu="matMenu"> <mat-menu #action_menu="matMenu">
<ng-container *ngIf="!is_playlist && !loading"> <ng-container *ngIf="!is_playlist && !loading">
<button (click)="emitToggleFavorite()" mat-menu-item>
<mat-icon>{{file_obj.favorite ? 'favorite_filled' : 'favorite_outline'}}</mat-icon>
<ng-container *ngIf="!file_obj.favorite" i18n="Favorite button">Favorite</ng-container>
<ng-container *ngIf="file_obj.favorite" i18n="Unfavorite button">Unfavorite</ng-container>
</button>
<button (click)="openFileInfoDialog()" mat-menu-item><mat-icon>info</mat-icon><ng-container i18n="Video info button">Info</ng-container></button> <button (click)="openFileInfoDialog()" mat-menu-item><mat-icon>info</mat-icon><ng-container i18n="Video info button">Info</ng-container></button>
<button (click)="navigateToSubscription()" mat-menu-item *ngIf="file_obj.sub_id"><mat-icon>{{file_obj.isAudio ? 'library_music' : 'video_library'}}</mat-icon>&nbsp;<ng-container i18n="Go to subscription menu item">Go to subscription</ng-container></button> <button (click)="navigateToSubscription()" mat-menu-item *ngIf="file_obj.sub_id"><mat-icon>{{file_obj.isAudio ? 'library_music' : 'video_library'}}</mat-icon>&nbsp;<ng-container i18n="Go to subscription menu item">Go to subscription</ng-container></button>
<button [disabled]="!availablePlaylists || availablePlaylists.length === 0" [matMenuTriggerFor]="addtoplaylist" mat-menu-item><mat-icon>playlist_add</mat-icon>&nbsp;<ng-container i18n="Add to playlist menu item">Add to playlist</ng-container></button> <button [disabled]="!availablePlaylists || availablePlaylists.length === 0" [matMenuTriggerFor]="addtoplaylist" mat-menu-item><mat-icon>playlist_add</mat-icon>&nbsp;<ng-container i18n="Add to playlist menu item">Add to playlist</ng-container></button>

@ -21,12 +21,15 @@
.menuButton { .menuButton {
right: 0px; right: 0px;
width: 40px !important; width: 32px !important;
height: 40px !important; height: 32px !important;
position: absolute; position: absolute;
display: flex; display: flex;
align-items: center; align-items: center;
z-index: 999; z-index: 999;
justify-content: center;
padding: 0px !important;
top: 2px;
} }
/* Coerce the <span> icon container away from display:inline */ /* Coerce the <span> icon container away from display:inline */

@ -9,6 +9,7 @@ import localeES from '@angular/common/locales/es';
import localeDE from '@angular/common/locales/de'; import localeDE from '@angular/common/locales/de';
import localeZH from '@angular/common/locales/zh'; import localeZH from '@angular/common/locales/zh';
import localeNB from '@angular/common/locales/nb'; import localeNB from '@angular/common/locales/nb';
import { DatabaseFile } from 'api-types';
registerLocaleData(localeGB); registerLocaleData(localeGB);
registerLocaleData(localeFR); registerLocaleData(localeFR);
@ -50,6 +51,7 @@ export class UnifiedFileCardComponent implements OnInit {
@Input() jwtString = null; @Input() jwtString = null;
@Input() availablePlaylists = null; @Input() availablePlaylists = null;
@Output() goToFile = new EventEmitter<any>(); @Output() goToFile = new EventEmitter<any>();
@Output() toggleFavorite = new EventEmitter<DatabaseFile>();
@Output() goToSubscription = new EventEmitter<any>(); @Output() goToSubscription = new EventEmitter<any>();
@Output() deleteFile = new EventEmitter<any>(); @Output() deleteFile = new EventEmitter<any>();
@Output() addFileToPlaylist = new EventEmitter<any>(); @Output() addFileToPlaylist = new EventEmitter<any>();
@ -158,6 +160,10 @@ export class UnifiedFileCardComponent implements OnInit {
this.hide_image = false; this.hide_image = false;
} }
emitToggleFavorite() {
this.toggleFavorite.emit(this.file_obj);
}
} }
function fancyTimeFormat(time) { function fancyTimeFormat(time) {

@ -1,4 +1,7 @@
<h4 mat-dialog-title>{{file.title}}</h4> <h4 mat-dialog-title>
{{file.title}}
<button [disabled]="!initialized || retrieving_file" (click)="toggleFavorite()" mat-icon-button class="favorite-button"><mat-icon>{{file.favorite ? 'favorite_filled' : 'favorite_outline'}}</mat-icon></button>
</h4>
<mat-dialog-content> <mat-dialog-content>
<div style="width: 100%; position: relative;"> <div style="width: 100%; position: relative;">

@ -24,3 +24,9 @@
.a-wrap { .a-wrap {
word-wrap: break-word word-wrap: break-word
} }
.favorite-button {
position: absolute;
right: 4px;
top: 4px;
}

@ -19,6 +19,7 @@ export class VideoInfoDialogComponent implements OnInit {
category: Category; category: Category;
editing = false; editing = false;
initialized = false; initialized = false;
retrieving_file = false;
constructor(@Inject(MAT_DIALOG_DATA) public data: any, public postsService: PostsService, private datePipe: DatePipe) { } constructor(@Inject(MAT_DIALOG_DATA) public data: any, public postsService: PostsService, private datePipe: DatePipe) { }
@ -58,9 +59,14 @@ export class VideoInfoDialogComponent implements OnInit {
} }
getFile(): void { getFile(): void {
this.retrieving_file = true;
this.postsService.getFile(this.file.uid).subscribe(res => { this.postsService.getFile(this.file.uid).subscribe(res => {
this.retrieving_file = false;
this.file = res['file']; this.file = res['file'];
this.initializeFile(this.file); this.initializeFile(this.file);
}, err => {
this.retrieving_file = false;
console.error(err);
}); });
} }
@ -85,4 +91,12 @@ export class VideoInfoDialogComponent implements OnInit {
return JSON.stringify(this.file) !== JSON.stringify(this.new_file); return JSON.stringify(this.file) !== JSON.stringify(this.new_file);
} }
toggleFavorite(): void {
this.file.favorite = !this.file.favorite;
this.retrieving_file = true;
this.postsService.updateFile(this.file.uid, {favorite: this.file.favorite}).subscribe(res => {
this.getFile();
});
}
} }

@ -377,8 +377,8 @@ export class PostsService implements CanActivate {
return this.http.post<GetFileResponse>(this.path + 'getFile', body, this.httpOptions); return this.http.post<GetFileResponse>(this.path + 'getFile', body, this.httpOptions);
} }
getAllFiles(sort: Sort = null, range: number[] = null, text_search: string = null, file_type_filter: FileTypeFilter = FileTypeFilter.BOTH, sub_id: string = null) { getAllFiles(sort: Sort = null, range: number[] = null, text_search: string = null, file_type_filter: FileTypeFilter = FileTypeFilter.BOTH, favorite_filter = false, sub_id: string = null) {
const body: GetAllFilesRequest = {sort: sort, range: range, text_search: text_search, file_type_filter: file_type_filter, sub_id: sub_id}; const body: GetAllFilesRequest = {sort: sort, range: range, text_search: text_search, file_type_filter: file_type_filter, favorite_filter: favorite_filter, sub_id: sub_id};
return this.http.post<GetAllFilesResponse>(this.path + 'getAllFiles', body, this.httpOptions); return this.http.post<GetAllFilesResponse>(this.path + 'getAllFiles', body, this.httpOptions);
} }

Loading…
Cancel
Save