mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-16 00:30:02 +00:00
Fix rating calculation
This commit is contained in:
@@ -238,6 +238,7 @@ export function metadataCompleteness(game: GameDto) {
|
|||||||
* @returns The scaled number
|
* @returns The scaled number
|
||||||
*/
|
*/
|
||||||
function convertRange(value: number, originalRange: number[], targetRange: number[]): number {
|
function convertRange(value: number, originalRange: number[], targetRange: number[]): number {
|
||||||
|
if (originalRange[0] === targetRange[0] && originalRange[1] === targetRange[1]) return value;
|
||||||
return (value - originalRange[0]) * (targetRange[1] - targetRange[0]) / (originalRange[1] - originalRange[0]) + targetRange[0];
|
return (value - originalRange[0]) * (targetRange[1] - targetRange[0]) / (originalRange[1] - originalRange[0]) + targetRange[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,22 +248,25 @@ function convertRange(value: number, originalRange: number[], targetRange: numbe
|
|||||||
* If only one rating is present, that rating is returned.
|
* If only one rating is present, that rating is returned.
|
||||||
* If neither rating is present, 0 is returned.
|
* If neither rating is present, 0 is returned.
|
||||||
* @param game The GameDto object containing the ratings.
|
* @param game The GameDto object containing the ratings.
|
||||||
* @returns The compound rating as a number between 0 and 100.
|
* @param scale The scale to convert the rating to (default is [0, 100]).
|
||||||
|
* @returns The compound rating.
|
||||||
*/
|
*/
|
||||||
export function compoundRating(game: GameDto): number {
|
export function compoundRating(game: GameDto, scale = [0, 100]): number {
|
||||||
const weights = {
|
const weights = {
|
||||||
critic: 0.4,
|
critic: 0.4,
|
||||||
user: 0.6
|
user: 0.6
|
||||||
};
|
};
|
||||||
|
const originalRange = [0, 100];
|
||||||
|
|
||||||
const criticRating = game.criticRating ?? 0;
|
const criticRating = game.criticRating ?? 0;
|
||||||
const userRating = game.userRating ?? 0;
|
const userRating = game.userRating ?? 0;
|
||||||
|
|
||||||
if (criticRating === 0 && userRating === 0) return 0;
|
if (criticRating === 0 && userRating === 0) return 0;
|
||||||
if (criticRating === 0) return userRating;
|
if (criticRating === 0) return convertRange(userRating, originalRange, scale);
|
||||||
if (userRating === 0) return criticRating;
|
if (userRating === 0) return convertRange(criticRating, originalRange, scale);
|
||||||
|
|
||||||
return Math.round((criticRating * weights.critic + userRating * weights.user) * 10) / 10;
|
const avgRating = Math.round((criticRating * weights.critic + userRating * weights.user) * 10) / 10;
|
||||||
|
return convertRange(avgRating, originalRange, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -272,12 +276,11 @@ export function compoundRating(game: GameDto): number {
|
|||||||
* @param game The GameDto object containing the ratings.
|
* @param game The GameDto object containing the ratings.
|
||||||
* @returns A string representing the star rating out of 5, or "N/A" if no ratings are available.
|
* @returns A string representing the star rating out of 5, or "N/A" if no ratings are available.
|
||||||
*/
|
*/
|
||||||
export function gameRatingInStars(game: GameDto) {
|
export function starRatingAsString(game: GameDto) {
|
||||||
const originalRange = [0, 100];
|
|
||||||
const starRange = [1, 5];
|
const starRange = [1, 5];
|
||||||
|
|
||||||
const rating = compoundRating(game);
|
const rating = compoundRating(game, starRange);
|
||||||
if (rating === 0) return "N/A";
|
if (rating === 0) return "N/A";
|
||||||
|
|
||||||
return convertRange(rating, originalRange, starRange).toFixed(1);
|
return rating.toFixed(1);
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ import {GameCover} from "Frontend/components/general/covers/GameCover";
|
|||||||
import ComboButton, {ComboButtonOption} from "Frontend/components/general/input/ComboButton";
|
import ComboButton, {ComboButtonOption} from "Frontend/components/general/input/ComboButton";
|
||||||
import ImageCarousel from "Frontend/components/general/covers/ImageCarousel";
|
import ImageCarousel from "Frontend/components/general/covers/ImageCarousel";
|
||||||
import {Accordion, AccordionItem, addToast, Button, Chip, Link, Tooltip, useDisclosure} from "@heroui/react";
|
import {Accordion, AccordionItem, addToast, Button, Chip, Link, Tooltip, useDisclosure} from "@heroui/react";
|
||||||
import {gameRatingInStars, humanFileSize, isAdmin, toTitleCase} from "Frontend/util/utils";
|
import {humanFileSize, isAdmin, starRatingAsString, toTitleCase} from "Frontend/util/utils";
|
||||||
import {DownloadEndpoint} from "Frontend/endpoints/endpoints";
|
import {DownloadEndpoint} from "Frontend/endpoints/endpoints";
|
||||||
import {gameState} from "Frontend/state/GameState";
|
import {gameState} from "Frontend/state/GameState";
|
||||||
import {useSnapshot} from "valtio/react";
|
import {useSnapshot} from "valtio/react";
|
||||||
@@ -108,7 +108,7 @@ export default function GameView() {
|
|||||||
</p>
|
</p>
|
||||||
<div className="flex flex-row gap-1 mb-0.5 text-default-500">
|
<div className="flex flex-row gap-1 mb-0.5 text-default-500">
|
||||||
<Star weight="fill"/>
|
<Star weight="fill"/>
|
||||||
{gameRatingInStars(game)}
|
{starRatingAsString(game)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row items-center gap-2">
|
<div className="flex flex-row items-center gap-2">
|
||||||
|
|||||||
@@ -235,11 +235,11 @@ export default function SearchView() {
|
|||||||
// Apply minimum rating filter
|
// Apply minimum rating filter
|
||||||
if (minRating > 1) {
|
if (minRating > 1) {
|
||||||
filtered = filtered.filter(game => {
|
filtered = filtered.filter(game => {
|
||||||
const rating = compoundRating(game);
|
const starRating = compoundRating(game, [1, 5]);
|
||||||
if (minRating === 5) {
|
if (minRating === 5) {
|
||||||
return rating > 4.5;
|
return starRating > 4.5;
|
||||||
}
|
}
|
||||||
return rating >= minRating;
|
return starRating >= minRating;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return filtered;
|
return filtered;
|
||||||
|
|||||||
Reference in New Issue
Block a user