From 4ddfd0e322d79fb1b3b6603a252c0f3fa5a98270 Mon Sep 17 00:00:00 2001 From: MohamedBassem Date: Tue, 5 Mar 2024 13:52:19 +0000 Subject: extension: Use react-query and trpc in the extension --- packages/browser-extension/package.json | 7 ++ packages/browser-extension/src/App.tsx | 11 ++- packages/browser-extension/src/OptionsPage.tsx | 6 +- packages/browser-extension/src/SavePage.tsx | 83 ++++++++++------------ packages/browser-extension/src/main.tsx | 5 +- packages/browser-extension/src/providers.tsx | 30 ++++++++ packages/browser-extension/src/settings.ts | 13 ---- packages/browser-extension/src/utils/providers.tsx | 40 +++++++++++ packages/browser-extension/src/utils/settings.ts | 13 ++++ packages/browser-extension/src/utils/trpc.ts | 4 ++ packages/web/package.json | 1 + 11 files changed, 147 insertions(+), 66 deletions(-) create mode 100644 packages/browser-extension/src/providers.tsx delete mode 100644 packages/browser-extension/src/settings.ts create mode 100644 packages/browser-extension/src/utils/providers.tsx create mode 100644 packages/browser-extension/src/utils/settings.ts create mode 100644 packages/browser-extension/src/utils/trpc.ts (limited to 'packages') diff --git a/packages/browser-extension/package.json b/packages/browser-extension/package.json index 297ba18e..b205a257 100644 --- a/packages/browser-extension/package.json +++ b/packages/browser-extension/package.json @@ -10,12 +10,19 @@ "preview": "vite preview" }, "dependencies": { + "@hoarder/trpc": "0.1.0", + "@tanstack/react-query": "^5.24.8", + "@trpc/client": "11.0.0-next-beta.308", + "@trpc/next": "11.0.0-next-beta.308", + "@trpc/react-query": "11.0.0-next-beta.308", + "@trpc/server": "11.0.0-next-beta.308", "@types/chrome": "^0.0.260", "lucide-react": "^0.330.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.22.0", "use-chrome-storage": "^1.2.2", + "superjson": "^2.2.1", "zod": "^3.22.4" }, "devDependencies": { diff --git a/packages/browser-extension/src/App.tsx b/packages/browser-extension/src/App.tsx index 1044363b..279c8b7a 100644 --- a/packages/browser-extension/src/App.tsx +++ b/packages/browser-extension/src/App.tsx @@ -1,6 +1,6 @@ -import { Settings, X } from "lucide-react"; +import { RefreshCw, Settings, X } from "lucide-react"; import SavePage from "./SavePage"; -import usePluginSettings from "./settings"; +import usePluginSettings from "./utils/settings"; import { useNavigate } from "react-router-dom"; function App() { @@ -18,9 +18,14 @@ function App() { return (
- +
+ {process.env.NODE_ENV == "development" && ( + + )} diff --git a/packages/browser-extension/src/OptionsPage.tsx b/packages/browser-extension/src/OptionsPage.tsx index 11a1a76d..5cb4a45b 100644 --- a/packages/browser-extension/src/OptionsPage.tsx +++ b/packages/browser-extension/src/OptionsPage.tsx @@ -1,5 +1,5 @@ import { useRef, useState } from "react"; -import usePluginSettings from "./settings"; +import usePluginSettings from "./utils/settings"; export default function OptionsPage() { const [settings, setSettings, _1, _2, _3] = usePluginSettings(); @@ -38,7 +38,7 @@ export default function OptionsPage() {
@@ -46,7 +46,7 @@ export default function OptionsPage() {
diff --git a/packages/browser-extension/src/SavePage.tsx b/packages/browser-extension/src/SavePage.tsx index 955cc7cb..003d4025 100644 --- a/packages/browser-extension/src/SavePage.tsx +++ b/packages/browser-extension/src/SavePage.tsx @@ -1,13 +1,19 @@ import { useEffect, useState } from "react"; -import { Settings } from "./settings"; import Spinner from "./Spinner"; +import { api } from "./utils/trpc"; -export default function SavePage({ settings }: { settings: Settings }) { - const [loading, setLoading] = useState(true); +export default function SavePage() { const [error, setError] = useState(undefined); + const { mutate: createBookmark, status } = + api.bookmarks.createBookmark.useMutation({ + onError: (e) => { + setError("Something went wrong: " + e.message); + }, + }); + useEffect(() => { - async function runFetch() { + async function runSave() { let currentUrl; const [currentTab] = await chrome.tabs.query({ active: true, @@ -17,52 +23,37 @@ export default function SavePage({ settings }: { settings: Settings }) { currentUrl = currentTab.url; } else { setError("Couldn't find the URL of the current tab"); - setLoading(false); return; } - try { - const resp = await fetch( - `${settings.address}/api/trpc/bookmarks.createBookmark`, - { - method: "POST", - headers: { - Authorization: `Bearer ${settings.apiKey}`, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - json: { - type: "link", - url: currentUrl, - }, - }), - }, - ); - if (!resp.ok) { - setError( - "Something went wrong: " + JSON.stringify(await resp.json()), - ); - } - } catch (e) { - setError("Message: " + (e as Error).message); - } - - setLoading(false); + createBookmark({ + type: "link", + url: currentUrl, + }); } - runFetch(); - }, [settings]); - - if (loading) { - return ( -
- -
- ); - } + runSave(); + }, [createBookmark]); - if (error) { - return
{error} ...
; + switch (status) { + case "error": { + return
{error}
; + } + case "success": { + return
Bookmark Saved
; + } + case "pending": { + return ( +
+ +
+ ); + } + case "idle": { + return ( +
+ +
+ ); + } } - - return
Bookmark Saved
; } diff --git a/packages/browser-extension/src/main.tsx b/packages/browser-extension/src/main.tsx index c4f5a2d9..3e269982 100644 --- a/packages/browser-extension/src/main.tsx +++ b/packages/browser-extension/src/main.tsx @@ -5,6 +5,7 @@ import "./index.css"; import { createHashRouter, RouterProvider } from "react-router-dom"; import OptionsPage from "./OptionsPage.tsx"; import NotConfiguredPage from "./NotConfiguredPage.tsx"; +import { Providers } from "./utils/providers.tsx"; const router = createHashRouter([ { @@ -24,7 +25,9 @@ const router = createHashRouter([ ReactDOM.createRoot(document.getElementById("root")!).render(
- + + +
, ); diff --git a/packages/browser-extension/src/providers.tsx b/packages/browser-extension/src/providers.tsx new file mode 100644 index 00000000..a055f3d1 --- /dev/null +++ b/packages/browser-extension/src/providers.tsx @@ -0,0 +1,30 @@ +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { httpBatchLink } from "@trpc/client"; +import React, { useState } from "react"; +import { trpc } from "./trpc"; + +export function App() { + const [queryClient] = useState(() => new QueryClient()); + const [trpcClient] = useState(() => + trpc.createClient({ + links: [ + httpBatchLink({ + url: "http://localhost:3000/trpc", + // You can pass any HTTP headers you wish here + async headers() { + return { + // authorization: getAuthCookie(), + }; + }, + }), + ], + }), + ); + return ( + + + {/* Your app here */} + + + ); +} diff --git a/packages/browser-extension/src/settings.ts b/packages/browser-extension/src/settings.ts deleted file mode 100644 index ee7f0722..00000000 --- a/packages/browser-extension/src/settings.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { useChromeStorageSync } from "use-chrome-storage"; - -export type Settings = { - apiKey: string; - address: string; -}; - -export default function usePluginSettings() { - return useChromeStorageSync("settings", { - apiKey: "", - address: "", - } as Settings); -} diff --git a/packages/browser-extension/src/utils/providers.tsx b/packages/browser-extension/src/utils/providers.tsx new file mode 100644 index 00000000..c11331f0 --- /dev/null +++ b/packages/browser-extension/src/utils/providers.tsx @@ -0,0 +1,40 @@ +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { httpBatchLink } from "@trpc/client"; +import { useCallback, useEffect, useState } from "react"; +import { api } from "./trpc"; +import usePluginSettings from "./settings"; +import superjson from "superjson"; + +export function Providers({ children }: { children: React.ReactNode }) { + const [settings] = usePluginSettings(); + const [queryClient] = useState(() => new QueryClient()); + + const getTrpcClient = useCallback(() => { + console.log(settings); + return api.createClient({ + links: [ + httpBatchLink({ + url: `${settings.address}/api/trpc`, + async headers() { + return { + Authorization: `Bearer ${settings.apiKey}`, + }; + }, + transformer: superjson, + }), + ], + }); + }, [settings]); + + const [trpcClient, setTrpcClient] = useState(getTrpcClient()); + + useEffect(() => { + setTrpcClient(getTrpcClient()); + }, [getTrpcClient]); + + return ( + + {children} + + ); +} diff --git a/packages/browser-extension/src/utils/settings.ts b/packages/browser-extension/src/utils/settings.ts new file mode 100644 index 00000000..ee7f0722 --- /dev/null +++ b/packages/browser-extension/src/utils/settings.ts @@ -0,0 +1,13 @@ +import { useChromeStorageSync } from "use-chrome-storage"; + +export type Settings = { + apiKey: string; + address: string; +}; + +export default function usePluginSettings() { + return useChromeStorageSync("settings", { + apiKey: "", + address: "", + } as Settings); +} diff --git a/packages/browser-extension/src/utils/trpc.ts b/packages/browser-extension/src/utils/trpc.ts new file mode 100644 index 00000000..da21a55a --- /dev/null +++ b/packages/browser-extension/src/utils/trpc.ts @@ -0,0 +1,4 @@ +import { createTRPCReact } from "@trpc/react-query"; +import type { AppRouter } from "@hoarder/trpc/routers/_app"; + +export const api = createTRPCReact(); diff --git a/packages/web/package.json b/packages/web/package.json index e0c9d407..e8dfcbe1 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -36,6 +36,7 @@ "@trpc/next": "11.0.0-next-beta.304", "@trpc/react-query": "^11.0.0-next-beta.304", "@trpc/server": "11.0.0-next-beta.304", + "bcrypt": "^5.1.1", "better-sqlite3": "^9.4.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", -- cgit v1.2.3-70-g09d2