feat: Added games
All checks were successful
Build Gameflow Site / build (push) Successful in 58s

This commit is contained in:
Simeon Radivoev 2026-05-15 23:47:00 +03:00
parent 87f8f485aa
commit d3779fb46e
Signed by: simeonradivoev
GPG key ID: 7611A451D2A5D37A
5 changed files with 106 additions and 6 deletions

View file

@ -46,7 +46,9 @@
"bun",
"es-de",
"store",
"free"
"free",
"internet-archive",
"retro-achievements"
],
"devDependencies": {
"@types/bun": "latest"

View file

@ -10,6 +10,8 @@ import {
RefreshCcw,
Joystick,
Puzzle,
Grid2x2,
LayoutGrid,
} from "@lucide/astro";
import Feature from "./Feature.astro";
---
@ -79,8 +81,14 @@ import Feature from "./Feature.astro";
</Feature>
<Feature
title="Plugins System"
description="Extent functionality with plugins. Hosted on the NPM registry."
description="Extent functionality with plugins. Hosted on the NPM registry. From download sources to more emulator integrations. Everyone can easily create plugins and publish them on NPM"
>
<Puzzle size={64} slot="icon" />
</Feature>
<Feature
title="All Your Games"
description="Download thousands of games and roms from the internet archive by installing the internet archive plugin."
>
<LayoutGrid size={64} slot="icon" />
</Feature>
</div>

View file

@ -1,9 +1,9 @@
---
import { Github, Discord } from "simple-icons-astro";
import { HandCoins, Puzzle } from "@lucide/astro";
import { Gamepad2, HandCoins, Puzzle } from "@lucide/astro";
import Icon from "../assets/icon.svg";
import pkg from "../../package.json";
import { plugins, releaseData } from "../scripts/getters";
import { games, plugins, releaseData } from "../scripts/getters";
import Image from "astro/components/Image.astro";
---
@ -26,12 +26,24 @@ import Image from "astro/components/Image.astro";
`${import.meta.env.BASE_URL}/plugins`,
)}
class="flex group gap-2 bg-base-300 data-[active=true]:cursor-default rounded-full p-1 px-3 text-xl hover:bg-accent hover:text-accent-content data-[active=true]:bg-accent data-[active=true]:text-accent-content items-center"
href={`${import.meta.env.BASE_URL}plugins`}
href={`${import.meta.env.BASE_URL}/plugins`}
><Puzzle />Plugins<span
class="bg-base-100 px-2 text-sm font-semibold rounded-full group-hover:bg-accent-content group-hover:text-accent in-data-[active=true]:bg-accent-content in-data-[active=true]:text-accent-content"
class="bg-base-100 px-2 text-sm font-semibold rounded-full group-hover:bg-accent-content group-hover:text-accent in-data-[active=true]:bg-accent-content in-data-[active=true]:text-accent"
>{plugins.total}</span
>
</a>
<a
title="View a list of free games you can download for gameflow"
data-active={Astro.url.pathname.startsWith(
`${import.meta.env.BASE_URL}/games`,
)}
class="flex group gap-2 bg-base-300 data-[active=true]:cursor-default rounded-full p-1 px-3 text-xl hover:bg-accent hover:text-accent-content data-[active=true]:bg-accent data-[active=true]:text-accent-content items-center"
href={`${import.meta.env.BASE_URL}/games`}
><Gamepad2 />Games<span
class="bg-base-100 px-2 text-sm font-semibold rounded-full group-hover:bg-accent-content group-hover:text-accent in-data-[active=true]:bg-accent-content in-data-[active=true]:text-accent"
>{games.length}</span
>
</a>
<div class="divider divider-horizontal"></div>
<a
title="Support Gameflow development"

69
src/pages/games.astro Normal file
View file

@ -0,0 +1,69 @@
---
import { Dot, Download, Gamepad2, Puzzle, ScrollText } from "@lucide/astro";
import Header from "../components/Header.astro";
import Welcome from "../components/Welcome.astro";
import Layout from "../layouts/Layout.astro";
import { createHash } from "crypto"; // Node.js built-in
import { games } from "../scripts/getters";
import { Git, Npm } from "simple-icons-astro";
import Dock from "../components/Dock.astro";
import Icon from "../assets/icon.svg";
---
<Layout title="Gameflow Deck - Games">
<Header />
<div class="divider">
<Gamepad2 size={48} />Games <span
class="bg-base-300 font-semibold px-2 rounded-2xl">{games.length}</span
>
</div>
<div class="p-8 pb-16">
<div
class="grid h-fit gap-2 md:gap-4 justify-center auto-rows-min grid-cols-[repeat(auto-fill,16rem)]"
>
{
games
.concat({
name: (
<div class="flex gap-2 ">
<ScrollText />
{"Contribute to the Store"}
</div>
),
homepage: "https://github.com/simeonradivoev/gameflow-store/issues",
covers: [Icon.src],
})
.map((g: any) => {
return (
<a
class="bg-base-300 p-2 rounded-2xl cursor-pointer hover:ring-4 ring-primary transition-all"
title={g.name}
href={g.homepage}
target="_blank"
>
<div
id="preview"
class="overflow-hidden bg-base-400 rounded-t-xl rounded-b-md transition-all"
>
<img
alt={`Cover Image of ${g.name}`}
src={
g.covers.find((c: string) => c.startsWith("http")) ??
g.covers[0]
}
class="object-cover aspect-3/4 w-full h-full"
/>
</div>
<div class="flex flex-col grow p-3 justify-center">
<div class="font-bold text-nowrap text-ellipsis overflow-hidden">
{g.name}
</div>
</div>
</a>
);
})
}
</div>
</div>
<Dock />
</Layout>

View file

@ -109,6 +109,15 @@ async function getTotalDownloads (owner: string, repo: string): Promise<number>
return totalDownloads;
}
export const games = await fetch('https://cdn.jsdelivr.net/npm/@simeonradivoev/gameflow-store@latest/manifests/games.json')
.then(res => res.json())
.then(v => v.emulators)
.catch((e) =>
{
console.error(e);
return [] as any[];
});
export const totalDownloads = await getTotalDownloads(
"simeonradivoev",
"gameflow-deck",