clients get file change notifications

This commit is contained in:
2024-11-15 07:56:53 -07:00
parent 0366b37586
commit a37071b584
9 changed files with 454 additions and 17 deletions

View File

@@ -22,19 +22,19 @@ laborDay:
- 9/1/2024`;
export const holidaysAreEqual = (
obj1: {
holidays1: {
name: string;
days: string[];
}[],
obj2: {
holidays2: {
name: string;
days: string[];
}[]
): boolean => {
if (obj1.length !== obj2.length) return false;
if (holidays1.length !== holidays2.length) return false;
const sortedObj1 = [...obj1].sort((a, b) => a.name.localeCompare(b.name));
const sortedObj2 = [...obj2].sort((a, b) => a.name.localeCompare(b.name));
const sortedObj1 = [...holidays1].sort((a, b) => a.name.localeCompare(b.name));
const sortedObj2 = [...holidays2].sort((a, b) => a.name.localeCompare(b.name));
for (let i = 0; i < sortedObj1.length; i++) {
const holiday1 = sortedObj1[i];
@@ -64,7 +64,6 @@ export default function HolidayConfig() {
}
function InnerHolidayConfig() {
const [settings] = useLocalCourseSettingsQuery();
console.log(settings.holidays);
const updateSettings = useUpdateLocalCourseSettingsMutation();
const [rawText, setRawText] = useState(holidaysToString(settings.holidays));

View File

@@ -9,6 +9,7 @@ import { trpcAppRouter } from "@/services/trpc/router/app";
import { createTrpcContext } from "@/services/trpc/context";
import superjson from "superjson";
import { fileStorageService } from "@/services/fileStorage/fileStorageService";
import { ClientCacheInvalidation } from "./realtime/ClientCacheInvalidation";
export const dynamic = "force-dynamic";
export const metadata: Metadata = {
@@ -28,7 +29,10 @@ export default async function RootLayout({
<MyToaster />
<Suspense>
<Providers>
<DataHydration>{children}</DataHydration>
<DataHydration>
<ClientCacheInvalidation></ClientCacheInvalidation>
{children}
</DataHydration>
</Providers>
</Suspense>
</div>

View File

@@ -0,0 +1,39 @@
"use client";
import React, { useEffect } from 'react';
import { io, Socket } from 'socket.io-client';
interface ServerToClientEvents {
message: (data: string) => void;
fileChanged: (filePath: string) => void;
}
interface ClientToServerEvents {
sendMessage: (data: string) => void;
}
const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io('/');
export function ClientCacheInvalidation() {
useEffect(() => {
socket.on('message', (data) => {
console.log('Received message:', data);
});
socket.on('fileChanged', (filePath) => {
console.log('File changed:', filePath);
});
socket.on('connect_error', (error) => {
console.error('Connection error:', error);
});
return () => {
socket.off('message');
socket.off('fileChanged');
socket.off('connect_error');
};
}, []);
return <></>;
}

View File

@@ -16,7 +16,6 @@ export const useAssignmentQuery = (
export const useAssignmentNamesQuery = (moduleName: string) => {
const { courseName } = useCourseContext();
console.log("rendering all assignments query");
return trpc.assignment.getAllAssignments.useSuspenseQuery(
{
moduleName,

55
nextjs/src/websocket.js Normal file
View File

@@ -0,0 +1,55 @@
import { createServer } from "node:http";
import next from "next";
import { Server } from "socket.io";
import chokidar from "chokidar";
import path from "path";
const dev = process.env.NODE_ENV !== "production";
const hostname = "localhost";
const port = 3000;
// when using middleware `hostname` and `port` must be provided below
const app = next({ dev, hostname, port });
const handler = app.getRequestHandler();
const folderToWatch = path.join(process.cwd(), "./storage");
console.log("watching folder", folderToWatch);
app.prepare().then(() => {
const httpServer = createServer(handler);
const io = new Server(httpServer);
const watcher = chokidar.watch(folderToWatch, { persistent: true });
io.on("connection", (socket) => {
console.log("websocket connection created");
// Define a change event handler
const changeHandler = (filePath) => {
const relativePath = filePath.replace(folderToWatch, "")
console.log(`Sending file changed websocket message: ${relativePath}`);
socket.emit("fileChanged", `File changed: ${filePath}`);
};
// 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
});
});
httpServer
.once("error", (err) => {
console.error(err);
process.exit(1);
})
.listen(port, () => {
console.log(`> Ready on http://${hostname}:${port}`);
});
});