Simple live moves
This commit is contained in:
@@ -9,7 +9,7 @@ import { json } from "@codemirror/lang-json";
|
|||||||
import { python } from "@codemirror/lang-python";
|
import { python } from "@codemirror/lang-python";
|
||||||
import { java } from "@codemirror/lang-java";
|
import { java } from "@codemirror/lang-java";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import useAction, { useActionOnce } from "@/hook/use-action";
|
import useAction from "@/hook/use-action";
|
||||||
import { getLiveRunMoves } from "@/modules/live-run/actions";
|
import { getLiveRunMoves } from "@/modules/live-run/actions";
|
||||||
import { LiveRun, LiveRunMove } from "@/modules/live-run/types";
|
import { LiveRun, LiveRunMove } from "@/modules/live-run/types";
|
||||||
|
|
||||||
@@ -43,13 +43,31 @@ function getLanguageExtension(lang: Language) {
|
|||||||
|
|
||||||
export default function Editor({ run }: { run: LiveRun | null | undefined }) {
|
export default function Editor({ run }: { run: LiveRun | null | undefined }) {
|
||||||
const [editorView, setEditorView] = useState<EditorView>();
|
const [editorView, setEditorView] = useState<EditorView>();
|
||||||
const [moves] = useAction<LiveRunMove[]>(
|
const [rawMoves] = useAction<LiveRunMove[]>(
|
||||||
async () => (run ? await getLiveRunMoves(run.id) : []),
|
async () => (run ? await getLiveRunMoves(run.id) : []),
|
||||||
[run],
|
[run],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [lastMoveId, setLastMoveId] = useState<number>(-1);
|
||||||
|
const [moves, setMoves] = useState<LiveRunMove[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(moves);
|
let moves = rawMoves?.filter((move) => move.moveId > lastMoveId) || [];
|
||||||
|
|
||||||
|
if (moves.length === 0) return;
|
||||||
|
|
||||||
|
setMoves(moves);
|
||||||
|
setLastMoveId(lastMoveId + moves.length);
|
||||||
|
|
||||||
|
if (rawMoves?.length || 0 > 0) {
|
||||||
|
console.log("raw", rawMoves);
|
||||||
|
}
|
||||||
|
}, [rawMoves]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (moves.length > 0) {
|
||||||
|
console.log("moves", moves);
|
||||||
|
}
|
||||||
}, [moves]);
|
}, [moves]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -63,7 +81,7 @@ export default function Editor({ run }: { run: LiveRun | null | undefined }) {
|
|||||||
if (!editorView || cancelled) return resolve();
|
if (!editorView || cancelled) return resolve();
|
||||||
|
|
||||||
editorView.dispatch({
|
editorView.dispatch({
|
||||||
selection: { anchor: move.cursor },
|
// selection: { anchor: move.cursor },
|
||||||
scrollIntoView: true,
|
scrollIntoView: true,
|
||||||
changes: move.changes,
|
changes: move.changes,
|
||||||
});
|
});
|
||||||
@@ -86,7 +104,7 @@ export default function Editor({ run }: { run: LiveRun | null | undefined }) {
|
|||||||
return () => {
|
return () => {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
};
|
};
|
||||||
}, [editorView, moves]);
|
}, [moves]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CodeMirror
|
<CodeMirror
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import "server-only";
|
|||||||
import { LiveRun, LiveRunMove } from "./types";
|
import { LiveRun, LiveRunMove } from "./types";
|
||||||
import { SupabaseClient } from "@supabase/supabase-js";
|
import { SupabaseClient } from "@supabase/supabase-js";
|
||||||
import { redis } from "@/lib/redis";
|
import { redis } from "@/lib/redis";
|
||||||
|
import { randomInt } from "crypto";
|
||||||
|
|
||||||
/** -------------------- Live Runs in Redis -------------------- */
|
/** -------------------- Live Runs in Redis -------------------- */
|
||||||
|
|
||||||
@@ -55,13 +56,12 @@ export async function addLiveRunMoves(id: string, moves: LiveRunMove[]) {
|
|||||||
const pipeline = redis.pipeline();
|
const pipeline = redis.pipeline();
|
||||||
moves.forEach((move) => {
|
moves.forEach((move) => {
|
||||||
pipeline.rpush(`liveRunMoves:${id}`, JSON.stringify(move));
|
pipeline.rpush(`liveRunMoves:${id}`, JSON.stringify(move));
|
||||||
setTimeout(() => {
|
|
||||||
redis.del(`liveRunMoves:${id}`);
|
|
||||||
}, 3000);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Optional: keep moves ephemeral automatically after 3s
|
setTimeout(() => {
|
||||||
pipeline.expire(`liveRunMoves:${id}`, 3);
|
redis.del(`liveRunMoves:${id}`);
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
await pipeline.exec();
|
await pipeline.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export interface LiveRun {
|
|||||||
export interface LiveRunMove {
|
export interface LiveRunMove {
|
||||||
latency: number;
|
latency: number;
|
||||||
cursor: number;
|
cursor: number;
|
||||||
|
moveId: number;
|
||||||
changes?: {
|
changes?: {
|
||||||
from: number;
|
from: number;
|
||||||
to: number;
|
to: number;
|
||||||
|
|||||||
Reference in New Issue
Block a user