aboutsummaryrefslogtreecommitdiffstats
path: root/packages/browser-extension
diff options
context:
space:
mode:
Diffstat (limited to 'packages/browser-extension')
-rw-r--r--packages/browser-extension/.eslintrc.cjs18
-rw-r--r--packages/browser-extension/manifest.json5
-rw-r--r--packages/browser-extension/package.json9
-rw-r--r--packages/browser-extension/src/App.tsx29
-rw-r--r--packages/browser-extension/src/SavePage.tsx40
-rw-r--r--packages/browser-extension/src/SettingsPage.tsx53
-rw-r--r--packages/browser-extension/src/main.tsx33
-rw-r--r--packages/browser-extension/src/settings.ts13
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);
+}