0.12.0-19 Final Build
Deploy Docs to GitHub Pages / Build Documentation (push) Has been cancelled
Deploy Docs to GitHub Pages / Deploy to GitHub Pages (push) Has been cancelled

This commit is contained in:
michael committed 2026-04-07 19:12:40 +00:00
1 parent ccad7ec9f4
commit 43702b0138
39 files changed
+2829 -460

No files matched your search

@@ -5,6 +5,7 @@ import { InputText } from 'primereact/inputtext';
import { InputNumber } from 'primereact/inputnumber';
import { InputSwitch } from 'primereact/inputswitch';
import { Dropdown } from 'primereact/dropdown';
import { Checkbox } from 'primereact/checkbox';
import { Tag } from 'primereact/tag';
import { Button } from 'primereact/button';
import { api } from '../api/client';
@@ -444,6 +445,81 @@ const DOWNLOAD_PATH_KEYS = ['download_dir'];
const LOG_PATH_KEYS = ['log_dir'];
const EXTERNAL_STORAGE_PATH_KEYS = [EXTERNAL_STORAGE_PATHS_KEY];
const CONVERTER_PATH_KEYS = ['converter_raw_dir', 'converter_movie_dir', 'converter_audio_dir', 'converter_output_template_video', 'converter_output_template_audio'];
const CONVERTER_SCAN_EXTENSION_KEY = 'converter_scan_extensions';
const CONVERTER_SCAN_EXTENSION_OPTIONS = [
'mkv', 'mp4', 'm2ts', 'iso', 'avi', 'mov',
'flac', 'mp3', 'wav', 'm4a', 'ogg', 'opus'
];
function parseConverterScanExtensions(value) {
const tokens = String(value || '')
.split(',')
.map((item) => item.trim().toLowerCase())
.filter(Boolean);
const known = new Set(CONVERTER_SCAN_EXTENSION_OPTIONS);
const seen = new Set();
const selected = [];
for (const token of tokens) {
if (!known.has(token) || seen.has(token)) {
continue;
}
seen.add(token);
selected.push(token);
}
return selected;
}
function serializeConverterScanExtensions(values) {
const list = Array.isArray(values) ? values : [];
const known = new Set(CONVERTER_SCAN_EXTENSION_OPTIONS);
const seen = new Set();
const normalized = [];
for (const item of list) {
const ext = String(item || '').trim().toLowerCase();
if (!known.has(ext) || seen.has(ext)) {
continue;
}
seen.add(ext);
normalized.push(ext);
}
return normalized.join(',');
}
function ConverterScanExtensionsEditor({ value, onChange, settingKey }) {
const selected = parseConverterScanExtensions(value);
const selectedSet = new Set(selected);
const handleToggle = (extension) => {
const ext = String(extension || '').trim().toLowerCase();
if (!ext) {
return;
}
let next = selected.filter((item) => item !== ext);
if (!selectedSet.has(ext)) {
next = [...selected, ext];
}
// Setting ist required/minLength: mindestens eine Endung aktiv lassen.
if (next.length === 0) {
return;
}
onChange?.(settingKey, serializeConverterScanExtensions(next));
};
return (
<div className="converter-scan-extensions-grid">
{CONVERTER_SCAN_EXTENSION_OPTIONS.map((extension) => (
<label key={extension} htmlFor={`${settingKey}-${extension}`} className="converter-scan-extension-option">
<Checkbox
inputId={`${settingKey}-${extension}`}
checked={selectedSet.has(extension)}
onChange={() => handleToggle(extension)}
/>
<span>.{extension}</span>
</label>
))}
</div>
);
}
function buildSectionsForCategory(categoryName, settings) {
const list = Array.isArray(settings) ? settings : [];
@@ -526,7 +602,8 @@ function SettingField({
{(setting.type === 'string' || setting.type === 'path')
&& setting.key !== 'drive_devices'
&& setting.key !== EXTERNAL_STORAGE_PATHS_KEY ? (
&& setting.key !== EXTERNAL_STORAGE_PATHS_KEY
&& setting.key !== CONVERTER_SCAN_EXTENSION_KEY ? (
<InputText
id={setting.key}
value={value ?? ''}
@@ -550,6 +627,14 @@ function SettingField({
/>
) : null}
{setting.key === CONVERTER_SCAN_EXTENSION_KEY ? (
<ConverterScanExtensionsEditor
value={value}
onChange={onChange}
settingKey={setting.key}
/>
) : null}
{setting.type === 'number' ? (
<InputNumber
id={setting.key}