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", "bun",
"es-de", "es-de",
"store", "store",
"free" "free",
"internet-archive",
"retro-achievements"
], ],
"devDependencies": { "devDependencies": {
"@types/bun": "latest" "@types/bun": "latest"

View file

@ -10,6 +10,8 @@ import {
RefreshCcw, RefreshCcw,
Joystick, Joystick,
Puzzle, Puzzle,
Grid2x2,
LayoutGrid,
} from "@lucide/astro"; } from "@lucide/astro";
import Feature from "./Feature.astro"; import Feature from "./Feature.astro";
--- ---
@ -79,8 +81,14 @@ import Feature from "./Feature.astro";
</Feature> </Feature>
<Feature <Feature
title="Plugins System" 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" /> <Puzzle size={64} slot="icon" />
</Feature> </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> </div>

View file

@ -1,9 +1,9 @@
--- ---
import { Github, Discord } from "simple-icons-astro"; 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 Icon from "../assets/icon.svg";
import pkg from "../../package.json"; 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"; import Image from "astro/components/Image.astro";
--- ---
@ -26,12 +26,24 @@ import Image from "astro/components/Image.astro";
`${import.meta.env.BASE_URL}/plugins`, `${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" 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 ><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 >{plugins.total}</span
> >
</a> </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> <div class="divider divider-horizontal"></div>
<a <a
title="Support Gameflow development" 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; 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( export const totalDownloads = await getTotalDownloads(
"simeonradivoev", "simeonradivoev",
"gameflow-deck", "gameflow-deck",