feat: improve chatgpt website notification (go back button, hide button) (#270, #287)

This commit is contained in:
josc146
2023-04-29 00:08:12 +08:00
parent 66053ec62e
commit 3960ee1479
11 changed files with 136 additions and 45 deletions
+2 -1
View File
@@ -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"
}
+2 -1
View File
@@ -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": "返回"
}
+2 -1
View File
@@ -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": "返回"
}
+23 -13
View File
@@ -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
}
@@ -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') ? (
<span
{...linkProperties}
onClick={() => {
Browser.runtime.sendMessage({
type: 'NEW_URL',
data: {
url: href,
pinned: true,
saveAsChatgptConfig: true,
},
})
}}
>
{children}
</span>
) : (
<a href={href} {...linkProperties}>
{children}
</a>
)
}
Hyperlink.propTypes = {
href: PropTypes.string.isRequired,
children: PropTypes.object.isRequired,
}
@@ -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 (
<div dir="auto">
<ReactMarkdown
@@ -26,11 +22,7 @@ export function MarkdownRender(props) {
],
]}
components={{
a: (props) => (
<a href={props.href} {...linkProperties}>
{props.children}
</a>
),
a: Hyperlink,
pre: Pre,
}}
{...props}
+2 -10
View File
@@ -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 (
<div dir="auto">
<ReactMarkdown
@@ -30,11 +26,7 @@ export function MarkdownRender(props) {
],
]}
components={{
a: (props) => (
<a href={props.href} {...linkProperties}>
{props.children}
</a>
),
a: Hyperlink,
pre: Pre,
}}
{...props}
@@ -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 (
<div className="chatgptbox-notification">
<div>{t('Please keep this tab open. You can now use the web mode of ChatGPTBox')}</div>
<button
style={buttonStyle}
onClick={() => {
Browser.runtime.sendMessage({
type: 'ACTIVATE_URL',
data: {
tabId: config.chatgptJumpBackTabId,
},
})
}}
>
{t('Go Back')}
</button>
<button
style={buttonStyle}
onClick={() => {
props.container.remove()
}}
>
X
</button>
</div>
)
}
NotificationForChatGPTWeb.propTypes = {
container: PropTypes.object.isRequired,
}
export default NotificationForChatGPTWeb
+1
View File
@@ -133,6 +133,7 @@ export const defaultConfig = {
],
accessToken: '',
tokenSavedOn: 0,
chatgptJumpBackTabId: 0,
chatgptTabId: 0,
// unchangeable
+3 -9
View File
@@ -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(<NotificationForChatGPTWeb container={div} />, div)
await Browser.runtime.sendMessage({
type: 'PIN_TAB',
+14
View File
@@ -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;
}