diff --git a/packages/web/src/app/[domain]/browse/hooks/useBrowseParams.ts b/packages/web/src/app/[domain]/browse/hooks/useBrowseParams.ts
index b671d3fc..d7917f72 100644
--- a/packages/web/src/app/[domain]/browse/hooks/useBrowseParams.ts
+++ b/packages/web/src/app/[domain]/browse/hooks/useBrowseParams.ts
@@ -1,48 +1,18 @@
-'use client';
-
import { usePathname } from "next/navigation";
+import { useMemo } from "react";
+import { getBrowseParamsFromPathParam } from "./utils";
export const useBrowseParams = () => {
const pathname = usePathname();
- const startIndex = pathname.indexOf('/browse/');
- if (startIndex === -1) {
- throw new Error(`Invalid browse pathname: "${pathname}" - expected to contain "/browse/"`);
- }
-
- const rawPath = pathname.substring(startIndex + '/browse/'.length);
- const sentinalIndex = rawPath.search(/\/-\/(tree|blob)\//);
- if (sentinalIndex === -1) {
- throw new Error(`Invalid browse pathname: "${pathname}" - expected to contain "/-/(tree|blob)/" pattern`);
- }
-
- const repoAndRevisionName = rawPath.substring(0, sentinalIndex).split('@');
- const repoName = repoAndRevisionName[0];
- const revisionName = repoAndRevisionName.length > 1 ? repoAndRevisionName[1] : undefined;
-
- const { path, pathType } = ((): { path: string, pathType: 'tree' | 'blob' } => {
- const path = rawPath.substring(sentinalIndex + '/-/'.length);
- const pathType = path.startsWith('tree/') ? 'tree' : 'blob';
-
- // @note: decodedURIComponent is needed here incase the path contains a space.
- switch (pathType) {
- case 'tree':
- return {
- path: decodeURIComponent(path.substring('tree/'.length)),
- pathType,
- };
- case 'blob':
- return {
- path: decodeURIComponent(path.substring('blob/'.length)),
- pathType,
- };
+ return useMemo(() => {
+ const startIndex = pathname.indexOf('/browse/');
+ if (startIndex === -1) {
+ throw new Error(`Invalid browse pathname: "${pathname}" - expected to contain "/browse/"`);
}
- })();
- return {
- repoName,
- revisionName,
- path,
- pathType,
- }
-}
\ No newline at end of file
+ const rawPath = pathname.substring(startIndex + '/browse/'.length);
+ return getBrowseParamsFromPathParam(rawPath);
+ }, [pathname]);
+}
+
diff --git a/packages/web/src/app/[domain]/browse/hooks/utils.ts b/packages/web/src/app/[domain]/browse/hooks/utils.ts
new file mode 100644
index 00000000..a0e423be
--- /dev/null
+++ b/packages/web/src/app/[domain]/browse/hooks/utils.ts
@@ -0,0 +1,37 @@
+
+export const getBrowseParamsFromPathParam = (pathParam: string) => {
+ const sentinalIndex = pathParam.search(/\/-\/(tree|blob)\//);
+ if (sentinalIndex === -1) {
+ throw new Error(`Invalid browse pathname: "${pathParam}" - expected to contain "/-/(tree|blob)/" pattern`);
+ }
+
+ const repoAndRevisionName = pathParam.substring(0, sentinalIndex).split('@');
+ const repoName = repoAndRevisionName[0];
+ const revisionName = repoAndRevisionName.length > 1 ? repoAndRevisionName[1] : undefined;
+
+ const { path, pathType } = ((): { path: string, pathType: 'tree' | 'blob' } => {
+ const path = pathParam.substring(sentinalIndex + '/-/'.length);
+ const pathType = path.startsWith('tree/') ? 'tree' : 'blob';
+
+ // @note: decodedURIComponent is needed here incase the path contains a space.
+ switch (pathType) {
+ case 'tree':
+ return {
+ path: decodeURIComponent(path.substring('tree/'.length)),
+ pathType,
+ };
+ case 'blob':
+ return {
+ path: decodeURIComponent(path.substring('blob/'.length)),
+ pathType,
+ };
+ }
+ })();
+
+ return {
+ repoName,
+ revisionName,
+ path,
+ pathType,
+ }
+}
\ No newline at end of file
diff --git a/packages/web/src/app/[domain]/components/pathHeader.tsx b/packages/web/src/app/[domain]/components/pathHeader.tsx
index d4fd1e74..5118392f 100644
--- a/packages/web/src/app/[domain]/components/pathHeader.tsx
+++ b/packages/web/src/app/[domain]/components/pathHeader.tsx
@@ -8,8 +8,6 @@ import { useBrowseNavigation } from "../browse/hooks/useBrowseNavigation";
import { Copy, CheckCircle2, ChevronRight, MoreHorizontal } from "lucide-react";
import { useCallback, useState, useMemo, useRef, useEffect } from "react";
import { useToast } from "@/components/hooks/use-toast";
-import { usePrefetchFolderContents } from "@/hooks/usePrefetchFolderContents";
-import { usePrefetchFileSource } from "@/hooks/usePrefetchFileSource";
import {
DropdownMenu,
DropdownMenuContent,
@@ -62,8 +60,6 @@ export const PathHeader = ({
const { navigateToPath } = useBrowseNavigation();
const { toast } = useToast();
const [copied, setCopied] = useState(false);
- const { prefetchFolderContents } = usePrefetchFolderContents();
- const { prefetchFileSource } = usePrefetchFileSource();
const containerRef = useRef(null);
const breadcrumbsRef = useRef(null);
@@ -188,19 +184,6 @@ export const PathHeader = ({
});
}, [repo.name, branchDisplayName, navigateToPath, pathType]);
- const onBreadcrumbMouseEnter = useCallback((segment: BreadcrumbSegment) => {
- if (segment.isLastSegment && pathType === 'blob') {
- prefetchFileSource(repo.name, branchDisplayName ?? 'HEAD', segment.fullPath);
- } else {
- prefetchFolderContents(repo.name, branchDisplayName ?? 'HEAD', segment.fullPath);
- }
- }, [
- repo.name,
- branchDisplayName,
- prefetchFolderContents,
- pathType,
- prefetchFileSource,
- ]);
const renderSegmentWithHighlight = (segment: BreadcrumbSegment) => {
if (!segment.highlightRange) {
@@ -274,7 +257,6 @@ export const PathHeader = ({
onBreadcrumbClick(segment)}
- onMouseEnter={() => onBreadcrumbMouseEnter(segment)}
className="font-mono text-sm cursor-pointer"
>
{renderSegmentWithHighlight(segment)}
@@ -292,7 +274,6 @@ export const PathHeader = ({
"font-mono text-sm truncate cursor-pointer hover:underline",
)}
onClick={() => onBreadcrumbClick(segment)}
- onMouseEnter={() => onBreadcrumbMouseEnter(segment)}
>
{renderSegmentWithHighlight(segment)}
diff --git a/packages/web/src/ee/features/codeNav/components/exploreMenu/referenceList.tsx b/packages/web/src/ee/features/codeNav/components/exploreMenu/referenceList.tsx
index b55edc3f..0458ecbc 100644
--- a/packages/web/src/ee/features/codeNav/components/exploreMenu/referenceList.tsx
+++ b/packages/web/src/ee/features/codeNav/components/exploreMenu/referenceList.tsx
@@ -8,7 +8,6 @@ import { RepositoryInfo, SourceRange } from "@/features/search/types";
import { useMemo, useRef } from "react";
import useCaptureEvent from "@/hooks/useCaptureEvent";
import { useVirtualizer } from "@tanstack/react-virtual";
-import { usePrefetchFileSource } from "@/hooks/usePrefetchFileSource";
interface ReferenceListProps {
data: FindRelatedSymbolsResponse;
@@ -31,7 +30,6 @@ export const ReferenceList = ({
const { navigateToPath } = useBrowseNavigation();
const captureEvent = useCaptureEvent();
- const { prefetchFileSource } = usePrefetchFileSource();
// Virtualization setup
const parentRef = useRef(null);
@@ -120,13 +118,6 @@ export const ReferenceList = ({
highlightRange: match.range,
})
}}
- // @note: We prefetch the file source when the user hovers over a file.
- // This is to try and mitigate having a loading spinner appear when
- // the user clicks on a file to open it.
- // @see: /browse/[...path]/page.tsx
- onMouseEnter={() => {
- prefetchFileSource(file.repository, revisionName, file.fileName);
- }}
/>
))}
@@ -144,7 +135,6 @@ interface ReferenceListItemProps {
range: SourceRange;
language: string;
onClick: () => void;
- onMouseEnter: () => void;
}
const ReferenceListItem = ({
@@ -152,7 +142,6 @@ const ReferenceListItem = ({
range,
language,
onClick,
- onMouseEnter,
}: ReferenceListItemProps) => {
const highlightRanges = useMemo(() => [range], [range]);
@@ -160,7 +149,6 @@ const ReferenceListItem = ({
void,
- onMouseEnter: () => void,
parentRef: React.RefObject,
}) => {
const ref = useRef(null);
@@ -67,7 +65,6 @@ export const FileTreeItemComponent = ({
}
}}
onClick={onClick}
- onMouseEnter={onMouseEnter}
>
& {
@@ -44,7 +43,6 @@ export const PureFileTreePanel = ({ tree: _tree, path }: PureFileTreePanelProps)
const scrollAreaRef = useRef(null);
const { navigateToPath } = useBrowseNavigation();
const { repoName, revisionName } = useBrowseParams();
- const { prefetchFileSource } = usePrefetchFileSource();
// @note: When `_tree` changes, it indicates that a new tree has been loaded.
// In that case, we need to rebuild the collapsable tree.
@@ -89,18 +87,6 @@ export const PureFileTreePanel = ({ tree: _tree, path }: PureFileTreePanelProps)
}
}, [setIsCollapsed, navigateToPath, repoName, revisionName]);
- // @note: We prefetch the file source when the user hovers over a file.
- // This is to try and mitigate having a loading spinner appear when
- // the user clicks on a file to open it.
- // @see: /browse/[...path]/page.tsx
- const onNodeMouseEnter = useCallback((node: FileTreeNode) => {
- if (node.type !== 'blob') {
- return;
- }
-
- prefetchFileSource(repoName, revisionName ?? 'HEAD', node.path);
- }, [prefetchFileSource, repoName, revisionName]);
-
const renderTree = useCallback((nodes: FileTreeNode, depth = 0): React.ReactNode => {
return (
<>
@@ -115,7 +101,6 @@ export const PureFileTreePanel = ({ tree: _tree, path }: PureFileTreePanelProps)
isCollapsed={node.isCollapsed}
isCollapseChevronVisible={node.type === 'tree'}
onClick={() => onNodeClicked(node)}
- onMouseEnter={() => onNodeMouseEnter(node)}
parentRef={scrollAreaRef}
/>
{node.children.length > 0 && !node.isCollapsed && renderTree(node, depth + 1)}
@@ -124,7 +109,7 @@ export const PureFileTreePanel = ({ tree: _tree, path }: PureFileTreePanelProps)
})}
>
);
- }, [path, onNodeClicked, onNodeMouseEnter]);
+ }, [path, onNodeClicked]);
const renderedTree = useMemo(() => renderTree(tree), [tree, renderTree]);
diff --git a/packages/web/src/hooks/usePrefetchFileSource.ts b/packages/web/src/hooks/usePrefetchFileSource.ts
deleted file mode 100644
index de9cce34..00000000
--- a/packages/web/src/hooks/usePrefetchFileSource.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-'use client';
-
-import { useQueryClient } from "@tanstack/react-query";
-import { useDomain } from "./useDomain";
-import { unwrapServiceError } from "@/lib/utils";
-import { getFileSource } from "@/features/search/fileSourceApi";
-import { useDebounceCallback } from "usehooks-ts";
-
-interface UsePrefetchFileSourceProps {
- debounceDelay?: number;
- staleTime?: number;
-}
-
-export const usePrefetchFileSource = ({
- debounceDelay = 200,
- staleTime = 5 * 60 * 1000, // 5 minutes
-}: UsePrefetchFileSourceProps = {}) => {
- const queryClient = useQueryClient();
- const domain = useDomain();
-
- const prefetchFileSource = useDebounceCallback((repoName: string, revisionName: string, path: string) => {
- queryClient.prefetchQuery({
- queryKey: ['fileSource', repoName, revisionName, path, domain],
- queryFn: () => unwrapServiceError(getFileSource({
- fileName: path,
- repository: repoName,
- branch: revisionName,
- }, domain)),
- staleTime,
- });
- }, debounceDelay);
-
- return { prefetchFileSource };
-}
\ No newline at end of file
diff --git a/packages/web/src/hooks/usePrefetchFolderContents.ts b/packages/web/src/hooks/usePrefetchFolderContents.ts
deleted file mode 100644
index e135cb7a..00000000
--- a/packages/web/src/hooks/usePrefetchFolderContents.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-'use client';
-
-import { useQueryClient } from "@tanstack/react-query";
-import { useDomain } from "./useDomain";
-import { unwrapServiceError } from "@/lib/utils";
-import { getFolderContents } from "@/features/fileTree/actions";
-import { useDebounceCallback } from "usehooks-ts";
-
-interface UsePrefetchFolderContentsProps {
- debounceDelay?: number;
- staleTime?: number;
-}
-
-export const usePrefetchFolderContents = ({
- debounceDelay = 200,
- staleTime = 5 * 60 * 1000, // 5 minutes
-}: UsePrefetchFolderContentsProps = {}) => {
- const queryClient = useQueryClient();
- const domain = useDomain();
-
- const prefetchFolderContents = useDebounceCallback((repoName: string, revisionName: string, path: string) => {
- queryClient.prefetchQuery({
- queryKey: ['tree', repoName, revisionName, path, domain],
- queryFn: () => unwrapServiceError(
- getFolderContents({
- repoName,
- revisionName,
- path,
- }, domain)
- ),
- staleTime,
- });
- }, debounceDelay);
-
- return { prefetchFolderContents };
-}
\ No newline at end of file