Skip to content

Commit

Permalink
simplify themecard props
Browse files Browse the repository at this point in the history
  • Loading branch information
beebls committed Dec 27, 2024
1 parent ad201bb commit 861f81a
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 69 deletions.
89 changes: 89 additions & 0 deletions src/lib/components/theme-card/ThemeCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { PartialCSSThemeInfo } from "@/types";
import { ColumnNumbers, useThemeBrowserSharedValue, useThemeBrowserStoreValue } from "../context";
import { forwardRef } from "react";
import { shortenNumber, useThemeInstallState } from "@/lib";
import { useCSSLoaderValue } from "@/backend";
import { AiOutlineDownload } from "react-icons/ai";
import { Focusable } from "@decky/ui";
import { FaBullseye, FaDownload, FaStar } from "react-icons/fa6";
import { useExpandedViewAction } from "@/modules/expanded-view";

interface ThemeCardProps {
theme: PartialCSSThemeInfo;
size?: ColumnNumbers;
onClick?: () => void;
}

const cardWidth = {
5: 152,
4: 195,
3: 260,
};

export const ThemeCard = forwardRef<HTMLDivElement, ThemeCardProps>(
({ theme, size, onClick }, ref) => {
const apiUrl = useCSSLoaderValue("apiUrl");
const browserCardSize = useThemeBrowserSharedValue("browserCardSize");
const cols = size ?? browserCardSize;
const installStatus = useThemeInstallState(theme);

const openTheme = useExpandedViewAction("openTheme");

const imageUrl =
theme?.images[0]?.id && theme.images[0].id !== "MISSING"
? `${apiUrl}/blobs/${theme.images[0].id}`
: `https://share.deckthemes.com/cssplaceholder.png`;

return (
<div className="relative">
{installStatus === "outdated" && (
<div className="cl_storeitem_notifbubble">
<AiOutlineDownload className="cl_storeitem_bubbleicon" />
</div>
)}
<Focusable
ref={ref}
className="cl_storeitem_container"
focusWithinClassName="gpfocuswithin"
onActivate={() => {
onClick?.();
openTheme(theme.id);
}}
>
<div className="cl_storeitem_imagecontainer">
<img
className="cl_storeitem_image"
src={imageUrl}
width={cardWidth[cols]}
height={(cardWidth[cols] / 16) * 10}
/>
<div className="cl_storeitem_imagedarkener" />
<div className="cl_storeitem_supinfocontainer">
<div className="cl_storeitem_iconinfoitem">
<FaDownload />
<span>
{shortenNumber(theme.download.downloadCount) ?? theme.download.downloadCount}
</span>
</div>
<div className="cl_storeitem_iconinfoitem">
<FaStar />
<span>{shortenNumber(theme.starCount) ?? theme.starCount}</span>
</div>
<div className="cl_storeitem_iconinfoitem">
<FaBullseye />
<span>{theme.target}</span>
</div>
</div>
</div>
<div className="cl_storeitem_maininfocontainer">
<span className="cl_storeitem_title">{theme.displayName}</span>
<span className="cl_storeitem_subtitle">
{theme.version} - Last Updated {new Date(theme.updated).toLocaleDateString()}
</span>
<span className="cl_storeitem_subtitle">By {theme.specifiedAuthor}</span>
</div>
</Focusable>
</div>
);
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { themeCardStylesGenerator } from "@/styles";
import { ColumnNumbers, useThemeBrowserSharedValue } from "../context";

export function ThemeCardCSSVariableProvider({ cardSize }: { cardSize?: ColumnNumbers }) {
const browserCardSize = useThemeBrowserSharedValue("browserCardSize");

return <style>{themeCardStylesGenerator(cardSize || browserCardSize)}</style>;
}
123 changes: 54 additions & 69 deletions src/modules/theme-store/components/ThemeCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PartialCSSThemeInfo } from "@/types";
import { ColumnNumbers, useThemeBrowserSharedValue, useThemeBrowserStoreValue } from "../context";
import { ColumnNumbers } from "../context";
import { forwardRef } from "react";
import { shortenNumber, useThemeInstallState } from "@/lib";
import { useCSSLoaderValue } from "@/backend";
Expand All @@ -14,76 +14,61 @@ interface ThemeCardProps {
onClick?: () => void;
}

const cardWidth = {
5: 152,
4: 195,
3: 260,
};
export const ThemeCard = forwardRef<HTMLDivElement, ThemeCardProps>(({ theme, onClick }, ref) => {
const apiUrl = useCSSLoaderValue("apiUrl");
const installStatus = useThemeInstallState(theme);

export const ThemeCard = forwardRef<HTMLDivElement, ThemeCardProps>(
({ theme, size, onClick }, ref) => {
const apiUrl = useCSSLoaderValue("apiUrl");
const browserCardSize = useThemeBrowserSharedValue("browserCardSize");
const cols = size ?? browserCardSize;
const installStatus = useThemeInstallState(theme);
const openTheme = useExpandedViewAction("openTheme");

const openTheme = useExpandedViewAction("openTheme");
const imageUrl =
theme?.images[0]?.id && theme.images[0].id !== "MISSING"
? `${apiUrl}/blobs/${theme.images[0].id}`
: `https://share.deckthemes.com/cssplaceholder.png`;

const imageUrl =
theme?.images[0]?.id && theme.images[0].id !== "MISSING"
? `${apiUrl}/blobs/${theme.images[0].id}`
: `https://share.deckthemes.com/cssplaceholder.png`;

return (
<div className="relative">
{installStatus === "outdated" && (
<div className="cl_storeitem_notifbubble">
<AiOutlineDownload className="cl_storeitem_bubbleicon" />
</div>
)}
<Focusable
ref={ref}
className="cl_storeitem_container"
focusWithinClassName="gpfocuswithin"
onActivate={() => {
onClick?.();
openTheme(theme.id);
}}
>
<div className="cl_storeitem_imagecontainer">
<img
className="cl_storeitem_image"
src={imageUrl}
width={cardWidth[cols]}
height={(cardWidth[cols] / 16) * 10}
/>
<div className="cl_storeitem_imagedarkener" />
<div className="cl_storeitem_supinfocontainer">
<div className="cl_storeitem_iconinfoitem">
<FaDownload />
<span>
{shortenNumber(theme.download.downloadCount) ?? theme.download.downloadCount}
</span>
</div>
<div className="cl_storeitem_iconinfoitem">
<FaStar />
<span>{shortenNumber(theme.starCount) ?? theme.starCount}</span>
</div>
<div className="cl_storeitem_iconinfoitem">
<FaBullseye />
<span>{theme.target}</span>
</div>
return (
<div className="relative">
{installStatus === "outdated" && (
<div className="cl_storeitem_notifbubble">
<AiOutlineDownload className="cl_storeitem_bubbleicon" />
</div>
)}
<Focusable
ref={ref}
className="cl_storeitem_container"
focusWithinClassName="gpfocuswithin"
onActivate={() => {
onClick?.();
openTheme(theme.id);
}}
>
<div className="cl_storeitem_imagecontainer">
<img className="cl_storeitem_image" src={imageUrl} />
<div className="cl_storeitem_imagedarkener" />
<div className="cl_storeitem_supinfocontainer">
<div className="cl_storeitem_iconinfoitem">
<FaDownload />
<span>
{shortenNumber(theme.download.downloadCount) ?? theme.download.downloadCount}
</span>
</div>
<div className="cl_storeitem_iconinfoitem">
<FaStar />
<span>{shortenNumber(theme.starCount) ?? theme.starCount}</span>
</div>
<div className="cl_storeitem_iconinfoitem">
<FaBullseye />
<span>{theme.target}</span>
</div>
</div>
<div className="cl_storeitem_maininfocontainer">
<span className="cl_storeitem_title">{theme.displayName}</span>
<span className="cl_storeitem_subtitle">
{theme.version} - Last Updated {new Date(theme.updated).toLocaleDateString()}
</span>
<span className="cl_storeitem_subtitle">By {theme.specifiedAuthor}</span>
</div>
</Focusable>
</div>
);
}
);
</div>
<div className="cl_storeitem_maininfocontainer">
<span className="cl_storeitem_title">{theme.displayName}</span>
<span className="cl_storeitem_subtitle">
{theme.version} - Last Updated {new Date(theme.updated).toLocaleDateString()}
</span>
<span className="cl_storeitem_subtitle">By {theme.specifiedAuthor}</span>
</div>
</Focusable>
</div>
);
});
2 changes: 2 additions & 0 deletions src/styles/styles-as-string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,8 @@ MARK: Store
font-size: var(--cl-storeitem-fontsize) !important;
}
.cl_storeitem_image {
width: 100%;
height: 100%;
object-fit: cover !important;
transition-property: filter,transform !important;
transition-duration: 0.32s !important;
Expand Down
2 changes: 2 additions & 0 deletions src/styles/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,8 @@ MARK: Store
font-size: var(--cl-storeitem-fontsize) !important;
}
.cl_storeitem_image {
width: 100%;
height: 100%;
object-fit: cover !important;
transition-property: filter,transform !important;
transition-duration: 0.32s !important;
Expand Down

0 comments on commit 861f81a

Please sign in to comment.