Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions client/src/components/ui/GameEmbed.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// notes:
// - width and height don't match itch.io, making games look smaller
// - you can just embed from itch.io, but only the developer can get the embed link as far as i can tell
// - would need to save embed link, width and height to db
// - this method is reliant on itch.io staying up and not changing anything
// - would want a play button so it doesn't autoload (especially for bigger more intense games)
import Image from "next/image";
import React, { useState } from "react";

import { Button } from "./button";

type GameEmbedProps = {
embedID: string;
gameWidth: number;
gameHeight: number;
gameImage: string;
};

export function GameEmbed({
embedID,
gameWidth,
gameHeight,
gameImage,
}: GameEmbedProps) {
const [isPlaying, setIsPlaying] = useState(false);

return (
<div
className={`retroBorder flex items-center justify-center bg-background`}
style={{ width: gameWidth + 26 * 2, height: gameHeight + 26 * 2 }}
>
{!isPlaying ? (
<div>
<Image
src={gameImage}
alt="Game Cover"
width={gameWidth}
height={gameHeight}
className="absolute left-[50%] top-[50%] translate-x-[-50%] translate-y-[calc(-50%-26px)] blur-sm"
style={{ width: "auto", height: gameHeight - 26 }}
/>
<Button
onClick={() => setIsPlaying(!isPlaying)}
size={"lg"}
className="absolute left-[50%] top-[50%] translate-x-[-50%] translate-y-[calc(-50%-52px)] text-3xl"
>
Play
</Button>
</div>
) : (
<div>
<iframe
src={`https://itch.io/embed-upload/${embedID}?color=110e1a`}
width={gameWidth}
height={gameHeight}
></iframe>
</div>
)}
</div>
);
}
3 changes: 3 additions & 0 deletions client/src/hooks/useGames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ type ApiGame = {
itchEmbedID: string;
thumbnail: string | null;
event: number | null;
itchGameEmbedID: string;
itchGameWidth: number;
itchGameHeight: number;
contributors: Contributor[];
};

Expand Down
2 changes: 0 additions & 2 deletions client/src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import type { AppProps } from "next/app";
import { Fira_Code, Inter as FontSans, Jersey_10 } from "next/font/google";

import Footer from "@/components/main/Footer";
import Navbar from "@/components/main/Navbar";

