Skip to content

Commit

Permalink
Merge pull request #92 from agrattan0820/dev
Browse files Browse the repository at this point in the history
v0.3.6
  • Loading branch information
agrattan0820 authored Sep 22, 2023
2 parents b329746 + 239e46b commit 1f16edf
Show file tree
Hide file tree
Showing 14 changed files with 188 additions and 257 deletions.
4 changes: 2 additions & 2 deletions apps/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@vercel/analytics": "^1.0.2",
"@vercel/kv": "^0.2.3",
"@xstate/react": "^3.2.2",
"autoprefixer": "10.4.15",
"autoprefixer": "10.4.16",
"clsx": "^2.0.0",
"database": "workspace:*",
"drizzle-orm": "^0.28.6",
Expand All @@ -38,7 +38,7 @@
"xstate": "^4.38.2"
},
"devDependencies": {
"@playwright/test": "^1.38.0",
"@playwright/test": "^1.38.1",
"@tailwindcss/typography": "^0.5.10",
"@types/node": "^20.6.3",
"@types/react": "^18.2.22",
Expand Down
7 changes: 7 additions & 0 deletions apps/client/src/app/api/host/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getServerSession } from "next-auth";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import * as Sentry from "@sentry/nextjs";

import { existingHost } from "@ai/utils/queries";
import { authOptions } from "@ai/pages/api/auth/[...nextauth]";
Expand All @@ -16,6 +17,12 @@ export async function GET(req: Request): Promise<never> {
redirect("/");
}

Sentry.setUser({
id: session.user.id,
email: session.user.email ?? "",
username: session.user.nickname,
});

const searchParams = new URL(req.url).searchParams;

const nickname = searchParams.get("nickname");
Expand Down
7 changes: 7 additions & 0 deletions apps/client/src/app/api/join/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { redirect } from "next/navigation";
import { getServerSession } from "next-auth";
import { cookies } from "next/headers";
import * as Sentry from "@sentry/nextjs";

import { joinRoom } from "@ai/utils/queries";
import { authOptions } from "@ai/pages/api/auth/[...nextauth]";
Expand All @@ -16,6 +17,12 @@ export async function GET(req: Request): Promise<never> {
redirect("/");
}

Sentry.setUser({
id: session.user.id,
email: session.user.email ?? "",
username: session.user.nickname,
});

const searchParams = new URL(req.url).searchParams;

const nickname = searchParams.get("nickname");
Expand Down
20 changes: 18 additions & 2 deletions apps/client/src/app/room/[code]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
import { authOptions } from "@ai/pages/api/auth/[...nextauth]";
import QueryProvider from "@ai/utils/query-provider";
import SocketProvider from "@ai/utils/socket-provider";
import { getServerSession } from "next-auth";
import { redirect } from "next/navigation";
import * as Sentry from "@sentry/nextjs";

