From 3a95e751d00582c8c7344ab29031c0f29543e072 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Wed, 24 Sep 2025 01:17:58 +0200 Subject: [PATCH] Fixup --- .../routes/users/parentalcontrol.tsx | 93 +++++++++++-------- 1 file changed, 55 insertions(+), 38 deletions(-) diff --git a/src/apps/dashboard/routes/users/parentalcontrol.tsx b/src/apps/dashboard/routes/users/parentalcontrol.tsx index 1707ed8d77..df930ae17c 100644 --- a/src/apps/dashboard/routes/users/parentalcontrol.tsx +++ b/src/apps/dashboard/routes/users/parentalcontrol.tsx @@ -1,4 +1,4 @@ -import type { AccessSchedule, ParentalRating, ParentalRatingScore, UserDto } from '@jellyfin/sdk/lib/generated-client'; +import type { AccessSchedule, ParentalRating, UserDto } from '@jellyfin/sdk/lib/generated-client'; import { UnratedItem } from '@jellyfin/sdk/lib/generated-client/models/unrated-item'; import { DynamicDayOfWeek } from '@jellyfin/sdk/lib/generated-client/models/dynamic-day-of-week'; import escapeHTML from 'escape-html'; @@ -30,6 +30,7 @@ type UnratedNamedItem = NamedItem & { function handleSaveUser( page: HTMLDivElement, + parentalRatingsRef: React.MutableRefObject, getSchedulesFromPage: () => AccessSchedule[], getAllowedTagsFromPage: () => string[], getBlockedTagsFromPage: () => string[], @@ -42,9 +43,10 @@ function handleSaveUser( throw new Error('Unexpected null user id or policy'); } - const parentalRating = page.querySelector('#selectMaxParentalRating') as ParentalRatingScore; - const score = parentalRating.score; - const subScore = parentalRating.subScore; + const parentalRatingIndex = parseInt((page.querySelector('#selectMaxParentalRating') as HTMLSelectElement).value, 10); + const parentalRating = parentalRatingsRef.current[parentalRatingIndex] as ParentalRating; + const score = parentalRating?.RatingScore?.score; + const subScore = parentalRating?.RatingScore?.subScore; userPolicy.MaxParentalRating = Number.isNaN(score) ? null : score; userPolicy.MaxParentalSubRating = Number.isNaN(subScore) ? null : subScore; userPolicy.BlockUnratedItems = Array.prototype.filter @@ -75,28 +77,7 @@ const UserParentalControl = () => { const libraryMenu = useMemo(async () => ((await import('../../../../scripts/libraryMenu')).default), []); const element = useRef(null); - - const populateRatings = useCallback((allParentalRatings: ParentalRating[]) => { - let rating; - const ratings: ParentalRating[] = []; - - for (let i = 0, length = allParentalRatings.length; i < length; i++) { - rating = allParentalRatings[i]; - - if (ratings.length) { - const lastRating = ratings[ratings.length - 1]; - - if (lastRating.RatingScore?.score === rating.RatingScore?.score && lastRating.RatingScore?.subScore == rating.RatingScore?.subScore) { - lastRating.Name += '/' + rating.Name; - continue; - } - } - - ratings.push(rating); - } - - setParentalRatings(ratings); - }, []); + const parentalRatingsRef = useRef([]); const loadUnratedItems = useCallback((user: UserDto) => { const page = element.current; @@ -161,16 +142,52 @@ const UserParentalControl = () => { setAllowedTags(user.Policy?.AllowedTags || []); setBlockedTags(user.Policy?.BlockedTags || []); - populateRatings(allParentalRatings); - let ratingValue = ''; - allParentalRatings.forEach(rating => { - if (rating.Value != null && user.Policy?.MaxParentalRating != null && user.Policy.MaxParentalRating >= rating.Value) { - ratingValue = `${rating.Value}`; + // Build the grouped ratings array + const ratings: ParentalRating[] = []; + for (let i = 0, length = allParentalRatings.length; i < length; i++) { + const rating = allParentalRatings[i]; + + if (ratings.length) { + const lastRating = ratings[ratings.length - 1]; + + if (lastRating.RatingScore?.score === rating.RatingScore?.score && lastRating.RatingScore?.subScore == rating.RatingScore?.subScore) { + lastRating.Name += '/' + rating.Name; + continue; + } } - }); - setMaxParentalRating(ratingValue); + ratings.push(rating); + } + setParentalRatings(ratings); + parentalRatingsRef.current = ratings; + + // Find matching rating - first try exact match with score and subscore + let ratingIndex = ''; + const userMaxRating = user.Policy?.MaxParentalRating; + const userMaxSubRating = user.Policy?.MaxParentalSubRating; + + if (userMaxRating != null) { + // First try to find exact match with both score and subscore + ratings.forEach((rating, index) => { + if (rating.RatingScore?.score === userMaxRating + && rating.RatingScore?.subScore === userMaxSubRating) { + ratingIndex = `${index}`; + } + }); + + // If no exact match found, fallback to score-only match + if (!ratingIndex) { + ratings.forEach((rating, index) => { + if (rating.RatingScore?.score != null + && rating.RatingScore.score <= userMaxRating) { + ratingIndex = `${index}`; + } + }); + } + } + + setMaxParentalRating(ratingIndex); if (user.Policy?.IsAdministrator) { (page.querySelector('.accessScheduleSection') as HTMLDivElement).classList.add('hide'); @@ -179,7 +196,7 @@ const UserParentalControl = () => { } setAccessSchedules(user.Policy?.AccessSchedules || []); loading.hide(); - }, [libraryMenu, setAllowedTags, setBlockedTags, loadUnratedItems, populateRatings]); + }, [libraryMenu, setAllowedTags, setBlockedTags, loadUnratedItems]); const loadData = useCallback(() => { if (!userId) { @@ -286,7 +303,7 @@ const UserParentalControl = () => { toast(globalize.translate('SettingsSaved')); }; - const saveUser = handleSaveUser(page, getSchedulesFromPage, getAllowedTagsFromPage, getBlockedTagsFromPage, onSaveComplete); + const saveUser = handleSaveUser(page, parentalRatingsRef, getSchedulesFromPage, getAllowedTagsFromPage, getBlockedTagsFromPage, onSaveComplete); const onSubmit = (e: Event) => { if (!userId) { @@ -342,11 +359,11 @@ const UserParentalControl = () => { const optionMaxParentalRating = () => { let content = ''; content += ''; - for (const rating of parentalRatings) { + parentalRatings.forEach((rating, index) => { if (rating.RatingScore != null) { - content += ``; + content += ``; } - } + }); return content; };