From 3960ee1479c027f3713d8d13972c8c728d8f5948 Mon Sep 17 00:00:00 2001 From: josc146 Date: Sat, 29 Apr 2023 00:08:12 +0800 Subject: [PATCH] feat: improve chatgpt website notification (go back button, hide button) (#270, #287) --- src/_locales/en/main.json | 3 +- src/_locales/zh-hans/main.json | 3 +- src/_locales/zh-hant/main.json | 3 +- src/background/index.mjs | 36 +++++++++----- src/components/MarkdownRender/Hyperlink.jsx | 37 ++++++++++++++ .../MarkdownRender/markdown-without-katex.jsx | 12 +---- src/components/MarkdownRender/markdown.jsx | 12 +---- .../NotificationForChatGPTWeb/index.jsx | 48 +++++++++++++++++++ src/config/index.mjs | 1 + src/content-script/index.jsx | 12 ++--- src/content-script/styles.scss | 14 ++++++ 11 files changed, 136 insertions(+), 45 deletions(-) create mode 100644 src/components/MarkdownRender/Hyperlink.jsx create mode 100644 src/components/NotificationForChatGPTWeb/index.jsx diff --git a/src/_locales/en/main.json b/src/_locales/en/main.json index add05f4..3742671 100644 --- a/src/_locales/en/main.json +++ b/src/_locales/en/main.json @@ -105,5 +105,6 @@ "Always pin the floating window": "Always pin the floating window", "Export": "Export", "Always Create New Conversation Window": "Always Create New Conversation Window", - "Please keep this tab open. You can now use the web mode of ChatGPTBox": "Please keep this tab open. You can now use the web mode of ChatGPTBox" + "Please keep this tab open. You can now use the web mode of ChatGPTBox": "Please keep this tab open. You can now use the web mode of ChatGPTBox", + "Go Back": "Go Back" } diff --git a/src/_locales/zh-hans/main.json b/src/_locales/zh-hans/main.json index 428e839..fe0c8f8 100644 --- a/src/_locales/zh-hans/main.json +++ b/src/_locales/zh-hans/main.json @@ -105,5 +105,6 @@ "Always pin the floating window": "总是固定浮动窗口", "Export": "导出", "Always Create New Conversation Window": "总是创建新的对话窗口", - "Please keep this tab open. You can now use the web mode of ChatGPTBox": "请保持这个页面打开, 现在你可以使用ChatGPTBox的网页版模式" + "Please keep this tab open. You can now use the web mode of ChatGPTBox": "请保持这个页面打开, 现在你可以使用ChatGPTBox的网页版模式", + "Go Back": "返回" } diff --git a/src/_locales/zh-hant/main.json b/src/_locales/zh-hant/main.json index 5c65e3e..fd6b06e 100644 --- a/src/_locales/zh-hant/main.json +++ b/src/_locales/zh-hant/main.json @@ -105,5 +105,6 @@ "Always pin the floating window": "總是固定浮動視窗", "Export": "匯出", "Always Create New Conversation Window": "總是建立新的對話視窗", - "Please keep this tab open. You can now use the web mode of ChatGPTBox": "請保持這個頁面開啟, 現在妳可以使用ChatGPTBox的網頁版模式" + "Please keep this tab open. You can now use the web mode of ChatGPTBox": "請保持這個頁面開啟, 現在妳可以使用ChatGPTBox的網頁版模式", + "Go Back": "返回" } diff --git a/src/background/index.mjs b/src/background/index.mjs index 52a736a..024e32b 100644 --- a/src/background/index.mjs +++ b/src/background/index.mjs @@ -47,7 +47,7 @@ function setPortProxy(port, proxyTabId) { const proxyOnDisconnect = () => { port.proxy = Browser.tabs.connect(proxyTabId) } - const portOnDisconnect = (msg) => { + const portOnDisconnect = () => { port.proxy.onMessage.removeListener(proxyOnMessage) port.onMessage.removeListener(portOnMessage) port.proxy.onDisconnect.removeListener(proxyOnDisconnect) @@ -118,7 +118,7 @@ async function executeApi(session, port, config) { } } -Browser.runtime.onMessage.addListener(async (message) => { +Browser.runtime.onMessage.addListener(async (message, sender) => { switch (message.type) { case 'FEEDBACK': { const token = await getChatGptAccessToken() @@ -130,6 +130,22 @@ Browser.runtime.onMessage.addListener(async (message) => { await deleteConversation(token, message.data.conversationId) break } + case 'NEW_URL': { + const newTab = await Browser.tabs.create({ + url: message.data.url, + pinned: message.data.pinned, + }) + if (message.data.saveAsChatgptConfig) { + await setUserConfig({ + chatgptTabId: newTab.id, + chatgptJumpBackTabId: sender.tab.id, + }) + } + break + } + case 'ACTIVATE_URL': + await Browser.tabs.update(message.data.tabId, { active: true }) + break case 'OPEN_URL': openUrl(message.data.url) break @@ -139,17 +155,11 @@ Browser.runtime.onMessage.addListener(async (message) => { case 'PIN_TAB': { let tabId if (message.data.tabId) tabId = message.data.tabId - else { - const currentTab = (await Browser.tabs.query({ active: true, currentWindow: true }))[0] - if (message.data.saveAsChatgptConfig) { - if (currentTab.url.includes('chat.openai.com')) tabId = currentTab.id - } else { - tabId = currentTab.id - } - } - if (tabId) { - await Browser.tabs.update(tabId, { pinned: true }) - if (message.data.saveAsChatgptConfig) await setUserConfig({ chatgptTabId: tabId }) + else tabId = sender.tab.id + + await Browser.tabs.update(tabId, { pinned: true }) + if (message.data.saveAsChatgptConfig) { + await setUserConfig({ chatgptTabId: tabId }) } break } diff --git a/src/components/MarkdownRender/Hyperlink.jsx b/src/components/MarkdownRender/Hyperlink.jsx new file mode 100644 index 0000000..b758c6e --- /dev/null +++ b/src/components/MarkdownRender/Hyperlink.jsx @@ -0,0 +1,37 @@ +import PropTypes from 'prop-types' +import Browser from 'webextension-polyfill' + +export function Hyperlink({ href, children }) { + const linkProperties = { + target: '_blank', + style: 'color: #8ab4f8; cursor: pointer;', + rel: 'nofollow noopener noreferrer', + } + + return href.includes('chat.openai.com') ? ( + { + Browser.runtime.sendMessage({ + type: 'NEW_URL', + data: { + url: href, + pinned: true, + saveAsChatgptConfig: true, + }, + }) + }} + > + {children} + + ) : ( + + {children} + + ) +} + +Hyperlink.propTypes = { + href: PropTypes.string.isRequired, + children: PropTypes.object.isRequired, +} diff --git a/src/components/MarkdownRender/markdown-without-katex.jsx b/src/components/MarkdownRender/markdown-without-katex.jsx index 50ac088..f415c42 100644 --- a/src/components/MarkdownRender/markdown-without-katex.jsx +++ b/src/components/MarkdownRender/markdown-without-katex.jsx @@ -4,13 +4,9 @@ import rehypeHighlight from 'rehype-highlight' import remarkGfm from 'remark-gfm' import remarkBreaks from 'remark-breaks' import { Pre } from './Pre' +import { Hyperlink } from './Hyperlink' export function MarkdownRender(props) { - const linkProperties = { - target: '_blank', - style: 'color: #8ab4f8;', - rel: 'nofollow noopener noreferrer', - } return (
( - - {props.children} - - ), + a: Hyperlink, pre: Pre, }} {...props} diff --git a/src/components/MarkdownRender/markdown.jsx b/src/components/MarkdownRender/markdown.jsx index 493b1f9..5bf2e3c 100644 --- a/src/components/MarkdownRender/markdown.jsx +++ b/src/components/MarkdownRender/markdown.jsx @@ -7,13 +7,9 @@ import remarkMath from 'remark-math' import remarkGfm from 'remark-gfm' import remarkBreaks from 'remark-breaks' import { Pre } from './Pre' +import { Hyperlink } from './Hyperlink' export function MarkdownRender(props) { - const linkProperties = { - target: '_blank', - style: 'color: #8ab4f8;', - rel: 'nofollow noopener noreferrer', - } return (
( - - {props.children} - - ), + a: Hyperlink, pre: Pre, }} {...props} diff --git a/src/components/NotificationForChatGPTWeb/index.jsx b/src/components/NotificationForChatGPTWeb/index.jsx new file mode 100644 index 0000000..a7a9fe4 --- /dev/null +++ b/src/components/NotificationForChatGPTWeb/index.jsx @@ -0,0 +1,48 @@ +import { useTranslation } from 'react-i18next' +import PropTypes from 'prop-types' +import Browser from 'webextension-polyfill' +import { useConfig } from '../../hooks/use-config.mjs' + +const NotificationForChatGPTWeb = (props) => { + const { t } = useTranslation() + const config = useConfig() + const buttonStyle = { + padding: '0 8px', + border: '1px solid', + borderRadius: '4px', + cursor: 'pointer', + } + + return ( +
+
{t('Please keep this tab open. You can now use the web mode of ChatGPTBox')}
+ + +
+ ) +} + +NotificationForChatGPTWeb.propTypes = { + container: PropTypes.object.isRequired, +} + +export default NotificationForChatGPTWeb diff --git a/src/config/index.mjs b/src/config/index.mjs index 777822d..ab50e53 100644 --- a/src/config/index.mjs +++ b/src/config/index.mjs @@ -133,6 +133,7 @@ export const defaultConfig = { ], accessToken: '', tokenSavedOn: 0, + chatgptJumpBackTabId: 0, chatgptTabId: 0, // unchangeable diff --git a/src/content-script/index.jsx b/src/content-script/index.jsx index 10e031a..e79b1fa 100644 --- a/src/content-script/index.jsx +++ b/src/content-script/index.jsx @@ -21,10 +21,11 @@ import FloatingToolbar from '../components/FloatingToolbar' import Browser from 'webextension-polyfill' import { getPreferredLanguage } from '../config/language.mjs' import '../_locales/i18n-react' -import { changeLanguage, t } from 'i18next' +import { changeLanguage } from 'i18next' import { initSession } from '../services/init-session.mjs' import { getChatGptAccessToken, registerPortListener } from '../services/wrappers.mjs' import { generateAnswersWithChatgptWebApi } from '../services/apis/chatgpt-web.mjs' +import NotificationForChatGPTWeb from '../components/NotificationForChatGPTWeb' /** * @param {SiteConfig} siteConfig @@ -304,15 +305,8 @@ async function prepareForForegroundRequests() { if (location.hostname !== 'chat.openai.com') return const div = document.createElement('div') - div.innerText = t('Please keep this tab open. You can now use the web mode of ChatGPTBox') - div.style.position = 'fixed' - div.style.top = '25px' - div.style.right = '25px' - div.style.zIndex = '2147483647' - div.style.padding = '4px 10px' - div.style.border = '1px solid' - div.style.borderRadius = '4px' document.body.append(div) + render(, div) await Browser.runtime.sendMessage({ type: 'PIN_TAB', diff --git a/src/content-script/styles.scss b/src/content-script/styles.scss index d1d7e06..76650de 100644 --- a/src/content-script/styles.scss +++ b/src/content-script/styles.scss @@ -296,3 +296,17 @@ background-color: var(--theme-color); box-shadow: 4px 4px 4px rgba(0, 0, 0, 0.2); } + +.chatgptbox-notification { + display: flex; + flex-direction: row; + align-items: center; + gap: 6px; + position: fixed; + top: 25px; + right: 25px; + z-index: 2147483647; + padding: 4px 10px; + border: 1px solid; + border-radius: 4px; +}