mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-18 08:43:57 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20c0d3174b | ||
|
|
cd3fa10bf7 | ||
|
|
a57cc83076 | ||
|
|
05d68fa23b | ||
|
|
527a65e9bc | ||
|
|
fe6bb5763d | ||
|
|
002dff098c |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hydralauncher",
|
"name": "hydralauncher",
|
||||||
"version": "3.7.5",
|
"version": "3.7.4",
|
||||||
"description": "Hydra",
|
"description": "Hydra",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "Los Broxas",
|
"author": "Los Broxas",
|
||||||
|
|||||||
@@ -7,9 +7,25 @@ export function useLibrary() {
|
|||||||
const library = useAppSelector((state) => state.library.value);
|
const library = useAppSelector((state) => state.library.value);
|
||||||
|
|
||||||
const updateLibrary = useCallback(async () => {
|
const updateLibrary = useCallback(async () => {
|
||||||
return window.electron
|
return window.electron.getLibrary().then(async (updatedLibrary) => {
|
||||||
.getLibrary()
|
const libraryWithAchievements = await Promise.all(
|
||||||
.then((updatedLibrary) => dispatch(setLibrary(updatedLibrary)));
|
updatedLibrary.map(async (game) => {
|
||||||
|
const unlockedAchievements =
|
||||||
|
await window.electron.getUnlockedAchievements(
|
||||||
|
game.objectId,
|
||||||
|
game.shop
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...game,
|
||||||
|
unlockedAchievementCount:
|
||||||
|
game.unlockedAchievementCount || unlockedAchievements.length,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatch(setLibrary(libraryWithAchievements));
|
||||||
|
});
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
return { library, updateLibrary };
|
return { library, updateLibrary };
|
||||||
|
|||||||
@@ -12,12 +12,18 @@ interface LibraryGameCardLargeProps {
|
|||||||
) => void;
|
) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const normalizePathForCss = (url: string | null | undefined): string => {
|
||||||
|
if (!url) return "";
|
||||||
|
return url.replaceAll("\\", "/");
|
||||||
|
};
|
||||||
|
|
||||||
const getImageWithCustomPriority = (
|
const getImageWithCustomPriority = (
|
||||||
customUrl: string | null | undefined,
|
customUrl: string | null | undefined,
|
||||||
originalUrl: string | null | undefined,
|
originalUrl: string | null | undefined,
|
||||||
fallbackUrl?: string | null | undefined
|
fallbackUrl?: string | null | undefined
|
||||||
) => {
|
) => {
|
||||||
return customUrl || originalUrl || fallbackUrl || "";
|
const selectedUrl = customUrl || originalUrl || fallbackUrl || "";
|
||||||
|
return normalizePathForCss(selectedUrl);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LibraryGameCardLarge = memo(function LibraryGameCardLarge({
|
export const LibraryGameCardLarge = memo(function LibraryGameCardLarge({
|
||||||
@@ -30,15 +36,21 @@ export const LibraryGameCardLarge = memo(function LibraryGameCardLarge({
|
|||||||
const backgroundImage = useMemo(
|
const backgroundImage = useMemo(
|
||||||
() =>
|
() =>
|
||||||
getImageWithCustomPriority(
|
getImageWithCustomPriority(
|
||||||
|
game.customHeroImageUrl,
|
||||||
game.libraryHeroImageUrl,
|
game.libraryHeroImageUrl,
|
||||||
game.libraryImageUrl,
|
game.libraryImageUrl ?? game.iconUrl
|
||||||
game.iconUrl
|
|
||||||
),
|
),
|
||||||
[game.libraryHeroImageUrl, game.libraryImageUrl, game.iconUrl]
|
[
|
||||||
|
game.customHeroImageUrl,
|
||||||
|
game.libraryHeroImageUrl,
|
||||||
|
game.libraryImageUrl,
|
||||||
|
game.iconUrl,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
const backgroundStyle = useMemo(
|
const backgroundStyle = useMemo(
|
||||||
() => ({ backgroundImage: `url(${backgroundImage})` }),
|
() =>
|
||||||
|
backgroundImage ? { backgroundImage: `url(${backgroundImage})` } : {},
|
||||||
[backgroundImage]
|
[backgroundImage]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -49,7 +61,7 @@ export const LibraryGameCardLarge = memo(function LibraryGameCardLarge({
|
|||||||
[game.unlockedAchievementCount, game.achievementCount]
|
[game.unlockedAchievementCount, game.achievementCount]
|
||||||
);
|
);
|
||||||
|
|
||||||
const logoImage = game.logoImageUrl;
|
const logoImage = game.customLogoImageUrl ?? game.logoImageUrl;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -25,12 +25,14 @@ export const LibraryGameCard = memo(function LibraryGameCard({
|
|||||||
const { formatPlayTime, handleCardClick, handleContextMenuClick } =
|
const { formatPlayTime, handleCardClick, handleContextMenuClick } =
|
||||||
useGameCard(game, onContextMenu);
|
useGameCard(game, onContextMenu);
|
||||||
|
|
||||||
const coverImage =
|
const coverImage = (
|
||||||
|
game.customIconUrl ??
|
||||||
game.coverImageUrl ??
|
game.coverImageUrl ??
|
||||||
game.libraryImageUrl ??
|
game.libraryImageUrl ??
|
||||||
game.libraryHeroImageUrl ??
|
game.libraryHeroImageUrl ??
|
||||||
game.iconUrl ??
|
game.iconUrl ??
|
||||||
undefined;
|
""
|
||||||
|
).replaceAll("\\", "/");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -19,7 +19,10 @@ export default function Library() {
|
|||||||
onLibraryBatchComplete?: (cb: () => void) => () => void;
|
onLibraryBatchComplete?: (cb: () => void) => () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const [viewMode, setViewMode] = useState<ViewMode>("compact");
|
const [viewMode, setViewMode] = useState<ViewMode>(() => {
|
||||||
|
const savedViewMode = localStorage.getItem("library-view-mode");
|
||||||
|
return (savedViewMode as ViewMode) || "compact";
|
||||||
|
});
|
||||||
const [filterBy, setFilterBy] = useState<FilterOption>("all");
|
const [filterBy, setFilterBy] = useState<FilterOption>("all");
|
||||||
const [contextMenu, setContextMenu] = useState<{
|
const [contextMenu, setContextMenu] = useState<{
|
||||||
game: LibraryGame | null;
|
game: LibraryGame | null;
|
||||||
@@ -31,6 +34,11 @@ export default function Library() {
|
|||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation("library");
|
const { t } = useTranslation("library");
|
||||||
|
|
||||||
|
const handleViewModeChange = useCallback((mode: ViewMode) => {
|
||||||
|
setViewMode(mode);
|
||||||
|
localStorage.setItem("library-view-mode", mode);
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(setHeaderTitle(t("library")));
|
dispatch(setHeaderTitle(t("library")));
|
||||||
const electron = (globalThis as unknown as { electron?: ElectronAPI })
|
const electron = (globalThis as unknown as { electron?: ElectronAPI })
|
||||||
@@ -71,7 +79,7 @@ export default function Library() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleCloseContextMenu = useCallback(() => {
|
const handleCloseContextMenu = useCallback(() => {
|
||||||
setContextMenu({ game: null, visible: false, position: { x: 0, y: 0 } });
|
setContextMenu((prev) => ({ ...prev, visible: false }));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const filteredLibrary = useMemo(() => {
|
const filteredLibrary = useMemo(() => {
|
||||||
@@ -147,7 +155,10 @@ export default function Library() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="library__controls-right">
|
<div className="library__controls-right">
|
||||||
<ViewOptions viewMode={viewMode} onViewModeChange={setViewMode} />
|
<ViewOptions
|
||||||
|
viewMode={viewMode}
|
||||||
|
onViewModeChange={handleViewModeChange}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user