diff --git a/client/src/hooks/useListGIFs.js b/client/src/hooks/useListGIFs.js index 300e449..122c7e2 100644 --- a/client/src/hooks/useListGIFs.js +++ b/client/src/hooks/useListGIFs.js @@ -9,6 +9,7 @@ export default function useListGIFs() { const [isLoading, setIsLoading] = useState(true) const [data, setData] = useState([]) const [page, setPageState] = useState(0) + const [listening, setListening] = useState(false) const gifCount = data.length const pageCount = Math.ceil(gifCount / itemsPerPage) @@ -49,6 +50,19 @@ export default function useListGIFs() { } }, []) + useEffect(() => { + if (!listening) { + const eventSource = new EventSource('http://localhost:3001/events') + eventSource.onmessage = (e) => { + if (JSON.parse(e.data) === 'new gif') { + listGifs() + } + } + + setListening(true) + } + }, [listening, data]) + return { page, gifCount: data.length, diff --git a/server/server.js b/server/server.js index 7caf4e8..7aa3e20 100644 --- a/server/server.js +++ b/server/server.js @@ -30,6 +30,9 @@ app.set('port', process.env.PORT || 3001) app.use(express.json()) app.use(express.urlencoded({ extended: false })) +// Clients for SSE +let clients = [] + const storage = multer.diskStorage({ destination(req, file, cb) { cb(null, './uploads/') @@ -78,6 +81,12 @@ const listGifs = async () => { return OrderedContents } +function sendEventsToAll(event) { + clients.forEach((client) => { + client.res.write(`data: ${JSON.stringify(event)}\n\n`) + }) +} + app.get('/listGifs', async (_, res) => { try { const result = await listGifs() @@ -87,6 +96,33 @@ app.get('/listGifs', async (_, res) => { } }) +app.get('/events', (req, res) => { + res.set({ + 'Content-Type': 'text/event-stream', + 'Cache-Control': 'no-cache', + Connection: 'keep-alive', + + // enabling CORS + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': + 'Origin, X-Requested-With, Content-Type, Accept', + }) + + res.write(`data: ${JSON.stringify('listening for events...')}\n\n`) + + const clientId = Date.now() + const newClient = { + id: clientId, + res, + } + + clients.push(newClient) + + req.on('close', () => { + clients = clients.filter((client) => client.id !== clientId) + }) +}) + const groupPhotoPath = 'public/group_photo.jpeg' app.post('/getGroupPhoto', async (_, res) => { @@ -174,6 +210,7 @@ app.post('/uploadUserGIF', upload.single('gif'), async (req, res) => { app.post('/uploadGIF', ({ body }, res) => { const { filename } = body uploadGIF(res, filename, 'temp', () => { + sendEventsToAll('new gif') fs.unlink(`uploads/${filename}.webm`, () => console.log('.webm file was deleted'), )