Files
suwayomi-material-you-webui/src/screens/Migration.tsx

76 lines
2.6 KiB
TypeScript
Raw Normal View History

/*
* 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 { useTranslation } from 'react-i18next';
import { useMemo } from 'react';
import List from '@mui/material/List';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder.tsx';
2024-04-29 15:29:33 +02:00
import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx';
import { GetMigratableSourcesQuery } from '@/lib/graphql/generated/graphql.ts';
import { MigrationCard, TMigratableSource } from '@/components/MigrationCard.tsx';
import { StyledGroupItemWrapper } from '@/components/virtuoso/StyledGroupItemWrapper.tsx';
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
type TMigratableSourcesResult = GetMigratableSourcesQuery['mangas']['nodes'];
type TMigratableSources = Record<string, TMigratableSource>;
const getMigratableSources = (mangas?: TMigratableSourcesResult): TMigratableSources => {
if (!mangas) {
return {};
}
const uniqueSources: TMigratableSources = {};
mangas.forEach(({ sourceId, source }) => {
const uniqueSource = uniqueSources[sourceId] ?? {
...{ id: sourceId, name: sourceId, lang: 'unknown', iconUrl: null, mangaCount: 0, ...source },
};
uniqueSources[sourceId] = {
...uniqueSource,
mangaCount: uniqueSource.mangaCount + 1,
};
});
return uniqueSources;
};
export const Migration = () => {
const { t } = useTranslation();
const { data, loading, error, refetch } = requestManager.useGetMigratableSources({
2024-04-27 22:28:55 +02:00
notifyOnNetworkStatusChange: true,
});
const migratableSources = useMemo(() => getMigratableSources(data?.mangas.nodes), [data?.mangas.nodes]);
if (loading) {
return <LoadingPlaceholder />;
}
if (error) {
return (
2024-04-29 15:29:33 +02:00
<EmptyViewAbsoluteCentered
message={t('global.error.label.failed_to_load_data')}
messageExtra={error.message}
retry={() => refetch().catch(defaultPromiseErrorHandler('Migration::refetch'))}
/>
);
}
return (
<List>
2024-07-11 17:22:52 +02:00
{Object.values(migratableSources).map((migratableSource) => (
<StyledGroupItemWrapper key={migratableSource.id}>
<MigrationCard {...migratableSource} />
</StyledGroupItemWrapper>
))}
</List>
);
};