- Spotify playlist, library, album and artist browsing with in-app playback - Song, playlist and album downloads via spotdl with YouTube and Bandcamp fallbacks - Electron desktop app (castLabs Widevine) with a permanent sidebar layout - Linux and Windows packaging scripts
58 lines
1.2 KiB
TypeScript
58 lines
1.2 KiB
TypeScript
|
|
import { useState, useLayoutEffect } from "react";
|
|
|
|
type UseMediaQueryOptions = {
|
|
defaultValue?: boolean;
|
|
initializeWithValue?: boolean;
|
|
};
|
|
|
|
const IS_SERVER = typeof window === "undefined";
|
|
|
|
export function useMediaQuery(
|
|
query: string,
|
|
{
|
|
defaultValue = false,
|
|
initializeWithValue = true,
|
|
}: UseMediaQueryOptions = {},
|
|
): boolean {
|
|
const getMatches = (query: string): boolean => {
|
|
if (IS_SERVER) {
|
|
return defaultValue;
|
|
}
|
|
return window.matchMedia(query).matches;
|
|
};
|
|
|
|
const [matches, setMatches] = useState<boolean>(() => {
|
|
if (initializeWithValue) {
|
|
return getMatches(query);
|
|
}
|
|
return defaultValue;
|
|
});
|
|
|
|
function handleChange() {
|
|
setMatches(getMatches(query));
|
|
}
|
|
|
|
useLayoutEffect(() => {
|
|
const matchMedia = window.matchMedia(query);
|
|
|
|
handleChange();
|
|
|
|
if (matchMedia.addListener) {
|
|
matchMedia.addListener(handleChange);
|
|
} else {
|
|
matchMedia.addEventListener("change", handleChange);
|
|
}
|
|
|
|
return () => {
|
|
if (matchMedia.removeListener) {
|
|
matchMedia.removeListener(handleChange);
|
|
} else {
|
|
matchMedia.removeEventListener("change", handleChange);
|
|
}
|
|
};
|
|
}, [query]);
|
|
|
|
return matches;
|
|
}
|