Skip to content

Commit

Permalink
Merge pull request #1462 from hydralauncher/feat/improve-theming
Browse files Browse the repository at this point in the history
Feat/improve theming
  • Loading branch information
zamitto authored Feb 18, 2025
2 parents 0bf70ff + 21cec50 commit 92ac5b0
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 54 deletions.
2 changes: 1 addition & 1 deletion src/main/services/window-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class WindowManager {
trafficLightPosition: { x: 16, y: 16 },
titleBarOverlay: {
symbolColor: "#DADBE1",
color: "#151515",
color: "#00000000",
height: 34,
},
webPreferences: {
Expand Down
51 changes: 10 additions & 41 deletions src/renderer/src/pages/game-details/game-details-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,8 @@ import { useUserDetails } from "@renderer/hooks";
import { useSubscription } from "@renderer/hooks/use-subscription";
import "./game-details.scss";

const HERO_HEIGHT = 300;
const HERO_ANIMATION_THRESHOLD = 25;

export function GameDetailsContent() {
const heroRef = useRef<HTMLDivElement | null>(null);
const containerRef = useRef<HTMLDivElement | null>(null);
const [isHeaderStuck, setIsHeaderStuck] = useState(false);

const { t } = useTranslation("game_details");

Expand Down Expand Up @@ -61,7 +56,7 @@ export function GameDetailsContent() {
return t("no_shop_details");
}, [shopDetails, t]);

const [backdropOpactiy, setBackdropOpacity] = useState(1);
const [backdropOpacity, setBackdropOpacity] = useState(1);

const handleHeroLoad = async () => {
const output = await average(steamUrlBuilder.libraryHero(objectId!), {
Expand All @@ -80,26 +75,6 @@ export function GameDetailsContent() {
setBackdropOpacity(1);
}, [objectId]);

const onScroll: React.UIEventHandler<HTMLElement> = (event) => {
const heroHeight = heroRef.current?.clientHeight ?? HERO_HEIGHT;

const scrollY = (event.target as HTMLDivElement).scrollTop;
const opacity = Math.max(
0,
1 - scrollY / (heroHeight - HERO_ANIMATION_THRESHOLD)
);

if (scrollY >= heroHeight && !isHeaderStuck) {
setIsHeaderStuck(true);
}

if (scrollY <= heroHeight && isHeaderStuck) {
setIsHeaderStuck(false);
}

setBackdropOpacity(opacity);
};

const handleCloudSaveButtonClick = () => {
if (!userDetails) {
window.electron.openAuthWindow(AuthPage.SignIn);
Expand All @@ -122,31 +97,25 @@ export function GameDetailsContent() {
<div
className={`game-details__wrapper ${hasNSFWContentBlocked ? "game-details__wrapper--blurred" : ""}`}
>
<img
src={steamUrlBuilder.libraryHero(objectId!)}
className="game-details__hero-image"
alt={game?.title}
onLoad={handleHeroLoad}
/>

<section
ref={containerRef}
onScroll={onScroll}
className="game-details__container"
>
<section className="game-details__container">
<div ref={heroRef} className="game-details__hero">
<img
src={steamUrlBuilder.libraryHero(objectId!)}
className="game-details__hero-image"
alt={game?.title}
onLoad={handleHeroLoad}
/>
<div
className="game-details__hero-backdrop"
style={{
backgroundColor: gameColor,
flex: 1,
opacity: Math.min(1, 1 - backdropOpactiy),
}}
/>

<div
className="game-details__hero-logo-backdrop"
style={{ opacity: backdropOpactiy }}
style={{ opacity: backdropOpacity }}
>
<div className="game-details__hero-content">
<img
Expand All @@ -173,7 +142,7 @@ export function GameDetailsContent() {
</div>
</div>

<HeroPanel isHeaderStuck={isHeaderStuck} />
<HeroPanel />

<div className="game-details__description-container">
<div className="game-details__description-content">
Expand Down
11 changes: 2 additions & 9 deletions src/renderer/src/pages/game-details/hero/hero-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ import { HeroPanelPlaytime } from "./hero-panel-playtime";
import { gameDetailsContext } from "@renderer/context";
import "./hero-panel.scss";

export interface HeroPanelProps {
isHeaderStuck: boolean;
}

export function HeroPanel({ isHeaderStuck }: HeroPanelProps) {
export function HeroPanel() {
const { t } = useTranslation("game_details");

const { formatDate } = useDate();
Expand Down Expand Up @@ -54,10 +50,7 @@ export function HeroPanel({ isHeaderStuck }: HeroPanelProps) {
game?.download?.status === "paused";

return (
<div
style={{ backgroundColor: gameColor }}
className={`hero-panel ${isHeaderStuck ? "hero-panel--stuck" : ""}`}
>
<div style={{ backgroundColor: gameColor }} className="hero-panel">
<div className="hero-panel__content">{getInfo()}</div>
<div className="hero-panel__actions">
<HeroPanelActions />
Expand Down
26 changes: 23 additions & 3 deletions src/renderer/src/pages/settings/aparence/settings-appearance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ThemeActions, ThemeCard, ThemePlaceholder } from "./index";
import type { Theme } from "@types";
import { ImportThemeModal } from "./modals/import-theme-modal";
import { settingsContext } from "@renderer/context";
import { useNavigate } from "react-router-dom";

interface SettingsAppearanceProps {
appearance: {
Expand All @@ -24,8 +25,10 @@ export function SettingsAppearance({
authorId: string;
authorName: string;
} | null>(null);
const [hasShownModal, setHasShownModal] = useState(false);

const { clearTheme } = useContext(settingsContext);
const navigate = useNavigate();

const loadThemes = useCallback(async () => {
const themesList = await window.electron.getAllCustomThemes();
Expand All @@ -45,20 +48,37 @@ export function SettingsAppearance({
}, [loadThemes]);

useEffect(() => {
if (appearance.theme && appearance.authorId && appearance.authorName) {
if (
appearance.theme &&
appearance.authorId &&
appearance.authorName &&
!hasShownModal
) {
setIsImportThemeModalVisible(true);
setImportTheme({
theme: appearance.theme,
authorId: appearance.authorId,
authorName: appearance.authorName,
});
setHasShownModal(true);

navigate("/settings", { replace: true });
clearTheme();
}
}, [appearance.theme, appearance.authorId, appearance.authorName]);
}, [
appearance.theme,
appearance.authorId,
appearance.authorName,
navigate,
hasShownModal,
clearTheme,
]);

const onThemeImported = useCallback(() => {
setIsImportThemeModalVisible(false);
setImportTheme(null);
loadThemes();
}, [clearTheme, loadThemes]);
}, [loadThemes]);

return (
<div className="settings-appearance">
Expand Down

0 comments on commit 92ac5b0

Please sign in to comment.