diff --git a/backend/app/data/utils.py b/backend/app/data/utils.py
index e1b3617..1cdea1b 100644
--- a/backend/app/data/utils.py
+++ b/backend/app/data/utils.py
@@ -29,7 +29,8 @@ PROFILE_FIELDS = [
"custom_formats", # Array of {name, score} objects
"qualities", # Array of strings
"upgrade_until",
- "language"
+ "language",
+ "tweaks"
]
# Category mappings
diff --git a/frontend/src/components/profile/ProfileModal.jsx b/frontend/src/components/profile/ProfileModal.jsx
index ec31ef6..203dd7d 100644
--- a/frontend/src/components/profile/ProfileModal.jsx
+++ b/frontend/src/components/profile/ProfileModal.jsx
@@ -8,8 +8,18 @@ import ProfileGeneralTab from './ProfileGeneralTab';
import ProfileScoringTab from './ProfileScoringTab';
import ProfileQualitiesTab from './ProfileQualitiesTab';
import ProfileLanguagesTab from './ProfileLangaugesTab';
+import ProfileTweaksTab from './ProfileTweaksTab';
import QUALITIES from '../../constants/qualities';
+const DEFAULT_TWEAKS = {
+ preferFreeleech: true,
+ allowLosslessAudio: true,
+ allowDVNoFallback: false,
+ allowBleedingEdgeCodecs: false,
+ allowPrereleases: false,
+ languageStrictness: 'disabled'
+};
+
function unsanitize(text) {
if (!text) return '';
return text.replace(/\\:/g, ':').replace(/\\n/g, '\n');
@@ -61,11 +71,15 @@ function ProfileModal({
// Language state
const [selectedLanguage, setSelectedLanguage] = useState('any');
+ // Tweaks state
+ const [tweaks, setTweaks] = useState({});
+
const tabs = [
{id: 'general', label: 'General'},
{id: 'scoring', label: 'Scoring'},
{id: 'qualities', label: 'Qualities'},
- {id: 'languages', label: 'Languages'}
+ {id: 'languages', label: 'Languages'},
+ {id: 'tweaks', label: 'Tweaks'}
];
useEffect(() => {
@@ -122,6 +136,12 @@ function ProfileModal({
});
setTagScores(initialTagScores);
+ // Tweaks
+ setTweaks({
+ ...DEFAULT_TWEAKS,
+ ...(content.tweaks || {})
+ });
+
// Qualities setup - include all qualities, set enabled status
const allQualitiesMap = {}; // Map of all qualities by id
QUALITIES.forEach(quality => {
@@ -149,7 +169,7 @@ function ProfileModal({
newSortedQualities.push({
id: q.id,
name: q.name,
- description: q.description, // Changed: removed || '' to preserve null/undefined
+ description: q.description,
qualities: groupQualities,
enabled: true
});
@@ -266,6 +286,9 @@ function ProfileModal({
id: defaultQuality.id,
name: defaultQuality.name
});
+
+ // Initialize empty tweaks
+ setTweaks(DEFAULT_TWEAKS);
}
setLoading(false);
@@ -346,7 +369,8 @@ function ProfileModal({
})
}
: null,
- language: selectedLanguage
+ language: selectedLanguage,
+ tweaks
};
if (isCloning || !initialProfile) {
@@ -385,7 +409,6 @@ function ProfileModal({
setError('An unexpected error occurred');
}
};
-
const handleDelete = async () => {
if (!initialProfile) return;
@@ -547,6 +570,12 @@ function ProfileModal({
onLanguageChange={setSelectedLanguage}
/>
)}
+ {activeTab === 'tweaks' && (
+
+ Tweaks are custom changes that can be toggled according + to your preference. These settings are profile-specific + and won't create merge conflicts when synchronizing with + remote repositories. Use tweaks to fine-tune your + profile's behavior without affecting the core + configuration. +
++ Allow Dolby Vision releases that don't include + HDR10 fallback. These may display incorrectly on + non-Dolby Vision displays. +
++ Only enable if your display supports Dolby + Vision +
++ Allow releases using newer codecs like AV1 and + H.266/VVC. These may offer better compression + but have limited hardware support. +
++ Allow high-quality lossless audio formats + including TrueHD + Atmos, DTS-HD MA, DTS-X, + FLAC, and PCM. +
++ May skip better quality releases if disabled +
++ Allow early releases like CAMs, Telecines, + Telesyncs, and Screeners. These are typically + available before official releases but at lower + quality. +
++ Prioritize releases tagged as freeleech when + choosing between different indexers' releases. +
++ Set strict language requirements for + releases. Select 'Disabled' to use normal + language preferences. +
+