Skip to content

Commit

Permalink
feat: 🎸 Stargazers remotion dev comleted (#461)
Browse files Browse the repository at this point in the history
* feat: 🎸 Remotion environment setup

✅ Closes: #439

* feat: 🎸 Remotion video studio setup completed

✅ Closes: #441

* perf: ⚡️ Components to fetch Repo data using REST & GRAPH apis

✅ Closes: #452

* feat: 🎸 Stargazers remotion dev comleted

✅ Closes: #453
  • Loading branch information
yashksaini-coder authored Nov 10, 2024
1 parent c7df98b commit 0338cdb
Show file tree
Hide file tree
Showing 5 changed files with 683 additions and 0 deletions.
162 changes: 162 additions & 0 deletions stargazers/src/Content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import { Img, useVideoConfig } from "remotion";
import { Stargazer } from "./cache";
import { RepoHeader } from "./repo-header";

const W = 1280 / 2.5;
const H = 720 / 2.5;

export function Content({
stargazers,
repoOrg,
repoName,
progress,
}: {
stargazers: Stargazer[];
repoOrg: string;
repoName: string;
progress: number;
}) {
const gap = 102;
const startY = 76 - gap;
const dy = progress * gap;
const { width } = useVideoConfig();

return (
<div
style={{
flex: 1,
backgroundColor: "#f6f8fa",
position: "relative",
maxWidth: W,
maxHeight: H,
minHeight: H,
transformOrigin: "top left",
transform: `scale(${width / W})`,
}}
>
{stargazers.map((stargazer, index) => {
const isHidden = Math.abs(index - progress) > 3;
const grow = 0;
const opacity = Math.min(0.1 + progress - index, 1);
return isHidden ? null : (
<StarBox
key={stargazer.login}
avatarUrl={stargazer.avatarUrl}
name={stargazer.name}
date={stargazer.date}
repoName={repoName}
y={startY - gap * index + dy}
grow={grow}
opacity={opacity}
starNumber={index + 1}
/>
);
})}

<RepoHeader stars={Math.round(progress)} org={repoOrg} name={repoName} />
</div>
);
}

function StarBox({
avatarUrl,
name,
date,
repoName,
y,
starNumber,
grow,
opacity,
}: {
avatarUrl: string;
name: string;
date: string;
repoName: string;
y: number;
starNumber: number;
grow: number;
opacity: number;
}) {
const d = new Date(date);
const dateString = d.toLocaleDateString("en-US", {
month: "short",
day: "2-digit",
year: "numeric",
});

return (
<div
style={{
background: "white",
border: "1px solid #e1e4e8",
borderRadius: 6,
padding: 12,
display: "flex",
position: "absolute",
opacity,
top: 0,
right: 24,
left: 24,
height: 88,
minHeight: 88,
maxHeight: 88,
transform: `translateY(${y}px) scale(${1 + grow * 0.07})`,
}}
>
<Img
width="64"
height="64"
src={avatarUrl}
style={{ borderRadius: "50%" }}
/>
<div
style={{
display: "flex",
flexDirection: "column",
marginLeft: "12px",
flex: 1,
maxWidth: 560,
minWidth: 0,
}}
>
<h3
style={{
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
maxWidth: 360,
fontWeight: 400,
}}
>
{name}
</h3>
<div
style={{
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
}}
>
starred <b>{repoName}</b>{" "}
<span style={{ color: "#586069" }}>on {dateString}</span>
</div>
</div>
<div
style={{
width: 64,
height: 64,
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
}}
>
<span style={{ fontSize: "0.8em", color: "#586069" }}>Star</span>
<div style={{ fontSize: "1.2em" }}>
<span style={{ fontSize: "1em", color: "#586069" }}>#</span>
{starNumber}
</div>
</div>
</div>
);
}
51 changes: 51 additions & 0 deletions stargazers/src/Root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { useCallback } from "react";
import { CalculateMetadataFunction, Composition } from "remotion";
import { Main, MainProps, mainSchema } from "./Main";
import { fetchStargazers } from "./fetch/fetch-data";
import { waitForNoInput } from "./wait-for-no-input";

const FPS = 30;

export const RemotionRoot = () => {
const calculateMetadata: CalculateMetadataFunction<MainProps> = useCallback(
async ({ props, abortSignal }) => {
await waitForNoInput(abortSignal, 500);

const stargazers = await fetchStargazers({
repoOrg: props.repoOrg,
repoName: props.repoName,
starCount: props.starCount,
abortSignal,
});

return {
props: {
...props,
stargazers,
},
durationInFrames: props.duration * FPS,
};
},
[],
);

return (
<Composition
id="main"
component={Main}
durationInFrames={15 * FPS}
fps={FPS}
width={960}
height={540}
schema={mainSchema}
calculateMetadata={calculateMetadata}
defaultProps={{
repoOrg: "code-hike",
repoName: "codehike",
starCount: 100,
duration: 15,
stargazers: null,
}}
/>
);
};
68 changes: 68 additions & 0 deletions stargazers/src/cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
export type QueryResult = {
cursor: string;
results: Stargazer[];
};

export type Stargazer = {
avatarUrl: string;
name: string;
date: string;
login: string;
};

const makeKey = ({
count,
cursor,
repoName,
repoOrg,
}: {
repoOrg: string;
repoName: string;
count: number;
cursor: string | null;
}) => {
return ["__stargazer", repoOrg, repoName, count, cursor].join("-");
};

export const saveResult = ({
count,
cursor,
repoName,
repoOrg,
result,
}: {
repoOrg: string;
repoName: string;
count: number;
cursor: string | null;
result: QueryResult;
}) => {
try {
const key = makeKey({ count, cursor, repoName, repoOrg });
window.localStorage.setItem(key, JSON.stringify(result));
} catch (err) {
// If quota is exceeded, don't cache
if (!(err as Error).message.toLowerCase().includes("quota")) {
throw err;
}
}
};

export const getFromCache = ({
count,
cursor,
repoName,
repoOrg,
}: {
repoOrg: string;
repoName: string;
count: number;
cursor: string | null;
}): QueryResult | null => {
const key = makeKey({ count, cursor, repoName, repoOrg });
const value = window.localStorage.getItem(key);
if (!value) {
return null;
}
return JSON.parse(value);
};
Loading

0 comments on commit 0338cdb

Please sign in to comment.