mirror of
https://github.com/Tzahi12345/YoutubeDL-Material.git
synced 2026-04-18 13:11:28 +03:00
Added ability to generate RSS feed URLs from the UI
Moved property sorting into its own component
This commit is contained in:
@@ -2029,13 +2029,13 @@ app.get('/api/rss', async function (req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// these are returned
|
// these are returned
|
||||||
const sort = req.query.sort;
|
const sort = req.query.sort ? JSON.parse(decodeURIComponent(req.query.sort)) : {by: 'registered', order: -1};
|
||||||
const range = req.query.range;
|
const range = req.query.range ? req.query.range.map(range_num => parseInt(range_num)) : null;
|
||||||
const text_search = req.query.text_search;
|
const text_search = req.query.text_search ? decodeURIComponent(req.query.text_search) : null;
|
||||||
const file_type_filter = req.query.file_type_filter;
|
const file_type_filter = req.query.file_type_filter;
|
||||||
const favorite_filter = req.query.favorite_filter;
|
const favorite_filter = req.query.favorite_filter === 'true';
|
||||||
const sub_id = req.query.sub_id;
|
const sub_id = req.query.sub_id ? decodeURIComponent(req.query.sub_id) : null;
|
||||||
const uuid = req.query.uuid;
|
const uuid = req.query.uuid ? decodeURIComponent(req.query.uuid) : null;
|
||||||
|
|
||||||
const {files} = await db_api.getAllFiles(sort, range, text_search, file_type_filter, favorite_filter, sub_id, uuid);
|
const {files} = await db_api.getAllFiles(sort, range, text_search, file_type_filter, favorite_filter, sub_id, uuid);
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ import { RestoreDbDialogComponent } from './dialogs/restore-db-dialog/restore-db
|
|||||||
import { NotificationsComponent } from './components/notifications/notifications.component';
|
import { NotificationsComponent } from './components/notifications/notifications.component';
|
||||||
import { NotificationsListComponent } from './components/notifications-list/notifications-list.component';
|
import { NotificationsListComponent } from './components/notifications-list/notifications-list.component';
|
||||||
import { TaskSettingsComponent } from './components/task-settings/task-settings.component';
|
import { TaskSettingsComponent } from './components/task-settings/task-settings.component';
|
||||||
|
import { GenerateRssUrlComponent } from './dialogs/generate-rss-url/generate-rss-url.component';
|
||||||
|
import { SortPropertyComponent } from './components/sort-property/sort-property.component';
|
||||||
|
|
||||||
registerLocaleData(es, 'es');
|
registerLocaleData(es, 'es');
|
||||||
|
|
||||||
@@ -139,7 +141,9 @@ registerLocaleData(es, 'es');
|
|||||||
RestoreDbDialogComponent,
|
RestoreDbDialogComponent,
|
||||||
NotificationsComponent,
|
NotificationsComponent,
|
||||||
NotificationsListComponent,
|
NotificationsListComponent,
|
||||||
TaskSettingsComponent
|
TaskSettingsComponent,
|
||||||
|
GenerateRssUrlComponent,
|
||||||
|
SortPropertyComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
|||||||
@@ -2,20 +2,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<!-- Sorting -->
|
<!-- 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>
|
<app-sort-property [(sortProperty)]="sortProperty" [(descendingMode)]="descendingMode" (sortOptionChanged)="sortOptionChanged($event)"></app-sort-property>
|
||||||
<div style="display: inline-block;">
|
|
||||||
<mat-form-field appearance="outline" style="width: 165px;">
|
|
||||||
<mat-select [(ngModel)]="this.sortProperty" (selectionChange)="filterOptionChanged($event.value)">
|
|
||||||
<mat-option *ngFor="let sortOption of sortProperties | keyvalue" [value]="sortOption.value">
|
|
||||||
{{sortOption['value']['label']}}
|
|
||||||
</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
<div class="sort-dir-div">
|
|
||||||
<button (click)="toggleModeChange()" mat-icon-button><mat-icon>{{descendingMode ? 'arrow_downward' : 'arrow_upward'}}</mat-icon></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- Files title -->
|
<!-- 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">
|
||||||
|
|||||||
@@ -41,12 +41,6 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sort-dir-div {
|
|
||||||
display: inline-block;
|
|
||||||
position: absolute;
|
|
||||||
top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.paginator {
|
.paginator {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||||
import { PostsService } from 'app/posts.services';
|
import { PostsService } from 'app/posts.services';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { DatabaseFile, FileType, FileTypeFilter } from '../../../api-types';
|
import { DatabaseFile, FileType, FileTypeFilter, Sort } from '../../../api-types';
|
||||||
import { MatPaginator } from '@angular/material/paginator';
|
import { MatPaginator } from '@angular/material/paginator';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { distinctUntilChanged } from 'rxjs/operators';
|
import { distinctUntilChanged } from 'rxjs/operators';
|
||||||
@@ -47,33 +47,6 @@ export class RecentVideosComponent implements OnInit {
|
|||||||
search_text = '';
|
search_text = '';
|
||||||
searchIsFocused = false;
|
searchIsFocused = false;
|
||||||
descendingMode = true;
|
descendingMode = true;
|
||||||
sortProperties = {
|
|
||||||
'registered': {
|
|
||||||
'key': 'registered',
|
|
||||||
'label': $localize`Download Date`,
|
|
||||||
'property': 'registered'
|
|
||||||
},
|
|
||||||
'upload_date': {
|
|
||||||
'key': 'upload_date',
|
|
||||||
'label': $localize`Upload Date`,
|
|
||||||
'property': 'upload_date'
|
|
||||||
},
|
|
||||||
'name': {
|
|
||||||
'key': 'name',
|
|
||||||
'label': $localize`Name`,
|
|
||||||
'property': 'title'
|
|
||||||
},
|
|
||||||
'file_size': {
|
|
||||||
'key': 'file_size',
|
|
||||||
'label': $localize`File Size`,
|
|
||||||
'property': 'size'
|
|
||||||
},
|
|
||||||
'duration': {
|
|
||||||
'key': 'duration',
|
|
||||||
'label': $localize`Duration`,
|
|
||||||
'property': 'duration'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fileFilters = {
|
fileFilters = {
|
||||||
video_only: {
|
video_only: {
|
||||||
@@ -94,7 +67,7 @@ export class RecentVideosComponent implements OnInit {
|
|||||||
|
|
||||||
selectedFilters = [];
|
selectedFilters = [];
|
||||||
|
|
||||||
sortProperty = this.sortProperties['upload_date'];
|
sortProperty = 'registered';
|
||||||
|
|
||||||
playlists = null;
|
playlists = null;
|
||||||
|
|
||||||
@@ -109,8 +82,8 @@ export class RecentVideosComponent implements OnInit {
|
|||||||
|
|
||||||
// set filter property to cached value
|
// set filter property to cached value
|
||||||
const cached_sort_property = localStorage.getItem('sort_property');
|
const cached_sort_property = localStorage.getItem('sort_property');
|
||||||
if (cached_sort_property && this.sortProperties[cached_sort_property]) {
|
if (cached_sort_property) {
|
||||||
this.sortProperty = this.sortProperties[cached_sort_property];
|
this.sortProperty = cached_sort_property;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set file type filter to cached value
|
// set file type filter to cached value
|
||||||
@@ -189,8 +162,12 @@ export class RecentVideosComponent implements OnInit {
|
|||||||
this.searchChangedSubject.next(newvalue);
|
this.searchChangedSubject.next(newvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
filterOptionChanged(value: string): void {
|
sortOptionChanged(value: Sort): void {
|
||||||
localStorage.setItem('filter_property', value['key']);
|
localStorage.setItem('sort_property', value['by']);
|
||||||
|
localStorage.setItem('recent_videos_sort_order', value['order'] === -1 ? 'descending' : 'ascending');
|
||||||
|
this.descendingMode = value['order'] === -1;
|
||||||
|
this.sortProperty = value['by'];
|
||||||
|
|
||||||
this.getAllFiles();
|
this.getAllFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,18 +204,13 @@ export class RecentVideosComponent implements OnInit {
|
|||||||
return this.selectedFilters.includes('favorited');
|
return this.selectedFilters.includes('favorited');
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleModeChange(): void {
|
|
||||||
this.descendingMode = !this.descendingMode;
|
|
||||||
localStorage.setItem('recent_videos_sort_order', this.descendingMode ? 'descending' : 'ascending');
|
|
||||||
this.getAllFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get files
|
// get files
|
||||||
|
|
||||||
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.sortProperty['property'], order: this.descendingMode ? -1 : 1};
|
const sort = {by: this.sortProperty, 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];
|
||||||
const fileTypeFilter = this.getFileTypeFilter();
|
const fileTypeFilter = this.getFileTypeFilter();
|
||||||
const favoriteFilter = this.getFavoriteFilter();
|
const favoriteFilter = this.getFavoriteFilter();
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<div>
|
||||||
|
<div style="display: inline-block;">
|
||||||
|
<mat-form-field appearance="outline" style="width: 165px;">
|
||||||
|
<mat-select [(ngModel)]="this.sortProperty" (selectionChange)="emitSortOptionChanged()">
|
||||||
|
<mat-option *ngFor="let sortOption of sortProperties | keyvalue" [value]="sortOption.key">
|
||||||
|
{{sortOption['value']['label']}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="sort-dir-div">
|
||||||
|
<button (click)="toggleModeChange()" mat-icon-button><mat-icon>{{descendingMode ? 'arrow_downward' : 'arrow_upward'}}</mat-icon></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
.sort-dir-div {
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { SortPropertyComponent } from './sort-property.component';
|
||||||
|
|
||||||
|
describe('SortPropertyComponent', () => {
|
||||||
|
let component: SortPropertyComponent;
|
||||||
|
let fixture: ComponentFixture<SortPropertyComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ SortPropertyComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(SortPropertyComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
54
src/app/components/sort-property/sort-property.component.ts
Normal file
54
src/app/components/sort-property/sort-property.component.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { Component, Input, EventEmitter, Output } from '@angular/core';
|
||||||
|
import { Sort } from 'api-types';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-sort-property',
|
||||||
|
templateUrl: './sort-property.component.html',
|
||||||
|
styleUrls: ['./sort-property.component.scss']
|
||||||
|
})
|
||||||
|
export class SortPropertyComponent {
|
||||||
|
sortProperties = {
|
||||||
|
'registered': {
|
||||||
|
'key': 'registered',
|
||||||
|
'label': $localize`Download Date`
|
||||||
|
},
|
||||||
|
'upload_date': {
|
||||||
|
'key': 'upload_date',
|
||||||
|
'label': $localize`Upload Date`
|
||||||
|
},
|
||||||
|
'title': {
|
||||||
|
'key': 'title',
|
||||||
|
'label': $localize`Name`
|
||||||
|
},
|
||||||
|
'size': {
|
||||||
|
'key': 'size',
|
||||||
|
'label': $localize`File Size`
|
||||||
|
},
|
||||||
|
'duration': {
|
||||||
|
'key': 'duration',
|
||||||
|
'label': $localize`Duration`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Input() sortProperty = 'registered';
|
||||||
|
@Input() descendingMode = true;
|
||||||
|
|
||||||
|
@Output() sortPropertyChange = new EventEmitter<unknown>();
|
||||||
|
@Output() descendingModeChange = new EventEmitter<number>();
|
||||||
|
@Output() sortOptionChanged = new EventEmitter<Sort>();
|
||||||
|
|
||||||
|
toggleModeChange(): void {
|
||||||
|
this.descendingMode = !this.descendingMode;
|
||||||
|
this.emitSortOptionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
emitSortOptionChanged(): void {
|
||||||
|
if (!this.sortProperty || !this.sortProperties[this.sortProperty]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.sortOptionChanged.emit({
|
||||||
|
by: this.sortProperty,
|
||||||
|
order: this.descendingMode ? -1 : 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<h4 mat-dialog-title><ng-container i18n="Generate RSS URL">Generate RSS URL</ng-container></h4>
|
||||||
|
|
||||||
|
<mat-dialog-content>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-12 col-md-6 mt-2">
|
||||||
|
<mat-form-field class="filter-field">
|
||||||
|
<mat-label i18n="Title filter">Title filter</mat-label>
|
||||||
|
<input [(ngModel)]="titleFilter" matInput (input)="rebuildURL()">
|
||||||
|
<mat-hint i18n="Supports regex">Supports regex</mat-hint>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-6 mt-2">
|
||||||
|
<mat-form-field class="filter-field">
|
||||||
|
<mat-label><ng-container i18n="File type">File type</ng-container></mat-label>
|
||||||
|
<mat-select color="accent" [(ngModel)]="fileTypeFilter" (selectionChange)="rebuildURL()">
|
||||||
|
<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>
|
||||||
|
<div class="col-12 col-md-6 mt-2">
|
||||||
|
<mat-form-field class="filter-field">
|
||||||
|
<mat-label><ng-container i18n="User">User</ng-container></mat-label>
|
||||||
|
<mat-select color="accent" [(ngModel)]="userFilter" (selectionChange)="rebuildURL()" [disabled]="!usersList">
|
||||||
|
<mat-option [value]="''"><ng-container i18n="None">None</ng-container></mat-option>
|
||||||
|
<mat-option *ngFor="let user of usersList" [value]="user.uid"><ng-container>{{user.name}}</ng-container></mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-6 mt-2">
|
||||||
|
<mat-form-field class="filter-field">
|
||||||
|
<mat-label><ng-container i18n="Subscription">Subscription</ng-container></mat-label>
|
||||||
|
<mat-select color="accent" [(ngModel)]="subscriptionFilter" (selectionChange)="rebuildURL()">
|
||||||
|
<mat-option [value]="''"><ng-container i18n="None">None</ng-container></mat-option>
|
||||||
|
<mat-option *ngFor="let sub of postsService.subscriptions" [value]="sub.id"><ng-container>{{sub.name}}</ng-container></mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-6 mt-2">
|
||||||
|
<app-sort-property (sortOptionChanged)="sortOptionChanged($event)"></app-sort-property>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-6 mt-2">
|
||||||
|
<mat-form-field class="filter-field">
|
||||||
|
<mat-label i18n="Item limit">Item limit</mat-label>
|
||||||
|
<input type="number" [(ngModel)]="itemLimit" (input)="rebuildURL()" matInput>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 mb-4">
|
||||||
|
<mat-checkbox (change)="rebuildURL()" [(ngModel)]="favoriteFilter"><ng-container i18n="Favorited">Favorited</ng-container></mat-checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<mat-form-field style="width: 100%;">
|
||||||
|
<mat-label i18n="URL">URL</mat-label>
|
||||||
|
<input readonly [(ngModel)]="url" matInput>
|
||||||
|
<button mat-icon-button matSuffix (click)="copyURL()">
|
||||||
|
<mat-icon>content_copy</mat-icon>
|
||||||
|
</button>
|
||||||
|
</mat-form-field>
|
||||||
|
</mat-dialog-content>
|
||||||
|
|
||||||
|
<mat-dialog-actions>
|
||||||
|
<button mat-button mat-dialog-close><ng-container i18n="Close">Close</ng-container></button>
|
||||||
|
</mat-dialog-actions>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
.filter-field {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { GenerateRssUrlComponent } from './generate-rss-url.component';
|
||||||
|
|
||||||
|
describe('GenerateRssUrlComponent', () => {
|
||||||
|
let component: GenerateRssUrlComponent;
|
||||||
|
let fixture: ComponentFixture<GenerateRssUrlComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ GenerateRssUrlComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(GenerateRssUrlComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { Router, UrlSerializer } from '@angular/router';
|
||||||
|
import { Sort } from 'api-types';
|
||||||
|
import { PostsService } from 'app/posts.services';
|
||||||
|
import { Clipboard } from '@angular/cdk/clipboard';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-generate-rss-url',
|
||||||
|
templateUrl: './generate-rss-url.component.html',
|
||||||
|
styleUrls: ['./generate-rss-url.component.scss']
|
||||||
|
})
|
||||||
|
export class GenerateRssUrlComponent {
|
||||||
|
usersList = null;
|
||||||
|
userFilter = '';
|
||||||
|
titleFilter = '';
|
||||||
|
subscriptionFilter = '';
|
||||||
|
fileTypeFilter = 'both';
|
||||||
|
itemLimit = null;
|
||||||
|
favoriteFilter = false;
|
||||||
|
url = '';
|
||||||
|
baseURL = `${this.postsService.config.Host.url}:${this.postsService.config.Host.port}/api/rss`
|
||||||
|
sortProperty = 'registered'
|
||||||
|
descendingMode = true
|
||||||
|
constructor(public postsService: PostsService, private router: Router, private serializer: UrlSerializer, private clipboard: Clipboard) {
|
||||||
|
if (postsService.isLoggedIn) {
|
||||||
|
this.usersList = [this.postsService.user];
|
||||||
|
this.userFilter = postsService.user.uid;
|
||||||
|
this.getUsers();
|
||||||
|
}
|
||||||
|
this.url = this.baseURL;
|
||||||
|
this.rebuildURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
getUsers() {
|
||||||
|
this.postsService.getUsers().subscribe(res => {
|
||||||
|
this.usersList = res['users'];
|
||||||
|
console.log(this.usersList)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sortOptionChanged(sort: Sort) {
|
||||||
|
this.descendingMode = sort['order'] === -1;
|
||||||
|
this.sortProperty = sort['by'];
|
||||||
|
this.rebuildURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
rebuildURL() {
|
||||||
|
// code can be cleaned up
|
||||||
|
const params = {};
|
||||||
|
|
||||||
|
if (this.userFilter) {
|
||||||
|
params['uuid'] = encodeURIComponent(this.userFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.titleFilter) {
|
||||||
|
params['text_search'] = encodeURIComponent(this.titleFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.subscriptionFilter) {
|
||||||
|
params['sub_id'] = encodeURIComponent(this.subscriptionFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.itemLimit) {
|
||||||
|
params['range'] = [0, this.itemLimit];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.favoriteFilter) {
|
||||||
|
params['favorite_filter'] = this.favoriteFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.fileTypeFilter !== 'both') {
|
||||||
|
params['file_type_filter'] = this.fileTypeFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.sortProperty !== 'registered' || !this.descendingMode) {
|
||||||
|
params['sort'] = encodeURIComponent(JSON.stringify({by: this.sortProperty, order: this.descendingMode ? -1 : 1}));
|
||||||
|
}
|
||||||
|
|
||||||
|
const tree = this.router.createUrlTree(['..'], { queryParams: params });
|
||||||
|
|
||||||
|
this.url = `${this.baseURL}${this.serializer.serialize(tree)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
copyURL() {
|
||||||
|
this.clipboard.copy(this.url);
|
||||||
|
this.postsService.openSnackBar('URL copied!');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -105,7 +105,8 @@ import {
|
|||||||
DeleteNotificationRequest,
|
DeleteNotificationRequest,
|
||||||
SetNotificationsToReadRequest,
|
SetNotificationsToReadRequest,
|
||||||
GetNotificationsResponse,
|
GetNotificationsResponse,
|
||||||
UpdateTaskOptionsRequest
|
UpdateTaskOptionsRequest,
|
||||||
|
User
|
||||||
} from '../api-types';
|
} from '../api-types';
|
||||||
import { isoLangs } from './settings/locales_list';
|
import { isoLangs } from './settings/locales_list';
|
||||||
import { Title } from '@angular/platform-browser';
|
import { Title } from '@angular/platform-browser';
|
||||||
@@ -134,7 +135,7 @@ export class PostsService implements CanActivate {
|
|||||||
// must be reset after logout
|
// must be reset after logout
|
||||||
isLoggedIn = false;
|
isLoggedIn = false;
|
||||||
token = null;
|
token = null;
|
||||||
user = null;
|
user: User = null;
|
||||||
permissions = null;
|
permissions = null;
|
||||||
|
|
||||||
available_permissions = null;
|
available_permissions = null;
|
||||||
@@ -828,7 +829,7 @@ export class PostsService implements CanActivate {
|
|||||||
return this.http.post(this.path + 'auth/changePassword', {user_uid: user_uid, new_password: new_password}, this.httpOptions);
|
return this.http.post(this.path + 'auth/changePassword', {user_uid: user_uid, new_password: new_password}, this.httpOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
getUsers() {
|
getUsers(): Observable<GetUsersResponse> {
|
||||||
return this.http.post<GetUsersResponse>(this.path + 'getUsers', {}, this.httpOptions);
|
return this.http.post<GetUsersResponse>(this.path + 'getUsers', {}, this.httpOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -303,7 +303,8 @@
|
|||||||
<h6>RSS Feed</h6>
|
<h6>RSS Feed</h6>
|
||||||
<mat-checkbox color="accent" [(ngModel)]="new_config['Extra']['enable_rss_feed']" ><ng-container i18n="Enable RSS Feed setting">Enable RSS Feed</ng-container></mat-checkbox>
|
<mat-checkbox color="accent" [(ngModel)]="new_config['Extra']['enable_rss_feed']" ><ng-container i18n="Enable RSS Feed setting">Enable RSS Feed</ng-container></mat-checkbox>
|
||||||
<p><ng-container i18n="RSS Feed prefix">Be careful enabling this with multi-user mode! User data may be exposed.</ng-container></p>
|
<p><ng-container i18n="RSS Feed prefix">Be careful enabling this with multi-user mode! User data may be exposed.</ng-container></p>
|
||||||
<p><a target="_blank" href="https://github.com/Tzahi12345/YoutubeDL-Material/wiki/RSS-Feed"><ng-container i18n="RSS feed documentation">See documentation here.</ng-container></a></p>
|
<button mat-stroked-button (click)="openGenerateRSSURLDialog()" [disabled]="!new_config['Extra']['enable_rss_feed']" i18n="Generate RSS URL">Generate RSS URL</button>
|
||||||
|
<p style="margin-top: 12px;"><a target="_blank" href="https://github.com/Tzahi12345/YoutubeDL-Material/wiki/RSS-Feed"><ng-container i18n="RSS feed documentation">See documentation here.</ng-container></a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { InputDialogComponent } from 'app/input-dialog/input-dialog.component';
|
|||||||
import { EditCategoryDialogComponent } from 'app/dialogs/edit-category-dialog/edit-category-dialog.component';
|
import { EditCategoryDialogComponent } from 'app/dialogs/edit-category-dialog/edit-category-dialog.component';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { Category } from 'api-types';
|
import { Category } from 'api-types';
|
||||||
|
import { GenerateRssUrlComponent } from 'app/dialogs/generate-rss-url/generate-rss-url.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-settings',
|
selector: 'app-settings',
|
||||||
@@ -366,4 +367,11 @@ export class SettingsComponent implements OnInit {
|
|||||||
this.postsService.openSnackBar($localize`Connection failed! Error: Server error. See logs for more info.`);
|
this.postsService.openSnackBar($localize`Connection failed! Error: Server error. See logs for more info.`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openGenerateRSSURLDialog(): void {
|
||||||
|
this.dialog.open(GenerateRssUrlComponent, {
|
||||||
|
width: '80vw',
|
||||||
|
maxWidth: '880px'
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user