Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion hooks/useSandboxFileContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useCallback, useState } from "react";
import { useMutation } from "@tanstack/react-query";
import { usePrivy } from "@privy-io/react-auth";
import { getFileContents } from "@/lib/sandboxes/getFileContents";
import { useAccountOverride } from "@/providers/AccountOverrideProvider";

interface UseSandboxFileContentReturn {
selectedPath: string | undefined;
Expand All @@ -14,6 +15,7 @@ interface UseSandboxFileContentReturn {

export default function useSandboxFileContent(): UseSandboxFileContentReturn {
const { getAccessToken } = usePrivy();
const { accountIdOverride } = useAccountOverride();
const [selectedPath, setSelectedPath] = useState<string>();

const mutation = useMutation({
Expand All @@ -23,7 +25,7 @@ export default function useSandboxFileContent(): UseSandboxFileContentReturn {
throw new Error("Please sign in to view file contents");
}

return getFileContents(accessToken, path);
return getFileContents(accessToken, path, accountIdOverride);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reset file preview state when override account changes

After wiring accountIdOverride into getFileContents, this hook still retains prior selectedPath and mutation data across account switches, so changing override (or clearing it) can leave SandboxFilePreview showing content fetched for the previous account until another file is clicked. Since this path is now account-scoped, clear/reset mutation state on override change (or key mutation state by account) to prevent stale cross-account previews.

Useful? React with 👍 / 👎.

},
});

Expand Down
6 changes: 4 additions & 2 deletions hooks/useSandboxes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { usePrivy } from "@privy-io/react-auth";
import { getSandboxes } from "@/lib/sandboxes/getSandboxes";
import { convertFileTreeEntries } from "@/lib/sandboxes/convertFileTreeEntries";
import getSubtreeAtPath from "@/lib/sandboxes/getSubtreeAtPath";
import { useAccountOverride } from "@/providers/AccountOverrideProvider";
import type { Sandbox } from "@/lib/sandboxes/createSandbox";
import type { FileNode } from "@/lib/sandboxes/parseFileTree";

Expand All @@ -17,15 +18,16 @@ interface UseSandboxesReturn {

export default function useSandboxes(): UseSandboxesReturn {
const { getAccessToken, authenticated } = usePrivy();
const { accountIdOverride } = useAccountOverride();

const query = useQuery({
queryKey: ["sandboxes"],
queryKey: ["sandboxes", accountIdOverride],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Delay sandbox query until account override is resolved

This query now keys on accountIdOverride, but it is still enabled whenever authenticated is true, so /files?email=... will fire an initial request with accountIdOverride === null while AccountOverrideProvider is still resolving the override. In that window, the page can render the signed-in user’s file tree before re-fetching the override account, which shows incorrect data and can expose the wrong account context briefly; gate the query on override-resolution state (or provider loading state) to avoid the initial null-account fetch.

Useful? React with 👍 / 👎.

queryFn: async () => {
const accessToken = await getAccessToken();
if (!accessToken) {
throw new Error("Please sign in to view sandboxes");
}
return getSandboxes(accessToken);
return getSandboxes(accessToken, accountIdOverride);
},
enabled: authenticated,
});
Expand Down
20 changes: 12 additions & 8 deletions lib/sandboxes/getFileContents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,20 @@ interface FileContentsResult {
export async function getFileContents(
accessToken: string,
path: string,
accountId?: string | null,
): Promise<FileContentsResult> {
const response = await fetch(
`${getClientApiBaseUrl()}/api/sandboxes/file?path=${encodeURIComponent(path)}`,
{
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
},
const url = new URL(`${getClientApiBaseUrl()}/api/sandboxes/file`);
url.searchParams.set("path", path);
if (accountId) {
url.searchParams.set("account_id", accountId);
}

const response = await fetch(url.toString(), {
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
},
);
});

const data: GetFileContentsResponse = await response.json();

Expand Down
10 changes: 8 additions & 2 deletions lib/sandboxes/getSandboxes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ export interface GetSandboxesResult {
}

export async function getSandboxes(
accessToken: string
accessToken: string,
accountId?: string | null,
): Promise<GetSandboxesResult> {
const response = await fetch(`${getClientApiBaseUrl()}/api/sandboxes`, {
const url = new URL(`${getClientApiBaseUrl()}/api/sandboxes`);
if (accountId) {
url.searchParams.set("account_id", accountId);
}

const response = await fetch(url.toString(), {
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
Expand Down
Loading