mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 15:18:32 -06:00
server websockets
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
MAJOR_VERSION="2"
|
||||
MINOR_VERSION="2"
|
||||
MINOR_VERSION="3"
|
||||
VERSION="$MAJOR_VERSION.$MINOR_VERSION"
|
||||
|
||||
docker build -t canvas_management:$VERSION .
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { MonacoEditor } from "@/components/editor/MonacoEditor";
|
||||
import { useLecturesSuspenseQuery, useLectureUpdateMutation } from "@/hooks/localCourse/lectureHooks";
|
||||
import {
|
||||
useLecturesSuspenseQuery,
|
||||
useLectureUpdateMutation,
|
||||
} from "@/hooks/localCourse/lectureHooks";
|
||||
import {
|
||||
lectureToString,
|
||||
parseLecture,
|
||||
@@ -10,11 +13,16 @@ import { useEffect, useState } from "react";
|
||||
import LecturePreview from "./LecturePreview";
|
||||
import EditLectureTitle from "./EditLectureTitle";
|
||||
import LectureButtons from "./LectureButtons";
|
||||
import { trpc } from "@/services/trpc/utils";
|
||||
import { useCourseContext } from "../../context/courseContext";
|
||||
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
|
||||
|
||||
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();
|
||||
|
||||
@@ -26,6 +26,22 @@ export default function EditAssignment({
|
||||
}: {
|
||||
assignmentName: string;
|
||||
moduleName: string;
|
||||
}) {
|
||||
const [_, {dataUpdatedAt}] = useAssignmentQuery(moduleName, assignmentName);
|
||||
return (
|
||||
<InnerEditAssignment
|
||||
key={dataUpdatedAt}
|
||||
assignmentName={assignmentName}
|
||||
moduleName={moduleName}
|
||||
/>
|
||||
);
|
||||
}
|
||||
export function InnerEditAssignment({
|
||||
moduleName,
|
||||
assignmentName,
|
||||
}: {
|
||||
assignmentName: string;
|
||||
moduleName: string;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const { courseName } = useCourseContext();
|
||||
|
||||
@@ -21,10 +21,28 @@ export default function EditPage({
|
||||
}: {
|
||||
pageName: string;
|
||||
moduleName: string;
|
||||
}) {
|
||||
const [_, { dataUpdatedAt }] = usePageQuery(moduleName, pageName);
|
||||
|
||||
return (
|
||||
<InnerEditPage
|
||||
key={dataUpdatedAt}
|
||||
pageName={pageName}
|
||||
moduleName={moduleName}
|
||||
></InnerEditPage>
|
||||
);
|
||||
}
|
||||
|
||||
function InnerEditPage({
|
||||
moduleName,
|
||||
pageName,
|
||||
}: {
|
||||
pageName: string;
|
||||
moduleName: string;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const { courseName } = useCourseContext();
|
||||
const [page] = usePageQuery(moduleName, pageName);
|
||||
const [page, pageQuery] = usePageQuery(moduleName, pageName);
|
||||
const updatePage = useUpdatePageMutation();
|
||||
const [pageText, setPageText] = useState(
|
||||
localPageMarkdownUtils.toMarkdown(page)
|
||||
@@ -32,6 +50,10 @@ export default function EditPage({
|
||||
const [error, setError] = useState("");
|
||||
const [settings] = useLocalCourseSettingsQuery();
|
||||
|
||||
useEffect(() => {
|
||||
console.log("page data updated on sever", pageQuery.dataUpdatedAt);
|
||||
}, [pageQuery.dataUpdatedAt]);
|
||||
|
||||
useEffect(() => {
|
||||
const delay = 500;
|
||||
const handler = setTimeout(() => {
|
||||
|
||||
@@ -61,6 +61,22 @@ export default function EditQuiz({
|
||||
}: {
|
||||
quizName: string;
|
||||
moduleName: string;
|
||||
}) {
|
||||
const [_, {dataUpdatedAt}] = useQuizQuery(moduleName, quizName);
|
||||
return (
|
||||
<InnerEditQuiz
|
||||
key={dataUpdatedAt}
|
||||
quizName={quizName}
|
||||
moduleName={moduleName}
|
||||
/>
|
||||
);
|
||||
}
|
||||
export function InnerEditQuiz({
|
||||
moduleName,
|
||||
quizName,
|
||||
}: {
|
||||
quizName: string;
|
||||
moduleName: string;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const { courseName } = useCourseContext();
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
import { io, Socket } from 'socket.io-client';
|
||||
import { trpc } from "@/services/trpc/utils";
|
||||
import React, { useEffect } from "react";
|
||||
import { io, Socket } from "socket.io-client";
|
||||
|
||||
interface ServerToClientEvents {
|
||||
message: (data: string) => void;
|
||||
@@ -12,28 +13,106 @@ interface ClientToServerEvents {
|
||||
sendMessage: (data: string) => void;
|
||||
}
|
||||
|
||||
const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io('/');
|
||||
const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io("/");
|
||||
|
||||
function removeFileExtension(fileName: string): string {
|
||||
const lastDotIndex = fileName.lastIndexOf(".");
|
||||
if (lastDotIndex > 0) {
|
||||
return fileName.substring(0, lastDotIndex);
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
export function ClientCacheInvalidation() {
|
||||
const utils = trpc.useUtils();
|
||||
useEffect(() => {
|
||||
socket.on('message', (data) => {
|
||||
console.log('Received message:', data);
|
||||
socket.on("message", (data) => {
|
||||
console.log("Received message:", data);
|
||||
});
|
||||
|
||||
socket.on('fileChanged', (filePath) => {
|
||||
console.log('File changed:', filePath);
|
||||
socket.on("fileChanged", (filePath) => {
|
||||
const [courseName, moduleOrLectures, itemType, itemFile] =
|
||||
filePath.split("/");
|
||||
|
||||
const itemName = removeFileExtension(itemFile);
|
||||
|
||||
const allParts = [courseName, moduleOrLectures, itemType, itemName];
|
||||
|
||||
if (moduleOrLectures === "settings.yml") {
|
||||
utils.settings.allCoursesSettings.invalidate();
|
||||
utils.settings.courseSettings.invalidate({ courseName });
|
||||
return;
|
||||
}
|
||||
|
||||
if (moduleOrLectures === "00 - lectures") {
|
||||
console.log("lecture updated on FS ", allParts);
|
||||
utils.lectures.getLectures.invalidate({ courseName });
|
||||
return;
|
||||
}
|
||||
|
||||
if (itemType === "assignments") {
|
||||
console.log("assignment updated on FS ", allParts);
|
||||
utils.assignment.getAllAssignments.invalidate({
|
||||
courseName,
|
||||
moduleName: moduleOrLectures,
|
||||
});
|
||||
utils.assignment.getAssignment.invalidate({
|
||||
courseName,
|
||||
moduleName: moduleOrLectures,
|
||||
assignmentName: itemName,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (itemType === "quizzes") {
|
||||
console.log("quiz updated on FS ", allParts);
|
||||
utils.quiz.getAllQuizzes.invalidate({
|
||||
courseName,
|
||||
moduleName: moduleOrLectures,
|
||||
});
|
||||
utils.quiz.getQuiz.invalidate({
|
||||
courseName,
|
||||
moduleName: moduleOrLectures,
|
||||
quizName: itemName,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (itemType === "pages") {
|
||||
console.log("page updated on FS ", allParts);
|
||||
utils.page.getAllPages.invalidate({
|
||||
courseName,
|
||||
moduleName: moduleOrLectures,
|
||||
});
|
||||
utils.page.getPage.invalidate({
|
||||
courseName,
|
||||
moduleName: moduleOrLectures,
|
||||
pageName: itemName,
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('connect_error', (error) => {
|
||||
console.error('Connection error:', error);
|
||||
socket.on("connect_error", (error) => {
|
||||
console.error("Connection error:", error);
|
||||
});
|
||||
|
||||
return () => {
|
||||
socket.off('message');
|
||||
socket.off('fileChanged');
|
||||
socket.off('connect_error');
|
||||
socket.off("message");
|
||||
socket.off("fileChanged");
|
||||
socket.off("connect_error");
|
||||
};
|
||||
}, []);
|
||||
}, [
|
||||
utils.assignment.getAllAssignments,
|
||||
utils.assignment.getAssignment,
|
||||
utils.lectures.getLectures,
|
||||
utils.page.getAllPages,
|
||||
utils.page.getPage,
|
||||
utils.quiz.getAllQuizzes,
|
||||
utils.quiz.getQuiz,
|
||||
utils.settings.allCoursesSettings,
|
||||
utils.settings.courseSettings,
|
||||
]);
|
||||
|
||||
return <></>;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ const port = 3000;
|
||||
const app = next({ dev, hostname, port });
|
||||
const handler = app.getRequestHandler();
|
||||
|
||||
const folderToWatch = path.join(process.cwd(), "./storage");
|
||||
const folderToWatch = path.join(process.cwd(), "./storage", "/");
|
||||
console.log("watching folder", folderToWatch);
|
||||
|
||||
app.prepare().then(() => {
|
||||
@@ -23,21 +23,14 @@ app.prepare().then(() => {
|
||||
|
||||
io.on("connection", (socket) => {
|
||||
console.log("websocket connection created");
|
||||
|
||||
// Define a change event handler
|
||||
const changeHandler = (filePath) => {
|
||||
const relativePath = filePath.replace(folderToWatch, "")
|
||||
const relativePath = filePath.replace(folderToWatch, "");
|
||||
console.log(`Sending file changed websocket message: ${relativePath}`);
|
||||
|
||||
|
||||
|
||||
socket.emit("fileChanged", `File changed: ${filePath}`);
|
||||
socket.emit("fileChanged", relativePath);
|
||||
};
|
||||
|
||||
// Attach the change event handler
|
||||
watcher.on("change", changeHandler);
|
||||
|
||||
// Clean up the change event handler when the client disconnects
|
||||
socket.on("disconnect", () => {
|
||||
console.log("Client disconnected");
|
||||
watcher.off("change", changeHandler); // Remove the event listener
|
||||
|
||||
Reference in New Issue
Block a user