mirror of
https://github.com/Tzahi12345/YoutubeDL-Material.git
synced 2026-03-07 12:00:01 +03:00
Merge branch 'master' into subscribe_to_channel_and_playlist
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -52,4 +52,7 @@ backend/subscriptions/archives/*
|
||||
backend/subscriptions/playlists/*
|
||||
backend/subscriptions/channels/*
|
||||
backend/db.json
|
||||
backend/subscriptions/channels/*
|
||||
backend/subscriptions/playlists/*
|
||||
backend/subscriptions/archives/*
|
||||
src/assets/default.json
|
||||
|
||||
@@ -557,6 +557,20 @@ app.get('/api/config', function(req, res) {
|
||||
});
|
||||
});
|
||||
|
||||
app.post('/api/setConfig', function(req, res) {
|
||||
let new_config_file = req.body.new_config_file;
|
||||
if (new_config_file && new_config_file['YoutubeDLMaterial']) {
|
||||
let success = config_api.setConfigFile(new_config_file);
|
||||
res.send({
|
||||
success: success
|
||||
});
|
||||
} else {
|
||||
console.log('ERROR: Tried to save invalid config file!')
|
||||
res.sendStatus(400);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
app.get('/api/using-encryption', function(req, res) {
|
||||
res.send(usingEncryption);
|
||||
});
|
||||
|
||||
@@ -112,5 +112,6 @@ module.exports = {
|
||||
setConfigItem: setConfigItem,
|
||||
setConfigItems: setConfigItems,
|
||||
getConfigFile: getConfigFile,
|
||||
setConfigFile: setConfigFile,
|
||||
CONFIG_ITEMS: CONFIG_ITEMS
|
||||
}
|
||||
@@ -10,4 +10,10 @@
|
||||
flex-direction: column;
|
||||
flex-basis: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.theme-slide-toggle {
|
||||
top: 2px;
|
||||
left: 10px;
|
||||
position: relative;
|
||||
}
|
||||
@@ -13,8 +13,25 @@
|
||||
<button *ngIf="allowThemeChange" mat-icon-button (click)="flipTheme()"><mat-icon>{{(postsService.theme.key === 'default') ? 'brightness_5' : 'brightness_2'}}</mat-icon></button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-toolbar>
|
||||
</div>
|
||||
<div class="flex-column" style="text-align: center; margin-top: 5px;">
|
||||
<div>{{topBarTitle}}</div>
|
||||
</div>
|
||||
<div class="flex-column" style="text-align: right; align-items: flex-end;">
|
||||
<button [matMenuTriggerFor]="menuSettings" mat-icon-button><mat-icon>more_vert</mat-icon></button>
|
||||
<mat-menu #menuSettings="matMenu">
|
||||
<button (click)="$event.stopPropagation();" *ngIf="allowThemeChange" mat-menu-item>
|
||||
<mat-icon>{{(postsService.theme.key === 'default') ? 'brightness_5' : 'brightness_2'}}</mat-icon>
|
||||
<span>Dark</span>
|
||||
<mat-slide-toggle class="theme-slide-toggle" [checked]="postsService.theme.key === 'dark'" (change)="flipTheme()"></mat-slide-toggle>
|
||||
</button>
|
||||
<button (click)="openSettingsDialog()" mat-menu-item>
|
||||
<mat-icon>settings</mat-icon>
|
||||
<span>Settings</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
</mat-toolbar>
|
||||
|
||||
<div style="height: calc(100% - 64px)">
|
||||
<mat-sidenav-container style="height: 100%">
|
||||
|
||||
@@ -4,7 +4,7 @@ import {FileCardComponent} from './file-card/file-card.component';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import {FormControl, Validators} from '@angular/forms';
|
||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {MatSnackBar, MatSidenav} from '@angular/material';
|
||||
import {MatSnackBar, MatDialog, MatSidenav} from '@angular/material';
|
||||
import { saveAs } from 'file-saver';
|
||||
import 'rxjs/add/observable/of';
|
||||
import 'rxjs/add/operator/mapTo';
|
||||
@@ -18,6 +18,7 @@ import { YoutubeSearchService, Result } from './youtube-search.service';
|
||||
import { Router, NavigationStart } from '@angular/router';
|
||||
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||
import { THEMES_CONFIG } from '../themes';
|
||||
import { SettingsComponent } from './settings/settings.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -37,7 +38,7 @@ export class AppComponent implements OnInit {
|
||||
@ViewChild('sidenav', {static: false}) sidenav: MatSidenav;
|
||||
navigator: string = null;
|
||||
|
||||
constructor(public postsService: PostsService, public snackBar: MatSnackBar,
|
||||
constructor(public postsService: PostsService, public snackBar: MatSnackBar, private dialog: MatDialog,
|
||||
public router: Router, public overlayContainer: OverlayContainer, private elementRef: ElementRef) {
|
||||
|
||||
this.navigator = localStorage.getItem('player_navigator');
|
||||
@@ -132,5 +133,9 @@ onSetTheme(theme, old_theme) {
|
||||
this.router.navigateByUrl(this.navigator);
|
||||
}
|
||||
}
|
||||
|
||||
openSettingsDialog() {
|
||||
const dialogRef = this.dialog.open(SettingsComponent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import {MatNativeDateModule, MatRadioModule, MatInputModule, MatButtonModule, Ma
|
||||
MatButtonToggleModule,
|
||||
MatDialogModule,
|
||||
MatRippleModule,
|
||||
MatSlideToggleModule,
|
||||
MatMenuModule} from '@angular/material';
|
||||
import {DragDropModule} from '@angular/cdk/drag-drop';
|
||||
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||
@@ -35,6 +36,7 @@ import { SubscribeDialogComponent } from './dialogs/subscribe-dialog/subscribe-d
|
||||
import { SubscriptionComponent } from './subscription//subscription/subscription.component';
|
||||
import { SubscriptionFileCardComponent } from './subscription/subscription-file-card/subscription-file-card.component';
|
||||
import { SubscriptionInfoDialogComponent } from './dialogs/subscription-info-dialog/subscription-info-dialog.component';
|
||||
import { SettingsComponent } from './settings/settings.component';
|
||||
|
||||
export function isVisible({ event, element, scrollContainer, offset }: IsVisibleProps<any>) {
|
||||
return (element.id === 'video' ? videoFilesMouseHovering || videoFilesOpened : audioFilesMouseHovering || audioFilesOpened);
|
||||
@@ -53,7 +55,8 @@ export function isVisible({ event, element, scrollContainer, offset }: IsVisible
|
||||
SubscribeDialogComponent,
|
||||
SubscriptionComponent,
|
||||
SubscriptionFileCardComponent,
|
||||
SubscriptionInfoDialogComponent
|
||||
SubscriptionInfoDialogComponent,
|
||||
SettingsComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@@ -82,6 +85,8 @@ export function isVisible({ event, element, scrollContainer, offset }: IsVisible
|
||||
MatRippleModule,
|
||||
MatMenuModule,
|
||||
MatDialogModule,
|
||||
MatSlideToggleModule,
|
||||
MatMenuModule,
|
||||
DragDropModule,
|
||||
VgCoreModule,
|
||||
VgControlsModule,
|
||||
@@ -96,7 +101,8 @@ export function isVisible({ event, element, scrollContainer, offset }: IsVisible
|
||||
InputDialogComponent,
|
||||
CreatePlaylistComponent,
|
||||
SubscribeDialogComponent,
|
||||
SubscriptionInfoDialogComponent
|
||||
SubscriptionInfoDialogComponent,
|
||||
SettingsComponent
|
||||
],
|
||||
providers: [PostsService],
|
||||
bootstrap: [AppComponent]
|
||||
|
||||
@@ -92,6 +92,10 @@ export class PostsService {
|
||||
}
|
||||
}
|
||||
|
||||
setConfig(config) {
|
||||
return this.http.post(this.path + 'setConfig', {new_config_file: config});
|
||||
}
|
||||
|
||||
deleteFile(name: string, isAudio: boolean) {
|
||||
if (isAudio) {
|
||||
return this.http.post(this.path + 'deleteMp3', {name: name});
|
||||
|
||||
193
src/app/settings/settings.component.html
Normal file
193
src/app/settings/settings.component.html
Normal file
@@ -0,0 +1,193 @@
|
||||
<h4 mat-dialog-title>Settings</h4>
|
||||
|
||||
<mat-dialog-content>
|
||||
<!-- Host -->
|
||||
<mat-expansion-panel class="settings-expansion-panel">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Host
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div *ngIf="new_config" class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<mat-form-field>
|
||||
<input [(ngModel)]="new_config['Host']['url']" matInput placeholder="URL" required>
|
||||
<mat-hint></mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<mat-form-field>
|
||||
<input [(ngModel)]="new_config['Host']['port']" matInput placeholder="Port" required>
|
||||
<mat-hint></mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<!-- Encryption -->
|
||||
<mat-expansion-panel class="settings-expansion-panel">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Encryption
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div *ngIf="new_config" class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<mat-checkbox [(ngModel)]="new_config['Encryption']['use-encryption']">Use encryption</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<mat-form-field>
|
||||
<input [disabled]="!new_config['Encryption']['use-encryption']" [(ngModel)]="new_config['Encryption']['cert-file-path']" matInput placeholder="Cert file path">
|
||||
<mat-hint></mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<mat-form-field>
|
||||
<input [disabled]="!new_config['Encryption']['use-encryption']" [(ngModel)]="new_config['Encryption']['key-file-path']" matInput placeholder="Key file path">
|
||||
<mat-hint></mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<!-- Downloader -->
|
||||
<mat-expansion-panel class="settings-expansion-panel">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Downloader
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div *ngIf="new_config" class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<mat-form-field>
|
||||
<input matInput [(ngModel)]="new_config['Downloader']['path-audio']" placeholder="Audio folder path" required>
|
||||
<mat-hint></mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<mat-form-field>
|
||||
<input matInput [(ngModel)]="new_config['Downloader']['path-video']" placeholder="Video folder path" required>
|
||||
<mat-hint></mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<!-- Extra -->
|
||||
<mat-expansion-panel class="settings-expansion-panel">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Extra
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div *ngIf="new_config" class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<mat-form-field>
|
||||
<input [(ngModel)]="new_config['Extra']['title_top']" matInput placeholder="Top title" required>
|
||||
<mat-hint></mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<mat-checkbox [(ngModel)]="new_config['Extra']['file_manager_enabled']">File manager enabled</mat-checkbox>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<mat-checkbox [(ngModel)]="new_config['Extra']['allow_quality_select']">Allow quality select</mat-checkbox>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<mat-checkbox [(ngModel)]="new_config['Extra']['download_only_mode']">Download only mode</mat-checkbox>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<mat-checkbox [(ngModel)]="new_config['Extra']['allow_multi_download_mode']">Allow multi-download mode</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<!-- API -->
|
||||
<mat-expansion-panel class="settings-expansion-panel">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
API
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div *ngIf="new_config" class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<mat-checkbox [(ngModel)]="new_config['API']['use_youtube_api']">Use YouTube API</mat-checkbox>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<mat-form-field>
|
||||
<input [disabled]="!new_config['API']['use_youtube_api']" [(ngModel)]="new_config['API']['youtube_API_key']" matInput placeholder="Youtube API Key" required>
|
||||
<mat-hint></mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<!-- Themes -->
|
||||
<mat-expansion-panel class="settings-expansion-panel">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Themes
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div *ngIf="new_config" class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<mat-select style="width: 100px" [(ngModel)]="new_config['Themes']['default_theme']">
|
||||
<mat-option value="default">Default</mat-option>
|
||||
<mat-option value="dark">Dark</mat-option>
|
||||
</mat-select>
|
||||
</div>
|
||||
|
||||
<div class="col-12 mt-4">
|
||||
<mat-checkbox [(ngModel)]="new_config['Themes']['allow_theme_change']">Allow theme change</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<!-- Advanced -->
|
||||
<mat-expansion-panel class="settings-expansion-panel">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Advanced
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div *ngIf="new_config" class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<mat-checkbox [(ngModel)]="new_config['Advanced']['use_default_downloading_agent']">Use default downloading agent</mat-checkbox>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<mat-form-field>
|
||||
<input [disabled]="!new_config['Advanced']['use_default_downloading_agent']" [(ngModel)]="new_config['Advanced']['custom_downloading_agent']" matInput placeholder="Custom agent" required>
|
||||
<mat-hint></mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<mat-checkbox [(ngModel)]="new_config['Advanced']['allow_advanced_download']">Allow advanced download</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions>
|
||||
<div style="margin-bottom: 10px;">
|
||||
<button color="accent" (click)="saveSettings()" [disabled]="settingsSame()" mat-raised-button><mat-icon>done</mat-icon> Save</button>
|
||||
<button mat-flat-button [mat-dialog-close]="false"><mat-icon>cancel</mat-icon> Cancel</button>
|
||||
</div>
|
||||
</mat-dialog-actions>
|
||||
3
src/app/settings/settings.component.scss
Normal file
3
src/app/settings/settings.component.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
.settings-expansion-panel {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
25
src/app/settings/settings.component.spec.ts
Normal file
25
src/app/settings/settings.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SettingsComponent } from './settings.component';
|
||||
|
||||
describe('SettingsComponent', () => {
|
||||
let component: SettingsComponent;
|
||||
let fixture: ComponentFixture<SettingsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SettingsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SettingsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
48
src/app/settings/settings.component.ts
Normal file
48
src/app/settings/settings.component.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { PostsService } from 'app/posts.services';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings',
|
||||
templateUrl: './settings.component.html',
|
||||
styleUrls: ['./settings.component.scss']
|
||||
})
|
||||
export class SettingsComponent implements OnInit {
|
||||
|
||||
initial_config = null;
|
||||
new_config = null
|
||||
loading_config = false;
|
||||
|
||||
constructor(private postsService: PostsService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.getConfig();
|
||||
}
|
||||
|
||||
getConfig() {
|
||||
this.loading_config = true;
|
||||
this.postsService.loadNavItems().subscribe(res => {
|
||||
this.loading_config = false;
|
||||
// successfully loaded config
|
||||
|
||||
this.initial_config = !this.postsService.debugMode ? res['config_file']['YoutubeDLMaterial'] : res['YoutubeDLMaterial'];
|
||||
this.new_config = JSON.parse(JSON.stringify(this.initial_config));
|
||||
});
|
||||
}
|
||||
|
||||
settingsSame() {
|
||||
return JSON.stringify(this.new_config) === JSON.stringify(this.initial_config);
|
||||
}
|
||||
|
||||
saveSettings() {
|
||||
const settingsToSave = {'YoutubeDLMaterial': this.new_config};
|
||||
this.postsService.setConfig(settingsToSave).subscribe(res => {
|
||||
if (res['success']) {
|
||||
// sets new config as old config
|
||||
this.initial_config = JSON.parse(JSON.stringify(this.new_config));
|
||||
}
|
||||
}, err => {
|
||||
console.error('Failed to save config!');
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user