feat: chatgpt web mode improvement, now when official website is open requests will be sent in the foreground (#25, #53, #65, #112, #127, #161, #192, #204, #230, #248, #281)

This commit is contained in:
josc146
2023-04-27 22:51:43 +08:00
parent 17778f5a14
commit 10e1a8b650
8 changed files with 116 additions and 30 deletions
+2 -1
View File
@@ -104,5 +104,6 @@
"Max Conversation Length": "Max Conversation Length",
"Always pin the floating window": "Always pin the floating window",
"Export": "Export",
"Always Create New Conversation Window": "Always Create New Conversation Window"
"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"
}
+2 -1
View File
@@ -104,5 +104,6 @@
"Max Conversation Length": "对话处理的最大长度",
"Always pin the floating window": "总是固定浮动窗口",
"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": "请保持这个页面打开, 现在你可以使用ChatGPTBox的网页版模式"
}
+2 -1
View File
@@ -104,5 +104,6 @@
"Max Conversation Length": "對話處理的最大長度",
"Always pin the floating window": "總是固定浮動視窗",
"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": "請保持這個頁面開啟, 現在妳可以使用ChatGPTBox的網頁版模式"
}
+54 -18
View File
@@ -1,5 +1,4 @@
import Browser from 'webextension-polyfill'
import { v4 as uuidv4 } from 'uuid'
import {
deleteConversation,
generateAnswersWithChatgptWebApi,
@@ -20,10 +19,12 @@ import {
chatgptApiModelKeys,
chatgptWebModelKeys,
customApiModelKeys,
defaultConfig,
githubThirdPartyApiModelKeys,
gptApiModelKeys,
Models,
poeWebModelKeys,
setUserConfig,
} from '../config/index.mjs'
import '../_locales/i18n'
import { openUrl } from '../utils/open-url'
@@ -37,12 +38,27 @@ import { registerCommands } from './commands.mjs'
async function executeApi(session, port, config) {
if (chatgptWebModelKeys.includes(session.modelName)) {
const accessToken = await getChatGptAccessToken()
session.messageId = uuidv4()
if (session.parentMessageId == null) {
session.parentMessageId = uuidv4()
let tabId
if (
config.chatgptTabId &&
config.customChatGptWebApiUrl === defaultConfig.customChatGptWebApiUrl
) {
const tab = await Browser.tabs.get(config.chatgptTabId).catch(() => {})
if (tab) tabId = tab.id
}
if (tabId) {
const proxyPort = Browser.tabs.connect(tabId)
proxyPort.onMessage.addListener((msg) => {
port.postMessage(msg)
})
port.onMessage.addListener((msg) => {
proxyPort.postMessage(msg)
})
proxyPort.postMessage({ session })
} else {
const accessToken = await getChatGptAccessToken()
await generateAnswersWithChatgptWebApi(port, session.question, session, accessToken)
}
await generateAnswersWithChatgptWebApi(port, session.question, session, accessToken)
} else if (bingWebModelKeys.includes(session.modelName)) {
const accessToken = await getBingAccessToken()
if (session.modelName === 'bingFreeSydney')
@@ -84,18 +100,38 @@ async function executeApi(session, port, config) {
}
Browser.runtime.onMessage.addListener(async (message) => {
if (message.type === 'FEEDBACK') {
const token = await getChatGptAccessToken()
await sendMessageFeedback(token, message.data)
} else if (message.type === 'DELETE_CONVERSATION') {
const token = await getChatGptAccessToken()
const data = message.data
await deleteConversation(token, data.conversationId)
} else if (message.type === 'OPEN_URL') {
const data = message.data
openUrl(data.url)
} else if (message.type === 'REFRESH_MENU') {
refreshMenu()
let token
switch (message.type) {
case 'FEEDBACK':
token = await getChatGptAccessToken()
await sendMessageFeedback(token, message.data)
break
case 'DELETE_CONVERSATION':
token = await getChatGptAccessToken()
await deleteConversation(token, message.data.conversationId)
break
case 'OPEN_URL':
openUrl(message.data.url)
break
case 'REFRESH_MENU':
refreshMenu()
break
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 })
}
break
}
})
+1
View File
@@ -132,6 +132,7 @@ export const defaultConfig = {
],
accessToken: '',
tokenSavedOn: 0,
chatgptTabId: 0,
// unchangeable
+39 -2
View File
@@ -5,7 +5,12 @@ import DecisionCard from '../components/DecisionCard'
import { config as siteConfig } from './site-adapters'
import { config as toolsConfig } from './selection-tools'
import { config as menuConfig } from './menu-tools'
import { getPreferredLanguageKey, getUserConfig, setAccessToken } from '../config/index.mjs'
import {
chatgptWebModelKeys,
getPreferredLanguageKey,
getUserConfig,
setAccessToken,
} from '../config/index.mjs'
import {
createElementAtPosition,
cropText,
@@ -16,8 +21,10 @@ import FloatingToolbar from '../components/FloatingToolbar'
import Browser from 'webextension-polyfill'
import { getPreferredLanguage } from '../config/language.mjs'
import '../_locales/i18n-react'
import { changeLanguage } from 'i18next'
import { changeLanguage, t } from 'i18next'
import { initSession } from '../services/init-session.mjs'
import { getChatGptAccessToken, registerPortListener } from '../services/wrappers.mjs'
import { generateAnswersWithChatgptWebApi } from '../services/apis/chatgpt-web.mjs'
/**
* @param {SiteConfig} siteConfig
@@ -293,6 +300,35 @@ async function overwriteAccessToken() {
}
}
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)
await Browser.runtime.sendMessage({
type: 'PIN_TAB',
data: {
saveAsChatgptConfig: true,
},
})
registerPortListener(async (session, port) => {
if (chatgptWebModelKeys.includes(session.modelName)) {
const accessToken = await getChatGptAccessToken()
await generateAnswersWithChatgptWebApi(port, session.question, session, accessToken)
}
})
}
async function run() {
await getPreferredLanguageKey().then((lang) => {
changeLanguage(lang)
@@ -305,6 +341,7 @@ async function run() {
})
await overwriteAccessToken()
await prepareForForegroundRequests()
prepareForSelectionTools()
prepareForSelectionToolsTouch()
+1 -1
View File
@@ -271,7 +271,7 @@ function GeneralPart({ config, updateConfig }) {
lang,
},
})
.catch(() => ({}))
.catch(() => {})
})
})
}}
+15 -6
View File
@@ -5,6 +5,7 @@ import { isEmpty } from 'lodash-es'
import { chatgptWebModelKeys, getUserConfig, Models } from '../../config/index.mjs'
import { pushRecord, setAbortController } from './shared.mjs'
import Browser from 'webextension-polyfill'
import { v4 as uuidv4 } from 'uuid'
async function request(token, method, path, data) {
const apiUrl = (await getUserConfig()).customChatGptWebApiUrl
@@ -54,6 +55,11 @@ export async function getModels(token) {
* @param {string} accessToken
*/
export async function generateAnswersWithChatgptWebApi(port, question, session, accessToken) {
session.messageId = uuidv4()
if (session.parentMessageId == null) {
session.parentMessageId = uuidv4()
}
const { controller, messageListener } = setAbortController(port, null, () => {
if (session.autoClean) deleteConversation(accessToken, session.conversationId)
})
@@ -68,20 +74,23 @@ export async function generateAnswersWithChatgptWebApi(port, question, session,
models && models.includes(selectedModel) ? selectedModel : Models[chatgptWebModelKeys[0]].value
console.debug('usedModel', usedModel)
const cookie = (await Browser.cookies.getAll({ url: 'https://chat.openai.com/' }))
.map((cookie) => {
return `${cookie.name}=${cookie.value}`
})
.join('; ')
let cookie
if (Browser.cookies && Browser.cookies.getAll)
cookie = (await Browser.cookies.getAll({ url: 'https://chat.openai.com/' }))
.map((cookie) => {
return `${cookie.name}=${cookie.value}`
})
.join('; ')
let answer = ''
await fetchSSE(`${config.customChatGptWebApiUrl}${config.customChatGptWebApiPath}`, {
method: 'POST',
signal: controller.signal,
credentials: 'include',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
Cookie: cookie,
...(cookie && { Cookie: cookie }),
},
body: JSON.stringify({
action: 'next',