From dc5b4de5fa322e3627460288ca7621a81c2ffbde Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 2 Aug 2021 15:19:20 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=B9=B3=E5=8F=B0=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/config/index.tsx | 48 +---------- src/pages/crontab/index.tsx | 27 +----- src/pages/diff/index.tsx | 49 +---------- src/pages/env/index.tsx | 30 +------ src/pages/log/index.tsx | 48 +---------- src/pages/script/index.tsx | 50 ++--------- src/pages/setting/index.tsx | 28 +------ src/utils/browser.ts | 160 ++++++++++++++++++++++++++++++++++++ src/utils/hooks.ts | 62 ++++++++++++++ 9 files changed, 250 insertions(+), 252 deletions(-) create mode 100644 src/utils/browser.ts create mode 100644 src/utils/hooks.ts diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index 59a56d16..74542ec6 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -5,18 +5,16 @@ import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; import Editor from '@monaco-editor/react'; import { Controlled as CodeMirror } from 'react-codemirror2'; +import { useCtx, useTheme } from '@/utils/hooks'; const Config = () => { - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState(''); const [loading, setLoading] = useState(true); const [title, setTitle] = useState('config.sh'); const [select, setSelect] = useState('config.sh'); const [data, setData] = useState([]); - const [theme, setTheme] = useState(''); - const [isPhone, setIsPhone] = useState(false); + const { headerStyle, isPhone } = useCtx(); + const { theme } = useTheme(); const getConfig = (name: string) => { request.get(`${config.apiPrefix}configs/${name}`).then((data: any) => { @@ -51,38 +49,10 @@ const Config = () => { }; useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - setIsPhone(true); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - setIsPhone(false); - } getFiles(); getConfig('config.sh'); }, []); - useEffect(() => { - const media = window.matchMedia('(prefers-color-scheme: dark)'); - const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = - (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark ? 'vs-dark' : 'vs'); - media.addEventListener('change', (e) => { - if (storageTheme === 'auto' || !storageTheme) { - if (e.matches) { - setTheme('vs-dark'); - } else { - setTheme('vs'); - } - } - }); - }, []); - return ( { , ]} header={{ - style: { - padding: '4px 16px 4px 15px', - position: 'sticky', - top: 0, - left: 0, - zIndex: 20, - marginTop, - width, - marginLeft, - }, + style: headerStyle, }} > {isPhone ? ( @@ -136,7 +97,6 @@ const Config = () => { theme={theme} options={{ fontSize: 12, - minimap: { enabled: width === '100%' }, lineNumbersMinChars: 3, folding: false, glyphMargin: false, diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index 02c8689e..fb423a26 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -31,6 +31,7 @@ import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; import CronModal from './modal'; import CronLogModal from './logModal'; +import { useCtx, useTheme } from '@/utils/hooks'; const { Text } = Typography; const { Search } = Input; @@ -139,7 +140,7 @@ const Crontab = () => { key: 'action', align: 'center' as const, render: (text: string, record: any, index: number) => { - const isPc = width === '100%'; + const isPc = !isPhone; return ( {record.status === CrontabStatus.idle && ( @@ -180,9 +181,6 @@ const Crontab = () => { }, ]; - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState([]); const [loading, setLoading] = useState(true); const [isModalVisible, setIsModalVisible] = useState(false); @@ -193,6 +191,7 @@ const Crontab = () => { const [selectedRowIds, setSelectedRowIds] = useState([]); const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(20); + const { headerStyle, isPhone } = useCtx(); const getCrons = () => { setLoading(true); @@ -535,15 +534,6 @@ const Crontab = () => { }, [searchText]); useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - } setPageSize(parseInt(localStorage.getItem('pageSize') || '20')); }, []); @@ -564,16 +554,7 @@ const Crontab = () => { , ]} header={{ - style: { - padding: '4px 16px 4px 15px', - position: 'sticky', - top: 0, - left: 0, - zIndex: 20, - marginTop, - width, - marginLeft, - }, + style: headerStyle, }} > {selectedRowIds.length > 0 && ( diff --git a/src/pages/diff/index.tsx b/src/pages/diff/index.tsx index 34eff25a..89055486 100644 --- a/src/pages/diff/index.tsx +++ b/src/pages/diff/index.tsx @@ -6,16 +6,14 @@ import { request } from '@/utils/http'; import './index.less'; import { DiffEditor } from '@monaco-editor/react'; import ReactDiffViewer from 'react-diff-viewer'; +import { useCtx, useTheme } from '@/utils/hooks'; const Crontab = () => { - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState(''); const [sample, setSample] = useState(''); const [loading, setLoading] = useState(true); - const [theme, setTheme] = useState(''); - const [isPhone, setIsPhone] = useState(false); + const { headerStyle, isPhone } = useCtx(); + const { theme } = useTheme(); const getConfig = () => { request.get(`${config.apiPrefix}configs/config.sh`).then((data) => { @@ -34,54 +32,17 @@ const Crontab = () => { }; useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - setIsPhone(true); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - setIsPhone(false); - } getConfig(); getSample(); }, []); - useEffect(() => { - const media = window.matchMedia('(prefers-color-scheme: dark)'); - const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = - (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark ? 'vs-dark' : 'vs'); - media.addEventListener('change', (e) => { - if (storageTheme === 'auto' || !storageTheme) { - if (e.matches) { - setTheme('vs-dark'); - } else { - setTheme('vs'); - } - } - }); - }, []); - return ( {isPhone ? ( @@ -118,11 +79,9 @@ const Crontab = () => { options={{ readOnly: true, fontSize: 12, - minimap: { enabled: width === '100%' }, lineNumbersMinChars: 3, folding: false, glyphMargin: false, - renderSideBySide: width === '100%', wordWrap: 'on', }} theme={theme} diff --git a/src/pages/env/index.tsx b/src/pages/env/index.tsx index 55f1f344..a4efb141 100644 --- a/src/pages/env/index.tsx +++ b/src/pages/env/index.tsx @@ -25,6 +25,7 @@ import EditNameModal from './editNameModal'; import { DndProvider, useDrag, useDrop } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import './index.less'; +import { useCtx } from '@/utils/hooks'; const { Text } = Typography; const { Search } = Input; @@ -194,9 +195,6 @@ const Env = () => { }, }, ]; - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState([]); const [loading, setLoading] = useState(true); const [isModalVisible, setIsModalVisible] = useState(false); @@ -204,6 +202,7 @@ const Env = () => { const [editedEnv, setEditedEnv] = useState(); const [selectedRowIds, setSelectedRowIds] = useState([]); const [searchText, setSearchText] = useState(''); + const { headerStyle, isPhone } = useCtx(); const getEnvs = () => { setLoading(true); @@ -423,18 +422,6 @@ const Env = () => { getEnvs(); }, [searchText]); - useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - } - }, []); - return ( { , ]} header={{ - style: { - padding: '4px 16px 4px 15px', - position: 'sticky', - top: 0, - left: 0, - zIndex: 20, - marginTop, - width, - marginLeft, - }, + style: headerStyle, }} > {selectedRowIds.length > 0 && ( @@ -511,7 +489,7 @@ const Env = () => { scroll={{ x: 768 }} components={components} loading={loading} - onRow={(record, index) => { + onRow={(record: any, index: number) => { return { index, moveRow, diff --git a/src/pages/log/index.tsx b/src/pages/log/index.tsx index 9e353352..6506eb14 100644 --- a/src/pages/log/index.tsx +++ b/src/pages/log/index.tsx @@ -6,6 +6,7 @@ import Editor from '@monaco-editor/react'; import { request } from '@/utils/http'; import styles from './index.module.less'; import { Controlled as CodeMirror } from 'react-codemirror2'; +import { useCtx, useTheme } from '@/utils/hooks'; function getFilterData(keyword: string, data: any) { const expandedKeys: string[] = []; @@ -37,19 +38,16 @@ function getFilterData(keyword: string, data: any) { } const Log = () => { - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [title, setTitle] = useState('请选择日志文件'); const [value, setValue] = useState('请选择日志文件'); const [select, setSelect] = useState(); const [data, setData] = useState([]); const [filterData, setFilterData] = useState([]); const [loading, setLoading] = useState(false); - const [isPhone, setIsPhone] = useState(false); const [height, setHeight] = useState(); const treeDom = useRef(); - const [theme, setTheme] = useState(''); + const { headerStyle, isPhone } = useCtx(); + const { theme } = useTheme(); const getLogs = () => { setLoading(true); @@ -106,38 +104,10 @@ const Log = () => { ); useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - setIsPhone(true); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - setIsPhone(false); - } getLogs(); setHeight(treeDom.current.clientHeight); }, []); - useEffect(() => { - const media = window.matchMedia('(prefers-color-scheme: dark)'); - const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = - (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark ? 'vs-dark' : 'vs'); - media.addEventListener('change', (e) => { - if (storageTheme === 'auto' || !storageTheme) { - if (e.matches) { - setTheme('vs-dark'); - } else { - setTheme('vs'); - } - } - }); - }, []); - return ( { ] } header={{ - style: { - padding: '4px 16px 4px 15px', - position: 'sticky', - top: 0, - left: 0, - zIndex: 20, - marginTop, - width, - marginLeft, - }, + style: headerStyle, }} >
@@ -212,7 +173,6 @@ const Log = () => { options={{ readOnly: true, fontSize: 12, - minimap: { enabled: width === '100%' }, lineNumbersMinChars: 3, fontFamily: 'Source Code Pro', folding: false, diff --git a/src/pages/script/index.tsx b/src/pages/script/index.tsx index 60c1fdbc..2f67047f 100644 --- a/src/pages/script/index.tsx +++ b/src/pages/script/index.tsx @@ -7,6 +7,7 @@ import { request } from '@/utils/http'; import styles from './index.module.less'; import EditModal from './editModal'; import { Controlled as CodeMirror } from 'react-codemirror2'; +import { useCtx, useTheme } from '@/utils/hooks'; function getFilterData(keyword: string, data: any) { if (keyword) { @@ -29,21 +30,18 @@ const LangMap: any = { }; const Script = () => { - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [title, setTitle] = useState('请选择脚本文件'); const [value, setValue] = useState('请选择脚本文件'); const [select, setSelect] = useState(); const [data, setData] = useState([]); const [filterData, setFilterData] = useState([]); const [loading, setLoading] = useState(false); - const [isPhone, setIsPhone] = useState(false); const [mode, setMode] = useState(''); const [height, setHeight] = useState(); const treeDom = useRef(); - const [theme, setTheme] = useState(''); const [isLogModalVisible, setIsLogModalVisible] = useState(false); + const { headerStyle, isPhone } = useCtx(); + const { theme } = useTheme(); const getScripts = () => { setLoading(true); @@ -64,7 +62,7 @@ const Script = () => { const onSelect = (value: any, node: any) => { const newMode = LangMap[value.slice(-3)] || ''; - setMode(newMode); + setMode(isPhone && newMode === 'typescript' ? 'javascript' : newMode); setSelect(value); setTitle(node.parent || node.value); getDetail(node); @@ -84,38 +82,10 @@ const Script = () => { ); useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - setIsPhone(true); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - setIsPhone(false); - } getScripts(); setHeight(treeDom.current.clientHeight); }, []); - useEffect(() => { - const media = window.matchMedia('(prefers-color-scheme: dark)'); - const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = - (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark ? 'vs-dark' : 'vs'); - media.addEventListener('change', (e) => { - if (storageTheme === 'auto' || !storageTheme) { - if (e.matches) { - setTheme('vs-dark'); - } else { - setTheme('vs'); - } - } - }); - }, []); - return ( { ] } header={{ - style: { - padding: '4px 16px 4px 15px', - position: 'sticky', - top: 0, - left: 0, - zIndex: 20, - marginTop, - width, - marginLeft, - }, + style: headerStyle, }} >
@@ -202,7 +163,6 @@ const Script = () => { options={{ readOnly: true, fontSize: 12, - minimap: { enabled: width === '100%' }, lineNumbersMinChars: 3, folding: false, glyphMargin: false, diff --git a/src/pages/setting/index.tsx b/src/pages/setting/index.tsx index 08827385..26ae123e 100644 --- a/src/pages/setting/index.tsx +++ b/src/pages/setting/index.tsx @@ -10,6 +10,7 @@ import { setFetchMethod, } from 'darkreader'; import { history } from 'umi'; +import { useCtx } from '@/utils/hooks'; const optionsWithDisabled = [ { label: '亮色', value: 'light' }, @@ -18,13 +19,11 @@ const optionsWithDisabled = [ ]; const Password = () => { - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState(''); const [loading, setLoading] = useState(true); const defaultDarken = localStorage.getItem('qinglong_dark_theme') || 'auto'; const [theme, setTheme] = useState(defaultDarken); + const { headerStyle, isPhone } = useCtx(); const handleOk = (values: any) => { request @@ -54,18 +53,6 @@ const Password = () => { }); }; - useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - } - }, []); - useEffect(() => { setFetchMethod(window.fetch); if (theme === 'dark') { @@ -90,16 +77,7 @@ const Password = () => { className="ql-container-wrapper" title="系统设置" header={{ - style: { - padding: '4px 16px 4px 15px', - position: 'sticky', - top: 0, - left: 0, - zIndex: 20, - marginTop, - width, - marginLeft, - }, + style: headerStyle, }} > 平台 > 内核 + 载体 + 内核版本 + 载体版本 > 外壳 + 外壳版本 + const ua = navigator.userAgent.toLowerCase(); + const testUa = (regexp: RegExp) => regexp.test(ua); + const testVs = (regexp: RegExp) => + (ua.match(regexp) || []) + .toString() + .replace(/[^0-9|_.]/g, '') + .replace(/_/g, '.'); + + // 系统 + let system = 'unknow'; + if (testUa(/windows|win32|win64|wow32|wow64/g)) { + system = 'windows'; // windows系统 + } else if (testUa(/macintosh|macintel/g)) { + system = 'macos'; // macos系统 + } else if (testUa(/x11/g)) { + system = 'linux'; // linux系统 + } else if (testUa(/android|adr/g)) { + system = 'android'; // android系统 + } else if (testUa(/ios|iphone|ipad|ipod|iwatch/g)) { + system = 'ios'; // ios系统 + } + + // 系统版本 + let systemVs = 'unknow'; + if (system === 'windows') { + if (testUa(/windows nt 5.0|windows 2000/g)) { + systemVs = '2000'; + } else if (testUa(/windows nt 5.1|windows xp/g)) { + systemVs = 'xp'; + } else if (testUa(/windows nt 5.2|windows 2003/g)) { + systemVs = '2003'; + } else if (testUa(/windows nt 6.0|windows vista/g)) { + systemVs = 'vista'; + } else if (testUa(/windows nt 6.1|windows 7/g)) { + systemVs = '7'; + } else if (testUa(/windows nt 6.2|windows 8/g)) { + systemVs = '8'; + } else if (testUa(/windows nt 6.3|windows 8.1/g)) { + systemVs = '8.1'; + } else if (testUa(/windows nt 10.0|windows 10/g)) { + systemVs = '10'; + } + } else if (system === 'macos') { + systemVs = testVs(/os x [\d._]+/g); + } else if (system === 'android') { + systemVs = testVs(/android [\d._]+/g); + } else if (system === 'ios') { + systemVs = testVs(/os [\d._]+/g); + } + + // 平台 + let platform = 'unknow'; + if (system === 'windows' || system === 'macos' || system === 'linux') { + platform = 'desktop'; // 桌面端 + } else if (system === 'android' || system === 'ios' || testUa(/mobile/g)) { + platform = 'mobile'; // 移动端 + } + + // 内核和载体 + let engine = 'unknow'; + let supporter = 'unknow'; + if (testUa(/applewebkit/g)) { + engine = 'webkit'; // webkit内核 + if (testUa(/edge/g)) { + supporter = 'edge'; // edge浏览器 + } else if (testUa(/opr/g)) { + supporter = 'opera'; // opera浏览器 + } else if (testUa(/chrome/g)) { + supporter = 'chrome'; // chrome浏览器 + } else if (testUa(/safari/g)) { + supporter = 'safari'; // safari浏览器 + } + } else if (testUa(/gecko/g) && testUa(/firefox/g)) { + engine = 'gecko'; // gecko内核 + supporter = 'firefox'; // firefox浏览器 + } else if (testUa(/presto/g)) { + engine = 'presto'; // presto内核 + supporter = 'opera'; // opera浏览器 + } else if (testUa(/trident|compatible|msie/g)) { + engine = 'trident'; // trident内核 + supporter = 'iexplore'; // iexplore浏览器 + } + + // 内核版本 + let engineVs = 'unknow'; + if (engine === 'webkit') { + engineVs = testVs(/applewebkit\/[\d._]+/g); + } else if (engine === 'gecko') { + engineVs = testVs(/gecko\/[\d._]+/g); + } else if (engine === 'presto') { + engineVs = testVs(/presto\/[\d._]+/g); + } else if (engine === 'trident') { + engineVs = testVs(/trident\/[\d._]+/g); + } + + // 载体版本 + let supporterVs = 'unknow'; + if (supporter === 'chrome') { + supporterVs = testVs(/chrome\/[\d._]+/g); + } else if (supporter === 'safari') { + supporterVs = testVs(/version\/[\d._]+/g); + } else if (supporter === 'firefox') { + supporterVs = testVs(/firefox\/[\d._]+/g); + } else if (supporter === 'opera') { + supporterVs = testVs(/opr\/[\d._]+/g); + } else if (supporter === 'iexplore') { + supporterVs = testVs(/(msie [\d._]+)|(rv:[\d._]+)/g); + } else if (supporter === 'edge') { + supporterVs = testVs(/edge\/[\d._]+/g); + } + + // 外壳和外壳版本 + let shell = 'none'; + let shellVs = 'unknow'; + if (testUa(/micromessenger/g)) { + shell = 'wechat'; // 微信浏览器 + shellVs = testVs(/micromessenger\/[\d._]+/g); + } else if (testUa(/qqbrowser/g)) { + shell = 'qq'; // QQ浏览器 + shellVs = testVs(/qqbrowser\/[\d._]+/g); + } else if (testUa(/ucbrowser/g)) { + shell = 'uc'; // UC浏览器 + shellVs = testVs(/ucbrowser\/[\d._]+/g); + } else if (testUa(/qihu 360se/g)) { + shell = '360'; // 360浏览器(无版本) + } else if (testUa(/2345explorer/g)) { + shell = '2345'; // 2345浏览器 + shellVs = testVs(/2345explorer\/[\d._]+/g); + } else if (testUa(/metasr/g)) { + shell = 'sougou'; // 搜狗浏览器(无版本) + } else if (testUa(/lbbrowser/g)) { + shell = 'liebao'; // 猎豹浏览器(无版本) + } else if (testUa(/maxthon/g)) { + shell = 'maxthon'; // 遨游浏览器 + shellVs = testVs(/maxthon\/[\d._]+/g); + } + + const result = Object.assign( + { + engine, // webkit gecko presto trident + engineVs, + platform, // desktop mobile + supporter, // chrome safari firefox opera iexplore edge + supporterVs, + system, // windows macos linux android ios + systemVs, + }, + shell === 'none' + ? {} + : { + shell, // wechat qq uc 360 2345 sougou liebao maxthon + shellVs, + }, + ); + + console.log(result); + return result; +} diff --git a/src/utils/hooks.ts b/src/utils/hooks.ts new file mode 100644 index 00000000..3310831a --- /dev/null +++ b/src/utils/hooks.ts @@ -0,0 +1,62 @@ +import { useState, useEffect } from 'react'; +import browserType from './browser'; + +export const useCtx = () => { + const [width, setWidth] = useState('100%'); + const [marginLeft, setMarginLeft] = useState(0); + const [marginTop, setMarginTop] = useState(-72); + const [isPhone, setIsPhone] = useState(false); + + useEffect(() => { + const { platform } = browserType(); + + if (platform === 'mobile') { + setWidth('auto'); + setMarginLeft(0); + setMarginTop(0); + setIsPhone(true); + } else { + setWidth('100%'); + setMarginLeft(0); + setMarginTop(-72); + setIsPhone(false); + } + }, []); + + return { + headerStyle: { + padding: '4px 16px 4px 15px', + position: 'sticky', + top: 0, + left: 0, + zIndex: 20, + marginTop, + width, + marginLeft, + } as any, + isPhone, + }; +}; + +export const useTheme = () => { + const [theme, setTheme] = useState(''); + + useEffect(() => { + const media = window.matchMedia('(prefers-color-scheme: dark)'); + const storageTheme = localStorage.getItem('qinglong_dark_theme'); + const isDark = + (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; + setTheme(isDark ? 'vs-dark' : 'vs'); + media.addEventListener('change', (e) => { + if (storageTheme === 'auto' || !storageTheme) { + if (e.matches) { + setTheme('vs-dark'); + } else { + setTheme('vs'); + } + } + }); + }, []); + + return { theme }; +};