const fontSans = FontSans({
Expand Down Expand Up @@ -37,7 +36,6 @@ export default function App({ Component, pageProps }: AppProps) {
>
<Navbar />
<Component {...pageProps} />
<Footer />
</main>
</QueryClientProvider>
);
Expand Down
38 changes: 26 additions & 12 deletions client/src/pages/games/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useRouter } from "next/router";
import React from "react";
import { SocialIcon } from "react-social-icons";

import { GameEmbed } from "@/components/ui/GameEmbed";
import { ItchEmbed } from "@/components/ui/ItchEmbed";
import { useGame } from "@/hooks/useGames";

Expand Down Expand Up @@ -51,6 +52,9 @@ export default function IndividualGamePage() {
const gameTitle = game.name;
const gameCover = game.gameCover;
const gameDescription = game.description.split("\n");
const gameEmbedID = game.itchGameEmbedID;
const gameWidth = game.itchGameWidth;
const gameHeight = game.itchGameHeight;

const completionLabels: Record<number, string> = {
1: "WIP",
Expand Down Expand Up @@ -83,16 +87,27 @@ export default function IndividualGamePage() {
return (
<div className="min-h-screen bg-background font-sans text-foreground">
<main>
<section className="w-full bg-popover">
<section className="w-full items-center justify-center bg-popover">
<div className="mx-auto max-w-7xl p-0 sm:p-8">
<Image
src={gameCover}
alt="Game Cover"
width={800}
height={800}
className="max-h-[60vh] w-full object-cover sm:mx-auto sm:h-auto sm:max-h-[60vh] sm:rounded-2xl sm:object-contain"
priority
/>
{gameEmbedID != "0" ? (
<div className="flex justify-center">
<GameEmbed
embedID={gameEmbedID}
gameWidth={gameWidth}
gameHeight={gameHeight}
gameImage={gameCover}
/>
</div>
Comment on lines +92 to +100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that we can supply a game embed but not a gameWidth, height or image? If this is possible, is there a case to catch this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could have a default case, but size of embed is dependent on game and different engines have different defaults.

) : (
<Image
src={gameCover}
alt="Game Cover"
width={800}
height={800}
className="max-h-[60vh] w-full object-cover sm:mx-auto sm:h-auto sm:max-h-[60vh] sm:rounded-2xl sm:object-contain"
priority
/>
)}
</div>
</section>

Expand Down Expand Up @@ -171,9 +186,8 @@ export default function IndividualGamePage() {
</section>

<section className="mt-8 flex w-full flex-col items-center gap-6">
{game.itchEmbedID && (
<ItchEmbed embedID={game.itchEmbedID} name={gameTitle} />
)}
<ItchEmbed embedID={game.itchEmbedID} name={gameTitle} />

<h2 className="font-jersey10 text-5xl text-primary">ARTWORK</h2>

<div className="mx-auto mb-6 flex h-auto w-full max-w-4xl flex-col items-center gap-4 px-4 sm:flex-row sm:justify-center sm:gap-6 sm:px-6 md:h-60">
Expand Down
2 changes: 1 addition & 1 deletion client/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export default function Landing() {
width={600}
height={430}
alt="placeholder"
className="min-w-80 border-[26px] border-accent [clip-path:polygon(20px_20px,calc(100%-20px)_20px,100%_32px,100%_30%,calc(100%-20px)_45%,calc(100%-20px)_calc(100%-8px),80%_calc(100%-8px),75%_calc(100%-20px),20px_calc(100%-20px),0%_60%,0%_30%,20px_25%)]"
className="retroBorder min-w-80"
/>
<Image
src="/bomb.png"
Expand Down
9 changes: 9 additions & 0 deletions client/src/placeholderData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ export const placeholderGames = [
hostURL: "/",
itchEmbedID: "1",
thumbnail: "/landing_placeholder.png",
itchGameEmbedID: 0,
itchGameWidth: 0,
itchGameHeight: 0,
event: 1,
},
{
Expand All @@ -67,6 +70,9 @@ export const placeholderGames = [
hostURL: "/",
itchEmbedID: "1",
thumbnail: "/landing_placeholder.png",
itchGameEmbedID: 0,
itchGameWidth: 0,
itchGameHeight: 0,
event: 1,
},
{
Expand All @@ -78,6 +84,9 @@ export const placeholderGames = [
hostURL: "/",
itchEmbedID: "1",
thumbnail: "/landing_placeholder.png",
itchGameEmbedID: 0,
itchGameWidth: 0,
itchGameHeight: 0,
event: 1,
},
];
4 changes: 4 additions & 0 deletions client/src/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,8 @@
body {
@apply bg-background text-foreground;
}

.retroBorder {
@apply border-[26px] border-accent [clip-path:polygon(20px_20px,calc(100%-20px)_20px,100%_32px,100%_30%,calc(100%-20px)_45%,calc(100%-20px)_calc(100%-8px),80%_calc(100%-8px),75%_calc(100%-20px),20px_calc(100%-20px),0%_60%,0%_30%,20px_25%)];
}
}
3 changes: 2 additions & 1 deletion server/game_dev/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ class GameShowcaseAdmin(admin.ModelAdmin):


class GamesAdmin(admin.ModelAdmin):
list_display = ("id", "name", "description", "completion", "active", "hostURL", "itchEmbedID", "thumbnail", "event")
list_display = ("id", "name", "description", "completion", "active", "hostURL", "itchEmbedID", "thumbnail", "itchGameEmbedID", "itchGameWidth",
"itchGameHeight", "event")
search_fields = ["name", "description"]


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 5.1.15 on 2026-02-04 07:39

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("game_dev", "0009_merge_20260131_1044"),
]

operations = [
migrations.AddField(
model_name="game",
name="itchGameEmbedID",
field=models.PositiveBigIntegerField(
blank=True,
default=0,
help_text="If a game has a web demo stored on itch.io, please enter the embed ID",
null=True,
),
),
migrations.AddField(
model_name="game",
name="itchGameHeight",
field=models.PositiveBigIntegerField(default=0),
),
migrations.AddField(
model_name="game",
name="itchGameWidth",
field=models.PositiveBigIntegerField(default=0),
),
]
13 changes: 13 additions & 0 deletions server/game_dev/migrations/0011_merge_20260205_1434.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Generated by Django 5.1.15 on 2026-02-05 06:34

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("game_dev", "0010_game_itchgameembedid_game_itchgameheight_and_more"),
("game_dev", "0010_merge_20260131_1118"),
]

operations = []
13 changes: 13 additions & 0 deletions server/game_dev/migrations/0012_merge_20260214_1112.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Generated by Django 5.1.15 on 2026-02-14 03:12

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("game_dev", "0011_alter_gameshowcase_game"),
("game_dev", "0011_merge_20260205_1434"),
]

operations = []
23 changes: 23 additions & 0 deletions server/game_dev/migrations/0013_alter_game_itchgameembedid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 5.1.15 on 2026-02-14 03:31

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("game_dev", "0012_merge_20260214_1112"),
]

operations = [
migrations.AlterField(
model_name="game",
name="itchGameEmbedID",
field=models.PositiveBigIntegerField(
blank=True,
default=None,
help_text="If a game has a web demo stored on itch.io, please enter the embed ID",
null=True,
),
),
]
13 changes: 13 additions & 0 deletions server/game_dev/migrations/0014_merge_20260214_1420.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Generated by Django 5.1.15 on 2026-02-14 06:20

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("game_dev", "0013_alter_game_itchgameembedid"),
("game_dev", "0013_merge_20260214_1347"),
]

operations = []
14 changes: 14 additions & 0 deletions server/game_dev/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@ class CompletionStatus(models.IntegerChoices):
thumbnail = models.ImageField(upload_to="games/", null=True)
event = models.ForeignKey(Event, on_delete=models.SET_NULL, null=True, blank=True)

itchGameEmbedID = models.PositiveBigIntegerField(
default=None,
null=True,
blank=True,
help_text="If a game has a web demo stored on itch.io, please enter the embed ID"
)

itchGameWidth = models.PositiveBigIntegerField(
default=0
)
itchGameHeight = models.PositiveBigIntegerField(
default=0
)

def __str__(self):
return str(self.name)

Expand Down
4 changes: 2 additions & 2 deletions server/game_dev/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ class GamesSerializer(serializers.ModelSerializer):

class Meta:
model = Game
fields = ('id', 'name', 'description', 'completion', 'active',
'hostURL', 'itchEmbedID', 'thumbnail', 'event', "contributors")
fields = ('id', 'name', 'description', 'completion', 'active', 'hostURL', 'itchEmbedID', 'thumbnail', 'event', 'itchGameEmbedID',
'itchGameWidth', 'itchGameHeight', "contributors")


# Contributor serializer for name and role
Expand Down