Merge pull request #21 from Tzahi12345/settings

Add settings page
pull/22/head^2
Tzahi12345 5 years ago committed by GitHub
commit 17e85196ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

3
.gitignore vendored

@ -49,4 +49,7 @@ backend/video/*
backend/audio/*
backend/public/*
backend/db.json
backend/subscriptions/channels/*
backend/subscriptions/playlists/*
backend/subscriptions/archives/*
src/assets/default.json

@ -510,6 +510,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);
});

@ -109,5 +109,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;
}

@ -8,7 +8,18 @@
<div>{{topBarTitle}}</div>
</div>
<div class="flex-column" style="text-align: right; align-items: flex-end;">
<button *ngIf="allowThemeChange" mat-icon-button (click)="flipTheme()"><mat-icon>{{(postsService.theme.key === 'default') ? 'brightness_5' : 'brightness_2'}}</mat-icon></button>
<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>

@ -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} from '@angular/material';
import {MatSnackBar, MatDialog} 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 } from '@angular/router';
import { OverlayContainer } from '@angular/cdk/overlay';
import { THEMES_CONFIG } from '../themes';
import { SettingsComponent } from './settings/settings.component';
@Component({
selector: 'app-root',
@ -36,7 +37,7 @@ export class AppComponent implements OnInit {
@ViewChild('urlinput', { read: ElementRef, static: false }) urlInput: ElementRef;
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) {
// loading config
@ -117,5 +118,9 @@ onSetTheme(theme, old_theme) {
goBack() {
this.router.navigate(['/home']);
}
openSettingsDialog() {
const dialogRef = this.dialog.open(SettingsComponent);
}
}

@ -5,7 +5,9 @@ import {MatNativeDateModule, MatRadioModule, MatInputModule, MatButtonModule, Ma
MatProgressBarModule, MatExpansionModule,
MatProgressSpinnerModule,
MatButtonToggleModule,
MatDialogModule} from '@angular/material';
MatDialogModule,
MatSlideToggleModule,
MatMenuModule} from '@angular/material';
import {DragDropModule} from '@angular/cdk/drag-drop';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import { AppComponent } from './app.component';
@ -28,6 +30,7 @@ import { NgxContentLoadingModule } from 'ngx-content-loading';
import { audioFilesMouseHovering, videoFilesMouseHovering, audioFilesOpened, videoFilesOpened } from './main/main.component';
import { CreatePlaylistComponent } from './create-playlist/create-playlist.component';
import { DownloadItemComponent } from './download-item/download-item.component';
import { SettingsComponent } from './settings/settings.component';
export function isVisible({ event, element, scrollContainer, offset }: IsVisibleProps<any>) {
return (element.id === 'video' ? videoFilesMouseHovering || videoFilesOpened : audioFilesMouseHovering || audioFilesOpened);
@ -41,7 +44,8 @@ export function isVisible({ event, element, scrollContainer, offset }: IsVisible
PlayerComponent,
InputDialogComponent,
CreatePlaylistComponent,
DownloadItemComponent
DownloadItemComponent,
SettingsComponent
],
imports: [
BrowserModule,
@ -68,6 +72,8 @@ export function isVisible({ event, element, scrollContainer, offset }: IsVisible
MatProgressSpinnerModule,
MatButtonToggleModule,
MatDialogModule,
MatSlideToggleModule,
MatMenuModule,
DragDropModule,
VgCoreModule,
VgControlsModule,
@ -80,7 +86,8 @@ export function isVisible({ event, element, scrollContainer, offset }: IsVisible
],
entryComponents: [
InputDialogComponent,
CreatePlaylistComponent
CreatePlaylistComponent,
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});

@ -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>&nbsp;&nbsp;Save</button>
<button mat-flat-button [mat-dialog-close]="false"><mat-icon>cancel</mat-icon>&nbsp;&nbsp;Cancel</button>
</div>
</mat-dialog-actions>

@ -0,0 +1,3 @@
.settings-expansion-panel {
margin-bottom: 20px;
}

@ -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();
});
});

@ -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!');
})
}
}
Loading…
Cancel
Save