Prevent being able to migrate entry to itself
This commit is contained in:
@@ -47,6 +47,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|||||||
- (**Migration**) Fix missing manual search option for in progress entry search without a selected match on mobile
|
- (**Migration**) Fix missing manual search option for in progress entry search without a selected match on mobile
|
||||||
- (**Migration**) Fix being unable to retry failed search for a match without a selected match
|
- (**Migration**) Fix being unable to retry failed search for a match without a selected match
|
||||||
- (**Migration**) Fix selecting a destination from a source browse search page
|
- (**Migration**) Fix selecting a destination from a source browse search page
|
||||||
|
- (**Migration**) Fix being able to migrate an entry to itself
|
||||||
- (**Reader**) Fix scrollbar appearing with "fit to widt/height/screen" page scale mode and applied safe area insets
|
- (**Reader**) Fix scrollbar appearing with "fit to widt/height/screen" page scale mode and applied safe area insets
|
||||||
- (**Reader**) Fix wrongly positioned mobile progress bar current page indicator
|
- (**Reader**) Fix wrongly positioned mobile progress bar current page indicator
|
||||||
- (**Reader**) Fix mobile progress bar previous/next chapter button visibility on hover and while disabled
|
- (**Reader**) Fix mobile progress bar previous/next chapter button visibility on hover and while disabled
|
||||||
|
|||||||
@@ -157,7 +157,8 @@ const SourceSearchPreview = React.memo(
|
|||||||
const { data: searchResult, isLoading, error, abortRequest } = results[0]!;
|
const { data: searchResult, isLoading, error, abortRequest } = results[0]!;
|
||||||
currentAbortRequest.current = abortRequest;
|
currentAbortRequest.current = abortRequest;
|
||||||
|
|
||||||
const mangas = searchResult?.fetchSourceManga?.mangas ?? STABLE_EMPTY_ARRAY;
|
const tmpMangas = searchResult?.fetchSourceManga?.mangas ?? STABLE_EMPTY_ARRAY;
|
||||||
|
const mangas = tmpMangas.filter((manga) => manga.id !== mangaId);
|
||||||
const noMangasFound = !error && !isLoading && !mangas.length;
|
const noMangasFound = !error && !isLoading && !mangas.length;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import { getMetadataServerSettings } from '@/features/settings/services/ServerSe
|
|||||||
import { Queue } from '@/lib/Queue.ts';
|
import { Queue } from '@/lib/Queue.ts';
|
||||||
import type { TrackerIdInfo } from '@/features/tracker/Tracker.types.ts';
|
import type { TrackerIdInfo } from '@/features/tracker/Tracker.types.ts';
|
||||||
import { assertIsDefined } from '@/base/Asserts.ts';
|
import { assertIsDefined } from '@/base/Asserts.ts';
|
||||||
|
import { t } from '@lingui/core/macro';
|
||||||
|
import { makeToast } from '@/base/utils/Toast.ts';
|
||||||
|
|
||||||
export class MangaMigration {
|
export class MangaMigration {
|
||||||
private static trackerQueue = new Map<TrackerIdInfo['id'], Queue>();
|
private static trackerQueue = new Map<TrackerIdInfo['id'], Queue>();
|
||||||
@@ -58,6 +60,11 @@ export class MangaMigration {
|
|||||||
throw new Error('MangaMigration::migrate: missing manga data');
|
throw new Error('MangaMigration::migrate: missing manga data');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mangaToMigrate.id === mangaToMigrateTo.id) {
|
||||||
|
makeToast(t`Can't migrate an entry to itself`, 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (migrateChapters && !mangaToMigrate.chapters) {
|
if (migrateChapters && !mangaToMigrate.chapters) {
|
||||||
throw new Error('MangaMigration::migrate: missing chapters data');
|
throw new Error('MangaMigration::migrate: missing chapters data');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -819,7 +819,8 @@ export class MigrationManager {
|
|||||||
);
|
);
|
||||||
const uniqueSearchResults = uniqBy('id', searchResults);
|
const uniqueSearchResults = uniqBy('id', searchResults);
|
||||||
const matches = uniqueSearchResults.filter(
|
const matches = uniqueSearchResults.filter(
|
||||||
(searchMatch) => enhancedCleanup(searchMatch.title) === enhancedCleanup(mangaTitle),
|
(searchMatch) =>
|
||||||
|
searchMatch.id !== mangaId && enhancedCleanup(searchMatch.title) === enhancedCleanup(mangaTitle),
|
||||||
);
|
);
|
||||||
|
|
||||||
const matchUpdatePromises = matches.map(async (match) => {
|
const matchUpdatePromises = matches.map(async (match) => {
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ const useSourceManga = (
|
|||||||
filters: IPos[],
|
filters: IPos[],
|
||||||
initialPages: number,
|
initialPages: number,
|
||||||
hideLibraryEntries: boolean,
|
hideLibraryEntries: boolean,
|
||||||
|
mangaId?: MangaIdInfo['id'],
|
||||||
): [
|
): [
|
||||||
AbortableApolloUseMutationPaginatedResponse<GetSourceMangasFetchMutation, GetSourceMangasFetchMutationVariables>[0],
|
AbortableApolloUseMutationPaginatedResponse<GetSourceMangasFetchMutation, GetSourceMangasFetchMutationVariables>[0],
|
||||||
AbortableApolloUseMutationPaginatedResponse<
|
AbortableApolloUseMutationPaginatedResponse<
|
||||||
@@ -168,7 +169,9 @@ const useSourceManga = (
|
|||||||
|
|
||||||
pages.forEach((page, index) => {
|
pages.forEach((page, index) => {
|
||||||
const pageItems = page.data?.fetchSourceManga?.mangas ?? [];
|
const pageItems = page.data?.fetchSourceManga?.mangas ?? [];
|
||||||
const nonLibraryPageItems = pageItems.filter((item) => !hideLibraryEntries || !item.inLibrary);
|
const nonLibraryPageItems = pageItems.filter(
|
||||||
|
(item) => item.id !== mangaId && (!hideLibraryEntries || !item.inLibrary),
|
||||||
|
);
|
||||||
const uniqueItems = getUniqueMangas([...allItems, ...nonLibraryPageItems]);
|
const uniqueItems = getUniqueMangas([...allItems, ...nonLibraryPageItems]);
|
||||||
|
|
||||||
const isLastPage = !isPageLoading && pages.length === index + 1;
|
const isLastPage = !isPageLoading && pages.length === index + 1;
|
||||||
@@ -287,7 +290,7 @@ export function SourceMangas() {
|
|||||||
const [
|
const [
|
||||||
loadPage,
|
loadPage,
|
||||||
{ data, error, isLoading: loading, size: lastPageNum, abortRequest, filteredOutAllItemsOfFetchedPage },
|
{ data, error, isLoading: loading, size: lastPageNum, abortRequest, filteredOutAllItemsOfFetchedPage },
|
||||||
] = useSourceManga(sourceId, contentType, query, filtersToApply, 1, hideLibraryEntries);
|
] = useSourceManga(sourceId, contentType, query, filtersToApply, 1, hideLibraryEntries, mangaId);
|
||||||
currentAbortRequest.current = abortRequest;
|
currentAbortRequest.current = abortRequest;
|
||||||
const mangas = data?.fetchSourceManga?.mangas ?? STABLE_EMPTY_ARRAY;
|
const mangas = data?.fetchSourceManga?.mangas ?? STABLE_EMPTY_ARRAY;
|
||||||
const hasNextPage = !!data?.fetchSourceManga?.hasNextPage;
|
const hasNextPage = !!data?.fetchSourceManga?.hasNextPage;
|
||||||
|
|||||||
Reference in New Issue
Block a user