mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 16:59:12 +00:00

* chore: update license header year * chore: update license header year tsx files * chore: update license header
60 lines
1.6 KiB
TypeScript
60 lines
1.6 KiB
TypeScript
/*
|
|
* Copyright (c) 2021 - 2024, Ludvig Lundgren and the autobrr contributors.
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
export function useToggle(initialValue = false): [boolean, () => void] {
|
|
const [value, setValue] = useState(initialValue);
|
|
const toggle = () => setValue(v => !v);
|
|
|
|
return [value, toggle];
|
|
}
|
|
|
|
const isBrowser = typeof(window) !== "undefined";
|
|
|
|
const getInitialState = (query: string, defaultState?: boolean) => {
|
|
// Prevent a React hydration mismatch when a default value is provided by not defaulting to window.matchMedia(query).matches.
|
|
if (defaultState !== undefined) {
|
|
return defaultState;
|
|
}
|
|
|
|
if (isBrowser) {
|
|
return window.matchMedia(query).matches;
|
|
}
|
|
|
|
// A default value has not been provided, and you are rendering on the server, warn of a possible hydration mismatch when defaulting to false.
|
|
if (process.env.NODE_ENV !== "production") {
|
|
console.warn(
|
|
"`useMedia` When server side rendering, defaultState should be defined to prevent a hydration mismatches."
|
|
);
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
export const useMedia = (query: string, defaultState?: boolean) => {
|
|
const [state, setState] = useState(getInitialState(query, defaultState));
|
|
|
|
useEffect(() => {
|
|
let mounted = true;
|
|
const mql = window.matchMedia(query);
|
|
const onChange = () => {
|
|
if (!mounted) {
|
|
return;
|
|
}
|
|
setState(!!mql.matches);
|
|
};
|
|
|
|
mql.addListener(onChange);
|
|
setState(mql.matches);
|
|
|
|
return () => {
|
|
mounted = false;
|
|
mql.removeListener(onChange);
|
|
};
|
|
}, [query]);
|
|
|
|
return state;
|
|
};
|