mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
clients get file change notifications
This commit is contained in:
@@ -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));
|
||||
|
||||
@@ -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>
|
||||
|
||||
39
nextjs/src/app/realtime/ClientCacheInvalidation.tsx
Normal file
39
nextjs/src/app/realtime/ClientCacheInvalidation.tsx
Normal 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 <></>;
|
||||
}
|
||||
@@ -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
55
nextjs/src/websocket.js
Normal 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}`);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user