diff options
Diffstat (limited to 'packages/browser-extension')
| -rw-r--r-- | packages/browser-extension/.eslintrc.cjs | 18 | ||||
| -rw-r--r-- | packages/browser-extension/manifest.json | 5 | ||||
| -rw-r--r-- | packages/browser-extension/package.json | 9 | ||||
| -rw-r--r-- | packages/browser-extension/src/App.tsx | 29 | ||||
| -rw-r--r-- | packages/browser-extension/src/SavePage.tsx | 40 | ||||
| -rw-r--r-- | packages/browser-extension/src/SettingsPage.tsx | 53 | ||||
| -rw-r--r-- | packages/browser-extension/src/main.tsx | 33 | ||||
| -rw-r--r-- | packages/browser-extension/src/settings.ts | 13 |
8 files changed, 170 insertions, 30 deletions
diff --git a/packages/browser-extension/.eslintrc.cjs b/packages/browser-extension/.eslintrc.cjs deleted file mode 100644 index d6c95379..00000000 --- a/packages/browser-extension/.eslintrc.cjs +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - root: true, - env: { browser: true, es2020: true }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:react-hooks/recommended', - ], - ignorePatterns: ['dist', '.eslintrc.cjs'], - parser: '@typescript-eslint/parser', - plugins: ['react-refresh'], - rules: { - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, - ], - }, -} diff --git a/packages/browser-extension/manifest.json b/packages/browser-extension/manifest.json index 0eb8879d..bf3293ca 100644 --- a/packages/browser-extension/manifest.json +++ b/packages/browser-extension/manifest.json @@ -5,5 +5,8 @@ "version": "1.0", "action": { "default_popup": "index.html" - } + }, + "permissions": [ + "storage" + ] } diff --git a/packages/browser-extension/package.json b/packages/browser-extension/package.json index a4688cd6..3c8a4e8d 100644 --- a/packages/browser-extension/package.json +++ b/packages/browser-extension/package.json @@ -10,8 +10,15 @@ "preview": "vite preview" }, "dependencies": { + "@types/chrome": "^0.0.260", + "localforage": "^1.10.0", + "match-sorter": "^6.3.4", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^6.22.0", + "sort-by": "^1.2.0", + "use-chrome-storage": "^1.2.2", + "zod": "^3.22.4" }, "devDependencies": { "@crxjs/vite-plugin": "^1.0.14", diff --git a/packages/browser-extension/src/App.tsx b/packages/browser-extension/src/App.tsx index 7daedc37..21fec92f 100644 --- a/packages/browser-extension/src/App.tsx +++ b/packages/browser-extension/src/App.tsx @@ -1,8 +1,31 @@ +import { redirect } from "react-router-dom"; +import SavePage from "./SavePage"; +import usePluginSettings from "./settings"; +import { useNavigate } from "react-router-dom"; + function App() { + const navigate = useNavigate(); + const [settings, _1, _2, _3, isInit] = usePluginSettings(); + + if (!isInit) { + return <div className="p-4">Loading ... </div>; + } + + if (!settings.apiKey || !settings.address) { + navigate("/settings"); + return; + } + return ( - <> - <div className="text-3xl">Test</div> - </> + <div className="flex flex-col space-y-2"> + <SavePage settings={settings} /> + <hr /> + <div className="flex justify-end"> + <button className="w-2/6" onClick={() => navigate("/settings")}> + Settings + </button> + </div> + </div> ); } diff --git a/packages/browser-extension/src/SavePage.tsx b/packages/browser-extension/src/SavePage.tsx new file mode 100644 index 00000000..c66cc0ad --- /dev/null +++ b/packages/browser-extension/src/SavePage.tsx @@ -0,0 +1,40 @@ +import { useEffect, useState } from "react"; +import { Settings } from "./settings"; + +export default function SavePage({ settings }: { settings: Settings }) { + const [loading, setLoading] = useState(true); + const [error, setError] = useState<string | undefined>(undefined); + + async function runFetch() { + const resp = await fetch( + `${settings.address}/api/trpc/bookmarks.bookmarkLink`, + { + method: "POST", + }, + ); + + if (!resp.ok) { + setError("Something went wrong: " + (await resp.json())); + } + setLoading(false); + } + + useEffect(() => { + runFetch(); + }, []); + + if (loading) { + return <div>Loading ...</div>; + } + + if (error) { + return <div className="text-red-500">{error} ...</div>; + } + + return ( + <div> + SAVED! + <button onClick={runFetch}> Reload </button> + </div> + ); +} diff --git a/packages/browser-extension/src/SettingsPage.tsx b/packages/browser-extension/src/SettingsPage.tsx new file mode 100644 index 00000000..bae870ac --- /dev/null +++ b/packages/browser-extension/src/SettingsPage.tsx @@ -0,0 +1,53 @@ +import { useRef } from "react"; +import usePluginSettings from "./settings"; +import { useNavigate } from "react-router-dom"; + +export default function SettingsPage() { + const navigate = useNavigate(); + const [settings, setSettings, _1, _2, _3] = usePluginSettings(); + + const apiKeyRef = useRef<HTMLInputElement>(null); + const addressRef = useRef<HTMLInputElement>(null); + + const onSave = () => { + setSettings({ + apiKey: apiKeyRef.current?.value || "", + address: addressRef.current?.value || "", + }); + }; + + return ( + <div className="flex flex-col space-y-2"> + <span className="text-lg">Settings</span> + <hr /> + <div className="flex space-x-2 pt-2"> + <label className="m-auto h-full">API Key</label> + <input + ref={apiKeyRef} + defaultValue={settings.apiKey} + className="h-8 flex-1 rounded-lg border border-gray-300 p-2" + /> + </div> + <div className="flex space-x-2"> + <label className="m-auto h-full">Server Address</label> + <input + ref={addressRef} + defaultValue={settings.address} + className="h-8 flex-1 rounded-lg border border-gray-300 p-2" + /> + </div> + <button + className="rounded-lg border border-gray-200" + onClick={onSave} + > + Save + </button> + <button + className="rounded-lg border border-gray-200" + onClick={() => navigate("/")} + > + Back + </button> + </div> + ); +} diff --git a/packages/browser-extension/src/main.tsx b/packages/browser-extension/src/main.tsx index 3d7150da..298ab388 100644 --- a/packages/browser-extension/src/main.tsx +++ b/packages/browser-extension/src/main.tsx @@ -1,10 +1,29 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import App from './App.tsx' -import './index.css' +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App.tsx"; +import "./index.css"; +import { createBrowserRouter, Navigate, RouterProvider } from "react-router-dom"; +import SettingsPage from "./SettingsPage.tsx"; -ReactDOM.createRoot(document.getElementById('root')!).render( +const router = createBrowserRouter([ + { + path: "/index.html", + element: <Navigate to="/" />, + }, + { + path: "/", + element: <App />, + }, + { + path: "/settings", + element: <SettingsPage />, + }, +]); + +ReactDOM.createRoot(document.getElementById("root")!).render( <React.StrictMode> - <App /> + <div className="p-4 w-96"> + <RouterProvider router={router} /> + </div> </React.StrictMode>, -) +); diff --git a/packages/browser-extension/src/settings.ts b/packages/browser-extension/src/settings.ts new file mode 100644 index 00000000..ee7f0722 --- /dev/null +++ b/packages/browser-extension/src/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); +} |
