diff --git a/extension/.vscode/extensions.json b/extension/.vscode/extensions.json new file mode 100644 index 0000000..24d7cc6 --- /dev/null +++ b/extension/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"] +} diff --git a/extension/.vscode/settings.json b/extension/.vscode/settings.json new file mode 100644 index 0000000..8b856a5 --- /dev/null +++ b/extension/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "editor.defaultFormatter": "esbenp.prettier-vscode", + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } +} diff --git a/extension/src/background/messages/getGpts.ts b/extension/src/background/messages/getGpts.ts index 3dc849f..8d95e2e 100644 --- a/extension/src/background/messages/getGpts.ts +++ b/extension/src/background/messages/getGpts.ts @@ -3,6 +3,11 @@ import type { PlasmoMessaging } from "@plasmohq/messaging" import { getGpts } from "~services/gpts" const handler: PlasmoMessaging.MessageHandler = async (req, res) => { + console.log( + "debug", + process.env.PLASMO_BROWSER, + process.env.PLASMO_INDEX_API_BASE_URI + ) const data = await getGpts() console.log("get gpts in back", data) diff --git a/extension/src/background/messages/searchGpts.ts b/extension/src/background/messages/searchGpts.ts new file mode 100644 index 0000000..b02e6ed --- /dev/null +++ b/extension/src/background/messages/searchGpts.ts @@ -0,0 +1,15 @@ +import type { PlasmoMessaging } from "@plasmohq/messaging" + +import { searchGpts } from "~services/gpts" + +const handler: PlasmoMessaging.MessageHandler = async (req, res) => { + const { question } = req.body + const data = await searchGpts(question) + console.log("search gpts in back", data) + + res.send({ + data + }) +} + +export default handler diff --git a/extension/src/components/GptsList/index.tsx b/extension/src/components/GptsList/index.tsx new file mode 100644 index 0000000..e23481c --- /dev/null +++ b/extension/src/components/GptsList/index.tsx @@ -0,0 +1,43 @@ +import type { Gpts } from "~types/gpts" + +interface Props { + gpts: Gpts[] +} + +export default ({ gpts }: Props) => { + return ( + + ) +} diff --git a/extension/src/components/Search/index.tsx b/extension/src/components/Search/index.tsx new file mode 100644 index 0000000..8fb8374 --- /dev/null +++ b/extension/src/components/Search/index.tsx @@ -0,0 +1,94 @@ +"use client" + +import type { + ChangeEvent, + Dispatch, + KeyboardEvent, + SetStateAction +} from "react" +import { useRef, useState } from "react" + +import { sendToBackground } from "@plasmohq/messaging" + +import type { Gpts } from "~/types/gpts" + +interface Props { + setGpts: Dispatch> + setLoading: Dispatch> +} + +export default ({ setGpts, setLoading }: Props) => { + const [inputDisabled, setInputDisabled] = useState(false) + const inputRef = useRef(null) + const [content, setContent] = useState("") + + const handleInputChange = (e: ChangeEvent) => { + setContent(e.target.value) + } + + const handleInputKeydown = (e: KeyboardEvent) => { + if (e.code === "Enter" && !e.shiftKey) { + if (e.keyCode !== 229) { + e.preventDefault() + handleSubmit() + } + } + } + + const searchGpts = async (question: string) => { + const resp = await sendToBackground({ + name: "searchGpts", + body: { + question: question + } + }) + console.log("searchGpts resp", resp) + if (resp && resp.data) { + setGpts(resp.data) + } else { + setGpts([]) + } + } + + const handleSubmit = async () => { + if (!content) { + return + } + + searchGpts(content) + } + + return ( +
+
+
+ + + + + +
+
+
+ ) +} diff --git a/extension/src/contents/discovery.tsx b/extension/src/contents/discovery.tsx index a7138bf..b8c4ebf 100644 --- a/extension/src/contents/discovery.tsx +++ b/extension/src/contents/discovery.tsx @@ -4,10 +4,12 @@ import { useEffect, useState } from "react" import { sendToBackground } from "@plasmohq/messaging" +import GptsList from "~components/GptsList" +import Search from "~components/Search" import type { Gpts } from "~types/gpts" export const config: PlasmoCSConfig = { - matches: ["https://chat.openai.com/gpts/discovery"] + matches: ["https://chat.openai.com/*"] } export const getStyle = () => { @@ -21,6 +23,7 @@ export const getOverlayAnchor: PlasmoGetOverlayAnchor = async () => export default () => { const [gpts, setGpts] = useState([]) + const [loading, setLoading] = useState(false) const fetchGpts = async () => { const resp = await sendToBackground({ @@ -55,52 +58,21 @@ export default () => { aria-label="close sidebar" className="drawer-overlay"> -
+
-

Third-party GPTs

+

Third-party GPTs

View more 👉
- + {/* */} + +
diff --git a/extension/src/services/gpts.ts b/extension/src/services/gpts.ts index c89a9fe..ef2998e 100644 --- a/extension/src/services/gpts.ts +++ b/extension/src/services/gpts.ts @@ -14,3 +14,30 @@ export const getGpts = async (): Promise => { return Promise.resolve([]) } + +export const searchGpts = async (question: string): Promise => { + const uri = `${process.env.PLASMO_INDEX_API_BASE_URI}/gpts/search` + const data = { + question: question + } + console.log("search request with params:", uri, data) + + try { + const resp = await fetch(uri, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${process.env.PLASMO_INDEX_API_KEY}` + }, + body: JSON.stringify(data) + }) + const res = await resp.json() + if (res.data) { + return res.data + } + } catch (e) { + console.log("request gpts search failed: ", e) + } + + return [] +} diff --git a/extension/src/style.css b/extension/src/style.css index b5c61c9..a9a3064 100644 --- a/extension/src/style.css +++ b/extension/src/style.css @@ -1,3 +1,19 @@ @tailwind base; @tailwind components; @tailwind utilities; + +.text-primary { + color: #2752f4; +} + +.border-primary { + border-color: #2752f4; +} + +.bg-panel { + background-color: #fff; +} + +.dark .bg-panel { + background-color: #000; +} diff --git a/extension/tailwind.config.js b/extension/tailwind.config.js index e9cc541..bf52da5 100644 --- a/extension/tailwind.config.js +++ b/extension/tailwind.config.js @@ -3,5 +3,23 @@ module.exports = { mode: "jit", darkMode: "class", content: ["./**/*.tsx"], + theme: { + extend: { + backgroundImage: { + "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", + "gradient-conic": + "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))" + }, + textColor: { + primary: "#2752f4" + }, + backgroundColor: { + primary: "#2752f4" + }, + borderColor: { + primary: "#2752f4" + } + } + }, plugins: [require("daisyui")] } diff --git a/web/app/components/Brand/index.tsx b/web/app/components/Brand/index.tsx index 7f7d4d2..8a9544d 100644 --- a/web/app/components/Brand/index.tsx +++ b/web/app/components/Brand/index.tsx @@ -7,33 +7,32 @@ interface Props { export default ({ count }: Props) => { return (
-
-
-

+
+
+

Third-party GPTs store -

- {count} fantastic GPTs - stored - - Submit yours 👉 - -

+

+ {count} fantastic GPTs stored + + Submit yours 👉 + +

); diff --git a/web/app/components/Header/index.tsx b/web/app/components/Header/index.tsx index 9ab7bfe..b84de70 100644 --- a/web/app/components/Header/index.tsx +++ b/web/app/components/Header/index.tsx @@ -7,18 +7,20 @@ import { usePathname } from "next/navigation"; export default () => { const pathname = usePathname(); return ( -
-

- - GPTs Works - +
+
+

+ + GPTs Works + +

+
  • @@ -82,7 +84,7 @@ export default () => { > -

+
); }; diff --git a/web/app/components/Search/index.tsx b/web/app/components/Search/index.tsx index 0b8c09b..d47e28d 100644 --- a/web/app/components/Search/index.tsx +++ b/web/app/components/Search/index.tsx @@ -64,12 +64,12 @@ export default ({ setGpts, setLoading }: Props) => { }; return ( -
-
-
+
+
+
{ strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" - className="-ml-8 cursor-pointer" + className="absolute right-4 cursor-pointer" onClick={handleSubmit} > diff --git a/web/app/globals.css b/web/app/globals.css index 71f619b..5f5aadb 100644 --- a/web/app/globals.css +++ b/web/app/globals.css @@ -17,5 +17,5 @@ } body { - color: rgb(var(--foreground-rgb)); + @apply bg-slate-50 text-base; } diff --git a/web/public/bgstar.svg b/web/public/bgstar.svg new file mode 100644 index 0000000..e85bf42 --- /dev/null +++ b/web/public/bgstar.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/web/public/brand.svg b/web/public/brand.svg new file mode 100644 index 0000000..221238c --- /dev/null +++ b/web/public/brand.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/tailwind.config.ts b/web/tailwind.config.ts index c7ead80..8c262a8 100644 --- a/web/tailwind.config.ts +++ b/web/tailwind.config.ts @@ -1,20 +1,29 @@ -import type { Config } from 'tailwindcss' +import type { Config } from "tailwindcss"; const config: Config = { content: [ - './pages/**/*.{js,ts,jsx,tsx,mdx}', - './components/**/*.{js,ts,jsx,tsx,mdx}', - './app/**/*.{js,ts,jsx,tsx,mdx}', + "./pages/**/*.{js,ts,jsx,tsx,mdx}", + "./components/**/*.{js,ts,jsx,tsx,mdx}", + "./app/**/*.{js,ts,jsx,tsx,mdx}", ], theme: { extend: { backgroundImage: { - 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', - 'gradient-conic': - 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', + "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", + "gradient-conic": + "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", + }, + textColor: { + primary: "#2752f4", + }, + backgroundColor: { + primary: "#2752f4", + }, + borderColor: { + primary: "#2752f4", }, }, }, plugins: [], -} -export default config +}; +export default config;