diff --git a/src/app/api/view-run/route.ts b/src/app/api/view-run/route.ts
index 7dc3097..3bc6c7c 100644
--- a/src/app/api/view-run/route.ts
+++ b/src/app/api/view-run/route.ts
@@ -2,6 +2,7 @@ import { WebSocketServer, WebSocket } from "ws";
import Redis from "ioredis";
import { NextRequest, NextResponse } from "next/server";
import { LiveRunEvent } from "@/modules/live-run/types";
+import { getLiveRun, updateLiveRunViews } from "@/modules/live-run/core";
export function GET(req: NextRequest) {
const headers = new Headers();
@@ -16,6 +17,9 @@ export function UPGRADE(client: WebSocket, server: WebSocketServer) {
client.once("message", async (message) => {
runId = message.toString();
+
+ await updateLiveRunViews(runId, 1);
+
let lastEvent: LiveRunEvent | null = null;
const sendText = async () => {
@@ -57,6 +61,7 @@ export function UPGRADE(client: WebSocket, server: WebSocketServer) {
client.once("close", async () => {
if (runId) await subscriber.unsubscribe(`liveRun:${runId}`);
subscriber.quit();
+ await updateLiveRunViews(runId, -1);
});
client.on("error", (err) => {
diff --git a/src/app/runs/[runId]/components/RunTimer.tsx b/src/app/runs/[runId]/components/RunTimer.tsx
index da520b8..dc5f38d 100644
--- a/src/app/runs/[runId]/components/RunTimer.tsx
+++ b/src/app/runs/[runId]/components/RunTimer.tsx
@@ -4,7 +4,13 @@ import { LiveRun } from "@/modules/live-run/types";
import { Eye } from "lucide-react";
import { useEffect, useState } from "react";
-export default function RunTimer({ run }: { run: LiveRun }) {
+export default function RunTimer({
+ run,
+ views,
+}: {
+ run: LiveRun;
+ views: number | null;
+}) {
const [time, setTime] = useState("00:00:00");
useEffect(() => {
@@ -29,7 +35,7 @@ export default function RunTimer({ run }: { run: LiveRun }) {
- {run.views}
+ {views || run.views}
diff --git a/src/app/runs/[runId]/page.tsx b/src/app/runs/[runId]/page.tsx
index 958c5fd..c47c258 100644
--- a/src/app/runs/[runId]/page.tsx
+++ b/src/app/runs/[runId]/page.tsx
@@ -7,7 +7,7 @@ import { FileTree } from "./components/FileTree";
import { File } from "lucide-react";
import Editor from "./components/Editor";
import useAction, { useActionInterval } from "@/hook/use-action";
-import { getLiveRun } from "@/modules/live-run/actions";
+import { getLiveRun, getLiveRunViews } from "@/modules/live-run/actions";
import ProblemCard from "@/app/problems/components/ProblemCard";
import ProfileCard from "./components/ProfileCard";
import { getProblem } from "@/modules/problems/actions";
@@ -18,6 +18,9 @@ export default function Run() {
const params = useParams<{ runId: string }>();
const [run] = useAction(() => getLiveRun(params.runId), [params]);
+ const [views] = useActionInterval(() => getLiveRunViews(params.runId), 2500, [
+ params,
+ ]);
const [problem] = useAction(
async () => (run?.id ? getProblem(run.problem) : null),
@@ -55,7 +58,7 @@ export default function Run() {
- {run && }
+ {run && }
diff --git a/src/modules/live-run/actions.ts b/src/modules/live-run/actions.ts
index 19d4cc5..b878f8d 100644
--- a/src/modules/live-run/actions.ts
+++ b/src/modules/live-run/actions.ts
@@ -10,3 +10,7 @@ export async function getLiveRuns(): Promise {
export async function getLiveRun(id: string): Promise {
return Core.getLiveRun(id);
}
+
+export async function getLiveRunViews(id: string): Promise {
+ return Core.getLiveRunViews(id);
+}
diff --git a/src/modules/live-run/core.ts b/src/modules/live-run/core.ts
index 55d4a7f..6d90c0a 100644
--- a/src/modules/live-run/core.ts
+++ b/src/modules/live-run/core.ts
@@ -28,6 +28,29 @@ export async function getLiveRun(id: string): Promise {
return JSON.parse(data) as LiveRun;
}
+/**
+ * Get live run views from Redis
+ */
+export async function getLiveRunViews(id: string): Promise {
+ const run = await getLiveRun(id);
+ if (!run) return null;
+ return run.views;
+}
+
+/**
+ * Get live run views from Redis
+ */
+export async function updateLiveRunViews(
+ id: string,
+ increment: number,
+): Promise {
+ const run = await getLiveRun(id);
+ if (!run) return null;
+ run.views += increment;
+ await redis.set(`liveRun:${run.id}`, JSON.stringify(run));
+ return run.views;
+}
+
/**
* Get all live runs
*/