diff --git a/src/App copy.tsx b/src/App copy.tsx deleted file mode 100644 index f8286aa..0000000 --- a/src/App copy.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { useState } from "react"; -import reactLogo from "./assets/react.svg"; -import { invoke } from "@tauri-apps/api/core"; -import "./App.css"; - -import { Routes, Route, Outlet, Link } from "react-router-dom"; -import { Sidebar, Menu, MenuItem, SubMenu } from 'react-pro-sidebar'; - -function App() { - const [greetMsg, setGreetMsg] = useState(""); - const [name, setName] = useState(""); - - async function greet() { - // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command - setGreetMsg(await invoke("greet", { name })); - } - - console.log("Rendering main app") - - return ( -
- - -
- - - - - Pie charts - Line charts - - Documentation - Calendar - -
-
-
- ); -} - -export default App; diff --git a/src/App.tsx b/src/App.tsx index 71fc697..d5067eb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,8 +1,4 @@ import { useState } from 'react'; -import Button from 'react-bootstrap/Button'; -import Modal from 'react-bootstrap/Modal'; -import reactLogo from "./assets/react.svg"; -import { invoke } from "@tauri-apps/api/core"; import "./App.css"; import { ToastContainer, toast } from 'react-toastify'; @@ -21,20 +17,19 @@ import ConnectionModal from "./components/connection_modal"; import ConsoleTab from "./components/console_tab"; import BackEnd from './backend'; -function App() { - const [greetMsg, setGreetMsg] = useState(""); - const [name, setName] = useState(""); - async function greet() { - // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command - setGreetMsg(await invoke("greet", { name })); - } +import createFastContext from "./global_context"; - console.log("Rendering main app") +export const { Provider, useStore } = createFastContext({ + console: "" +}); - return ( -
+function App() { + + return ( + +
{/* Routes nest inside one another. Nested route paths build upon parent route paths, and nested route elements render inside parent route elements. See the note about below. */} @@ -51,7 +46,9 @@ function App() { -
+
+ + ); } diff --git a/src/backend.tsx b/src/backend.tsx index 51130f8..c66cf43 100644 --- a/src/backend.tsx +++ b/src/backend.tsx @@ -1,37 +1,25 @@ -import { useEffect, useContext } from 'react'; +import { useEffect } from 'react'; import { listen } from "@tauri-apps/api/event"; -import Button from 'react-bootstrap/Button'; -import Modal from 'react-bootstrap/Modal'; -import Table from 'react-bootstrap/Table'; - -import { toast } from 'react-toastify'; - -import Container from 'react-bootstrap/Container'; -import Row from 'react-bootstrap/Row'; -import Col from 'react-bootstrap/Col'; - -import { store } from './store.js'; import { ConsoleEvent } from './interface/console_event'; +import {useStore} from "./App"; + interface ConsoleEventMessage { payload: ConsoleEvent; } function BackEnd() { - const { state, dispatch } = useContext(store); + const [_, setStore] = useStore((store) => store["console"]); - const changeColor = () => { - dispatch({ type: "CHANGE_COLOR", payload: "blue" }); - }; + let currentConsoleText = ""; useEffect(() => { console.log("Backend loaded"); + const unListen = listen("console", (e: ConsoleEventMessage) => { - //setConsoleText(consoleText + e.payload.message + "\n"); - console.log("Got console stuff off backend") - dispatch({ type: "CONSOLE", payload: e.payload.message }); - + currentConsoleText += e.payload.message + "\n"; + setStore({ ["console"]: currentConsoleText }); }); return () => { diff --git a/src/components/connection_modal.tsx b/src/components/connection_modal.tsx index 6284c14..c5aaa7d 100644 --- a/src/components/connection_modal.tsx +++ b/src/components/connection_modal.tsx @@ -5,24 +5,10 @@ import Modal from 'react-bootstrap/Modal'; import Table from 'react-bootstrap/Table'; import { toast } from 'react-toastify'; - -import Container from 'react-bootstrap/Container'; -import Row from 'react-bootstrap/Row'; -import Col from 'react-bootstrap/Col'; - import 'bootstrap/dist/css/bootstrap.min.css'; - import { invoke } from "@tauri-apps/api/core"; - import { ScanResponse } from '../interface/scan_response'; - -// interface ProgressEventPayload { -// matches_per_bs: Stats; -// hits_per_sensor: Stats; -// sync: Stats; -// } - interface ProgressEventProps { payload: ScanResponse; } diff --git a/src/components/console_tab.tsx b/src/components/console_tab.tsx index 7569dc3..a280858 100644 --- a/src/components/console_tab.tsx +++ b/src/components/console_tab.tsx @@ -1,31 +1,18 @@ -import { useContext, useState } from 'react'; -import { listen } from "@tauri-apps/api/event"; -import Button from 'react-bootstrap/Button'; -import Modal from 'react-bootstrap/Modal'; -import Table from 'react-bootstrap/Table'; - -import { toast } from 'react-toastify'; - -import Container from 'react-bootstrap/Container'; import Row from 'react-bootstrap/Row'; import Col from 'react-bootstrap/Col'; - -import { store } from './../store.js'; - -import { ConsoleEvent } from '../interface/console_event'; - -interface ConsoleEventMessage { - payload: ConsoleEvent; -} +import {useStore} from "./../App"; function ConsoleTab() { - const [consoleText, setConsoleText] = useState(""); - const { state, dispatch } = useContext(store); + const [crazyflieConsole] = useStore((store) => store["console"]); return (
-
{state.console}
+ + +
{crazyflieConsole}
+ +
); } diff --git a/src/global_context.tsx b/src/global_context.tsx new file mode 100644 index 0000000..92d3f16 --- /dev/null +++ b/src/global_context.tsx @@ -0,0 +1,73 @@ +// Source https://github.com/jherr/fast-react-context/tree/main/fast-context-generic + +import React, { + useRef, + createContext, + useContext, + useCallback, + useSyncExternalStore, +} from "react"; + +export default function createGlobalContext(initialState: Store) { + function useStoreData(): { + get: () => Store; + set: (value: Partial) => void; + subscribe: (callback: () => void) => () => void; + } { + const store = useRef(initialState); + + const get = useCallback(() => store.current, []); + + const subscribers = useRef(new Set<() => void>()); + + const set = useCallback((value: Partial) => { + store.current = { ...store.current, ...value }; + subscribers.current.forEach((callback) => {console.log("Calling callback"); callback()}); + }, []); + + const subscribe = useCallback((callback: () => void) => { + subscribers.current.add(callback); + return () => subscribers.current.delete(callback); + }, []); + + return { + get, + set, + subscribe, + }; + } + + type UseStoreDataReturnType = ReturnType; + + const StoreContext = createContext(null); + + function Provider({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); + } + + function useStore( + selector: (store: Store) => SelectorOutput + ): [SelectorOutput, (value: Partial) => void] { + const store = useContext(StoreContext); + if (!store) { + throw new Error("Store not found"); + } + + const state = useSyncExternalStore( + store.subscribe, + () => selector(store.get()), + () => selector(initialState), + ); + + return [state, store.set]; + } + + return { + Provider, + useStore, + }; +} \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index 9eef99b..b43fbd0 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -3,14 +3,11 @@ import ReactDOM from "react-dom/client"; import App from "./App"; import "./styles.css"; import { BrowserRouter } from "react-router-dom"; -import { StateProvider } from "./store"; ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - - ); diff --git a/src/store.tsx b/src/store.tsx deleted file mode 100644 index 6caac54..0000000 --- a/src/store.tsx +++ /dev/null @@ -1,24 +0,0 @@ -// store.js -import { createContext, useReducer } from "react"; -const initialState = { - color: "red", - console: "", -}; - -const store = createContext(initialState); -const { Provider } = store; - -const StateProvider = ({ children }) => { - const [state, dispatch] = useReducer((state, action) => { - switch (action.type) { - case "CHANGE_COLOR": - return { ...state, color: action.payload }; - case "CONSOLE": - return { ...state, console: state.console + action.payload + "\n" }; - default: - throw new Error(); - } - }, initialState); - return {children}; -}; -export { store, StateProvider }; \ No newline at end of file