[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:
Vítor Vasconcellos 2023-10-21 12:02:54 -03:00 committed by GitHub
parent e51a58fe28
commit ce568981c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 53 additions and 79 deletions

View file

@ -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,

View file

@ -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({

View file

@ -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(

View file

@ -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();

View file

@ -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';

View 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;
}
};

View file

@ -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])
}