mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-14 12:24:04 +00:00
[ENG-1338] Fix fresh Spacedrive install failing to start due to attempting to query a nonexistent Library (#1649)
Fix Spacedrive failing to start due to attempting to query a nonexistent Library - Rename useShoudRedirect to useRedirectToNewLocations - Improve behaviour for the immedite redirection after adding a new location
This commit is contained in:
parent
e51a58fe28
commit
ce568981c1
|
@ -8,8 +8,7 @@ import {
|
|||
type ExplorerItem,
|
||||
type ExplorerLayout,
|
||||
type ExplorerSettings,
|
||||
type SortOrder,
|
||||
JobGroup
|
||||
type SortOrder
|
||||
} from '@sd/client';
|
||||
|
||||
export enum ExplorerKind {
|
||||
|
@ -122,7 +121,7 @@ const state = {
|
|||
tagAssignMode: false,
|
||||
showInspector: false,
|
||||
showMoreInfo: false,
|
||||
jobsToRedirect: [] as {locationId: number | null}[],
|
||||
newLocationToRedirect: null as null | number,
|
||||
mediaPlayerVolume: 0.7,
|
||||
newThumbnails: proxySet() as Set<string>,
|
||||
cutCopyState: { type: 'Idle' } as CutCopyState,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import clsx from 'clsx';
|
||||
import { Suspense, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { Navigate, Outlet, useLocation, useNavigate, useResolvedPath } from 'react-router-dom';
|
||||
import { Suspense, useEffect, useMemo, useRef } from 'react';
|
||||
import { Navigate, Outlet, useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
ClientContextProvider,
|
||||
initPlausible,
|
||||
|
@ -16,10 +16,11 @@ import { LibraryIdParamsSchema } from '~/app/route-schemas';
|
|||
import {
|
||||
useKeybindEventHandler,
|
||||
useOperatingSystem,
|
||||
useRedirectToNewLocation,
|
||||
useShowControls,
|
||||
useWindowState,
|
||||
useZodRouteParams
|
||||
} from '~/hooks';
|
||||
import { useWindowState } from '~/hooks/useWindowState';
|
||||
import { usePlatform } from '~/util/Platform';
|
||||
|
||||
import { QuickPreviewContextProvider } from '../Explorer/QuickPreview/Context';
|
||||
|
@ -30,7 +31,7 @@ const Layout = () => {
|
|||
const { libraries, library } = useClientContext();
|
||||
const os = useOperatingSystem();
|
||||
const showControls = useShowControls();
|
||||
const platform = usePlatform();
|
||||
const { platform } = usePlatform();
|
||||
const windowState = useWindowState();
|
||||
|
||||
useKeybindEventHandler(library?.uuid);
|
||||
|
@ -41,7 +42,7 @@ const Layout = () => {
|
|||
const layoutRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
initPlausible({
|
||||
platformType: platform.platform === 'tauri' ? 'desktop' : 'web',
|
||||
platformType: platform === 'tauri' ? 'desktop' : 'web',
|
||||
buildInfo: buildInfo?.data
|
||||
});
|
||||
|
||||
|
@ -50,6 +51,8 @@ const Layout = () => {
|
|||
usePlausiblePageViewMonitor({ currentPath: rawPath });
|
||||
usePlausiblePingMonitor({ currentPath: rawPath });
|
||||
|
||||
useRedirectToNewLocation();
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
plausibleEvent({
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import { Controller, get } from 'react-hook-form';
|
||||
import { useNavigate } from 'react-router';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
import {
|
||||
extractInfoRSPCError,
|
||||
|
@ -11,7 +10,7 @@ import {
|
|||
useZodForm
|
||||
} from '@sd/client';
|
||||
import { CheckBox, Dialog, ErrorMessage, Label, toast, useDialog, UseDialogProps, z } from '@sd/ui';
|
||||
import { getExplorerStore, useExplorerStore } from '~/app/$libraryId/Explorer/store';
|
||||
import { getExplorerStore } from '~/app/$libraryId/Explorer/store';
|
||||
import Accordion from '~/components/Accordion';
|
||||
import { useCallbackToWatchForm } from '~/hooks';
|
||||
import { usePlatform } from '~/util/Platform';
|
||||
|
@ -60,7 +59,6 @@ export const AddLocationDialog = ({
|
|||
const relinkLocation = useLibraryMutation('locations.relink');
|
||||
const listIndexerRules = useLibraryQuery(['locations.indexer_rules.list']);
|
||||
const addLocationToLibrary = useLibraryMutation('locations.addLibrary');
|
||||
const explorerStore = useExplorerStore();
|
||||
|
||||
// This is required because indexRules is undefined on first render
|
||||
const indexerRulesIds = useMemo(
|
||||
|
@ -123,14 +121,10 @@ export const AddLocationDialog = ({
|
|||
default:
|
||||
throw new Error('Unimplemented custom remote error handling');
|
||||
}
|
||||
if (shouldRedirect) {
|
||||
getExplorerStore().jobsToRedirect = [
|
||||
{ locationId: id },
|
||||
...explorerStore.jobsToRedirect
|
||||
];
|
||||
}
|
||||
|
||||
if (shouldRedirect) getExplorerStore().newLocationToRedirect = id;
|
||||
},
|
||||
[createLocation, relinkLocation, addLocationToLibrary, submitPlausibleEvent, explorerStore]
|
||||
[createLocation, relinkLocation, addLocationToLibrary, submitPlausibleEvent]
|
||||
);
|
||||
|
||||
const handleAddError = useCallback(
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Navigate, Outlet, useMatches, type RouteObject } from 'react-router-dom
|
|||
import { currentLibraryCache, useCachedLibraries, useInvalidateQuery } from '@sd/client';
|
||||
import { Dialogs, Toaster } from '@sd/ui';
|
||||
import { RouterErrorBoundary } from '~/ErrorFallback';
|
||||
import { useShouldRedirect, useTheme } from '~/hooks';
|
||||
import { useTheme } from '~/hooks';
|
||||
|
||||
import libraryRoutes from './$libraryId';
|
||||
import onboardingRoutes from './onboarding';
|
||||
|
@ -28,7 +28,6 @@ const Index = () => {
|
|||
const Wrapper = () => {
|
||||
useInvalidateQuery();
|
||||
useTheme();
|
||||
useShouldRedirect();
|
||||
|
||||
const rawPath = useRawRoutePath();
|
||||
|
||||
|
|
|
@ -23,4 +23,5 @@ export * from './useIsTextTruncated';
|
|||
export * from './useKeyMatcher';
|
||||
export * from './useKeyCopyCutPaste';
|
||||
export * from './useMouseNavigate';
|
||||
export * from './useShouldRedirect';
|
||||
export * from './useRedirectToNewLocation';
|
||||
export * from './useWindowState';
|
||||
|
|
36
interface/hooks/useRedirectToNewLocation.ts
Normal file
36
interface/hooks/useRedirectToNewLocation.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { useNavigate } from 'react-router';
|
||||
import { useLibraryQuery } from '@sd/client';
|
||||
import { getExplorerStore, useExplorerStore } from '~/app/$libraryId/Explorer/store';
|
||||
|
||||
import { LibraryIdParamsSchema } from '../app/route-schemas';
|
||||
import { useZodRouteParams } from './useZodRouteParams';
|
||||
|
||||
/**
|
||||
* When a user adds a location and checks the should redirect box,
|
||||
* this hook will redirect them to the location
|
||||
* once the indexer has been invoked
|
||||
*/
|
||||
|
||||
export const useRedirectToNewLocation = () => {
|
||||
const navigate = useNavigate();
|
||||
const { libraryId } = useZodRouteParams(LibraryIdParamsSchema);
|
||||
const { newLocationToRedirect: newLocation } = useExplorerStore();
|
||||
const { data: jobGroups } = useLibraryQuery(['jobs.reports'], {
|
||||
enabled: newLocation != null,
|
||||
refetchOnWindowFocus: false
|
||||
});
|
||||
|
||||
const hasIndexerJob = jobGroups
|
||||
?.flatMap((j) => j.jobs)
|
||||
.some(
|
||||
(j) =>
|
||||
j.name === 'indexer' &&
|
||||
j.metadata.location.id === newLocation &&
|
||||
(j.completed_task_count > 0 || j.completed_at != null)
|
||||
);
|
||||
|
||||
if (hasIndexerJob) {
|
||||
navigate(`/${libraryId}/location/${newLocation}`);
|
||||
getExplorerStore().newLocationToRedirect = null;
|
||||
}
|
||||
};
|
|
@ -1,58 +0,0 @@
|
|||
import { getExplorerStore, useExplorerStore } from "~/app/$libraryId/Explorer/store"
|
||||
import { useLibraryQuery} from '@sd/client';
|
||||
import { useCallback, useEffect } from "react";
|
||||
import { useNavigate } from "react-router";
|
||||
import { useZodRouteParams } from "../hooks/useZodRouteParams";
|
||||
import { LibraryIdParamsSchema } from "../app/route-schemas";
|
||||
/**
|
||||
* When a user adds a location and checks the should redirect box,
|
||||
* this hook will redirect them to the location
|
||||
* once the indexer has been invoked
|
||||
*/
|
||||
|
||||
export const useShouldRedirect = () => {
|
||||
const { jobsToRedirect } = useExplorerStore();
|
||||
const navigate = useNavigate();
|
||||
const { libraryId } = useZodRouteParams(LibraryIdParamsSchema);
|
||||
const jobGroups = useLibraryQuery(['jobs.reports'], {
|
||||
enabled: !!(jobsToRedirect.length > 0),
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
|
||||
//We loop all job groups and pull the first job that matches the location id from the job group
|
||||
|
||||
const pullMatchingJob = useCallback(() => {
|
||||
if (jobsToRedirect.length === 0) return;
|
||||
let jobFound
|
||||
if (jobGroups.data) {
|
||||
for (const jobGroup of jobGroups.data) {
|
||||
for (const job of jobGroup.jobs) {
|
||||
if (job.name === 'indexer') {
|
||||
const locationId = jobsToRedirect.find((l) => l.locationId === job.metadata.location.id)?.locationId
|
||||
if (job.metadata.location.id === locationId && job.completed_task_count > 0) {
|
||||
jobFound = job;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return jobFound
|
||||
}, [jobGroups.data, jobsToRedirect])
|
||||
|
||||
//Once we have a matching job, we redirect the user to the location
|
||||
|
||||
useEffect(() => {
|
||||
if (jobGroups.data) {
|
||||
const matchingJob = pullMatchingJob();
|
||||
if (matchingJob) {
|
||||
const locationId = jobsToRedirect.find((l) => l.locationId === matchingJob.metadata.location.id)?.locationId
|
||||
navigate(`/${libraryId}/location/${locationId}`);
|
||||
getExplorerStore().jobsToRedirect = jobsToRedirect.filter((l) => l.locationId !== matchingJob.metadata.location.id);
|
||||
}
|
||||
}
|
||||
}, [jobGroups.data, pullMatchingJob, navigate, libraryId, jobsToRedirect])
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in a new issue