From 60b479729a1a793ce016d1f4c71798c1302fa201 Mon Sep 17 00:00:00 2001 From: josc146 Date: Sun, 2 Apr 2023 20:27:07 +0800 Subject: [PATCH] feat: Independent Panel (#63, #120) --- build.mjs | 15 ++- src/_locales/en/main.json | 7 +- src/_locales/i18n.mjs | 3 - src/_locales/zh-hans/main.json | 7 +- src/_locales/zh-hant/main.json | 7 +- src/background/apis/chatgpt-web.mjs | 2 +- src/components/ConfirmButton/index.jsx | 54 ++++++++ src/components/ConversationCard/index.jsx | 15 ++- src/components/DecisionCard/index.jsx | 24 ++-- src/components/DeleteButton/index.jsx | 5 +- src/config/index.mjs | 13 +- src/config/localSession.mjs | 61 +++++++++ src/content-script/styles.scss | 6 +- src/hooks/use-config.mjs | 2 + src/pages/IndependentPanel/App.jsx | 156 ++++++++++++++++++++++ src/pages/IndependentPanel/index.html | 13 ++ src/pages/IndependentPanel/index.jsx | 19 +++ src/pages/IndependentPanel/styles.scss | 131 ++++++++++++++++++ src/pages/styles.scss | 1 + src/utils/init-session.mjs | 28 +++- 20 files changed, 531 insertions(+), 38 deletions(-) create mode 100644 src/components/ConfirmButton/index.jsx create mode 100644 src/config/localSession.mjs create mode 100644 src/pages/IndependentPanel/App.jsx create mode 100644 src/pages/IndependentPanel/index.html create mode 100644 src/pages/IndependentPanel/index.jsx create mode 100644 src/pages/IndependentPanel/styles.scss create mode 100644 src/pages/styles.scss diff --git a/build.mjs b/build.mjs index 2a93603..3adcdba 100644 --- a/build.mjs +++ b/build.mjs @@ -32,6 +32,10 @@ async function runWebpack(isWithoutKatex, isWithoutTiktoken, callback) { import: './src/popup/index.jsx', dependOn: 'shared', }, + IndependentPanel: { + import: './src/pages/IndependentPanel/index.jsx', + dependOn: 'shared', + }, shared: [ 'preact', 'webextension-polyfill', @@ -238,14 +242,21 @@ async function copyFiles(entryPoints, targetDir) { async function finishOutput(outputDirSuffix) { const commonFiles = [ + { src: 'src/logo.png', dst: 'logo.png' }, + { src: 'build/shared.js', dst: 'shared.js' }, + { src: 'build/content-script.css', dst: 'content-script.css' }, // shared + { src: 'build/content-script.js', dst: 'content-script.js' }, - { src: 'build/content-script.css', dst: 'content-script.css' }, + { src: 'build/background.js', dst: 'background.js' }, + { src: 'build/popup.js', dst: 'popup.js' }, { src: 'build/popup.css', dst: 'popup.css' }, { src: 'src/popup/index.html', dst: 'popup.html' }, - { src: 'src/logo.png', dst: 'logo.png' }, + + { src: 'build/IndependentPanel.js', dst: 'IndependentPanel.js' }, + { src: 'src/pages/IndependentPanel/index.html', dst: 'IndependentPanel.html' }, ] // chromium diff --git a/src/_locales/en/main.json b/src/_locales/en/main.json index 143b66f..95f8146 100644 --- a/src/_locales/en/main.json +++ b/src/_locales/en/main.json @@ -87,5 +87,10 @@ "Clear Conversation": "Clear Conversation", "Retry": "Retry", "Exceeded maximum context length": "Exceeded maximum context length, please clear the conversation and try again", - "Regenerate the answer after switching model": "Regenerate the answer after switching model" + "Regenerate the answer after switching model": "Regenerate the answer after switching model", + "Pin": "Pin", + "Unpin": "Unpin", + "Delete Conversation": "Delete Conversation", + "Clear conversations": "Clear conversations", + "Settings": "Settings" } diff --git a/src/_locales/i18n.mjs b/src/_locales/i18n.mjs index b88f43f..29f672c 100644 --- a/src/_locales/i18n.mjs +++ b/src/_locales/i18n.mjs @@ -4,7 +4,4 @@ import { resources } from './resources' i18n.init({ resources, fallbackLng: 'en', - interpolation: { - escapeValue: false, // not needed for react as it escapes by default - }, }) diff --git a/src/_locales/zh-hans/main.json b/src/_locales/zh-hans/main.json index 1da8975..c765725 100644 --- a/src/_locales/zh-hans/main.json +++ b/src/_locales/zh-hans/main.json @@ -87,5 +87,10 @@ "Clear Conversation": "清理对话", "Retry": "重试", "Exceeded maximum context length": "超出最大上下文长度, 请清理对话并重试", - "Regenerate the answer after switching model": "快捷切换模型时自动重新生成回答" + "Regenerate the answer after switching model": "快捷切换模型时自动重新生成回答", + "Pin": "固定侧边", + "Unpin": "收缩侧边", + "Delete Conversation": "删除对话", + "Clear conversations": "清空记录", + "Settings": "设置" } diff --git a/src/_locales/zh-hant/main.json b/src/_locales/zh-hant/main.json index 53d1cf4..2f3e37b 100644 --- a/src/_locales/zh-hant/main.json +++ b/src/_locales/zh-hant/main.json @@ -87,5 +87,10 @@ "Clear Conversation": "清理對話", "Retry": "重試", "Exceeded maximum context length": "超出最大上下文長度, 請清理對話並重試", - "Regenerate the answer after switching model": "快捷切換模型時自動重新生成回答" + "Regenerate the answer after switching model": "快捷切換模型時自動重新生成回答", + "Pin": "固定側邊", + "Unpin": "收縮側邊", + "Delete Conversation": "刪除對話", + "Clear conversations": "清空記錄", + "Settings": "設置" } diff --git a/src/background/apis/chatgpt-web.mjs b/src/background/apis/chatgpt-web.mjs index cfaf840..17f1631 100644 --- a/src/background/apis/chatgpt-web.mjs +++ b/src/background/apis/chatgpt-web.mjs @@ -66,7 +66,7 @@ export async function generateAnswersWithChatgptWebApi(port, question, session, port.onDisconnect.addListener(() => { console.debug('port disconnected') controller.abort() - deleteConversation(accessToken, session.conversationId) + if (session.autoClean) deleteConversation(accessToken, session.conversationId) }) const models = await getModels(accessToken).catch(() => { diff --git a/src/components/ConfirmButton/index.jsx b/src/components/ConfirmButton/index.jsx new file mode 100644 index 0000000..3e2acdf --- /dev/null +++ b/src/components/ConfirmButton/index.jsx @@ -0,0 +1,54 @@ +import { useTranslation } from 'react-i18next' +import { useEffect, useRef, useState } from 'react' +import PropTypes from 'prop-types' + +ConfirmButton.propTypes = { + onConfirm: PropTypes.func.isRequired, + text: PropTypes.string.isRequired, +} + +function ConfirmButton({ onConfirm, text }) { + const { t } = useTranslation() + const [waitConfirm, setWaitConfirm] = useState(false) + const confirmRef = useRef(null) + + useEffect(() => { + if (waitConfirm) confirmRef.current.focus() + }, [waitConfirm]) + + return ( + + + + + ) +} + +export default ConfirmButton diff --git a/src/components/ConversationCard/index.jsx b/src/components/ConversationCard/index.jsx index 76bc7d6..7735e06 100644 --- a/src/components/ConversationCard/index.jsx +++ b/src/components/ConversationCard/index.jsx @@ -65,8 +65,8 @@ function ConversationCard(props) { const config = useConfig() useEffect(() => { - if (props.onUpdate) props.onUpdate() - }) + if (props.onUpdate) props.onUpdate(port, session, conversationItemData) + }, [session, conversationItemData]) useEffect(() => { bodyRef.current.scrollTop = bodyRef.current.scrollHeight @@ -201,6 +201,7 @@ function ConversationCard(props) { title={t('Close the Window')} size={16} onClick={() => { + port.disconnect() if (props.onClose) props.onClose() }} /> @@ -217,7 +218,7 @@ function ConversationCard(props) { )}