2024-05-23 02:28:37 +02:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) Contributors to the Suwayomi project
|
|
|
|
|
*
|
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import useMediaQuery from '@mui/material/useMediaQuery';
|
2024-08-30 15:50:17 +02:00
|
|
|
import { Breakpoint } from '@mui/material/styles';
|
2024-09-06 23:43:38 +02:00
|
|
|
import { useCallback, useState } from 'react';
|
2024-09-30 02:27:10 +02:00
|
|
|
import { getCurrentTheme } from '@/theme.tsx';
|
2024-10-05 22:12:32 +02:00
|
|
|
import { ThemeMode } from '@/modules/theme/contexts/ThemeModeContext.tsx';
|
2024-10-05 16:09:34 +02:00
|
|
|
import { AppStorage } from '@/lib/AppStorage.ts';
|
|
|
|
|
import { useResizeObserver } from '@/modules/core/hooks/useResizeObserver.tsx';
|
2024-05-23 02:28:37 +02:00
|
|
|
|
|
|
|
|
export class MediaQuery {
|
|
|
|
|
static useIsTouchDevice(): boolean {
|
|
|
|
|
return useMediaQuery('not (pointer: fine)');
|
|
|
|
|
}
|
2024-05-23 02:37:40 +02:00
|
|
|
|
2024-08-30 15:50:17 +02:00
|
|
|
static useIsBelowWidth(breakpoint: Breakpoint): boolean {
|
|
|
|
|
return useMediaQuery(getCurrentTheme().breakpoints.down(breakpoint));
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 02:37:40 +02:00
|
|
|
static useIsMobileWidth(): boolean {
|
2024-08-30 15:50:17 +02:00
|
|
|
return this.useIsBelowWidth('sm');
|
2024-05-23 02:37:40 +02:00
|
|
|
}
|
2024-09-04 23:46:04 +02:00
|
|
|
|
2024-09-06 23:50:38 +02:00
|
|
|
static useGetScrollbarSize(type: 'height' | 'width'): number {
|
2024-09-06 23:43:38 +02:00
|
|
|
const [scrollbarSize, setScrollbarSize] = useState(0);
|
|
|
|
|
|
|
|
|
|
useResizeObserver(
|
|
|
|
|
document.documentElement,
|
2024-09-06 23:50:38 +02:00
|
|
|
useCallback(() => {
|
|
|
|
|
const height = window.innerHeight - document.documentElement.clientHeight;
|
|
|
|
|
const width = window.innerWidth - document.documentElement.clientWidth;
|
|
|
|
|
const size = type === 'height' ? height : width;
|
|
|
|
|
|
|
|
|
|
setScrollbarSize(size);
|
|
|
|
|
}, []),
|
2024-09-06 23:43:38 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return scrollbarSize;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-04 23:46:04 +02:00
|
|
|
static getSystemThemeMode(): Exclude<ThemeMode, 'system'> {
|
|
|
|
|
const prefersDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
|
|
|
return prefersDarkMode ? ThemeMode.DARK : ThemeMode.LIGHT;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-05 00:08:23 +02:00
|
|
|
static getThemeMode(): Exclude<ThemeMode, 'system'> {
|
|
|
|
|
const themeMode = AppStorage.local.getItemParsed<ThemeMode>('themeMode', ThemeMode.SYSTEM);
|
|
|
|
|
|
|
|
|
|
const isSystemMode = themeMode === ThemeMode.SYSTEM;
|
|
|
|
|
if (isSystemMode) {
|
|
|
|
|
return this.getSystemThemeMode();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return themeMode;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-04 23:46:04 +02:00
|
|
|
static listenToSystemThemeChange(onChange: (themeMode: Exclude<ThemeMode, 'system'>) => void): () => void {
|
|
|
|
|
const handleSystemThemeModeChange = (e: MediaQueryListEvent) => {
|
|
|
|
|
onChange(e.matches ? ThemeMode.DARK : ThemeMode.LIGHT);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const matchSystemThemeMode = window.matchMedia('(prefers-color-scheme: dark)');
|
|
|
|
|
|
|
|
|
|
matchSystemThemeMode.addEventListener('change', handleSystemThemeModeChange);
|
|
|
|
|
|
|
|
|
|
return () => matchSystemThemeMode.removeEventListener('change', handleSystemThemeModeChange);
|
|
|
|
|
}
|
2024-05-23 02:28:37 +02:00
|
|
|
}
|