mirror of
https://github.com/Tzahi12345/YoutubeDL-Material.git
synced 2026-03-07 12:00:01 +03:00
Added support for generate NFO files for Kodi
Minor UI updates to settings
This commit is contained in:
@@ -33,7 +33,8 @@
|
||||
"use_twitch_API": false,
|
||||
"twitch_API_key": "",
|
||||
"twitch_auto_download_chat": false,
|
||||
"use_sponsorblock_API": false
|
||||
"use_sponsorblock_API": false,
|
||||
"generate_NFO_files": false
|
||||
},
|
||||
"Themes": {
|
||||
"default_theme": "default",
|
||||
|
||||
@@ -208,7 +208,8 @@ const DEFAULT_CONFIG = {
|
||||
"use_twitch_API": false,
|
||||
"twitch_API_key": "",
|
||||
"twitch_auto_download_chat": false,
|
||||
"use_sponsorblock_API": false
|
||||
"use_sponsorblock_API": false,
|
||||
"generate_NFO_files": false
|
||||
},
|
||||
"Themes": {
|
||||
"default_theme": "default",
|
||||
|
||||
@@ -114,6 +114,11 @@ exports.CONFIG_ITEMS = {
|
||||
'key': 'ytdl_use_sponsorblock_api',
|
||||
'path': 'YoutubeDLMaterial.API.use_sponsorblock_API'
|
||||
},
|
||||
'ytdl_generate_nfo_files': {
|
||||
'key': 'ytdl_generate_nfo_files',
|
||||
'path': 'YoutubeDLMaterial.API.generate_NFO_files'
|
||||
},
|
||||
|
||||
|
||||
// Themes
|
||||
'ytdl_default_theme': {
|
||||
|
||||
@@ -217,8 +217,7 @@ function generateFileObject(file_path, type) {
|
||||
var title = jsonobj.title;
|
||||
var url = jsonobj.webpage_url;
|
||||
var uploader = jsonobj.uploader;
|
||||
var upload_date = jsonobj.upload_date;
|
||||
upload_date = upload_date ? `${upload_date.substring(0, 4)}-${upload_date.substring(4, 6)}-${upload_date.substring(6, 8)}` : 'N/A';
|
||||
var upload_date = utils.formatDateString(jsonobj.upload_date);
|
||||
|
||||
var size = stats.size;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ const youtubedl = require('youtube-dl');
|
||||
const logger = require('./logger');
|
||||
const config_api = require('./config');
|
||||
const twitch_api = require('./twitch');
|
||||
const { create } = require('xmlbuilder2');
|
||||
const categories_api = require('./categories');
|
||||
const utils = require('./utils');
|
||||
|
||||
@@ -328,6 +329,10 @@ async function downloadQueuedFile(download_uid) {
|
||||
if (!success) logger.error('Failed to apply ID3 tag to audio file ' + output_json['_filename']);
|
||||
}
|
||||
|
||||
if (config_api.getConfigItem('ytdl_generate_nfo_files')) {
|
||||
exports.generateNFOFile(output_json, `${filepath_no_extension}.nfo`);
|
||||
}
|
||||
|
||||
if (options.cropFileSettings) {
|
||||
await utils.cropFile(full_file_path, options.cropFileSettings.cropFileStart, options.cropFileSettings.cropFileEnd, ext);
|
||||
}
|
||||
@@ -603,4 +608,19 @@ async function checkDownloadPercent(download_uid) {
|
||||
const percent_complete = (sum_size/resulting_file_size * 100).toFixed(2);
|
||||
await db_api.updateRecord('download_queue', {uid: download_uid}, {percent_complete: percent_complete});
|
||||
});
|
||||
}
|
||||
|
||||
exports.generateNFOFile = (info, output_path) => {
|
||||
const nfo_obj = {
|
||||
episodedetails: {
|
||||
title: info['fulltitle'],
|
||||
episode: info['playlist_index'] ? info['playlist_index'] : undefined,
|
||||
premiered: utils.formatDateString(info['upload_date']),
|
||||
plot: `${info['uploader_url']}\n${info['description']}\n${info['playlist_title'] ? info['playlist_title'] : ''}`,
|
||||
director: info['artist'] ? info['artist'] : info['uploader']
|
||||
}
|
||||
};
|
||||
const doc = create(nfo_obj);
|
||||
const xml = doc.end({ prettyPrint: true });
|
||||
fs.writeFileSync(output_path, xml);
|
||||
}
|
||||
73
backend/package-lock.json
generated
73
backend/package-lock.json
generated
@@ -4,6 +4,38 @@
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@oozcitak/dom": {
|
||||
"version": "1.15.10",
|
||||
"resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-1.15.10.tgz",
|
||||
"integrity": "sha512-0JT29/LaxVgRcGKvHmSrUTEvZ8BXvZhGl2LASRUgHqDTC1M5g1pLmVv56IYNyt3bG2CUjDkc67wnyZC14pbQrQ==",
|
||||
"requires": {
|
||||
"@oozcitak/infra": "1.0.8",
|
||||
"@oozcitak/url": "1.0.4",
|
||||
"@oozcitak/util": "8.3.8"
|
||||
}
|
||||
},
|
||||
"@oozcitak/infra": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.8.tgz",
|
||||
"integrity": "sha512-JRAUc9VR6IGHOL7OGF+yrvs0LO8SlqGnPAMqyzOuFZPSZSXI7Xf2O9+awQPSMXgIWGtgUf/dA6Hs6X6ySEaWTg==",
|
||||
"requires": {
|
||||
"@oozcitak/util": "8.3.8"
|
||||
}
|
||||
},
|
||||
"@oozcitak/url": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-1.0.4.tgz",
|
||||
"integrity": "sha512-kDcD8y+y3FCSOvnBI6HJgl00viO/nGbQoCINmQ0h98OhnGITrWR3bOGfwYCthgcrV8AnTJz8MzslTQbC3SOAmw==",
|
||||
"requires": {
|
||||
"@oozcitak/infra": "1.0.8",
|
||||
"@oozcitak/util": "8.3.8"
|
||||
}
|
||||
},
|
||||
"@oozcitak/util": {
|
||||
"version": "8.3.8",
|
||||
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.8.tgz",
|
||||
"integrity": "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ=="
|
||||
},
|
||||
"@sindresorhus/is": {
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
|
||||
@@ -1117,6 +1149,11 @@
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
|
||||
},
|
||||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
||||
},
|
||||
"etag": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
@@ -3030,6 +3067,11 @@
|
||||
"memory-pager": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
|
||||
@@ -3593,6 +3635,37 @@
|
||||
"resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
|
||||
"integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q=="
|
||||
},
|
||||
"xmlbuilder2": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-3.0.2.tgz",
|
||||
"integrity": "sha512-h4MUawGY21CTdhV4xm3DG9dgsqyhDkZvVJBx88beqX8wJs3VgyGQgAn5VreHuae6unTQxh115aMK5InCVmOIKw==",
|
||||
"requires": {
|
||||
"@oozcitak/dom": "1.15.10",
|
||||
"@oozcitak/infra": "1.0.8",
|
||||
"@oozcitak/util": "8.3.8",
|
||||
"@types/node": "*",
|
||||
"js-yaml": "3.14.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"requires": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
|
||||
"integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"unzipper": "^0.10.10",
|
||||
"uuidv4": "^6.0.6",
|
||||
"winston": "^3.2.1",
|
||||
"xmlbuilder2": "^3.0.2",
|
||||
"youtube-dl": "^3.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
1
backend/test/sample.info.json
Normal file
1
backend/test/sample.info.json
Normal file
File diff suppressed because one or more lines are too long
@@ -339,4 +339,14 @@ describe('Downloader', function() {
|
||||
const args = await downloader_api.generateArgs(url, 'video', sub_options, 'admin');
|
||||
console.log(args);
|
||||
});
|
||||
|
||||
it('Generate kodi NFO file', async function() {
|
||||
const nfo_file_path = './test/sample.nfo';
|
||||
if (fs.existsSync(nfo_file_path)) {
|
||||
fs.unlinkSync(nfo_file_path);
|
||||
}
|
||||
const sample_json = fs.readJSONSync('./test/sample.info.json');
|
||||
downloader_api.generateNFOFile(sample_json, nfo_file_path);
|
||||
assert(fs.existsSync(nfo_file_path), true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -45,8 +45,7 @@ async function getDownloadedFilesByType(basePath, type, full_metadata = false) {
|
||||
files.push(jsonobj);
|
||||
continue;
|
||||
}
|
||||
var upload_date = jsonobj.upload_date;
|
||||
upload_date = upload_date ? `${upload_date.substring(0, 4)}-${upload_date.substring(4, 6)}-${upload_date.substring(6, 8)}` : null;
|
||||
var upload_date = formatDateString(jsonobj.upload_date);
|
||||
|
||||
var isaudio = type === 'audio';
|
||||
var file_obj = new File(id, jsonobj.title, jsonobj.thumbnail, isaudio, jsonobj.duration, jsonobj.webpage_url, jsonobj.uploader,
|
||||
@@ -295,6 +294,10 @@ function removeFileExtension(filename) {
|
||||
return filename_parts.join('.');
|
||||
}
|
||||
|
||||
function formatDateString(date_string) {
|
||||
return date_string ? `${date_string.substring(0, 4)}-${date_string.substring(4, 6)}-${date_string.substring(6, 8)}` : 'N/A';
|
||||
}
|
||||
|
||||
function createEdgeNGrams(str) {
|
||||
if (str && str.length > 3) {
|
||||
const minGram = 3
|
||||
@@ -389,6 +392,7 @@ module.exports = {
|
||||
getCurrentDownloader: getCurrentDownloader,
|
||||
recFindByExt: recFindByExt,
|
||||
removeFileExtension: removeFileExtension,
|
||||
formatDateString: formatDateString,
|
||||
cropFile: cropFile,
|
||||
createEdgeNGrams: createEdgeNGrams,
|
||||
wait: wait,
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
<h4 class="settings-title" i18n="Settings title">Settings</h4>
|
||||
<!-- <ng-container i18n="Allow subscriptions setting"></ng-container> -->
|
||||
|
||||
<!-- Language
|
||||
<div style="margin-bottom: 10px;">
|
||||
|
||||
</div> -->
|
||||
|
||||
<mat-tab-group style="height: 76vh" mat-align-tabs="center">
|
||||
<mat-tab-group style="height: 76vh" mat-align-tabs="center" [selectedIndex]="tabIndex" (selectedTabChange)="tabChanged($event)">
|
||||
<!-- Server -->
|
||||
<mat-tab label="Main" i18n-label="Main settings label">
|
||||
<ng-template matTabContent style="padding: 15px;">
|
||||
@@ -272,9 +265,12 @@
|
||||
<mat-hint><ng-container i18n="Twitch API Key setting hint AKA preamble">Also known as a Client ID.</ng-container> <a target="_blank" href="https://dev.twitch.tv/docs/api/"><ng-container i18n="Twitch API Key setting hint">Generating a key is easy!</ng-container></a></mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-12 mt-4 mb-3">
|
||||
<div class="col-12 mt-4">
|
||||
<mat-checkbox color="accent" [(ngModel)]="new_config['API']['use_sponsorblock_API']" matTooltip="Enables a button to skip ads when viewing supported videos." i18n-matTooltip="SponsorBlock API tooltip"><ng-container i18n="Use SponsorBlock API setting">Use SponsorBlock API</ng-container></mat-checkbox>
|
||||
</div>
|
||||
<div class="col-12 mt-2 mb-3">
|
||||
<mat-checkbox color="accent" [(ngModel)]="new_config['API']['generate_NFO_files']" matTooltip="Generates NFO files with every download, primarily used by Kodi." i18n-matTooltip="Generate NFO files tooltip"><ng-container i18n="Generate NFO files setting">Generate NFO files</ng-container></mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
@@ -423,52 +419,59 @@
|
||||
</div>
|
||||
</ng-template>
|
||||
</mat-tab>
|
||||
<mat-tab *ngIf="postsService.config && postsService.config.Advanced.multi_user_mode" label="Users" i18n-label="Users settings label">
|
||||
<div *ngIf="new_config" style="margin-top: 24px; margin-bottom: -25px;">
|
||||
<div>
|
||||
<mat-checkbox color="accent" [(ngModel)]="new_config['Users']['allow_registration']"><ng-container i18n="Allow registration setting">Allow user registration</ng-container></mat-checkbox>
|
||||
<mat-tab [disabled]="!postsService.config?.Advanced.multi_user_mode">
|
||||
<ng-template mat-tab-label>
|
||||
<div [matTooltip]="!postsService.config?.Advanced.multi_user_mode ? usersTabDisabledTooltip : null">
|
||||
<ng-container i18n="Users settings label">Users</ng-container>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
<mat-form-field style="margin-top: 15px;">
|
||||
<mat-select [(ngModel)]="new_config['Users']['auth_method']" placeholder="Auth method" i18n-placeholder="Auth method select">
|
||||
<mat-option value="internal">
|
||||
<ng-container i18n="Internal auth method">Internal</ng-container>
|
||||
</mat-option>
|
||||
<mat-option value="ldap">
|
||||
<ng-container i18n="LDAP auth method">LDAP</ng-container>
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div *ngIf="new_config['Users']['auth_method'] === 'ldap'">
|
||||
</ng-template>
|
||||
<ng-container *ngIf="postsService.config?.Advanced.multi_user_mode">
|
||||
<div *ngIf="new_config" style="margin-top: 24px; margin-bottom: -25px;">
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput i18n-placeholder="LDAP URL" placeholder="LDAP URL" [(ngModel)]="new_config['Users']['ldap_config']['url']">
|
||||
</mat-form-field>
|
||||
<mat-checkbox color="accent" [(ngModel)]="new_config['Users']['allow_registration']"><ng-container i18n="Allow registration setting">Allow user registration</ng-container></mat-checkbox>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput i18n-placeholder="Bind DN" placeholder="Bind DN" [(ngModel)]="new_config['Users']['ldap_config']['bindDN']">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput i18n-placeholder="Bind Credentials" placeholder="Bind Credentials" [(ngModel)]="new_config['Users']['ldap_config']['bindCredentials']">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput i18n-placeholder="Search Base" placeholder="Search Base" [(ngModel)]="new_config['Users']['ldap_config']['searchBase']">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput i18n-placeholder="Search Filter" placeholder="Search Filter" [(ngModel)]="new_config['Users']['ldap_config']['searchFilter']">
|
||||
</mat-form-field>
|
||||
<mat-divider></mat-divider>
|
||||
<mat-form-field style="margin-top: 15px;">
|
||||
<mat-select [(ngModel)]="new_config['Users']['auth_method']" placeholder="Auth method" i18n-placeholder="Auth method select">
|
||||
<mat-option value="internal">
|
||||
<ng-container i18n="Internal auth method">Internal</ng-container>
|
||||
</mat-option>
|
||||
<mat-option value="ldap">
|
||||
<ng-container i18n="LDAP auth method">LDAP</ng-container>
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div *ngIf="new_config['Users']['auth_method'] === 'ldap'">
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput i18n-placeholder="LDAP URL" placeholder="LDAP URL" [(ngModel)]="new_config['Users']['ldap_config']['url']">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput i18n-placeholder="Bind DN" placeholder="Bind DN" [(ngModel)]="new_config['Users']['ldap_config']['bindDN']">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput i18n-placeholder="Bind Credentials" placeholder="Bind Credentials" [(ngModel)]="new_config['Users']['ldap_config']['bindCredentials']">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput i18n-placeholder="Search Base" placeholder="Search Base" [(ngModel)]="new_config['Users']['ldap_config']['searchBase']">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput i18n-placeholder="Search Filter" placeholder="Search Filter" [(ngModel)]="new_config['Users']['ldap_config']['searchFilter']">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
</div>
|
||||
<app-modify-users *ngIf="new_config"></app-modify-users>
|
||||
<app-modify-users *ngIf="new_config"></app-modify-users>
|
||||
</ng-container>
|
||||
</mat-tab>
|
||||
<mat-tab *ngIf="postsService.config" label="Logs" i18n-label="Logs settings label">
|
||||
<ng-template matTabContent>
|
||||
|
||||
@@ -12,6 +12,7 @@ import { ConfirmDialogComponent } from 'app/dialogs/confirm-dialog/confirm-dialo
|
||||
import { moveItemInArray, CdkDragDrop } from '@angular/cdk/drag-drop';
|
||||
import { InputDialogComponent } from 'app/input-dialog/input-dialog.component';
|
||||
import { EditCategoryDialogComponent } from 'app/dialogs/edit-category-dialog/edit-category-dialog.component';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings',
|
||||
@@ -38,17 +39,28 @@ export class SettingsComponent implements OnInit {
|
||||
latestGithubRelease = null;
|
||||
CURRENT_VERSION = CURRENT_VERSION
|
||||
|
||||
get settingsAreTheSame() {
|
||||
tabs = ['main', 'downloader', 'extra', 'database', 'advanced', 'users', 'logs'];
|
||||
tabIndex = 0;
|
||||
|
||||
INDEX_TO_TAB = Object.assign({}, this.tabs);
|
||||
TAB_TO_INDEX = {};
|
||||
|
||||
usersTabDisabledTooltip = $localize`You must enable multi-user mode to access this tab.`;
|
||||
|
||||
get settingsAreTheSame(): boolean {
|
||||
this._settingsSame = this.settingsSame()
|
||||
return this._settingsSame;
|
||||
}
|
||||
|
||||
set settingsAreTheSame(val) {
|
||||
set settingsAreTheSame(val: boolean) {
|
||||
this._settingsSame = val;
|
||||
}
|
||||
|
||||
constructor(public postsService: PostsService, private snackBar: MatSnackBar, private sanitizer: DomSanitizer,
|
||||
private dialog: MatDialog) { }
|
||||
private dialog: MatDialog, private router: Router, private route: ActivatedRoute) {
|
||||
// invert index to tab
|
||||
Object.keys(this.INDEX_TO_TAB).forEach(key => { this.TAB_TO_INDEX[this.INDEX_TO_TAB[key]] = key; });
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.postsService.initialized) {
|
||||
@@ -66,6 +78,9 @@ export class SettingsComponent implements OnInit {
|
||||
this.generated_bookmarklet_code = this.sanitizer.bypassSecurityTrustUrl(this.generateBookmarkletCode());
|
||||
|
||||
this.getLatestGithubRelease();
|
||||
|
||||
const tab = this.route.snapshot.paramMap.get('tab');
|
||||
this.tabIndex = tab && this.TAB_TO_INDEX[tab] ? this.TAB_TO_INDEX[tab] : 0;
|
||||
}
|
||||
|
||||
getConfig() {
|
||||
@@ -98,6 +113,11 @@ export class SettingsComponent implements OnInit {
|
||||
this.new_config = JSON.parse(JSON.stringify(this.initial_config));
|
||||
}
|
||||
|
||||
tabChanged(event) {
|
||||
const index = event['index'];
|
||||
this.router.navigate(['/settings', {tab: this.INDEX_TO_TAB[index]}]);
|
||||
}
|
||||
|
||||
dropCategory(event: CdkDragDrop<string[]>) {
|
||||
moveItemInArray(this.postsService.categories, event.previousIndex, event.currentIndex);
|
||||
this.postsService.updateCategories(this.postsService.categories).subscribe(res => {
|
||||
|
||||
Reference in New Issue
Block a user