diff options
| author | MohamedBassem <me@mbassem.com> | 2024-03-05 13:52:19 +0000 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-03-05 13:52:19 +0000 |
| commit | 4ddfd0e322d79fb1b3b6603a252c0f3fa5a98270 (patch) | |
| tree | 1e9ad6be760314b6561e9aceb02656911f2f2455 /packages | |
| parent | 8a46ecb7373d6c5e7300861169ea51a7917cd2b4 (diff) | |
| download | karakeep-4ddfd0e322d79fb1b3b6603a252c0f3fa5a98270.tar.zst | |
extension: Use react-query and trpc in the extension
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/browser-extension/package.json | 7 | ||||
| -rw-r--r-- | packages/browser-extension/src/App.tsx | 11 | ||||
| -rw-r--r-- | packages/browser-extension/src/OptionsPage.tsx | 6 | ||||
| -rw-r--r-- | packages/browser-extension/src/SavePage.tsx | 83 | ||||
| -rw-r--r-- | packages/browser-extension/src/main.tsx | 5 | ||||
| -rw-r--r-- | packages/browser-extension/src/providers.tsx | 30 | ||||
| -rw-r--r-- | packages/browser-extension/src/utils/providers.tsx | 40 | ||||
| -rw-r--r-- | packages/browser-extension/src/utils/settings.ts (renamed from packages/browser-extension/src/settings.ts) | 0 | ||||
| -rw-r--r-- | packages/browser-extension/src/utils/trpc.ts | 4 | ||||
| -rw-r--r-- | packages/web/package.json | 1 |
10 files changed, 134 insertions, 53 deletions
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 ( <div className="flex flex-col space-y-2"> - <SavePage settings={settings} /> + <SavePage /> <hr /> <div className="flex justify-end space-x-3"> + {process.env.NODE_ENV == "development" && ( + <button onClick={() => navigate(0)}> + <RefreshCw className="w-4" /> + </button> + )} <button onClick={() => navigate("/options")}> <Settings className="w-4" /> </button> 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() { <label className="m-auto h-full">Server Address</label> <input ref={addressRef} - defaultValue={settings.address || "https://demo.hoarder.app"} + value={settings.address || "https://demo.hoarder.app"} className="h-8 flex-1 rounded-lg border border-gray-300 p-2" /> </div> @@ -46,7 +46,7 @@ export default function OptionsPage() { <label className="m-auto h-full">API Key</label> <input ref={apiKeyRef} - defaultValue={settings.apiKey} + value={settings.apiKey} className="h-8 flex-1 rounded-lg border border-gray-300 p-2" /> </div> 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<string | undefined>(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 ( - <div className="m-auto"> - <Spinner /> - </div> - ); - } + runSave(); + }, [createBookmark]); - if (error) { - return <div className="text-red-500">{error} ...</div>; + switch (status) { + case "error": { + return <div className="text-red-500">{error}</div>; + } + case "success": { + return <div className="m-auto text-lg">Bookmark Saved</div>; + } + case "pending": { + return ( + <div className="m-auto"> + <Spinner /> + </div> + ); + } + case "idle": { + return ( + <div className="m-auto"> + <Spinner /> + </div> + ); + } } - - return <div className="m-auto text-lg">Bookmark Saved</div>; } 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( <React.StrictMode> <div className="w-96 p-4"> - <RouterProvider router={router} /> + <Providers> + <RouterProvider router={router} /> + </Providers> </div> </React.StrictMode>, ); 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 ( + <trpc.Provider client={trpcClient} queryClient={queryClient}> + <QueryClientProvider client={queryClient}> + {/* Your app here */} + </QueryClientProvider> + </trpc.Provider> + ); +} 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 ( + <api.Provider client={trpcClient} queryClient={queryClient}> + <QueryClientProvider client={queryClient}>{children}</QueryClientProvider> + </api.Provider> + ); +} diff --git a/packages/browser-extension/src/settings.ts b/packages/browser-extension/src/utils/settings.ts index ee7f0722..ee7f0722 100644 --- a/packages/browser-extension/src/settings.ts +++ b/packages/browser-extension/src/utils/settings.ts 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<AppRouter>(); 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", |
