Browse Source

implementing live updates

Kirk Trombley 5 years ago
parent
commit
71304c5eb8
1 changed files with 38 additions and 8 deletions
  1. 38 8
      client/src/App.js

+ 38 - 8
client/src/App.js

@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, useRef } from 'react';
 import { getAvailability, setAvailability } from './api';
 
 const NameForm = ({ onNameSet }) => {
@@ -47,8 +47,8 @@ const Tile = ({ user, month, day, availability, onClick }) => (
     style={{
       display: "flex",
       flexFlow: "column nowrap",
-      width: "5em",
-      height: "5em",
+      width: "10em",
+      height: "10em",
       border: "1px solid black",
       margin: "2px 2px 2px 2px",
       backgroundColor: colors[availability.filter(({ name }) => name === user)[0]?.status] || "#fff",
@@ -62,7 +62,11 @@ const Tile = ({ user, month, day, availability, onClick }) => (
         .map(({ name, status }) => (
           <span 
             key={name} 
-            style={{ color: colors[status] }}
+            style={{ 
+              backgroundColor: colors[status],
+              overflow: "hidden",
+              textOverflow: "ellipsis",
+            }}
           >
             {name}
           </span>
@@ -83,7 +87,17 @@ const chunk = (arr, len) => {
 function App() {
   const [name, setName] = useState(null);
   const [calendar, setCalendar] = useState(null);
-  useEffect(() => { getAvailability().then(({availability}) => setCalendar(availability)) }, []);
+  const lastUpdatedRef = useRef(null);
+
+  const updateCalendar = async () => {
+    const { availability, lastUpdated } = await getAvailability();
+    if (lastUpdated !== lastUpdatedRef.current) {
+      // only actually update if there are changes
+      lastUpdatedRef.current = lastUpdated;
+      setCalendar(availability);
+    }
+  };
+
   const advance = async (dates) => {
     const updates = dates.map(({ month, day }) => {
       const currentStatus = calendar
@@ -95,9 +109,18 @@ function App() {
       const status = nextState[currentStatus] || "unknown";
       return { month, day, status }
     });
-    const { availability } = await setAvailability(name, updates);
+    const { lastUpdated, availability } = await setAvailability(name, updates);
+    lastUpdatedRef.current = lastUpdated;
     setCalendar(availability);
-  }
+  };
+  
+  useEffect(() => { 
+    const interval = setInterval(updateCalendar, 5000); // update every few seconds
+
+    updateCalendar(); // do an update to get started
+
+    return () => clearInterval(interval); // cleanup if we unmount
+  }, []);
 
 
   if (name === null) {
@@ -138,7 +161,14 @@ function App() {
               }}
             >
               {
-                row.map(item => <Tile onClick={() => advance([item])} key={item.day} user={name} {...item}/>)
+                row.map(item => (
+                  <Tile
+                    onClick={() => advance([item])}
+                    key={item.day} 
+                    user={name} 
+                    {...item}
+                  />
+                ))
               }
             </div>
           </div>