mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
full migration to scss
This commit is contained in:
parent
d038398750
commit
138244d5aa
10 changed files with 70 additions and 68 deletions
|
@ -46,7 +46,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.toast__content {
|
&__content {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: $spacing-unit * 2;
|
gap: $spacing-unit * 2;
|
||||||
padding: $spacing-unit * 2;
|
padding: $spacing-unit * 2;
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toast__progress {
|
&__progress {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 5px;
|
height: 5px;
|
||||||
|
|
||||||
|
@ -67,21 +67,26 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.toast__close-button {
|
&__close-button {
|
||||||
color: $body-color;
|
color: $body-color;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toast__success-icon {
|
&__icon-container {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--spacing-unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__success-icon {
|
||||||
color: $success-color;
|
color: $success-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toast__error-icon {
|
&__error-icon {
|
||||||
color: $danger-color;
|
color: $danger-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toast__warning-icon {
|
&__warning-icon {
|
||||||
color: $warning-color;
|
color: $warning-color;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ export function Toast({ visible, message, type, onClose }: ToastProps) {
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div className="toast__content">
|
<div className="toast__content">
|
||||||
<div style={{ display: "flex", gap: `${SPACING_UNIT}px` }}>
|
<div className="toast__icon-container">
|
||||||
{type === "success" && (
|
{type === "success" && (
|
||||||
<CheckCircleFillIcon className="toast__success-icon" />
|
<CheckCircleFillIcon className="toast__success-icon" />
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -36,7 +36,7 @@ export function AchievementPanel({ achievements }: AchievementPanelProps) {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => showHydraCloudModal("achievements-points")}
|
onClick={() => showHydraCloudModal("achievements-points")}
|
||||||
className={styles.link}
|
className="achievement-panel__link"
|
||||||
>
|
>
|
||||||
<small style={{ color: "#ffc107" }}>
|
<small style={{ color: "#ffc107" }}>
|
||||||
{t("how_to_earn_achievements_points")}
|
{t("how_to_earn_achievements_points")}
|
||||||
|
|
|
@ -142,20 +142,20 @@ export function AchievementsContent({
|
||||||
|
|
||||||
setGameColor(backgroundColor);
|
setGameColor(backgroundColor);
|
||||||
};
|
};
|
||||||
const HERO_HEIGHT = 150;
|
const HERO_HEIGHT = 150;
|
||||||
|
|
||||||
const onScroll: React.UIEventHandler<HTMLElement> = (event) => {
|
const onScroll: React.UIEventHandler<HTMLElement> = (event) => {
|
||||||
const heroHeight = heroRef.current?.clientHeight ?? HERO_HEIGHT;
|
const heroHeight = heroRef.current?.clientHeight ?? HERO_HEIGHT;
|
||||||
|
|
||||||
const scrollY = (event.target as HTMLDivElement).scrollTop;
|
const scrollY = (event.target as HTMLDivElement).scrollTop;
|
||||||
if (scrollY >= heroHeight && !isHeaderStuck) {
|
if (scrollY >= heroHeight && !isHeaderStuck) {
|
||||||
setIsHeaderStuck(true);
|
setIsHeaderStuck(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scrollY <= heroHeight && isHeaderStuck) {
|
if (scrollY <= heroHeight && isHeaderStuck) {
|
||||||
setIsHeaderStuck(false);
|
setIsHeaderStuck(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getProfileImage = (
|
const getProfileImage = (
|
||||||
user: Pick<UserInfo, "profileImageUrl" | "displayName">
|
user: Pick<UserInfo, "profileImageUrl" | "displayName">
|
||||||
|
@ -269,4 +269,4 @@ const onScroll: React.UIEventHandler<HTMLElement> = (event) => {
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import * as styles from "./achievement-panel.css";
|
|
||||||
|
|
||||||
import HydraIcon from "@renderer/assets/icons/hydra.svg?react";
|
import HydraIcon from "@renderer/assets/icons/hydra.svg?react";
|
||||||
import { ComparedAchievements } from "@types";
|
import { ComparedAchievements } from "@types";
|
||||||
import { SPACING_UNIT } from "@renderer/theme.css";
|
|
||||||
import { useUserDetails } from "@renderer/hooks";
|
import { useUserDetails } from "@renderer/hooks";
|
||||||
|
|
||||||
|
import "./achievement-panel.scss";
|
||||||
|
import "../../scss/_variables.scss";
|
||||||
|
|
||||||
export interface ComparedAchievementPanelProps {
|
export interface ComparedAchievementPanelProps {
|
||||||
achievements: ComparedAchievements;
|
achievements: ComparedAchievements;
|
||||||
}
|
}
|
||||||
|
@ -18,27 +19,27 @@ export function ComparedAchievementPanel({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={styles.panel}
|
className={classNames("achievement-panel", {
|
||||||
style={{
|
"achievement-panel--subscribed": hasActiveSubscription,
|
||||||
display: "grid",
|
})}
|
||||||
gridTemplateColumns: hasActiveSubscription ? "3fr 1fr 1fr" : "3fr 2fr",
|
|
||||||
gap: `${SPACING_UNIT * 2}px`,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div style={{ display: "flex", gap: `${SPACING_UNIT}px` }}>
|
<div className="achievement-panel__points">
|
||||||
{t("available_points")} <HydraIcon width={20} height={20} />{" "}
|
{t("available_points")}
|
||||||
|
<HydraIcon width={20} height={20} />
|
||||||
{achievements.achievementsPointsTotal}
|
{achievements.achievementsPointsTotal}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{hasActiveSubscription && (
|
{hasActiveSubscription && (
|
||||||
<div className={styles.content}>
|
<div className="achievement-panel__content">
|
||||||
<HydraIcon width={20} height={20} />
|
<HydraIcon width={20} height={20} />
|
||||||
{achievements.owner.achievementsPointsEarnedSum ?? 0}
|
{achievements.owner.achievementsPointsEarnedSum ?? 0}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className={styles.content}>
|
|
||||||
|
<div className="achievement-panel__content">
|
||||||
<HydraIcon width={20} height={20} />
|
<HydraIcon width={20} height={20} />
|
||||||
{achievements.target.achievementsPointsEarnedSum}
|
{achievements.target.achievementsPointsEarnedSum}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__header {
|
&__header {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: calc(var(--spacing-unit) * 2);
|
gap: calc(var(--spacing-unit) * 2);
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
|
@ -21,6 +21,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__downloads-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: $spacing-unit * 2;
|
||||||
|
}
|
||||||
|
|
||||||
&__downloads {
|
&__downloads {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
gap: #{$spacing-unit * 2};
|
gap: #{$spacing-unit * 2};
|
||||||
|
|
|
@ -13,9 +13,9 @@ import { DOWNLOADER_NAME } from "@renderer/constants";
|
||||||
import { useAppSelector, useDownload } from "@renderer/hooks";
|
import { useAppSelector, useDownload } from "@renderer/hooks";
|
||||||
|
|
||||||
import "./download-group.scss";
|
import "./download-group.scss";
|
||||||
|
import "../../scss/_variables.scss";
|
||||||
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { SPACING_UNIT, vars } from "@renderer/theme.css";
|
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
|
@ -240,20 +240,14 @@ export function DownloadGroup({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="download-group">
|
<div className="download-group">
|
||||||
<div
|
<div className="download-group__downloads-group"
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
gap: `${SPACING_UNIT * 2}px`,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<h2>{title}</h2>
|
<h2>{title}</h2>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
flex: 1,
|
flex: 1,
|
||||||
backgroundColor: vars.color.border,
|
backgroundColor: "var(--border-color)",
|
||||||
height: "1px",
|
height: "1px",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -272,7 +266,7 @@ export function DownloadGroup({
|
||||||
<div className="download-group__cover-backdrop">
|
<div className="download-group__cover-backdrop">
|
||||||
<img
|
<img
|
||||||
src={steamUrlBuilder.library(game.objectID)}
|
src={steamUrlBuilder.library(game.objectID)}
|
||||||
className={styles.downloadCoverImage}
|
className="download-group__cover-image"
|
||||||
alt={game.title}
|
alt={game.title}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ export function DescriptionHeader() {
|
||||||
if (!shopDetails) return null;
|
if (!shopDetails) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.descriptionHeader}>
|
<div className="description-header">
|
||||||
<section className={styles.descriptionHeaderInfo}>
|
<section className="description-header__info">
|
||||||
<p>
|
<p>
|
||||||
{t("release_date", {
|
{t("release_date", {
|
||||||
date: shopDetails?.release_date.date,
|
date: shopDetails?.release_date.date,
|
||||||
|
|
|
@ -25,13 +25,8 @@ export function GameDetailsContent() {
|
||||||
|
|
||||||
const { t } = useTranslation("game_details");
|
const { t } = useTranslation("game_details");
|
||||||
|
|
||||||
const {
|
const { objectId, shopDetails, game, gameColor, setGameColor } =
|
||||||
objectId,
|
useContext(gameDetailsContext);
|
||||||
shopDetails,
|
|
||||||
game,
|
|
||||||
gameColor,
|
|
||||||
setGameColor,
|
|
||||||
} = useContext(gameDetailsContext);
|
|
||||||
|
|
||||||
const { showHydraCloudModal } = useSubscription();
|
const { showHydraCloudModal } = useSubscription();
|
||||||
|
|
||||||
|
@ -77,27 +72,27 @@ export function GameDetailsContent() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setBackdropOpacity(1);
|
setBackdropOpacity(1);
|
||||||
}, [objectId]);
|
}, [objectId]);
|
||||||
const HERO_HEIGHT = 150;
|
const HERO_HEIGHT = 150;
|
||||||
|
|
||||||
const onScroll: React.UIEventHandler<HTMLElement> = (event) => {
|
const onScroll: React.UIEventHandler<HTMLElement> = (event) => {
|
||||||
const heroHeight = heroRef.current?.clientHeight ?? HERO_HEIGHT;
|
const heroHeight = heroRef.current?.clientHeight ?? HERO_HEIGHT;
|
||||||
|
|
||||||
const scrollY = (event.target as HTMLDivElement).scrollTop;
|
const scrollY = (event.target as HTMLDivElement).scrollTop;
|
||||||
const opacity = Math.max(
|
const opacity = Math.max(
|
||||||
0,
|
0,
|
||||||
1 - scrollY / (heroHeight - HERO_ANIMATION_THRESHOLD)
|
1 - scrollY / (heroHeight - HERO_ANIMATION_THRESHOLD)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (scrollY >= heroHeight && !isHeaderStuck) {
|
if (scrollY >= heroHeight && !isHeaderStuck) {
|
||||||
setIsHeaderStuck(true);
|
setIsHeaderStuck(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scrollY <= heroHeight && isHeaderStuck) {
|
if (scrollY <= heroHeight && isHeaderStuck) {
|
||||||
setIsHeaderStuck(false);
|
setIsHeaderStuck(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
setBackdropOpacity(opacity);
|
setBackdropOpacity(opacity);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCloudSaveButtonClick = () => {
|
const handleCloudSaveButtonClick = () => {
|
||||||
if (!userDetails) {
|
if (!userDetails) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue