fixing authority on server

This commit is contained in:
2024-11-15 09:05:34 -07:00
parent 0c1b85af1a
commit 2641289b12

View File

@@ -1,5 +1,4 @@
"use client";
import { MonacoEditor } from "@/components/editor/MonacoEditor";
import {
useLecturesSuspenseQuery,
@@ -9,47 +8,63 @@ import {
lectureToString,
parseLecture,
} from "@/services/fileStorage/utils/lectureUtils";
import { useEffect, useState } from "react";
import { useCallback, useEffect, useState } from "react";
import LecturePreview from "./LecturePreview";
import EditLectureTitle from "./EditLectureTitle";
import LectureButtons from "./LectureButtons";
import { useCourseContext } from "../../context/courseContext";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { Lecture } from "@/models/local/lecture";
export default function EditLecture({ lectureDay }: { lectureDay: string }) {
const [_, {dataUpdatedAt}] = useLecturesSuspenseQuery();
return (
<InnerEditLecture key={dataUpdatedAt} lectureDay={lectureDay} />
);
}
export function InnerEditLecture({ lectureDay }: { lectureDay: string }) {
const { courseName } = useCourseContext();
const [settings] = useLocalCourseSettingsQuery();
const [weeks] = useLecturesSuspenseQuery();
const [weeks, { dataUpdatedAt: serverDataUpdatedAt }] =
useLecturesSuspenseQuery();
const updateLecture = useLectureUpdateMutation();
const lecture = weeks
.flatMap(({ lectures }) => lectures.map((lecture) => lecture))
.find((l) => l.date === lectureDay);
const startingText = lecture
? lectureToString(lecture)
: `Name:
Date: ${lectureDay}
---
`;
const serverVersionOfText = getLectureTextOrDefault(lecture, lectureDay);
const [text, setText] = useState(startingText);
const [text, setText] = useState(serverVersionOfText);
const [updateMonacoKey, setUpdateMonacoKey] = useState(1);
const [error, setError] = useState("");
const [clientDataUpdatedAt, setClientDataUpdatedAt] =
useState(serverDataUpdatedAt);
const clientIsAuthoritative = serverDataUpdatedAt <= clientDataUpdatedAt;
console.log("client it authoritative", clientIsAuthoritative);
const textUpdate = useCallback((t: string) => {
setText(t);
setClientDataUpdatedAt(Date.now());
}, []);
useEffect(() => {
const delay = 500;
const handler = setTimeout(() => {
try {
const parsed = parseLecture(text);
if (!lecture || lectureToString(parsed) !== lectureToString(lecture)) {
if (clientIsAuthoritative) {
console.log("updating lecture");
updateLecture.mutate({ lecture: parsed, settings, courseName });
} else {
if (lecture) {
console.log(
"client not authoritative, updating client with server data"
);
textUpdate(lectureToString(lecture));
setUpdateMonacoKey((k) => k + 1);
} else {
console.log(
"client not authoritative, but no lecture on server, this is a bug"
);
}
}
}
setError("");
} catch (e: any) {
@@ -60,14 +75,26 @@ Date: ${lectureDay}
return () => {
clearTimeout(handler);
};
}, [courseName, lecture, settings, text, updateLecture]);
}, [
clientIsAuthoritative,
courseName,
lecture,
settings,
text,
textUpdate,
updateLecture,
]);
return (
<div className="h-full flex flex-col">
<EditLectureTitle lectureDay={lectureDay} />
<div className="sm:columns-2 min-h-0 flex-1">
<div className="flex-1 h-full">
<MonacoEditor value={text} onChange={setText} />
<MonacoEditor
key={updateMonacoKey}
value={text}
onChange={textUpdate}
/>
</div>
<div className="h-full sm:block none overflow-auto">
<div className="text-red-300">{error && error}</div>
@@ -78,3 +105,15 @@ Date: ${lectureDay}
</div>
);
}
function getLectureTextOrDefault(
lecture: Lecture | undefined,
lectureDay: string
) {
return lecture
? lectureToString(lecture)
: `Name:
Date: ${lectureDay}
---
`;
}