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