Skip to content

Commit 2aca476

Browse files
Tanstack Devtools in web (#1049)
* update Tanstack packages + simple feature flagging system * format * cleanup unused exports --------- Co-authored-by: Brendan Allan <[email protected]>
1 parent 83bbacb commit 2aca476

File tree

5 files changed

+272
-62
lines changed

5 files changed

+272
-62
lines changed

apps/web/app/Layout/features.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Effect, Store, useStore } from "@tanstack/react-store";
2+
3+
const defaultFeatureFlags = {
4+
enableUploadProgress: false,
5+
};
6+
7+
type FeatureFlags = typeof defaultFeatureFlags;
8+
9+
function safeJsonFromLocalStorage(key: string) {
10+
try {
11+
return JSON.parse(localStorage.getItem(key) || "{}");
12+
} catch {
13+
return {};
14+
}
15+
}
16+
17+
const featureFlagsLocalStorageKey = "featureFlags";
18+
export const featureFlags = new Store<FeatureFlags>({
19+
...defaultFeatureFlags,
20+
...safeJsonFromLocalStorage(featureFlagsLocalStorageKey),
21+
});
22+
23+
new Effect({
24+
fn: () =>
25+
localStorage.setItem(
26+
featureFlagsLocalStorageKey,
27+
JSON.stringify(featureFlags.state),
28+
),
29+
deps: [featureFlags],
30+
}).mount();
31+
32+
export function useFeatureFlag(name: keyof FeatureFlags) {
33+
return useStore(featureFlags, (state) => state[name]);
34+
}
35+
36+
export function useFeatureFlags() {
37+
return useStore(featureFlags);
38+
}

apps/web/app/Layout/providers.tsx

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
"use client";
22

33
import { buildEnv } from "@cap/env";
4-
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4+
import { TanStackDevtools } from "@tanstack/react-devtools";
5+
import {
6+
QueryClient,
7+
QueryClientProvider,
8+
useQueryClient,
9+
} from "@tanstack/react-query";
10+
import { ReactQueryDevtoolsPanel } from "@tanstack/react-query-devtools";
511
import posthog from "posthog-js";
612
import { PostHogProvider as PHProvider } from "posthog-js/react";
713
import { type PropsWithChildren, useEffect, useState } from "react";
@@ -57,12 +63,65 @@ export function ReactQueryProvider({
5763
const [queryClient] = useState(() => new QueryClient());
5864

5965
return (
60-
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
66+
<QueryClientProvider client={queryClient}>
67+
{children}
68+
{process.env.NODE_ENV === "development" ? <Devtools /> : null}
69+
</QueryClientProvider>
6170
);
6271
}
6372

6473
import { SessionProvider as NASessionProvider } from "next-auth/react";
74+
import { featureFlags, useFeatureFlags } from "./features";
6575

6676
export function SessionProvider({ children }: PropsWithChildren) {
6777
return <NASessionProvider>{children}</NASessionProvider>;
6878
}
79+
80+
export function Devtools() {
81+
const client = useQueryClient();
82+
83+
return (
84+
<TanStackDevtools
85+
config={{
86+
// TODO: This doesn't seem to be working?
87+
position: "top-left",
88+
}}
89+
plugins={[
90+
{
91+
name: "Cap",
92+
render: <CapDevtools />,
93+
},
94+
{
95+
name: "Tanstack Query",
96+
render: <ReactQueryDevtoolsPanel client={client} />,
97+
},
98+
]}
99+
/>
100+
);
101+
}
102+
103+
function CapDevtools() {
104+
const flags = useFeatureFlags();
105+
106+
return (
107+
<div className="flex flex-col space-y-4 p-4">
108+
<h1 className="text-2xl font-semibold">Cap Devtools</h1>
109+
<div className="space-y-2">
110+
<h1 className="text-lg font-semibold">Features</h1>
111+
<label className="flex items-center space-x-2">
112+
<input
113+
type="checkbox"
114+
checked={flags.enableUploadProgress}
115+
onChange={(e) =>
116+
featureFlags.setState((prev) => ({
117+
...prev,
118+
enableUploadProgress: e.target.checked,
119+
}))
120+
}
121+
/>
122+
<span>Enable Upload Progress UI</span>
123+
</label>
124+
</div>
125+
</div>
126+
);
127+
}

apps/web/app/s/[videoId]/_components/ProgressCircle.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import type { Video } from "@cap/web-domain";
44
import clsx from "clsx";
55
import { Effect, Option } from "effect";
6+
import { useFeatureFlag } from "@/app/Layout/features";
67
import { useEffectQuery } from "@/lib/EffectRuntime";
78
import { withRpc } from "@/lib/Rpcs";
89

@@ -22,14 +23,8 @@ const MINUTE = 60 * SECOND;
2223
const HOUR = 60 * 60 * SECOND;
2324
const DAY = 24 * HOUR;
2425

25-
// TODO: Remove this once we are more confident in the feature
26-
// localStorage.setItem("betaUploadProgress", "true");
27-
const enableBetaUploadProgress =
28-
"localStorage" in globalThis
29-
? localStorage.getItem("betaUploadProgress") === "true"
30-
: false;
31-
3226
export function useUploadProgress(videoId: Video.VideoId, enabledRaw: boolean) {
27+
const enableBetaUploadProgress = useFeatureFlag("enableUploadProgress");
3328
const enabled = enableBetaUploadProgress ? enabledRaw : false;
3429

3530
const query = useEffectQuery({

apps/web/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,10 @@
5858
"@rive-app/react-canvas": "^4.18.7",
5959
"@stripe/stripe-js": "^3.3.0",
6060
"@t3-oss/env-nextjs": "^0.12.0",
61-
"@tanstack/react-query": "^5.75.4",
62-
"@tanstack/react-store": "^0.5.5",
63-
"@tanstack/store": "^0.5.5",
61+
"@tanstack/react-devtools": "^0.7.0",
62+
"@tanstack/react-query": "^5.90.1",
63+
"@tanstack/react-query-devtools": "^5.90.1",
64+
"@tanstack/react-store": "^0.7.7",
6465
"@ts-rest/core": "^3.52.1",
6566
"@uidotdev/usehooks": "^2.4.1",
6667
"@virtual-grid/react": "^2.0.3",

0 commit comments

Comments
 (0)