From c0274ee7e7ebdc9f436d434a97fb192749d26210 Mon Sep 17 00:00:00 2001 From: Hydra Date: Mon, 15 Apr 2024 00:38:25 +0100 Subject: [PATCH] feat: adding accuracy as text instead of colours --- .prettierrc.js | 1 - README.md | 2 + src/locales/en/translation.json | 7 +- src/locales/es/translation.json | 7 +- src/locales/pt/translation.json | 7 +- src/main/services/how-long-to-beat.ts | 23 +++--- .../pages/game-details/game-details.css.ts | 18 +++-- .../pages/game-details/game-details.tsx | 22 +++--- .../game-details/how-long-to-beat-section.tsx | 72 ++++++++++--------- .../pages/game-details/repacks-modal.tsx | 4 +- src/types/index.ts | 2 +- 11 files changed, 83 insertions(+), 82 deletions(-) diff --git a/.prettierrc.js b/.prettierrc.js index 4bc87a040..acb402ebb 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -2,5 +2,4 @@ module.exports = { semi: true, trailingComma: "all", singleQuote: false, - tabWidth: 2, }; diff --git a/README.md b/README.md index 59497b3b0..8c2a5d9bb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Hydra ![Discord](https://img.shields.io/discord/1220692017311645737?style=flat&logo=discord&label=Hydra&labelColor=%231c1c1c) +![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml) +![GitHub package.json version](https://img.shields.io/github/package-json/v/hydralauncher/hydra) Hydra is a game launcher with its own embedded bittorrent client and a self-managed repack scraper. The launcher is written in TypeScript (Electron) and Python, which handles the torrenting system by using [libtorrent](https://www.libtorrent.org/). diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 432d4b0d0..1f1f7b638 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -58,12 +58,9 @@ "publisher": "Published by {{publisher}}", "copy_link_to_clipboard": "Copy link", "copied_link_to_clipboard": "Link copied", - "main_story": "Main story", - "main_plus_sides": "Main story + sides", - "completionist": "Completionist", - "all_styles": "All styles", "hours": "hours", - "minutes": "minutes" + "minutes": "minutes", + "accuracy": "{{accuracy}}% accuracy" }, "activation": { "title": "Activate Hydra", diff --git a/src/locales/es/translation.json b/src/locales/es/translation.json index 8e877103a..d059c08c7 100644 --- a/src/locales/es/translation.json +++ b/src/locales/es/translation.json @@ -58,12 +58,9 @@ "publisher": "Publicado por {{publisher}}", "copy_link_to_clipboard": "Copiar enlace", "copied_link_to_clipboard": "Enlace copiado", - "main_story": "Historia principal", - "main_plus_sides": "Historia principal + extras", - "completionist": "Completista", - "all_styles": "Todo", "hours": "horas", - "minutes": "minutos" + "minutes": "minutos", + "accuracy": "{{accuracy}}% precisión" }, "activation": { "title": "Activar Hydra", diff --git a/src/locales/pt/translation.json b/src/locales/pt/translation.json index 8f5a2e7c2..0342fb893 100644 --- a/src/locales/pt/translation.json +++ b/src/locales/pt/translation.json @@ -58,12 +58,9 @@ "publisher": "Publicado por {{publisher}}", "copy_link_to_clipboard": "Copiar link", "copied_link_to_clipboard": "Link copiado", - "main_story": "História principal", - "main_plus_sides": "Historia principal + extras", - "completionist": "Completista", - "all_styles": "Tudo", "hours": "horas", - "minutes": "minutos" + "minutes": "minutos", + "accuracy": "{{accuracy}}% de precisão" }, "activation": { "title": "Ativação", diff --git a/src/main/services/how-long-to-beat.ts b/src/main/services/how-long-to-beat.ts index e8471a940..62393fdf6 100644 --- a/src/main/services/how-long-to-beat.ts +++ b/src/main/services/how-long-to-beat.ts @@ -2,6 +2,7 @@ import { formatName } from "@main/helpers"; import axios from "axios"; import { JSDOM } from "jsdom"; import { requestWebPage } from "./repack-tracker/helpers"; +import { HowLongToBeatCategory } from "@types"; export interface HowLongToBeatResult { game_id: number; @@ -27,23 +28,15 @@ export const searchHowLongToBeat = async (gameName: string) => { "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", Referer: "https://howlongtobeat.com/", }, - } + }, ); return response.data as HowLongToBeatSearchResponse; }; -export const classNameColor = { - time_40: "#ff3a3a", - time_50: "#cc3b51", - time_60: "#824985", - time_70: "#5650a1", - time_80: "#485cab", - time_90: "#3a6db5", - time_100: "#287fc2", -}; - -export const getHowLongToBeatGame = async (id: string) => { +export const getHowLongToBeatGame = async ( + id: string, +): Promise => { const response = await requestWebPage(`https://howlongtobeat.com/game/${id}`); const { window } = new JSDOM(response); @@ -54,12 +47,14 @@ export const getHowLongToBeatGame = async (id: string) => { return $lis.map(($li) => { const title = $li.querySelector("h4").textContent; - const [, time] = Array.from(($li as HTMLElement).classList); + const [, accuracyClassName] = Array.from(($li as HTMLElement).classList); + + const accuracy = accuracyClassName.split("time_").at(1); return { title, duration: $li.querySelector("h5").textContent, - color: classNameColor[time as keyof typeof classNameColor], + accuracy, }; }); }; diff --git a/src/renderer/pages/game-details/game-details.css.ts b/src/renderer/pages/game-details/game-details.css.ts index 49a994b58..a513a5e14 100644 --- a/src/renderer/pages/game-details/game-details.css.ts +++ b/src/renderer/pages/game-details/game-details.css.ts @@ -139,19 +139,19 @@ export const descriptionHeaderInfo = style({ }); export const howLongToBeatCategoriesList = style({ - margin: 0, - padding: 16, + margin: "0", + padding: "16px", display: "flex", flexDirection: "column", - gap: 16, + gap: "16px", }); export const howLongToBeatCategory = style({ display: "flex", flexDirection: "column", - gap: 4, + gap: "4px", backgroundColor: vars.color.background, - borderRadius: 8, + borderRadius: "8px", padding: `8px 16px`, border: `solid 1px ${vars.color.borderColor}`, }); @@ -161,13 +161,19 @@ export const howLongToBeatCategoryLabel = style({ color: "#DADBE1", }); +export const howLongToBeatCategorySkeleton = style({ + border: `solid 1px ${vars.color.borderColor}`, + borderRadius: "8px", + height: "76px", +}); + globalStyle(".bb_tag", { marginTop: `${SPACING_UNIT * 2}px`, marginBottom: `${SPACING_UNIT * 2}px`, }); globalStyle(`${description} img`, { - borderRadius: 5, + borderRadius: "5px", marginTop: `${SPACING_UNIT}px`, marginBottom: `${SPACING_UNIT}px`, marginLeft: "auto", diff --git a/src/renderer/pages/game-details/game-details.tsx b/src/renderer/pages/game-details/game-details.tsx index 38d23e0a6..856b3ede8 100644 --- a/src/renderer/pages/game-details/game-details.tsx +++ b/src/renderer/pages/game-details/game-details.tsx @@ -31,9 +31,10 @@ export function GameDetails() { const [color, setColor] = useState(""); const [clipboardLock, setClipboardLock] = useState(false); const [gameDetails, setGameDetails] = useState(null); - const [howLongToBeat, setHowLongToBeat] = useState< - HowLongToBeatCategory[] | null - >(null); + const [howLongToBeat, setHowLongToBeat] = useState<{ + isLoading: boolean; + data: HowLongToBeatCategory[] | null; + }>({ isLoading: true, data: null }); const [game, setGame] = useState(null); const [activeRequirement, setActiveRequirement] = @@ -81,7 +82,7 @@ export function GameDetails() { window.electron .getHowLongToBeat(objectID, "steam", result.name) .then((data) => { - setHowLongToBeat(data); + setHowLongToBeat({ isLoading: false, data }); }); setGameDetails(result); @@ -89,7 +90,7 @@ export function GameDetails() { }); getGame(); - setHowLongToBeat(null); + setHowLongToBeat({ isLoading: true, data: null }); setClipboardLock(false); }, [getGame, dispatch, navigate, objectID, i18n.language]); @@ -103,12 +104,12 @@ export function GameDetails() { shop, encodeURIComponent(gameDetails?.name), i18n.language, - ]) + ]), ), }); navigator.clipboard.writeText( - OPEN_HYDRA_URL + `/?${searchParams.toString()}` + OPEN_HYDRA_URL + `/?${searchParams.toString()}`, ); const zero = performance.now(); @@ -134,7 +135,7 @@ export function GameDetails() { repackId, gameDetails.objectID, gameDetails.name, - shop as GameShop + shop as GameShop, ).then(() => { getGame(); setShowRepacksModal(false); @@ -217,7 +218,10 @@ export function GameDetails() {
- +
= { - "Main Story": "main_story", - "Main + Sides": "main_plus_sides", - Completionist: "completionist", - "All Styles": "all_styles", -}; +import { vars } from "@renderer/theme.css"; +import * as styles from "./game-details.css"; const durationTranslation: Record = { Hours: "hours", @@ -17,49 +11,59 @@ const durationTranslation: Record = { export interface HowLongToBeatSectionProps { howLongToBeatData: HowLongToBeatCategory[] | null; + isLoading: boolean; } export function HowLongToBeatSection({ howLongToBeatData, + isLoading, }: HowLongToBeatSectionProps) { const { t } = useTranslation("game_details"); - if (!howLongToBeatData) return null; - const getDuration = (duration: string) => { const [value, unit] = duration.split(" "); return `${value} ${t(durationTranslation[unit])}`; }; + if (!howLongToBeatData && !isLoading) return null; + return ( - <> +

HowLongToBeat

    - {howLongToBeatData.map((category) => ( -
  • -

    - {titleTranslation[category.title] - ? t(titleTranslation[category.title]) - : category.title} -

    -

    - {getDuration(category.duration)} -

    -
  • - ))} + {howLongToBeatData + ? howLongToBeatData.map((category) => ( +
  • +

    + {category.title} +

    + +

    + {getDuration(category.duration)} +

    + + {category.accuracy !== "00" && ( + + {t("accuracy", { accuracy: category.accuracy })} + + )} +
  • + )) + : Array.from({ length: 4 }).map((_, index) => ( + + ))}
- +
); } diff --git a/src/renderer/pages/game-details/repacks-modal.tsx b/src/renderer/pages/game-details/repacks-modal.tsx index fcefe6740..421163d10 100644 --- a/src/renderer/pages/game-details/repacks-modal.tsx +++ b/src/renderer/pages/game-details/repacks-modal.tsx @@ -56,8 +56,8 @@ export function RepacksModal({ gameDetails.repacks.filter((repack) => repack.title .toLowerCase() - .includes(event.target.value.toLocaleLowerCase()) - ) + .includes(event.target.value.toLocaleLowerCase()), + ), ); }; diff --git a/src/types/index.ts b/src/types/index.ts index 580994cab..2ab27f9ae 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -106,5 +106,5 @@ export interface UserPreferences { export interface HowLongToBeatCategory { title: string; duration: string; - color: string; + accuracy: string; }