/* * 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 { useLayoutEffect } from 'react'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemText from '@mui/material/ListItemText'; import { useTranslation } from 'react-i18next'; import ListSubheader from '@mui/material/ListSubheader'; import Divider from '@mui/material/Divider'; import { requestManager } from '@/lib/requests/RequestManager.ts'; import { ListItemLink } from '@/modules/core/components/lists/ListItemLink.tsx'; import { LoadingPlaceholder } from '@/modules/core/components/feedback/LoadingPlaceholder.tsx'; import { UpdateState } from '@/lib/graphql/generated/graphql.ts'; import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'; import { EmptyViewAbsoluteCentered } from '@/modules/core/components/feedback/EmptyViewAbsoluteCentered.tsx'; import { VersionInfo } from '@/modules/app-updates/components/VersionInfo.tsx'; import { getErrorMessage } from '@/lib/HelperFunctions.ts'; import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx'; import { epochToDate } from '@/util/DateHelper.ts'; import { useAppTitle } from '@/modules/navigation-bar/hooks/useAppTitle.ts'; export function About() { const { t } = useTranslation(); const { setAction } = useNavBarContext(); useAppTitle(t('settings.about.title')); useLayoutEffect(() => { setAction(null); return () => { setAction(null); }; }, [t]); const { data, loading, error, refetch } = requestManager.useGetAbout({ notifyOnNetworkStatusChange: true }); const { data: serverUpdateCheckData, loading: isCheckingForServerUpdate, refetch: checkForServerUpdate, error: serverUpdateCheckError, } = requestManager.useCheckForServerUpdate({ notifyOnNetworkStatusChange: true }); const { data: webUIUpdateData, loading: isCheckingForWebUIUpdate, refetch: checkForWebUIUpdate, error: orgWebUIUpdateCheckError, } = requestManager.useCheckForWebUIUpdate({ notifyOnNetworkStatusChange: true }); const webUIUpdateCheckError = orgWebUIUpdateCheckError || webUIUpdateData?.checkForWebUIUpdate.tag === ''; const { data: webUIUpdateStatusData } = requestManager.useGetWebUIUpdateStatus(); const { state: webUIUpdateState, progress: webUIUpdateProgress } = webUIUpdateStatusData?.getWebUIUpdateStatus ?? { state: UpdateState.Idle, progress: 0, }; if (loading) { return ; } if (error) { return ( refetch().catch(defaultPromiseErrorHandler('About::refetch'))} /> ); } const { aboutServer, aboutWebUI } = data!; const selectedServerChannelInfo = serverUpdateCheckData?.checkForServerUpdates?.find( (channel) => channel.channel === aboutServer.buildType, ); const isServerUpdateAvailable = !!selectedServerChannelInfo?.tag && selectedServerChannelInfo.tag !== aboutServer.version; const isWebUIUpdateAvailable = !!webUIUpdateData?.checkForWebUIUpdate.updateAvailable; return ( {t('settings.server.title.server')} } > } /> {t('settings.webui.title.webui')} } > requestManager .updateWebUI() .response.catch(defaultPromiseErrorHandler('About::updateWebUI')) } progress={webUIUpdateProgress} updateState={webUIUpdateState} /> } /> {t('global.label.links')} } > ); }