Updated translation details to improve clarity

Added upload date property to files in UI

Subscription videos can now be filtered by some of their properties (size, upload date, name, duration)

Subscription videos are now centered
This commit is contained in:
Isaac Grynsztein
2020-03-17 21:38:49 -04:00
parent 9dc607e7ee
commit b2730926c8
8 changed files with 128 additions and 41 deletions

View File

@@ -84,7 +84,7 @@ app.use(bodyParser.json());
// objects
function File(id, title, thumbnailURL, isAudio, duration, url = null, uploader = null, size = null, path = null) {
function File(id, title, thumbnailURL, isAudio, duration, url, uploader, size, path, upload_date) {
this.id = id;
this.title = title;
this.thumbnailURL = thumbnailURL;
@@ -94,6 +94,7 @@ function File(id, title, thumbnailURL, isAudio, duration, url = null, uploader =
this.uploader = uploader;
this.size = size;
this.path = path;
this.upload_date = upload_date;
}
// actual functions
@@ -964,12 +965,15 @@ app.post('/api/getMp3s', function(req, res) {
var title = jsonobj.title;
var url = jsonobj.webpage_url;
var uploader = jsonobj.uploader;
var upload_date = jsonobj.upload_date;
upload_date = `${upload_date.substring(0, 4)}-${upload_date.substring(4, 6)}-${upload_date.substring(6, 8)}`;
var size = stats.size;
var thumbnail = jsonobj.thumbnail;
var duration = jsonobj.duration;
var isaudio = true;
var file_obj = new File(id, title, thumbnail, isaudio, duration, url, uploader, size, file);
var file_obj = new File(id, title, thumbnail, isaudio, duration, url, uploader, size, file, upload_date);
mp3s.push(file_obj);
}
@@ -998,12 +1002,15 @@ app.post('/api/getMp4s', function(req, res) {
var title = jsonobj.title;
var url = jsonobj.webpage_url;
var uploader = jsonobj.uploader;
var size = stats.size;
var upload_date = jsonobj.upload_date;
upload_date = `${upload_date.substring(0, 4)}-${upload_date.substring(4, 6)}-${upload_date.substring(6, 8)}`;
var thumbnail = jsonobj.thumbnail;
var duration = jsonobj.duration;
var size = stats.size;
var isaudio = false;
var file_obj = new File(id, title, thumbnail, isaudio, duration, url, uploader, size, file);
var file_obj = new File(id, title, thumbnail, isaudio, duration, url, uploader, size, file, upload_date);
mp4s.push(file_obj);
}
@@ -1118,10 +1125,12 @@ app.post('/api/getSubscription', async (req, res) => {
var duration = jsonobj.duration;
var url = jsonobj.webpage_url;
var uploader = jsonobj.uploader;
var upload_date = jsonobj.upload_date;
upload_date = `${upload_date.substring(0, 4)}-${upload_date.substring(4, 6)}-${upload_date.substring(6, 8)}`;
var size = stats.size;
var isaudio = false;
var file_obj = new File(id, title, thumbnail, isaudio, duration, url, uploader, size, file);
var file_obj = new File(id, title, thumbnail, isaudio, duration, url, uploader, size, file, upload_date);
parsed_files.push(file_obj);
}

View File

@@ -2,25 +2,29 @@
<mat-dialog-content>
<div class="info-item">
<div class="info-item-label"><strong><ng-container i18n="Subscription video name property">Name:</ng-container>&nbsp;</strong></div>
<div class="info-item-label"><strong><ng-container i18n="Video name property">Name:</ng-container>&nbsp;</strong></div>
<div class="info-item-value">{{file.title}}</div>
</div>
<div class="info-item">
<div class="info-item-label"><strong><ng-container i18n="Subscription video URL property">URL:</ng-container>&nbsp;</strong></div>
<div class="info-item-label"><strong><ng-container i18n="Video URL property">URL:</ng-container>&nbsp;</strong></div>
<div class="info-item-value"><a target="_blank" [href]="file.url">{{file.url}}</a></div>
</div>
<div class="info-item">
<div class="info-item-label"><strong><ng-container i18n="Subscription video ID property">Uploader:</ng-container>&nbsp;</strong></div>
<div class="info-item-label"><strong><ng-container i18n="Video ID property">Uploader:</ng-container>&nbsp;</strong></div>
<div class="info-item-value">{{file.uploader ? file.uploader : 'N/A'}}</div>
</div>
<div class="info-item">
<div class="info-item-label"><strong><ng-container i18n="Subscription video file size property">File size:</ng-container>&nbsp;</strong></div>
<div class="info-item-label"><strong><ng-container i18n="Video file size property">File size:</ng-container>&nbsp;</strong></div>
<div class="info-item-value">{{filesize(file.size)}}</div>
</div>
<div class="info-item">
<div class="info-item-label"><strong><ng-container i18n="Subscription video path property">Path:</ng-container>&nbsp;</strong></div>
<div class="info-item-label"><strong><ng-container i18n="Video path property">Path:</ng-container>&nbsp;</strong></div>
<div class="info-item-value">{{file.path}}</div>
</div>
<div class="info-item">
<div class="info-item-label"><strong><ng-container i18n="Video upload date property">Upload Date:</ng-container>&nbsp;</strong></div>
<div class="info-item-value">{{file.upload_date}}</div>
</div>
</mat-dialog-content>
<mat-dialog-actions>

View File

@@ -19,7 +19,7 @@
<button *ngIf="isPlaylist" (click)="deleteFile()" class="deleteButton" mat-icon-button><mat-icon>delete_forever</mat-icon></button>
<button [matMenuTriggerFor]="action_menu" *ngIf="!isPlaylist" class="deleteButton" 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="Video info button">Info</ng-container></button>
<button (click)="openVideoInfoDialog()" mat-menu-item><mat-icon>info</mat-icon><ng-container i18n="Video info button">Info</ng-container></button>
<button (click)="deleteFile()" mat-menu-item><mat-icon>delete</mat-icon><ng-container i18n="Delete video button">Delete</ng-container></button>
<button *ngIf="use_youtubedl_archive" (click)="deleteFile(true)" mat-menu-item><mat-icon>delete_forever</mat-icon><ng-container i18n="Delete and blacklist video button">Delete and blacklist</ng-container></button>
</mat-menu>

View File

@@ -61,11 +61,12 @@ export class FileCardComponent implements OnInit {
}
openSubscriptionInfoDialog() {
openVideoInfoDialog() {
const dialogRef = this.dialog.open(VideoInfoDialogComponent, {
data: {
file: this.file,
}
},
minWidth: '50vw'
});
}

View File

@@ -61,7 +61,8 @@ export class SubscriptionFileCardComponent implements OnInit {
const dialogRef = this.dialog.open(VideoInfoDialogComponent, {
data: {
file: this.file,
}
},
minWidth: '50vw'
});
}

View File

@@ -1,30 +1,44 @@
<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">
<div class="flex-grid">
<div class="col"></div>
<div class="col">
<h4 i18n="Subscription videos title" style="text-align: center; margin-bottom: 20px;">Videos</h4>
</div>
<div class="col">
<mat-form-field [ngClass]="searchIsFocused ? 'search-bar-focused' : 'search-bar-unfocused'" class="search-bar" color="accent">
<input (focus)="searchIsFocused = true" (blur)="searchIsFocused = false" class="search-input" type="text" placeholder="Search" i18n-placeholder="Subscription videos search placeholder" [(ngModel)]="search_text" (ngModelChange)="onSearchInputChanged($event)" matInput>
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
</div>
<div style="margin-top: 14px;">
<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>
<div class="container">
<div class="row">
<div *ngFor="let file of filtered_files" class="col-6 col-lg-4 mb-2 mt-2 sub-file-col">
<app-subscription-file-card (reloadSubscription)="getSubscription()" (goToFileEmit)="goToFile($event)" [file]="file" [sub]="subscription" [use_youtubedl_archive]="use_youtubedl_archive"></app-subscription-file-card>
<mat-divider style="width: 80%; margin: 0 auto"></mat-divider>
<br/>
<div *ngIf="subscription">
<div class="flex-grid">
<div class="filter-select-parent">
<div style="display: inline-block;">
<mat-select style="width: 110px;" [(ngModel)]="this.filterProperty" (selectionChange)="filterOptionChanged($event.value)">
<mat-option *ngFor="let filterOption of filterProperties | keyvalue" [value]="filterOption.value">
{{filterOption['value']['label']}}
</mat-option>
</mat-select>
</div>
<div style="display: inline-block;">
<button (click)="toggleModeChange()" mat-icon-button><mat-icon>{{descendingMode ? 'arrow_downward' : 'arrow_upward'}}</mat-icon></button>
</div>
</div>
<div class="col">
</div>
<div class="col">
<h4 i18n="Subscription videos title" style="text-align: center; margin-bottom: 20px;">Videos</h4>
</div>
<div style="top: -12px;" class="col">
<mat-form-field [ngClass]="searchIsFocused ? 'search-bar-focused' : 'search-bar-unfocused'" class="search-bar" color="accent">
<input (focus)="searchIsFocused = true" (blur)="searchIsFocused = false" class="search-input" type="text" placeholder="Search" i18n-placeholder="Subscription videos search placeholder" [(ngModel)]="search_text" (ngModelChange)="onSearchInputChanged($event)" matInput>
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
</div>
</div>
<div class="container">
<div class="row justify-content-center">
<div *ngFor="let file of filtered_files" class="col-6 col-lg-4 mb-2 mt-2 sub-file-col">
<app-subscription-file-card (reloadSubscription)="getSubscription()" (goToFileEmit)="goToFile($event)" [file]="file" [sub]="subscription" [use_youtubedl_archive]="use_youtubedl_archive"></app-subscription-file-card>
</div>
</div>
</div>
</div>

View File

@@ -8,6 +8,13 @@
left: 15px;
}
.filter-select-parent {
position: absolute;
top: 0px;
left: 20px;
display: block;
}
.search-bar {
transition: all .5s ease;
position: relative;
@@ -29,6 +36,7 @@
.flex-grid {
width: 100%;
display: block;
position: relative;
}
.col {
width: 33%;

View File

@@ -17,6 +17,30 @@ export class SubscriptionComponent implements OnInit {
search_mode = false;
search_text = '';
searchIsFocused = false;
descendingMode = true;
filterProperties = {
'upload_date': {
'key': 'upload_date',
'label': 'Upload Date',
'property': 'upload_date'
},
'name': {
'key': 'name',
'label': 'Name',
'property': 'title'
},
'file_size': {
'key': 'file_size',
'label': 'File Size',
'property': 'size'
},
'duration': {
'key': 'duration',
'label': 'Duration',
'property': 'duration'
}
};
filterProperty = this.filterProperties['upload_date'];
constructor(private postsService: PostsService, private route: ActivatedRoute, private router: Router) { }
@@ -27,6 +51,12 @@ export class SubscriptionComponent implements OnInit {
this.getSubscription();
this.getConfig();
}
// set filter property to cached
const cached_filter_property = localStorage.getItem('filter_property');
if (cached_filter_property && this.filterProperties[cached_filter_property]) {
this.filterProperty = this.filterProperties[cached_filter_property];
}
}
goBack() {
@@ -42,6 +72,7 @@ export class SubscriptionComponent implements OnInit {
} else {
this.filtered_files = this.files;
}
this.filterByProperty(this.filterProperty['property']);
});
}
@@ -72,4 +103,23 @@ export class SubscriptionComponent implements OnInit {
this.filtered_files = this.files.filter(option => option.id.toLowerCase().includes(filterValue));
}
filterByProperty(prop) {
if (this.descendingMode) {
this.filtered_files = this.filtered_files.sort((a, b) => (a[prop] > b[prop] ? -1 : 1));
} else {
this.filtered_files = this.filtered_files.sort((a, b) => (a[prop] > b[prop] ? 1 : -1));
}
}
filterOptionChanged(value) {
// this.filterProperty = value;
this.filterByProperty(value['property']);
localStorage.setItem('filter_property', value['key']);
}
toggleModeChange() {
this.descendingMode = !this.descendingMode;
this.filterByProperty(this.filterProperty['property']);
}
}