Skip to content

Commit

Permalink
api calls moved to backend, added download image button
Browse files Browse the repository at this point in the history
  • Loading branch information
Ajeet1606 committed Jul 28, 2024
1 parent 04a5147 commit a1c76a3
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 59 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
"preview": "vite preview"
},
"dependencies": {
"@google/generative-ai": "^0.16.0",
"@vercel/analytics": "^1.3.1",
"axios": "^1.7.2",
"html-to-image": "^1.11.11",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
Expand Down
17 changes: 8 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import "./App.css";
import Footer from "./components/Footer";
// import Main from "./components/Main";
import Main from "./components/Main";
import Navbar from "./components/Navbar";
import ServerDown from "./components/ServerDown";
// import ServerDown from "./components/ServerDown";

function App() {
return (
<>
<div className="h-[100vh] w-full font-montserrat flex flex-col justify-between">
<Navbar />
{/* <Main /> */}
<ServerDown />
<Main />
{/* <ServerDown /> */}
<Footer />
</div>
</>
Expand Down
124 changes: 79 additions & 45 deletions src/components/Main.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useState } from "react";
import { ProfileSchema, getProfileDetails } from "../utils/utils";
import { GoogleGenerativeAI } from "@google/generative-ai";
import { toPng } from "html-to-image";

const Main = () => {
const [inputUserName, setInputUserName] = useState("");
Expand All @@ -15,52 +14,55 @@ const Main = () => {
return;
}
const trimmedInput = inputUserName.trim();
const userDetails: ProfileSchema = await getProfileDetails(trimmedInput);
const URL = "https://roast-github.up.railway.app/api/v1/roast/" + trimmedInput;

if (!userDetails) {
setErrorMessage(`Github Profile not found.`);
setRoastMessage("");
return;
}

const prompt = `Here's a GitHub profile for you:
- Name: ${userDetails.name}
- Bio: ${userDetails.bio}
- Avatar URL: ${userDetails.avatarUrl}
- Repositories: ${userDetails.repositories.totalCount}
- Followers: ${userDetails.followers.totalCount}
- Following: ${userDetails.following.totalCount}
- Starred Repositories: ${userDetails.starredRepositories.totalCount}
- Total Commits: ${userDetails.contributionsCollection.totalCommitContributions} in this year.
Go ahead and give a satire roast of this GitHub user! Keep it in around 100 words. If they've done really great, appreaciate them as well.`;
return await getRoastResponse(prompt);
}

async function getRoastResponse(prompt: string) {
try {
setRoastMessage("Loading...");
setErrorMessage("");
const GEMINI_API_KEY = import.meta.env.VITE_GEMINI_API_KEY!;
const GEMINI_MODEL = import.meta.env.VITE_GEMINI_MODEL!;
const genAI = new GoogleGenerativeAI(GEMINI_API_KEY);
const model = genAI.getGenerativeModel({
model: GEMINI_MODEL,
systemInstruction: "Act as a satire and sarcastic person.",
});

const result = await model.generateContentStream(prompt);
setRoastMessage("");
for await (const chunk of result.stream) {
const chunkText = chunk.text();
console.log(chunkText);
setRoastMessage((prevData) => prevData + chunkText);
}
const eventSource = new EventSource(URL);
eventSource.onmessage = (event) => {
const newMessage = event.data;
if (newMessage === "[END]") {
eventSource.close();
} else {
setRoastMessage((prevMessages) => prevMessages + newMessage);
}
};
eventSource.onerror = (err) => {
if (err.eventPhase === EventSource.CLOSED) {
fetch(URL)
.then(async (response) => {
// Check if the response status is not OK (i.e., status code is not in the range 200-299)
if (!response.ok) {
// If the response is not OK, read the response body as text
const text = await response.text();
// Throw an error with the response text
console.log("line 42", text);

throw new Error(text);
}
// If the response is OK, read the response body as text and return it
return response.text();
})
.then((message) => {
// Handle the successful response text
console.log("Successful response:", message);
// Optionally update your state with the successful message
setErrorMessage(message);
})
.catch((error) => {
// Handle any errors that were thrown
console.error("Error fetching fallback response:", error);
setErrorMessage(error.message); // Set the error message in the state
});
}
eventSource.close();
console.error("EventSource failed:", err);
};
} catch (error) {
// console.error("Error calling Gemini API:", error);
console.error(error);
setErrorMessage("An error occurred. Please try again later.");
setRoastMessage("");
return error;
}
}

Expand All @@ -69,6 +71,22 @@ const Main = () => {
setInputUserName(e.target.value);
}

async function downloadImage() {
try {
const dataUrl = await toPng(document.body, { quality: 1 });

// Create a link element and trigger a download
const link = document.createElement("a");
link.href = dataUrl;
link.download = `roast-${inputUserName}.png`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} catch (error) {
console.log(error);
}
}

return (
<div className="w-10/12 md:w-1/2 flex flex-col justify-center mx-auto">
<form action="" className="w-full" onSubmit={getRoastMessage}>
Expand All @@ -89,10 +107,26 @@ const Main = () => {
</form>

<div className="w-full mt-4">
<p className="text-center">{roastMessage}</p>
{
errorMessage && <p className="text-center text-red-500">{errorMessage}</p>
}
{roastMessage === "Github Profile not found." ? (
<p className="text-center text-red-500">{roastMessage}</p>
) : (
<p className="text-center">{roastMessage}</p>
)}

{errorMessage && (
<p className="text-center text-red-500">{errorMessage}</p>
)}

{errorMessage === "" && roastMessage != "" && roastMessage != "Github Profile not found." && (
<div className="mt-2 w-full flex justify-center items-center">
<button
className="mt-2 rounded-md p-2 border border-green-400 text-green-400 mx-auto"
onClick={downloadImage}
>
Download Image
</button>
</div>
)}
</div>
</div>
);
Expand Down

0 comments on commit a1c76a3

Please sign in to comment.