diff --git a/packages/core/src/parser/regex.ts b/packages/core/src/parser/regex.ts index d6c2bd3b..fdca6ea5 100644 --- a/packages/core/src/parser/regex.ts +++ b/packages/core/src/parser/regex.ts @@ -1,10 +1,47 @@ +import { AUDIO_TAGS, QUALITIES, RESOLUTIONS } from '../utils/constants'; +import { VISUAL_TAGS } from '../utils/constants'; +import { ENCODES } from '../utils/constants'; +import { LANGUAGES } from '../utils/constants'; +import { AUDIO_CHANNELS } from '../utils/constants'; const createRegex = (pattern: string): RegExp => new RegExp(`(? createRegex(`${pattern}(?![ .\\-_]?sub(title)?s?)`); -export const PARSE_REGEX = { +type PARSE_REGEX = { + resolutions: Omit, 'Unknown'> & { + Unknown?: RegExp; + }; + qualities: Omit, 'Unknown'> & { + Unknown?: RegExp; + }; + visualTags: Omit< + Record<(typeof VISUAL_TAGS)[number], RegExp>, + 'Unknown' | 'HDR+DV' + > & { + Unknown?: RegExp; + 'HDR+DV'?: RegExp; + }; + audioTags: Omit, 'Unknown'> & { + Unknown?: RegExp; + }; + audioChannels: Omit< + Record<(typeof AUDIO_CHANNELS)[number], RegExp>, + 'Unknown' + > & { + Unknown?: RegExp; + }; + languages: Omit, 'Unknown'> & { + Unknown?: RegExp; + }; + encodes: Omit, 'Unknown'> & { + Unknown?: RegExp; + }; + releaseGroup: RegExp; +}; + +export const PARSE_REGEX: PARSE_REGEX = { resolutions: { '2160p': createRegex( '(bd|hd|m)?(4k|2160(p|i)?)|u(ltra)?[ .\\-_]?hd|3840\s?x\s?(\d{4})' @@ -20,7 +57,6 @@ export const PARSE_REGEX = { '480p': createRegex('(bd|hd|m)?(480(p|i)?)|sd'), '360p': createRegex('(bd|hd|m)?(360(p|i)?)'), '240p': createRegex('(bd|hd|m)?(240(p|i)?)'), - '180p': createRegex('(bd|hd|m)?(180(p|i)?)'), '144p': createRegex('(bd|hd|m)?(144(p|i)?)'), }, qualities: { @@ -86,7 +122,7 @@ export const PARSE_REGEX = { HEVC: createRegex('hevc[ .\\-_]?(10)?|[xh][ .\\-_]?265'), AVC: createRegex('avc|[xh][ .\\-_]?264'), AV1: createRegex('av1'), - Xvid: createRegex('xvid'), + XviD: createRegex('xvid'), DivX: createRegex('divx|dvix'), 'H-OU': createRegex('h?(alf)?[ .\\-_]?(ou|over[ .\\-_]?under)'), 'H-SBS': createRegex('h?(alf)?[ .\\-_]?(sbs|side[ .\\-_]?by[ .\\-_]?side)'), diff --git a/packages/core/src/utils/constants.ts b/packages/core/src/utils/constants.ts index 72ffb9a5..0039b476 100644 --- a/packages/core/src/utils/constants.ts +++ b/packages/core/src/utils/constants.ts @@ -506,8 +506,8 @@ const RESOLUTIONS = [ ] as const; const QUALITIES = [ - 'Bluray REMUX', - 'Bluray', + 'BluRay REMUX', + 'BluRay', 'WEB-DL', 'WEBRip', 'HDRip', @@ -532,6 +532,7 @@ const VISUAL_TAGS = [ 'IMAX', 'AI', 'SDR', + 'Unknown', ] as const; const AUDIO_TAGS = [ diff --git a/packages/frontend/src/components/menu/filters.tsx b/packages/frontend/src/components/menu/filters.tsx index 07d21973..4ccb7542 100644 --- a/packages/frontend/src/components/menu/filters.tsx +++ b/packages/frontend/src/components/menu/filters.tsx @@ -99,8 +99,8 @@ const defaultPreferredResolutions: Resolution[] = [ ]; const defaultPreferredQualities: Quality[] = [ - 'Bluray REMUX', - 'Bluray', + 'BluRay REMUX', + 'BluRay', 'WEB-DL', 'WEBRip', 'HDRip', @@ -1831,11 +1831,15 @@ function FilterSettings({ const [included, setIncluded] = useState(includedOptions); const [isDragging, setIsDragging] = useState(false); + const filterToAllowedValues = (filter: T[]) => { + return filter.filter((value) => options.some((opt) => opt.value === value)); + }; + useEffect(() => { - setRequired(requiredOptions); - setExcluded(excludedOptions); - setPreferred(preferredOptions); - setIncluded(includedOptions); + setRequired(filterToAllowedValues(requiredOptions)); + setExcluded(filterToAllowedValues(excludedOptions)); + setPreferred(filterToAllowedValues(preferredOptions)); + setIncluded(filterToAllowedValues(includedOptions)); }, [requiredOptions, excludedOptions, preferredOptions, includedOptions]); // DND logic @@ -2003,6 +2007,11 @@ function FilterSettings({ name={ options.find((opt) => opt.value === value)?.name || value } + onDelete={() => { + const newPreferred = preferred.filter((v) => v !== value); + setPreferred(newPreferred); + onPreferredChange(newPreferred); + }} /> ))} @@ -2014,7 +2023,15 @@ function FilterSettings({ ); } -function SortableFilterItem({ id, name }: { id: string; name: string }) { +function SortableFilterItem({ + id, + name, + onDelete, +}: { + id: string; + name: string; + onDelete: () => void; +}) { const { attributes, listeners, @@ -2041,6 +2058,19 @@ function SortableFilterItem({ id, name }: { id: string; name: string }) {
{name}
+
+ } + intent="alert-subtle" + onClick={(e) => { + e.preventDefault(); + e.stopPropagation(); + onDelete(); + }} + /> +
); diff --git a/packages/frontend/src/components/menu/save-install.tsx b/packages/frontend/src/components/menu/save-install.tsx index 66af793d..8b368af8 100644 --- a/packages/frontend/src/components/menu/save-install.tsx +++ b/packages/frontend/src/components/menu/save-install.tsx @@ -53,15 +53,12 @@ function Content() { React.useEffect(() => { const requirements: string[] = []; - console.log(uuid, password); // already created a config if (uuid && password) { + setPasswordRequirements([]); return; } - console.log(newPassword); - console.log('checking requirements'); - if (newPassword.length < 8) { requirements.push('Password must be at least 8 characters long'); } @@ -84,7 +81,7 @@ function Content() { } setPasswordRequirements(requirements); - }, [newPassword]); + }, [newPassword, uuid, password]); const handleSave = async (e?: React.FormEvent) => { e?.preventDefault();