import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import { Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Divider, List, ListItemButton, Switch } from '@mui/material'; import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { ListItem, ListItemText } from '@/components/ListItem'; import { usePromiseValue } from '@/helpers/useServiceValue'; import { usePreferenceObservable } from '@services/preferences/hooks'; import { Paper, SectionTitle } from '../PreferenceComponents'; import type { ISectionProps } from '../useSections'; export function DeveloperTools(props: ISectionProps): React.JSX.Element { const { t } = useTranslation(); const preference = usePreferenceObservable(); const [LOG_FOLDER, SETTINGS_FOLDER, V8_CACHE_FOLDER] = usePromiseValue<[string | undefined, string | undefined, string | undefined]>( async () => await Promise.all([window.service.context.get('LOG_FOLDER'), window.service.context.get('SETTINGS_FOLDER'), window.service.context.get('V8_CACHE_FOLDER')]), [undefined, undefined, undefined], )!; const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [externalApiInfo, setExternalApiInfo] = useState<{ exists: boolean; size?: number; path?: string }>({ exists: false }); useEffect(() => { const fetchInfo = async () => { try { const info = await window.service.database.getDatabaseInfo('externalApi'); const path = await window.service.database.getDatabasePath('externalApi'); setExternalApiInfo({ ...info, path }); } catch (error) { void window.service.native.log( 'error', 'DeveloperTools: fetch externalApi database info failed', { function: 'DeveloperTools.fetchInfo', error, }, ); } }; void fetchInfo(); }, []); return ( <> {t('Preference.DeveloperTools')} {LOG_FOLDER === undefined || SETTINGS_FOLDER === undefined ? {t('Loading')} : ( <> { if (LOG_FOLDER !== undefined) { void window.service.native.openPath(LOG_FOLDER, true); } }} > { if (SETTINGS_FOLDER !== undefined) { void window.service.native.openPath(SETTINGS_FOLDER, true); } }} > { if (V8_CACHE_FOLDER !== undefined) { try { await window.service.native.openPath(V8_CACHE_FOLDER, true); } catch (error: unknown) { void window.service.native.log( 'error', 'DeveloperTools: open V8 cache folder failed', { function: 'DeveloperTools.openV8CacheFolder', error: error as Error, }, ); } } }} > { await window.service.preference.resetWithConfirm(); }} > { await window.service.preference.set('externalAPIDebug', !preference?.externalAPIDebug); const info = await window.service.database.getDatabaseInfo('externalApi'); if (!info?.exists) { // if database didn't exist before, enabling externalAPIDebug requires application restart to initialize the database table props.requestRestartCountDown?.(); } }} name='externalAPIDebug' /> {preference?.externalAPIDebug && ( <> { if (externalApiInfo.path) { try { await window.service.native.openPath(externalApiInfo.path, true); } catch (error) { void window.service.native.log( 'error', 'DeveloperTools: open externalApi database folder failed', { function: 'DeveloperTools.openExternalApiDatabaseFolder', error, path: externalApiInfo.path, }, ); } } }} > { setDeleteDialogOpen(true); }} > )} )} { setDeleteDialogOpen(false); }} > {t('Preference.ConfirmDelete')} {t('Preference.ConfirmDeleteExternalApiDatabase')} ); }