diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 161708bb..a11ae546 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,9 @@ name: Build +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + on: pull_request jobs: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4e2a8c06..0a17b329 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,5 +1,9 @@ name: Lint +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + on: pull_request jobs: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index afa5502c..99a89245 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,5 +1,9 @@ name: Release +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + on: push: branches: main diff --git a/package.json b/package.json index f15861b2..38ea4434 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hydralauncher", - "version": "3.2.1", + "version": "3.2.3", "description": "Hydra", "main": "./out/main/index.js", "author": "Los Broxas", @@ -71,6 +71,7 @@ "react-loading-skeleton": "^3.4.0", "react-redux": "^9.1.1", "react-router-dom": "^6.22.3", + "react-tooltip": "^5.28.0", "sound-play": "^1.1.0", "sudo-prompt": "^9.2.1", "tar": "^7.4.3", diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index bf91cc40..f1e85019 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -444,9 +444,6 @@ "show_achievements_on_profile": "Show your achievements on your profile", "show_points_on_profile": "Show your earned points on your profile" }, - "badge": { - "badge_description_theme_creator": "Awarded to those who created a custom theme" - }, "achievement": { "achievement_unlocked": "Achievement unlocked", "user_achievements": "{{displayName}}'s Achievements", diff --git a/src/locales/pt-BR/translation.json b/src/locales/pt-BR/translation.json index 3556dbd1..0cefd188 100644 --- a/src/locales/pt-BR/translation.json +++ b/src/locales/pt-BR/translation.json @@ -440,9 +440,6 @@ "show_achievements_on_profile": "Exiba suas conquistas no perfil", "show_points_on_profile": "Exiba seus pontos ganhos no perfil" }, - "badge": { - "badge_description_theme_creator": "Concedido àqueles que criaram um tema customizado" - }, "achievement": { "achievement_unlocked": "Conquista desbloqueada", "your_achievements": "Suas Conquistas", diff --git a/src/main/events/index.ts b/src/main/events/index.ts index 572cba0f..8b8f4ebc 100644 --- a/src/main/events/index.ts +++ b/src/main/events/index.ts @@ -87,6 +87,7 @@ import "./themes/get-custom-theme-by-id"; import "./themes/get-active-custom-theme"; import "./themes/close-editor-window"; import "./themes/toggle-custom-theme"; +import "./misc/get-badges"; import { isPortableVersion } from "@main/helpers"; ipcMain.handle("ping", () => "pong"); diff --git a/src/main/events/misc/get-badges.ts b/src/main/events/misc/get-badges.ts new file mode 100644 index 00000000..7f4bc3ea --- /dev/null +++ b/src/main/events/misc/get-badges.ts @@ -0,0 +1,22 @@ +import { Badge } from "@types"; +import { registerEvent } from "../register-event"; +import { HydraApi } from "@main/services"; +import { db, levelKeys } from "@main/level"; + +const getBadges = async (_event: Electron.IpcMainInvokeEvent) => { + const language = await db + .get(levelKeys.language, { + valueEncoding: "utf-8", + }) + .then((language) => language || "en"); + + const params = new URLSearchParams({ + locale: language, + }); + + return HydraApi.get(`/badges?${params.toString()}`, null, { + needsAuth: false, + }); +}; + +registerEvent("getBadges", getBadges); diff --git a/src/main/main.ts b/src/main/main.ts index 6bcd0ff6..a7484f58 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -132,7 +132,9 @@ const migrateFromSqlite = async () => { ); if (rest.language) { - await db.put(levelKeys.language, rest.language); + await db.put(levelKeys.language, rest.language, { + valueEncoding: "utf-8", + }); } } }) diff --git a/src/preload/index.ts b/src/preload/index.ts index 5b3498ac..7b94cda1 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -266,6 +266,7 @@ contextBridge.exposeInMainWorld("electron", { showItemInFolder: (path: string) => ipcRenderer.invoke("showItemInFolder", path), getFeatures: () => ipcRenderer.invoke("getFeatures"), + getBadges: () => ipcRenderer.invoke("getBadges"), platform: process.platform, /* Auto update */ diff --git a/src/renderer/src/app.tsx b/src/renderer/src/app.tsx index daa93a6b..0b738c6f 100644 --- a/src/renderer/src/app.tsx +++ b/src/renderer/src/app.tsx @@ -263,9 +263,7 @@ export function App() { useEffect(() => { const unsubscribe = window.electron.onCssInjected((cssString) => { - if (cssString) { - injectCustomCss(cssString); - } + injectCustomCss(cssString); }); return () => unsubscribe(); diff --git a/src/renderer/src/assets/icons/badge-theme-creator.svg b/src/renderer/src/assets/icons/badge-theme-creator.svg deleted file mode 100644 index 0793a7e9..00000000 --- a/src/renderer/src/assets/icons/badge-theme-creator.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/renderer/src/components/avatar/avatar.scss b/src/renderer/src/components/avatar/avatar.scss index 57ad6ebf..c45c28b1 100644 --- a/src/renderer/src/components/avatar/avatar.scss +++ b/src/renderer/src/components/avatar/avatar.scss @@ -10,6 +10,7 @@ cursor: pointer; color: globals.$muted-color; position: relative; + overflow: hidden; &__image { height: 100%; diff --git a/src/renderer/src/components/avatar/avatar.tsx b/src/renderer/src/components/avatar/avatar.tsx index 9d68998a..99800acd 100644 --- a/src/renderer/src/components/avatar/avatar.tsx +++ b/src/renderer/src/components/avatar/avatar.tsx @@ -1,4 +1,5 @@ import { PersonIcon } from "@primer/octicons-react"; +import cn from "classnames"; import "./avatar.scss"; @@ -14,11 +15,18 @@ export interface AvatarProps src?: string | null; } -export function Avatar({ size, alt, src, ...props }: AvatarProps) { +export function Avatar({ size, alt, src, className, ...props }: AvatarProps) { return (
{src ? ( - {alt} + {alt} ) : ( )} diff --git a/src/renderer/src/components/backdrop/backdrop.tsx b/src/renderer/src/components/backdrop/backdrop.tsx index e62d42ee..5caedb0e 100644 --- a/src/renderer/src/components/backdrop/backdrop.tsx +++ b/src/renderer/src/components/backdrop/backdrop.tsx @@ -6,7 +6,10 @@ export interface BackdropProps { children: React.ReactNode; } -export function Backdrop({ isClosing = false, children }: BackdropProps) { +export function Backdrop({ + isClosing = false, + children, +}: Readonly) { return (
) { return (
) : ( diff --git a/src/renderer/src/pages/profile/profile-hero/user-badges.tsx b/src/renderer/src/pages/profile/profile-hero/user-badges.tsx deleted file mode 100644 index ed5d0571..00000000 --- a/src/renderer/src/pages/profile/profile-hero/user-badges.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import BadgeThemeCreator from "@renderer/assets/icons/badge-theme-creator.svg?react"; -import "./profile-hero.scss"; -import { useContext } from "react"; -import { userProfileContext } from "@renderer/context"; -import { UserBadge } from "@types"; -import { useTranslation } from "react-i18next"; - -export function UserBadges() { - const { t } = useTranslation("badge"); - const { userProfile } = useContext(userProfileContext); - - if (!userProfile?.badges?.length) return null; - - const getBadgeIcon = (badge: UserBadge) => { - if (badge === "THEME_CREATOR") { - return ; - } - - return null; - }; - - return ( -
- {userProfile.badges.map((badge) => { - const badgeIcon = getBadgeIcon(badge); - - if (!badgeIcon) return null; - return ( -
- {badgeIcon} -
- ); - })} -
- ); -} diff --git a/src/renderer/src/pages/settings/aparence/settings-appearance.tsx b/src/renderer/src/pages/settings/aparence/settings-appearance.tsx index 2cc5bec1..b8ab0b84 100644 --- a/src/renderer/src/pages/settings/aparence/settings-appearance.tsx +++ b/src/renderer/src/pages/settings/aparence/settings-appearance.tsx @@ -110,6 +110,7 @@ export function SettingsAppearance({ onClose={() => { setIsImportThemeModalVisible(false); clearTheme(); + setHasShownModal(false); }} onThemeImported={onThemeImported} themeName={importTheme.theme} diff --git a/src/types/index.ts b/src/types/index.ts index e17a694a..a8726b6b 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -130,7 +130,13 @@ export interface UserProfileCurrentGame extends Omit { export type ProfileVisibility = "PUBLIC" | "PRIVATE" | "FRIENDS"; -export type UserBadge = "THEME_CREATOR"; +export interface Badge { + name: string; + description: string; + badge: { + url: string; + }; +} export interface UserDetails { id: string; @@ -166,7 +172,7 @@ export interface UserProfile { quirks: { backupsPerGameLimit: number; }; - badges: UserBadge[]; + badges: string[]; } export interface UpdateProfileRequest { diff --git a/yarn.lock b/yarn.lock index 58d0cc9a..22b895e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1663,6 +1663,14 @@ "@floating-ui/core" "^1.6.0" "@floating-ui/utils" "^0.2.8" +"@floating-ui/dom@^1.6.1": + version "1.6.13" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.13.tgz#a8a938532aea27a95121ec16e667a7cbe8c59e34" + integrity sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w== + dependencies: + "@floating-ui/core" "^1.6.0" + "@floating-ui/utils" "^0.2.9" + "@floating-ui/react-dom@^2.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.1.2.tgz#a1349bbf6a0e5cb5ded55d023766f20a4d439a31" @@ -1675,6 +1683,11 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.8.tgz#21a907684723bbbaa5f0974cf7730bd797eb8e62" integrity sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig== +"@floating-ui/utils@^0.2.9": + version "0.2.9" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.9.tgz#50dea3616bc8191fb8e112283b49eaff03e78429" + integrity sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg== + "@fontsource/noto-sans@^5.1.0": version "5.1.0" resolved "https://registry.yarnpkg.com/@fontsource/noto-sans/-/noto-sans-5.1.0.tgz#54a5edd1b2b8c8e17bec6a85d4ee3a53b4b89c1f" @@ -4279,7 +4292,7 @@ classic-level@^2.0.0: napi-macros "^2.2.2" node-gyp-build "^4.3.0" -classnames@^2.2.1, classnames@^2.2.6, classnames@^2.5.1: +classnames@^2.2.1, classnames@^2.2.6, classnames@^2.3.0, classnames@^2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== @@ -8093,6 +8106,14 @@ react-style-singleton@^2.2.1: invariant "^2.2.4" tslib "^2.0.0" +react-tooltip@^5.28.0: + version "5.28.0" + resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.28.0.tgz#c7b5343ab2d740a428494a3d8315515af1f26f46" + integrity sha512-R5cO3JPPXk6FRbBHMO0rI9nkUG/JKfalBSQfZedZYzmqaZQgq7GLzF8vcCWx6IhUCKg0yPqJhXIzmIO5ff15xg== + dependencies: + "@floating-ui/dom" "^1.6.1" + classnames "^2.3.0" + react@^18.2.0: version "18.3.1" resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891"