mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-11 15:36:38 +00:00
Merge branch 'dev' into feat/login-page-customization
This commit is contained in:
99
src/hooks/useLocalStorage.ts
Normal file
99
src/hooks/useLocalStorage.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import {
|
||||
useState,
|
||||
useEffect,
|
||||
useCallback,
|
||||
Dispatch,
|
||||
SetStateAction
|
||||
} from "react";
|
||||
|
||||
type SetValue<T> = Dispatch<SetStateAction<T>>;
|
||||
|
||||
export function useLocalStorage<T>(
|
||||
key: string,
|
||||
initialValue: T
|
||||
): [T, SetValue<T>] {
|
||||
// Get initial value from localStorage or use the provided initial value
|
||||
const readValue = useCallback((): T => {
|
||||
// Prevent build error "window is undefined" during SSR
|
||||
if (typeof window === "undefined") {
|
||||
return initialValue;
|
||||
}
|
||||
|
||||
try {
|
||||
const item = window.localStorage.getItem(key);
|
||||
return item ? (JSON.parse(item) as T) : initialValue;
|
||||
} catch (error) {
|
||||
console.warn(`Error reading localStorage key "${key}":`, error);
|
||||
return initialValue;
|
||||
}
|
||||
}, [initialValue, key]);
|
||||
|
||||
// State to store our value
|
||||
const [storedValue, setStoredValue] = useState<T>(readValue);
|
||||
|
||||
// Return a wrapped version of useState's setter function that
|
||||
// persists the new value to localStorage
|
||||
const setValue: SetValue<T> = useCallback(
|
||||
(value) => {
|
||||
// Prevent build error "window is undefined" during SSR
|
||||
if (typeof window === "undefined") {
|
||||
console.warn(
|
||||
`Tried setting localStorage key "${key}" even though environment is not a client`
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// Allow value to be a function so we have the same API as useState
|
||||
const newValue =
|
||||
value instanceof Function ? value(storedValue) : value;
|
||||
|
||||
// Save to local storage
|
||||
window.localStorage.setItem(key, JSON.stringify(newValue));
|
||||
|
||||
// Save state
|
||||
setStoredValue(newValue);
|
||||
|
||||
// Dispatch a custom event so every useLocalStorage hook is notified
|
||||
window.dispatchEvent(new Event("local-storage"));
|
||||
} catch (error) {
|
||||
console.warn(`Error setting localStorage key "${key}":`, error);
|
||||
}
|
||||
},
|
||||
[key, storedValue]
|
||||
);
|
||||
|
||||
// Listen for changes to this key from other tabs/windows
|
||||
useEffect(() => {
|
||||
const handleStorageChange = (e: StorageEvent) => {
|
||||
if (e.key === key && e.newValue !== null) {
|
||||
try {
|
||||
setStoredValue(JSON.parse(e.newValue));
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
`Error parsing localStorage value for key "${key}":`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Listen for storage events (changes from other tabs)
|
||||
window.addEventListener("storage", handleStorageChange);
|
||||
|
||||
// Listen for custom event (changes from same tab)
|
||||
const handleLocalStorageChange = () => {
|
||||
setStoredValue(readValue());
|
||||
};
|
||||
window.addEventListener("local-storage", handleLocalStorageChange);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("storage", handleStorageChange);
|
||||
window.removeEventListener(
|
||||
"local-storage",
|
||||
handleLocalStorageChange
|
||||
);
|
||||
};
|
||||
}, [key, readValue]);
|
||||
|
||||
return [storedValue, setValue];
|
||||
}
|
||||
@@ -2,11 +2,15 @@
|
||||
|
||||
import RemoteExitNodeContext from "@app/contexts/remoteExitNodeContext";
|
||||
import { build } from "@server/build";
|
||||
import { GetRemoteExitNodeResponse } from "@server/routers/remoteExitNode/types";
|
||||
import { useContext } from "react";
|
||||
|
||||
export function useRemoteExitNodeContext() {
|
||||
if (build == "oss") {
|
||||
return null;
|
||||
return {
|
||||
remoteExitNode: {} as GetRemoteExitNodeResponse,
|
||||
updateRemoteExitNode: () => {},
|
||||
};
|
||||
}
|
||||
const context = useContext(RemoteExitNodeContext);
|
||||
if (context === undefined) {
|
||||
|
||||
Reference in New Issue
Block a user