From 26abc584a9e558119bdc4605231d813a0088544a Mon Sep 17 00:00:00 2001 From: AgentScrubbles Date: Wed, 5 Aug 2026 23:13:43 -0700 Subject: [PATCH] Set Age Restrictions on library with a slider (#468) * Adding groups logic and restrictions * Cleaning up some redundant code * hastily made translations * Linter issues * More linting * PR comments * Covering other APIs with age filters per comment * Add ages to age ratings * Making the linter happy --------- Co-authored-by: Robert Clabough --- server/i18n/locales/de.json | 6 + server/i18n/locales/en_pirate.json | 6 + server/i18n/locales/en_us.json | 6 + server/i18n/locales/fr.json | 6 + server/i18n/locales/pl.json | 6 + server/pages/admin/users/groups/[id].vue | 237 ++++++++++++++----- server/server/internal/metadata/giantbomb.ts | 26 +- server/server/internal/metadata/igdb.ts | 74 +++--- server/server/internal/metadata/steam.ts | 4 +- server/utils/ageRatings.ts | 139 ++++++++--- 10 files changed, 357 insertions(+), 153 deletions(-) diff --git a/server/i18n/locales/de.json b/server/i18n/locales/de.json index 9d9a6abf..6c22ab4e 100644 --- a/server/i18n/locales/de.json +++ b/server/i18n/locales/de.json @@ -702,6 +702,8 @@ "groups": { "addBannedRating": "Gesperrte Einstufung hinzufügen", "addMember": "Benutzer auswählen...", + "advancedOverrides": "Erweitert: Manuelle Überschreibungen", + "applyAgeRestriction": "Altersbeschränkung anwenden", "bannedRatings": "Gesperrte Alterseinstufungen", "createGroup": "Gruppe erstellen", "deleteConfirm": "Sind Sie sicher, dass Sie diese Gruppe löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.", @@ -709,6 +711,9 @@ "description": "Benutzergruppen und Altersbeschränkungen verwalten.", "descriptionField": "Beschreibung", "details": "Details", + "manualOverrideNote": "Die aktuellen gesperrten Bewertungen entsprechen keiner Standard-Altersschwelle. Sie wurden möglicherweise manuell konfiguriert.", + "maximumContentAge": "Altersbeschränkung", + "maximumContentAgeDescription": "Legen Sie das maximale Inhaltsalter für Mitglieder dieser Gruppe fest. Bewertungen über diesem Alter werden gesperrt.", "members": "Mitglieder", "name": "Name", "noBannedRatings": "Keine gesperrten Einstufungen konfiguriert.", @@ -716,6 +721,7 @@ "oidcManagedNote": "Die Gruppenmitgliedschaft wird von Ihrem OIDC-Anbieter verwaltet. Mitglieder werden bei der Anmeldung automatisch synchronisiert. Um die Gruppenmitgliedschaft zu ändern, aktualisieren Sie die Gruppenzuweisungen Ihres Identitätsanbieters.", "removeBannedRating": "Entfernen", "removeMember": "Entfernen", + "sliderOverrideWarning": "Das manuelle Hinzufügen oder Entfernen von Bewertungen überschreibt den Schieberegler. Verwenden Sie den obigen Schieberegler, um auf eine Standard-Altersschwelle zurückzusetzen.", "title": "Benutzergruppen", "unratedNote": "Spiele ohne Alterseinstufung werden für Benutzer in dieser Gruppe ebenfalls ausgeblendet." }, diff --git a/server/i18n/locales/en_pirate.json b/server/i18n/locales/en_pirate.json index 2201b510..69b8356e 100644 --- a/server/i18n/locales/en_pirate.json +++ b/server/i18n/locales/en_pirate.json @@ -501,6 +501,8 @@ "groups": { "addBannedRating": "Add forbidden rating", "addMember": "Pick a scallywag...", + "advancedOverrides": "Advanced: Manual Overrides", + "applyAgeRestriction": "Apply age restriction", "bannedRatings": "Forbidden Ratings", "createGroup": "Form a Crew", "deleteConfirm": "Be ye sure ye want to disband this crew? There be no turnin' back!", @@ -508,6 +510,9 @@ "description": "Manage yer crew groups and age restrictions on the plunder.", "descriptionField": "Description", "details": "Details", + "manualOverrideNote": "The current banned ratings don't match a standard age threshold. They may've been manually set by the captain.", + "maximumContentAge": "Age Restriction", + "maximumContentAgeDescription": "Set the maximum content age fer members of this crew. Ratings above this age be banned, arr!", "members": "Crew Members", "name": "Name", "noBannedRatings": "No forbidden ratings set, captain.", @@ -515,6 +520,7 @@ "oidcManagedNote": "Crew membership be managed by yer OIDC harbourmaster. Members be synced when they come aboard. To change crew membership, update yer identity provider's assignments.", "removeBannedRating": "Remove", "removeMember": "Cast overboard", + "sliderOverrideWarning": "Manually addin' or removin' ratings here will override the slider. Use the slider above to reset to a standard age threshold.", "title": "Crew Groups", "unratedNote": "Unrated plunder will also be hidden from scallywags in this crew." }, diff --git a/server/i18n/locales/en_us.json b/server/i18n/locales/en_us.json index 3352f2a0..22ae8eb8 100644 --- a/server/i18n/locales/en_us.json +++ b/server/i18n/locales/en_us.json @@ -820,6 +820,8 @@ "groups": { "addBannedRating": "Add banned rating", "addMember": "Select a user...", + "advancedOverrides": "Advanced: Manual Overrides", + "applyAgeRestriction": "Apply age restriction", "bannedRatings": "Banned Ratings", "createGroup": "Create Group", "deleteConfirm": "Are you sure you want to delete this group? This action cannot be undone.", @@ -827,6 +829,9 @@ "description": "Manage user groups and age rating restrictions.", "descriptionField": "Description", "details": "Details", + "manualOverrideNote": "The current banned ratings do not match a standard age threshold. They may have been manually configured.", + "maximumContentAge": "Age Restriction", + "maximumContentAgeDescription": "Set the maximum content age allowed for members of this group. Ratings above this age will be banned.", "members": "Members", "name": "Name", "noBannedRatings": "No banned ratings configured.", @@ -834,6 +839,7 @@ "oidcManagedNote": "Group membership is managed by your OIDC provider. Members are automatically synced when users log in. To change group membership, update your identity provider's group assignments.", "removeBannedRating": "Remove", "removeMember": "Remove", + "sliderOverrideWarning": "Manually adding or removing ratings here will override the slider. Use the slider above to reset to a standard age threshold.", "title": "User Groups", "unratedNote": "Games without age ratings will also be hidden from users in this group." }, diff --git a/server/i18n/locales/fr.json b/server/i18n/locales/fr.json index 4fc8f23c..141cd08c 100644 --- a/server/i18n/locales/fr.json +++ b/server/i18n/locales/fr.json @@ -702,6 +702,8 @@ "groups": { "addBannedRating": "Ajouter une classification interdite", "addMember": "Sélectionner un utilisateur...", + "advancedOverrides": "Avancé : Remplacements manuels", + "applyAgeRestriction": "Appliquer la restriction d'âge", "bannedRatings": "Classifications interdites", "createGroup": "Créer un groupe", "deleteConfirm": "Êtes-vous sûr de vouloir supprimer ce groupe ? Cette action est irréversible.", @@ -709,6 +711,9 @@ "description": "Gérer les groupes d'utilisateurs et les restrictions d'âge.", "descriptionField": "Description", "details": "Détails", + "manualOverrideNote": "Les classifications interdites actuelles ne correspondent pas à un seuil d'âge standard. Elles ont peut-être été configurées manuellement.", + "maximumContentAge": "Restriction d'âge", + "maximumContentAgeDescription": "Définissez l'âge maximum du contenu autorisé pour les membres de ce groupe. Les classifications au-dessus de cet âge seront interdites.", "members": "Membres", "name": "Nom", "noBannedRatings": "Aucune classification interdite configurée.", @@ -716,6 +721,7 @@ "oidcManagedNote": "L'appartenance aux groupes est gérée par votre fournisseur OIDC. Les membres sont automatiquement synchronisés lors de la connexion. Pour modifier l'appartenance aux groupes, mettez à jour les affectations de groupes de votre fournisseur d'identité.", "removeBannedRating": "Retirer", "removeMember": "Retirer", + "sliderOverrideWarning": "L'ajout ou la suppression manuelle de classifications remplacera le curseur. Utilisez le curseur ci-dessus pour revenir à un seuil d'âge standard.", "title": "Groupes d'utilisateurs", "unratedNote": "Les jeux sans classification d'âge seront également masqués pour les utilisateurs de ce groupe." }, diff --git a/server/i18n/locales/pl.json b/server/i18n/locales/pl.json index 2b5c11ff..72980b97 100644 --- a/server/i18n/locales/pl.json +++ b/server/i18n/locales/pl.json @@ -678,6 +678,8 @@ "groups": { "addBannedRating": "Dodaj zablokowaną kategorię", "addMember": "Wybierz użytkownika...", + "advancedOverrides": "Zaawansowane: Ręczne zastępowanie", + "applyAgeRestriction": "Zastosuj ograniczenie wiekowe", "bannedRatings": "Zablokowane kategorie wiekowe", "createGroup": "Utwórz grupę", "deleteConfirm": "Czy na pewno chcesz usunąć tę grupę? Tej akcji nie można cofnąć.", @@ -685,6 +687,9 @@ "description": "Zarządzaj grupami użytkowników i ograniczeniami wiekowymi.", "descriptionField": "Opis", "details": "Szczegóły", + "manualOverrideNote": "Obecne zablokowane oceny nie odpowiadają standardowemu progowi wiekowemu. Mogły zostać skonfigurowane ręcznie.", + "maximumContentAge": "Ograniczenie wiekowe", + "maximumContentAgeDescription": "Ustaw maksymalny wiek treści dozwolony dla członków tej grupy. Oceny powyżej tego wieku zostaną zablokowane.", "members": "Członkowie", "name": "Nazwa", "noBannedRatings": "Brak skonfigurowanych zablokowanych kategorii.", @@ -692,6 +697,7 @@ "oidcManagedNote": "Członkostwo w grupach jest zarządzane przez dostawcę OIDC. Członkowie są automatycznie synchronizowani podczas logowania. Aby zmienić członkostwo w grupach, zaktualizuj przypisania grup u dostawcy tożsamości.", "removeBannedRating": "Usuń", "removeMember": "Usuń", + "sliderOverrideWarning": "Ręczne dodawanie lub usuwanie ocen zastąpi suwak. Użyj suwaka powyżej, aby powrócić do standardowego progu wiekowego.", "title": "Grupy użytkowników", "unratedNote": "Gry bez kategorii wiekowej będą również ukryte przed użytkownikami w tej grupie." }, diff --git a/server/pages/admin/users/groups/[id].vue b/server/pages/admin/users/groups/[id].vue index b9878af5..fc79e485 100644 --- a/server/pages/admin/users/groups/[id].vue +++ b/server/pages/admin/users/groups/[id].vue @@ -92,7 +92,7 @@ - + + + + {{ bp.organization }}: {{ bp.rating }} + - -
- - - - +
+

+ {{ $t("users.admin.groups.noBannedRatings") }} +

+
+ + +
+
+ + {{ $t("users.admin.groups.advancedOverrides") }} + +
+

+ {{ $t("users.admin.groups.sliderOverrideWarning") }} +

+ +
+ {{ $t("users.admin.groups.noBannedRatings") }} +
+ +
+
+ + + {{ br.organization }}: {{ br.rating }} + + + +
+
+ +
+ + + + +
+ +
+
+