export default function RoomLayout({
export default async function RoomLayout({
children,
}: {
children: React.ReactNode;
}) {
const session = await getServerSession(authOptions());

if (!session) {
redirect("/");
}

Sentry.setUser({
id: session.user.id,
email: session.user.email ?? "",
username: session.user.nickname,
});

return (
<QueryProvider>
<SocketProvider>{children}</SocketProvider>
<SocketProvider session={session}>{children}</SocketProvider>
</QueryProvider>
);
}
2 changes: 1 addition & 1 deletion apps/client/src/components/game/prompt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const Prompt = ({

console.timeEnd("Execution Time");

if (images && images.length === 2) {
if (images && Array.isArray(images) && images.length === 2) {
if (userId) {
const generations = await createGenerations({
userId,
Expand Down
2 changes: 2 additions & 0 deletions apps/client/src/components/menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Session } from "next-auth";
import { signOut } from "next-auth/react";
import { useContext, useRef, useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import * as Sentry from "@sentry/nextjs";

import useClickAway from "@ai/utils/hooks/use-click-away";
import { SocketContext } from "@ai/utils/socket-provider";
Expand Down Expand Up @@ -31,6 +32,7 @@ const Menu = ({ session, roomCode }: MenuProps) => {
code: roomCode,
});
}
Sentry.setUser(null);
signOut();
};

Expand Down
21 changes: 21 additions & 0 deletions apps/client/src/components/sentry-provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"use client";

import { useSession } from "next-auth/react";
import { useEffect } from "react";
import * as Sentry from "@sentry/nextjs";

export default function SentryProvider() {
const { data: session } = useSession();

useEffect(() => {
if (session) {
Sentry.setUser({
id: session.user.id,
email: session.user.email ?? "",
username: session.user.nickname,
});
}
}, [session]);

return <></>;
}
23 changes: 15 additions & 8 deletions apps/client/src/components/sign-in-form.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { FormEvent, useState } from "react";
import { FormEvent, useEffect, useState } from "react";
import { Session } from "next-auth";
import { signIn } from "next-auth/react";
import { FaGoogle } from "react-icons/fa";
Expand Down Expand Up @@ -37,26 +37,29 @@ type SignInFormProps =
const SignInForm = ({ session, room, submitLabel, type }: SignInFormProps) => {
const [loading, setLoading] = useState(false);
const router = useRouter();
const [isMounted, setIsMounted] = useState(false);

const onSubmit = async (e: FormEvent<NicknameFormType>) => {
e.preventDefault();
setLoading(true);
try {
const formNickname: string = e.currentTarget.elements.nickname.value;

const callbackUrl =
const callbackUrl = new URL(
type === "HOME"
? `/api/host/?nickname=${formNickname.split(" ").join("+")}`
: `/api/join/?nickname=${formNickname.split(" ").join("+")}&code=${
room.code
}`;
? `/api/host/?nickname=${formNickname}`
: `/api/join/?nickname=${formNickname}&code=${room.code}`,
isMounted
? window.location.origin
: "https://www.artificialunintelligence.gg",
);

if (session) {
router.push(callbackUrl);
router.push(callbackUrl.toString());
return;
}

signIn("google", { callbackUrl });
signIn("google", { callbackUrl: callbackUrl.toString() });
} catch (error) {
setLoading(false);

Expand All @@ -79,6 +82,10 @@ const SignInForm = ({ session, room, submitLabel, type }: SignInFormProps) => {
}
};

useEffect(() => {
setIsMounted(true);
}, []);

return (
<form onSubmit={onSubmit}>
<Input
Expand Down
7 changes: 4 additions & 3 deletions apps/client/src/utils/socket-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ import { createContext, useEffect } from "react";
import toast from "react-hot-toast";

import { socket } from "./socket";
import { useSession } from "next-auth/react";
import { useParams } from "next/navigation";
import { Session } from "next-auth";

export const SocketContext = createContext(socket);

export default function SocketProvider({
children,
session,
}: {
children: React.ReactNode;
session: Session;
}) {
const { data: session } = useSession();
const params = useParams();

const socketMessage = (msg: string) => {
Expand All @@ -33,7 +34,7 @@ export default function SocketProvider({

useEffect(() => {
socket.auth = {
userId: session?.user?.id ?? "",
userId: session.user.id,
roomCode: params?.code ?? "",
gameId: params?.gameId ?? "",
};
Expand Down
10 changes: 6 additions & 4 deletions apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"sentry:sourcemaps": "sentry-cli sourcemaps inject --org alexander-grattan --project artificial-unintelligence-server ./dist && sentry-cli sourcemaps upload --org alexander-grattan --project artificial-unintelligence-server ./dist"
},
"dependencies": {
"@sentry/node": "^7.69.0",
"@sentry/node": "^7.70.0",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"database": "workspace:*",
Expand All @@ -24,16 +24,18 @@
"helmet": "^7.0.0",
"ioredis": "^5.3.2",
"morgan": "^1.10.0",
"socket.io": "^4.7.2"
"replicate": "^0.18.0",
"socket.io": "^4.7.2",
"zod": "^3.22.2"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"@sentry/cli": "^2.20.7",
"@sentry/cli": "^2.21.0",
"@types/cookie-parser": "^1.4.4",
"@types/cors": "^2.8.14",
"@types/express": "^4.17.17",
"@types/morgan": "^1.9.5",
"@types/node": "^20.6.2",
"@types/node": "^20.6.3",
"cross-env": "^7.0.3",
"eslint-config-custom": "workspace:*",
"jest": "^29.7.0",
Expand Down
5 changes: 5 additions & 0 deletions apps/server/src/replicate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Replicate from "replicate";

export const replicate = new Replicate({
auth: process.env.REPLICATE_API_TOKEN ?? "",
});
6 changes: 5 additions & 1 deletion apps/server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,16 @@ export function buildServer() {
return;
}

await redis.set(sessionToken, checkDBForSession.expires.toISOString());
Sentry.setUser({ id: checkDBForSession.userId });

await redis.set(sessionToken, checkDBForSession.userId);

await redis.expireat(
sessionToken,
Math.floor(checkDBForSession.expires.getTime() / 1000)
);
} else {
Sentry.setUser({ id: redisSession });
}

next();
Expand Down
88 changes: 10 additions & 78 deletions apps/server/src/services/generation.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
users,
} from "database";
import { GameRoundGeneration, QuestionGenerations } from "../types";
import { replicate } from "../replicate";
import { z } from "zod";

export async function getGameRoundGenerations({
gameId,
Expand Down Expand Up @@ -231,89 +233,19 @@ export async function setGenerationAsSubmitted({
return updatedGenerations[0];
}

const replicateAPISchema = z.array(z.string()).length(2);

export async function getReplicateAIImages({ prompt }: { prompt: string }) {
const startResponse = await fetch(
"https://api.replicate.com/v1/predictions",
const output = await replicate.run(
"stability-ai/sdxl:8beff3369e81422112d93b89ca01426147de542cd4684c244b673b105188fe5f",
{
method: "POST",
headers: {
Authorization: `Token ${process.env.REPLICATE_API_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
// Pinned to a specific version of Stable Diffusion
// See https://replicate.com/stability-ai/sdxl
version:
"8beff3369e81422112d93b89ca01426147de542cd4684c244b673b105188fe5f",

// This is the text prompt that will be submitted by a form on the frontend
input: { prompt, num_outputs: 2, width: 768, height: 768 },
}),
input: { prompt, num_outputs: 2, width: 768, height: 768 },
}
);

const startResponseJSON: unknown = await startResponse.json();

if (
typeof startResponseJSON !== "object" ||
!startResponseJSON ||
!("urls" in startResponseJSON) ||
typeof startResponseJSON.urls !== "object" ||
!startResponseJSON.urls ||
!("get" in startResponseJSON.urls) ||
typeof startResponseJSON.urls.get !== "string"
) {
throw new Error("Was unable to retrieve Replicate AI endpoint URL");
}

const endpointURL = startResponseJSON.urls.get;

let imageGenerations: string[] | null = null;

while (!imageGenerations) {
const finalResponse = await fetch(endpointURL, {
method: "GET",
headers: {
Authorization: `Token ${process.env.REPLICATE_API_TOKEN}`,
"Content-Type": "application/json",
},
});
const finalResponseJSON: unknown = await finalResponse.json();

if (
typeof finalResponseJSON !== "object" ||
!finalResponseJSON ||
!("status" in finalResponseJSON) ||
!finalResponseJSON.status ||
typeof finalResponseJSON.status !== "string"
) {
throw new Error("Unable to retrieve Replicate AI status");
}

if (
finalResponseJSON.status === "succeeded" &&
"output" in finalResponseJSON &&
typeof finalResponseJSON.output === "object" &&
Array.isArray(finalResponseJSON.output)
) {
imageGenerations = finalResponseJSON.output;
} else if (finalResponseJSON.status === "failed") {
throw new Error(
`Unable to generate image${
"error" in finalResponseJSON &&
typeof finalResponseJSON.error === "string"
? `, message: ${finalResponseJSON.error}`
: ``
}`
);
} else {
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}
console.log("Received images:", output);

if (imageGenerations) {
console.log("Received images:", imageGenerations);
}
const resultingImages = replicateAPISchema.parse(output);

return imageGenerations;
return resultingImages;
}
Loading

1 comment on commit 1f16edf

@vercel
Copy link

@vercel vercel bot commented on 1f16edf Sep 22, 2023

Choose a reason for hiding this comment

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

Please sign in to comment.