From de94d0824555d8ec003dc4057226751062d2cf62 Mon Sep 17 00:00:00 2001 From: d-nieto246 Date: Fri, 12 Jul 2024 16:37:33 -0400 Subject: [PATCH 1/4] First draft for saved status Included a text file with different methods and will incorporate it into the code at some point next week. --- .idea/workspace.xml | 74 ++++++++++++++++++++++++++++++++ src/client/savedstatus.txt | 87 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 .idea/workspace.xml create mode 100644 src/client/savedstatus.txt diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 00000000..72e80f1c --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + { + "customColor": "", + "associatedIndex": 8 +} + + + + + + + + + + + + + + + 1720805632675 + + + + + + \ No newline at end of file diff --git a/src/client/savedstatus.txt b/src/client/savedstatus.txt new file mode 100644 index 00000000..5eb5d380 --- /dev/null +++ b/src/client/savedstatus.txt @@ -0,0 +1,87 @@ +// src/hooks/usePending.js +import { useState, useEffect, useCallback, useRef } from 'react'; +import { runDelay } from '../constants'; + +export const usePending = (shareDBDoc) => { + const lastOpTimerRef = useRef(); + const [pending, setPending] = useState(false); + + const resetOnNoPending = useCallback(() => { + if (!shareDBDoc) return; + + shareDBDoc.whenNothingPending(() => { + setPending(false); + }); + }, [shareDBDoc, setPending]); + + useEffect(() => { + if (!shareDBDoc) return; + + shareDBDoc.on('before op', () => { + setPending(true); + + clearTimeout(lastOpTimerRef.current); + + lastOpTimerRef.current = setTimeout(() => { + // should be triggered only once, cause upcoming ops unschedule previous resetOnNoPending + resetOnNoPending(); + }, runDelay); + }); + }, [shareDBDoc, resetOnNoPending]); + + return pending; +}; + +// src/components/StatusIndicator.js +import React, { useEffect, useState } from 'react'; +import { usePending } from '../hooks/usePending'; +import ShareDB from 'sharedb/lib/client'; +import ReconnectingWebSocket from 'reconnecting-websocket'; + +// Assume you have your backend server URL +const backendUrl = 'ws://your-sharedb-server-url'; + +const StatusIndicator = () => { + const [doc, setDoc] = useState(null); + const pending = usePending(doc); + + useEffect(() => { + // Setup ShareDB connection + const socket = new ReconnectingWebSocket(backendUrl); + const connection = new ShareDB.Connection(socket); + + // Get document + const doc = connection.get('examples', 'counter'); + doc.subscribe((err) => { + if (err) throw err; + setDoc(doc); + }); + + return () => { + connection.close(); + }; + }, []); + + return ( +
+ {pending ? 'Saving...' : 'Connected, all changes saved'} +
+ ); +}; + +export default StatusIndicator; + +// src/App.js +import React from 'react'; +import StatusIndicator from './components/StatusIndicator'; + +const App = () => { + return ( +
+

ShareDB Status Indicator

+ +
+ ); +}; + +export default App; \ No newline at end of file From 86d7edf0bc96694d22421114e2f21caf7615b74f Mon Sep 17 00:00:00 2001 From: d-nieto246 Date: Fri, 19 Jul 2024 17:36:24 -0400 Subject: [PATCH 2/4] Helper files Added helper files to display a saved status. --- src/client/VZSidebar/VZCodeContext.tsx | 60 ++++++++++++++++++++++++++ src/client/VZSidebar/saveChanges.tsx | 24 +++++++++++ 2 files changed, 84 insertions(+) create mode 100644 src/client/VZSidebar/VZCodeContext.tsx create mode 100644 src/client/VZSidebar/saveChanges.tsx diff --git a/src/client/VZSidebar/VZCodeContext.tsx b/src/client/VZSidebar/VZCodeContext.tsx new file mode 100644 index 00000000..6de6f24a --- /dev/null +++ b/src/client/VZSidebar/VZCodeContext.tsx @@ -0,0 +1,60 @@ +import { createContext, useState, useEffect, useRef } from 'react'; + +export let VZCodeContext: React.Context; +// @ts-ignore +VZCodeContext = createContext(); + +export const VZCodeProvider = ({ children }) => { + const [files, setFiles] = useState(null); + const [openTab, setOpenTab] = useState(null); + const [isSettingsOpen, setIsSettingsOpen] = useState(false); + const [isDocOpen, setIsDocOpen] = useState(false); + const [isSearchOpen, setIsSearchOpen] = useState(false); + const [connected, setConnected] = useState(true); + const [enableAutoFollow, setEnableAutoFollow] = useState(false); + const [savingStatus, setSavingStatus] = useState('saved'); // New state for saving status + const sidebarRef = useRef(null); + + // Mock function to simulate saving process + const saveChanges = () => { + setSavingStatus('Saving...'); + setTimeout(() => { + setSavingStatus('Saved'); + }, 2000); + }; + + // Mock effect to simulate connection status check + useEffect(() => { + const interval = setInterval(() => { + // Simulate connection check + setConnected(navigator.onLine); + }, 5000); + + return () => clearInterval(interval); + }, []); + + return ( + setEnableAutoFollow(prev => !prev), + savingStatus, // Expose saving status in the context + saveChanges, // Expose the save function in the context + }} + > + {children} + + ); +}; diff --git a/src/client/VZSidebar/saveChanges.tsx b/src/client/VZSidebar/saveChanges.tsx new file mode 100644 index 00000000..4c65e5c2 --- /dev/null +++ b/src/client/VZSidebar/saveChanges.tsx @@ -0,0 +1,24 @@ +// Some file handling component +import { useContext } from 'react'; +import { VZCodeContext } from '../VZCodeContext'; + +const FileEditor = () => { + const { saveChanges } = useContext(VZCodeContext); + + const handleFileChange = (newContent) => { + // Handle file content change logic... + saveChanges(); // Trigger saving process + }; + + return ( +
+