From c53e232fbcff5e4437439995b642040a48076cd6 Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 00:09:13 +0800 Subject: [PATCH 01/69] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a0b97269..91158828 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,10 @@ Integrating ChatGPT into your browser deeply, everything you need is here. [![Android][Android-image]][Android-url] [![Github][Github-image]][Github-url] -[Guide](https://github.com/josStorer/chatGPTBox/wiki/Guide) -[Preview](https://github.com/josStorer/chatGPTBox#Preview) -[Development&Contributing][dev-url] -[Donation](https://www.buymeacoffee.com/josStorer) +[Guide](https://github.com/josStorer/chatGPTBox/wiki/Guide) | +[Preview](https://github.com/josStorer/chatGPTBox#Preview) | +[Development&Contributing][dev-url] | +[Donation](https://www.buymeacoffee.com/josStorer) | [Credit](https://github.com/josStorer/chatGPTBox#Credit) [dev-url]: https://github.com/josStorer/chatGPTBox/wiki/Development&Contributing From 832a0403fefd765cd2c71ca456c6931f4ca3ebca Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 00:15:29 +0800 Subject: [PATCH 02/69] feat: make the chat body resizable (#1) --- src/content-script/styles.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/content-script/styles.scss b/src/content-script/styles.scss index 9a896b58..54f15bbc 100644 --- a/src/content-script/styles.scss +++ b/src/content-script/styles.scss @@ -66,6 +66,7 @@ background-color: var(--theme-color); color: var(--font-color); max-height: 800px; + resize: vertical; overflow-y: auto; ul, From 617330dedcd357fe887ace7d8958407ac9b6f725 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 15 Mar 2023 16:17:31 +0000 Subject: [PATCH 03/69] release v2.0.1 --- src/manifest.json | 2 +- src/manifest.v2.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/manifest.json b/src/manifest.json index f34bd895..07023af5 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,7 +1,7 @@ { "name": "ChatGPTBox", "description": "Integrating ChatGPT into your browser deeply, everything you need is here", - "version": "2.0.0", + "version": "2.0.1", "manifest_version": 3, "icons": { "16": "logo.png", diff --git a/src/manifest.v2.json b/src/manifest.v2.json index 32da5fa3..0ba67dd3 100644 --- a/src/manifest.v2.json +++ b/src/manifest.v2.json @@ -1,7 +1,7 @@ { "name": "ChatGPTBox", "description": "Integrating ChatGPT into your browser deeply, everything you need is here", - "version": "2.0.0", + "version": "2.0.1", "manifest_version": 2, "icons": { "16": "logo.png", From 7d8706bfdc11a13820f2a95be91117cc3ee74075 Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 09:31:15 +0800 Subject: [PATCH 04/69] fix: repeat rendering (#3) --- src/content-script/index.jsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/content-script/index.jsx b/src/content-script/index.jsx index 0c9be193..25b10307 100644 --- a/src/content-script/index.jsx +++ b/src/content-script/index.jsx @@ -1,4 +1,5 @@ import './styles.scss' +import { unmountComponentAtNode } from 'react-dom' import { render } from 'preact' import DecisionCard from '../components/DecisionCard' import { config as siteConfig } from './site-adapters' @@ -27,13 +28,19 @@ async function mountComponent(siteConfig, userConfig) { ) return - document.querySelectorAll('.chat-gpt-container').forEach((e) => e.remove()) + document.querySelectorAll('.chat-gpt-container').forEach((e) => { + unmountComponentAtNode(e) + e.remove() + }) let question if (userConfig.inputQuery) question = await getInput([userConfig.inputQuery]) if (!question && siteConfig) question = await getInput(siteConfig.inputQuery) - document.querySelectorAll('.chat-gpt-container').forEach((e) => e.remove()) + document.querySelectorAll('.chat-gpt-container').forEach((e) => { + unmountComponentAtNode(e) + e.remove() + }) const container = document.createElement('div') container.className = 'chat-gpt-container' render( From 705b960f0533cb5a33979b5734fda64a106b3b9d Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 09:31:54 +0800 Subject: [PATCH 05/69] chore: add resultsContainerQuery for siteAdapters --- src/content-script/site-adapters/index.mjs | 14 +++++++------- src/content-script/site-adapters/youtube/index.mjs | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/content-script/site-adapters/index.mjs b/src/content-script/site-adapters/index.mjs index 4bcec9ee..642bc112 100644 --- a/src/content-script/site-adapters/index.mjs +++ b/src/content-script/site-adapters/index.mjs @@ -113,7 +113,7 @@ export const config = { inputQuery: bilibili.inputQuery, sidebarContainerQuery: ['#danmukuBox'], appendContainerQuery: [], - resultsContainerQuery: [], + resultsContainerQuery: ['#danmukuBox'], action: { init: bilibili.init, }, @@ -122,7 +122,7 @@ export const config = { inputQuery: youtube.inputQuery, sidebarContainerQuery: ['#secondary'], appendContainerQuery: [], - resultsContainerQuery: [], + resultsContainerQuery: ['#secondary'], action: { init: youtube.init, }, @@ -131,7 +131,7 @@ export const config = { inputQuery: github.inputQuery, sidebarContainerQuery: ['#diff', '.commit'], appendContainerQuery: [], - resultsContainerQuery: [], + resultsContainerQuery: ['#diff', '.commit'], action: { init: github.init, }, @@ -140,24 +140,24 @@ export const config = { inputQuery: gitlab.inputQuery, sidebarContainerQuery: ['.js-commit-box-info'], appendContainerQuery: [], - resultsContainerQuery: [], + resultsContainerQuery: ['.js-commit-box-info'], }, zhihu: { inputQuery: zhihu.inputQuery, sidebarContainerQuery: ['.Question-sideColumn', '.Post-Header'], appendContainerQuery: [], - resultsContainerQuery: [], + resultsContainerQuery: ['.Question-sideColumn', '.Post-Header'], }, reddit: { inputQuery: reddit.inputQuery, sidebarContainerQuery: ['.side .spacer .linkinfo'], appendContainerQuery: [], - resultsContainerQuery: [], + resultsContainerQuery: ['.side .spacer .linkinfo'], }, quora: { inputQuery: quora.inputQuery, sidebarContainerQuery: ['.q-box.PageContentsLayout___StyledBox-d2uxks-0'], appendContainerQuery: [], - resultsContainerQuery: [], + resultsContainerQuery: ['.q-box.PageContentsLayout___StyledBox-d2uxks-0'], }, } diff --git a/src/content-script/site-adapters/youtube/index.mjs b/src/content-script/site-adapters/youtube/index.mjs index 8a2140d2..3dbf1f8b 100644 --- a/src/content-script/site-adapters/youtube/index.mjs +++ b/src/content-script/site-adapters/youtube/index.mjs @@ -48,7 +48,7 @@ export default { return cropText( `Provide a brief summary of the video using concise language and incorporating the video title.` + - `The video title is:"${title}".The subtitle content is as follows:\n${subtitleContent}`, + `The video title is:"${title}".The subtitle content is as follows:\n${subtitleContent}`, ) } catch (e) { console.log(e) From c6caf565765e346c70225744164998ef6eecb8ae Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 10:18:13 +0800 Subject: [PATCH 06/69] feat: dynamic max-height and width (#1) --- src/components/ConversationCard/index.jsx | 4 +++- src/components/FloatingToolbar/index.jsx | 4 +++- src/content-script/styles.scss | 4 +--- src/hooks/use-clamp-window-size.mjs | 8 ++++++++ src/hooks/use-window-size.mjs | 16 ++++++++++++++++ src/utils/set-element-position-in-viewport.mjs | 4 ++-- 6 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 src/hooks/use-clamp-window-size.mjs create mode 100644 src/hooks/use-window-size.mjs diff --git a/src/components/ConversationCard/index.jsx b/src/components/ConversationCard/index.jsx index eaad4fc2..7adf2fc4 100644 --- a/src/components/ConversationCard/index.jsx +++ b/src/components/ConversationCard/index.jsx @@ -9,6 +9,7 @@ import { WindowDesktop, XLg } from 'react-bootstrap-icons' import FileSaver from 'file-saver' import { render } from 'preact' import FloatingToolbar from '../FloatingToolbar' +import { useClampWindowSize } from '../../hooks/use-clamp-window-size' const logo = Browser.runtime.getURL('logo.png') @@ -32,6 +33,7 @@ function ConversationCard(props) { const [isReady, setIsReady] = useState(!props.question) const [port, setPort] = useState(() => Browser.runtime.connect()) const [session, setSession] = useState(props.session) + const windowSize = useClampWindowSize([0, Infinity], [250, 1100]) /** * @type {[ConversationItemData[], (conversationItemData: ConversationItemData[]) => void]} */ @@ -213,7 +215,7 @@ function ConversationCard(props) {
-
+
{conversationItemData.map((data, idx) => ( { getUserConfig() @@ -68,7 +70,7 @@ function FloatingToolbar(props) { onStop={dragEvent.onStop} position={virtualPosition} > -
+
{ + function updateSize() { + setSize([window.innerWidth, window.innerHeight]) + } + window.addEventListener('resize', updateSize) + updateSize() + return () => window.removeEventListener('resize', updateSize) + }, []) + return size +} diff --git a/src/utils/set-element-position-in-viewport.mjs b/src/utils/set-element-position-in-viewport.mjs index 4f1c13b2..83cceb72 100644 --- a/src/utils/set-element-position-in-viewport.mjs +++ b/src/utils/set-element-position-in-viewport.mjs @@ -1,6 +1,6 @@ export function setElementPositionInViewport(element, x = 0, y = 0) { - const retX = Math.min(window.innerWidth - element.offsetWidth, Math.max(0, x)) - const retY = Math.min(window.innerHeight - element.offsetHeight, Math.max(0, y)) + const retX = Math.min(Math.max(0, window.innerWidth - element.offsetWidth), Math.max(0, x)) + const retY = Math.min(Math.max(0, window.innerHeight - element.offsetHeight), Math.max(0, y)) element.style.left = retX + 'px' element.style.top = retY + 'px' return { x: retX, y: retY } From 48c2618b7cb121e6415df0321e0b1fdcf8ced1f3 Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 11:20:21 +0800 Subject: [PATCH 07/69] feat: stop generating answers --- src/background/apis/chatgpt-web.mjs | 19 ++++++++++++-- src/background/apis/openai-api.mjs | 30 +++++++++++++++++++++-- src/background/index.mjs | 9 ++++--- src/components/ConversationCard/index.jsx | 1 + src/components/ConversationItem/index.jsx | 14 ++++++++++- src/content-script/styles.scss | 9 +++++++ src/utils/fetch-sse.mjs | 6 ++++- 7 files changed, 79 insertions(+), 9 deletions(-) diff --git a/src/background/apis/chatgpt-web.mjs b/src/background/apis/chatgpt-web.mjs index 0d4de345..ffaee9a5 100644 --- a/src/background/apis/chatgpt-web.mjs +++ b/src/background/apis/chatgpt-web.mjs @@ -53,13 +53,24 @@ export async function generateAnswersWithChatgptWebApi(port, question, session, } const controller = new AbortController() + const stopListener = (msg) => { + if (msg.stop) { + console.debug('stop generating') + port.postMessage({ done: true }) + controller.abort() + port.onMessage.removeListener(stopListener) + } + } + port.onMessage.addListener(stopListener) port.onDisconnect.addListener(() => { console.debug('port disconnected') controller.abort() deleteConversation() }) - const models = await getModels(accessToken).catch(() => {}) + const models = await getModels(accessToken).catch(() => { + port.onMessage.removeListener(stopListener) + }) const config = await getUserConfig() let answer = '' @@ -112,8 +123,12 @@ export async function generateAnswersWithChatgptWebApi(port, question, session, async onStart() { // sendModerations(accessToken, question, session.conversationId, session.messageId) }, - async onEnd() {}, + async onEnd() { + port.onMessage.removeListener(stopListener) + }, async onError(resp) { + if (resp instanceof Error) throw resp + port.onMessage.removeListener(stopListener) if (resp.status === 403) { throw new Error('CLOUDFLARE') } diff --git a/src/background/apis/openai-api.mjs b/src/background/apis/openai-api.mjs index 1aa5fdce..409cb521 100644 --- a/src/background/apis/openai-api.mjs +++ b/src/background/apis/openai-api.mjs @@ -35,6 +35,15 @@ export async function generateAnswersWithGptCompletionApi( modelName, ) { const controller = new AbortController() + const stopListener = (msg) => { + if (msg.stop) { + console.debug('stop generating') + port.postMessage({ done: true }) + controller.abort() + port.onMessage.removeListener(stopListener) + } + } + port.onMessage.addListener(stopListener) port.onDisconnect.addListener(() => { console.debug('port disconnected') controller.abort() @@ -79,8 +88,12 @@ export async function generateAnswersWithGptCompletionApi( port.postMessage({ answer: answer, done: false, session: null }) }, async onStart() {}, - async onEnd() {}, + async onEnd() { + port.onMessage.removeListener(stopListener) + }, async onError(resp) { + if (resp instanceof Error) throw resp + port.onMessage.removeListener(stopListener) if (resp.status === 403) { throw new Error('CLOUDFLARE') } @@ -99,6 +112,15 @@ export async function generateAnswersWithGptCompletionApi( */ export async function generateAnswersWithChatgptApi(port, question, session, apiKey, modelName) { const controller = new AbortController() + const stopListener = (msg) => { + if (msg.stop) { + console.debug('stop generating') + port.postMessage({ done: true }) + controller.abort() + port.onMessage.removeListener(stopListener) + } + } + port.onMessage.addListener(stopListener) port.onDisconnect.addListener(() => { console.debug('port disconnected') controller.abort() @@ -142,8 +164,12 @@ export async function generateAnswersWithChatgptApi(port, question, session, api port.postMessage({ answer: answer, done: false, session: null }) }, async onStart() {}, - async onEnd() {}, + async onEnd() { + port.onMessage.removeListener(stopListener) + }, async onError(resp) { + if (resp instanceof Error) throw resp + port.onMessage.removeListener(stopListener) if (resp.status === 403) { throw new Error('CLOUDFLARE') } diff --git a/src/background/index.mjs b/src/background/index.mjs index 8574be82..bcc8c9dd 100644 --- a/src/background/index.mjs +++ b/src/background/index.mjs @@ -51,8 +51,9 @@ Browser.runtime.onConnect.addListener((port) => { console.debug('connected') port.onMessage.addListener(async (msg) => { console.debug('received msg', msg) - const config = await getUserConfig() const session = msg.session + if (!session) return + const config = await getUserConfig() if (session.useApiKey == null) { session.useApiKey = isUsingApiKey(config) } @@ -84,8 +85,10 @@ Browser.runtime.onConnect.addListener((port) => { } } catch (err) { console.error(err) - port.postMessage({ error: err.message }) - cache.delete(KEY_ACCESS_TOKEN) + if (!err.message.includes('aborted')) { + port.postMessage({ error: err.message }) + cache.delete(KEY_ACCESS_TOKEN) + } } }) }) diff --git a/src/components/ConversationCard/index.jsx b/src/components/ConversationCard/index.jsx index 7adf2fc4..ab31c117 100644 --- a/src/components/ConversationCard/index.jsx +++ b/src/components/ConversationCard/index.jsx @@ -223,6 +223,7 @@ function ConversationCard(props) { type={data.type} session={data.session} done={data.done} + port={port} /> ))}
diff --git a/src/components/ConversationItem/index.jsx b/src/components/ConversationItem/index.jsx index 0682d14b..5896bd4d 100644 --- a/src/components/ConversationItem/index.jsx +++ b/src/components/ConversationItem/index.jsx @@ -5,7 +5,7 @@ import CopyButton from '../CopyButton' import PropTypes from 'prop-types' import MarkdownRender from '../MarkdownRender/markdown.jsx' -export function ConversationItem({ type, content, session, done }) { +export function ConversationItem({ type, content, session, done, port }) { const [collapsed, setCollapsed] = useState(false) switch (type) { @@ -36,6 +36,17 @@ export function ConversationItem({ type, content, session, done }) {

{session ? 'ChatGPT:' : 'Loading...'}

+ {!done && ( + + )} {done && session && session.conversationId && ( { + await onError(err) + }) + if (!resp) return if (!resp.ok) { await onError(resp) + return } const parser = createParser((event) => { if (event.type === 'event') { From 1ce1851cae80a1232e14332f18f31d6be14e8ff0 Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 11:31:51 +0800 Subject: [PATCH 08/69] feat: auto scroll to bottom when submitting a question or finishing an answer --- src/components/ConversationCard/index.jsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/ConversationCard/index.jsx b/src/components/ConversationCard/index.jsx index ab31c117..c50fba43 100644 --- a/src/components/ConversationCard/index.jsx +++ b/src/components/ConversationCard/index.jsx @@ -1,4 +1,4 @@ -import { memo, useEffect, useState } from 'react' +import { memo, useEffect, useRef, useState } from 'react' import PropTypes from 'prop-types' import Browser from 'webextension-polyfill' import InputBox from '../InputBox' @@ -34,6 +34,7 @@ function ConversationCard(props) { const [port, setPort] = useState(() => Browser.runtime.connect()) const [session, setSession] = useState(props.session) const windowSize = useClampWindowSize([0, Infinity], [250, 1100]) + const bodyRef = useRef(null) /** * @type {[ConversationItemData[], (conversationItemData: ConversationItemData[]) => void]} */ @@ -67,6 +68,10 @@ function ConversationCard(props) { if (props.onUpdate) props.onUpdate() }) + useEffect(() => { + bodyRef.current.scrollTop = bodyRef.current.scrollHeight + }, [session]) + useEffect(() => { // when the page is responsive, session may accumulate redundant data and needs to be cleared after remounting and before making a new request if (props.question) { @@ -215,7 +220,11 @@ function ConversationCard(props) {

-
+
{conversationItemData.map((data, idx) => ( Date: Thu, 16 Mar 2023 03:33:28 +0000 Subject: [PATCH 09/69] release v2.0.2 --- src/manifest.json | 2 +- src/manifest.v2.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/manifest.json b/src/manifest.json index 07023af5..2e67d665 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,7 +1,7 @@ { "name": "ChatGPTBox", "description": "Integrating ChatGPT into your browser deeply, everything you need is here", - "version": "2.0.1", + "version": "2.0.2", "manifest_version": 3, "icons": { "16": "logo.png", diff --git a/src/manifest.v2.json b/src/manifest.v2.json index 0ba67dd3..12254601 100644 --- a/src/manifest.v2.json +++ b/src/manifest.v2.json @@ -1,7 +1,7 @@ { "name": "ChatGPTBox", "description": "Integrating ChatGPT into your browser deeply, everything you need is here", - "version": "2.0.1", + "version": "2.0.2", "manifest_version": 2, "icons": { "16": "logo.png", From ec7eabc8e12fb03ef079bb0fd2b342305c783aeb Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 14:04:09 +0800 Subject: [PATCH 10/69] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 91158828..877ed7c0 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,10 @@ Integrating ChatGPT into your browser deeply, everything you need is here. ![preview_youtube](screenshots/preview_youtube.jpg) +**Mobile Effect** + +![image](https://user-images.githubusercontent.com/13366013/225529110-9221c8ce-ad41-423e-b6ec-097981e74b66.png) + **Settings** ![preview_settings](screenshots/preview_settings.jpg) From 6c3fd116761ed015f638352c69429006f6ba4523 Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 17:15:41 +0800 Subject: [PATCH 11/69] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 877ed7c0..57c2576d 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ Integrating ChatGPT into your browser deeply, everything you need is here. [![Android][Android-image]][Android-url] [![Github][Github-image]][Github-url] +(Waiting for store review) + [Guide](https://github.com/josStorer/chatGPTBox/wiki/Guide) | [Preview](https://github.com/josStorer/chatGPTBox#Preview) | [Development&Contributing][dev-url] | From 68f8f0082f4bea5af7aacc5e34457cc996b9f8fe Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 20:26:11 +0800 Subject: [PATCH 12/69] feat: improve mobile support --- src/content-script/index.jsx | 40 ++++++++++++++++++++++ src/content-script/site-adapters/index.mjs | 4 +-- src/utils/is-mobile.mjs | 1 + 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/content-script/index.jsx b/src/content-script/index.jsx index 25b10307..68a4be32 100644 --- a/src/content-script/index.jsx +++ b/src/content-script/index.jsx @@ -138,6 +138,45 @@ async function prepareForSelectionTools() { }) } +async function prepareForSelectionToolsTouch() { + document.addEventListener('touchend', (e) => { + if (toolbarContainer && toolbarContainer.contains(e.target)) return + if ( + toolbarContainer && + window.getSelection()?.rangeCount > 0 && + toolbarContainer.contains(window.getSelection()?.getRangeAt(0).endContainer.parentElement) + ) + return + + if (toolbarContainer) toolbarContainer.remove() + setTimeout(() => { + const selection = window.getSelection()?.toString() + if (selection) { + const position = { + x: e.changedTouches[0].clientX + 15, + y: e.changedTouches[0].clientY - 15, + } + toolbarContainer = createElementAtPosition(position.x, position.y) + toolbarContainer.className = 'toolbar-container' + render( + , + toolbarContainer, + ) + } + }) + }) + document.addEventListener('touchstart', (e) => { + if (toolbarContainer && toolbarContainer.contains(e.target)) return + + document.querySelectorAll('.toolbar-container').forEach((e) => e.remove()) + }) +} + let menuX, menuY async function prepareForRightClickMenu() { @@ -220,6 +259,7 @@ async function run() { userConfig = await getUserConfig() if (isSafari()) await prepareForSafari() prepareForSelectionTools() + prepareForSelectionToolsTouch() prepareForStaticCard() prepareForRightClickMenu() } diff --git a/src/content-script/site-adapters/index.mjs b/src/content-script/site-adapters/index.mjs index 642bc112..82023ac4 100644 --- a/src/content-script/site-adapters/index.mjs +++ b/src/content-script/site-adapters/index.mjs @@ -144,9 +144,9 @@ export const config = { }, zhihu: { inputQuery: zhihu.inputQuery, - sidebarContainerQuery: ['.Question-sideColumn', '.Post-Header'], + sidebarContainerQuery: ['.Question-sideColumn', '.Post-Header', '.Question-main'], appendContainerQuery: [], - resultsContainerQuery: ['.Question-sideColumn', '.Post-Header'], + resultsContainerQuery: ['.Question-sideColumn', '.Post-Header', '.Question-main'], }, reddit: { inputQuery: reddit.inputQuery, diff --git a/src/utils/is-mobile.mjs b/src/utils/is-mobile.mjs index 39c30a3d..be3e1fac 100644 --- a/src/utils/is-mobile.mjs +++ b/src/utils/is-mobile.mjs @@ -1,6 +1,7 @@ // https://stackoverflow.com/questions/11381673/detecting-a-mobile-browser export async function isMobile() { + if (navigator.userAgentData) return navigator.userAgentData.mobile let check = false ;(function (a) { if ( From b7af9956c9ee224d2287ebeeca0b1b99dfb0a5ec Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 20:31:10 +0800 Subject: [PATCH 13/69] feat: code explain for selection tools --- src/content-script/selection-tools/index.mjs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/content-script/selection-tools/index.mjs b/src/content-script/selection-tools/index.mjs index 9dc900b1..835cd063 100644 --- a/src/content-script/selection-tools/index.mjs +++ b/src/content-script/selection-tools/index.mjs @@ -5,6 +5,7 @@ import { Palette, QuestionCircle, Translate, + Braces, } from 'react-bootstrap-icons' import { getPreferredLanguage } from '../../config.mjs' @@ -49,6 +50,14 @@ export const config = { genPrompt: async (selection) => `Divide the following into paragraphs that are easy to read and understand:\n"${selection}"`, }, + code: { + icon: , + label: 'Code Explain', + genPrompt: async (selection) => { + const preferredLanguage = await getPreferredLanguage() + return `Reply in ${preferredLanguage}.Explain the following code:\n"${selection}"` + }, + }, ask: { icon: , label: 'Ask', From fd7388d3e17b124708e9779d85df88ee020589eb Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 20:32:21 +0800 Subject: [PATCH 14/69] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 57c2576d..a0375c6d 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ Integrating ChatGPT into your browser deeply, everything you need is here. - 📦 Integration adaptation for various commonly used websites (reddit, quora, youtube, github, gitlab, zhihu, bilibili). - 🔍 Adaptation to all mainstream search engines, and custom queries to support additional sites. - 🧰 Selection tool and right-click menu to perform various tasks, such as translation, summarization, polishing, - sentiment analysis, paragraph division, and queries. + sentiment analysis, paragraph division, code explain and queries. - 🗂️ Static cards support floating chat boxes for multi-branch conversations. - 🖨️ Easily save your complete chat records or copy them partially. - 🎨 Powerful rendering support, whether for code highlighting or complex mathematical formulas. From 9517772e0ab0ad2870c1e9147b3145400ff7830a Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 20:49:02 +0800 Subject: [PATCH 15/69] feat: lockWhenAnswer config (#5) --- src/components/ConversationCard/index.jsx | 10 +++++++++ src/config.mjs | 26 +++++++++++++++++------ src/popup/Popup.jsx | 12 +++++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/components/ConversationCard/index.jsx b/src/components/ConversationCard/index.jsx index c50fba43..013b8c52 100644 --- a/src/components/ConversationCard/index.jsx +++ b/src/components/ConversationCard/index.jsx @@ -10,6 +10,7 @@ import FileSaver from 'file-saver' import { render } from 'preact' import FloatingToolbar from '../FloatingToolbar' import { useClampWindowSize } from '../../hooks/use-clamp-window-size' +import { defaultConfig, getUserConfig } from '../../config' const logo = Browser.runtime.getURL('logo.png') @@ -63,6 +64,11 @@ function ConversationCard(props) { } })(), ) + const [config, setConfig] = useState(defaultConfig) + + useEffect(() => { + getUserConfig().then(setConfig) + }, []) useEffect(() => { if (props.onUpdate) props.onUpdate() @@ -72,6 +78,10 @@ function ConversationCard(props) { bodyRef.current.scrollTop = bodyRef.current.scrollHeight }, [session]) + useEffect(() => { + if (config.lockWhenAnswer) bodyRef.current.scrollTop = bodyRef.current.scrollHeight + }, [conversationItemData]) + useEffect(() => { // when the page is responsive, session may accumulate redundant data and needs to be cleared after remounting and before making a new request if (props.question) { diff --git a/src/config.mjs b/src/config.mjs index 5175365c..5833644b 100644 --- a/src/config.mjs +++ b/src/config.mjs @@ -42,6 +42,8 @@ export const maxResponseTokenLength = 1000 * @typedef {typeof defaultConfig} UserConfig */ export const defaultConfig = { + // general + /** @type {keyof TriggerMode}*/ triggerMode: 'manually', /** @type {keyof ThemeMode}*/ @@ -49,24 +51,34 @@ export const defaultConfig = { /** @type {keyof Models}*/ modelName: 'chatgptFree', apiKey: '', + preferredLanguage: navigator.language.substring(0, 2), insertAtTop: isMobile(), + lockWhenAnswer: false, + + // advanced + + customChatGptWebApiUrl: 'https://chat.openai.com', + customChatGptWebApiPath: '/backend-api/conversation', + customOpenAiApiUrl: 'https://api.openai.com', siteRegex: 'match nothing', userSiteRegexOnly: false, inputQuery: '', appendQuery: '', prependQuery: '', + + // others + + activeSelectionTools: Object.keys(toolsConfig), + activeSiteAdapters: ['bilibili', 'github', 'gitlab', 'quora', 'reddit', 'youtube', 'zhihu'], accessToken: '', tokenSavedOn: 0, - preferredLanguage: navigator.language.substring(0, 2), - userLanguage: navigator.language.substring(0, 2), // unchangeable - customChatGptWebApiUrl: 'https://chat.openai.com', - customChatGptWebApiPath: '/backend-api/conversation', - customOpenAiApiUrl: 'https://api.openai.com', + + // unchangeable + + userLanguage: navigator.language.substring(0, 2), selectionTools: Object.keys(toolsConfig), - activeSelectionTools: Object.keys(toolsConfig), // importing configuration will result in gpt-3-encoder being packaged into the output file siteAdapters: ['bilibili', 'github', 'gitlab', 'quora', 'reddit', 'youtube', 'zhihu'], - activeSiteAdapters: ['bilibili', 'github', 'gitlab', 'quora', 'reddit', 'youtube', 'zhihu'], } export async function getUserLanguage() { diff --git a/src/popup/Popup.jsx b/src/popup/Popup.jsx index 0fb7a4b3..879f171c 100644 --- a/src/popup/Popup.jsx +++ b/src/popup/Popup.jsx @@ -152,6 +152,18 @@ function GeneralPart({ config, updateConfig }) { /> Insert chatGPT at the top of search results + +
) } From a26c78e97583dc5c06f75a6355ef4aace781d49e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 16 Mar 2023 12:52:08 +0000 Subject: [PATCH 16/69] release v2.0.3 --- src/manifest.json | 2 +- src/manifest.v2.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/manifest.json b/src/manifest.json index 2e67d665..a4e940a5 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,7 +1,7 @@ { "name": "ChatGPTBox", "description": "Integrating ChatGPT into your browser deeply, everything you need is here", - "version": "2.0.2", + "version": "2.0.3", "manifest_version": 3, "icons": { "16": "logo.png", diff --git a/src/manifest.v2.json b/src/manifest.v2.json index 12254601..6231b20c 100644 --- a/src/manifest.v2.json +++ b/src/manifest.v2.json @@ -1,7 +1,7 @@ { "name": "ChatGPTBox", "description": "Integrating ChatGPT into your browser deeply, everything you need is here", - "version": "2.0.2", + "version": "2.0.3", "manifest_version": 2, "icons": { "16": "logo.png", From 858469ab27949a7a287f37391ac8f454c95dac4d Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 21:47:38 +0800 Subject: [PATCH 17/69] Update issue templates --- ...56\351\242\230\346\212\245\345\221\212.md" | 38 +++++++++++++++++++ ...37\350\203\275\350\257\267\346\261\202.md" | 20 ++++++++++ 2 files changed, 58 insertions(+) create mode 100644 ".github/ISSUE_TEMPLATE/bug-report---\351\227\256\351\242\230\346\212\245\345\221\212.md" create mode 100644 ".github/ISSUE_TEMPLATE/feature-request---\346\226\260\345\212\237\350\203\275\350\257\267\346\261\202.md" diff --git "a/.github/ISSUE_TEMPLATE/bug-report---\351\227\256\351\242\230\346\212\245\345\221\212.md" "b/.github/ISSUE_TEMPLATE/bug-report---\351\227\256\351\242\230\346\212\245\345\221\212.md" new file mode 100644 index 00000000..2ab0c089 --- /dev/null +++ "b/.github/ISSUE_TEMPLATE/bug-report---\351\227\256\351\242\230\346\212\245\345\221\212.md" @@ -0,0 +1,38 @@ +--- +name: Bug report / 问题报告 +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +**问题描述** +A clear and concise description of what the bug is. + +**To Reproduce** +**如何复现** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +**期望行为** +A clear and concise description of what you expected to happen. + +**Screenshots** +**截图说明** +If applicable, add screenshots to help explain your problem. + +**Please complete the following information):** +**请补全以下内容** + - OS: [e.g. Windows] + - Browser: [e.g. chrome, safari] + - Extension Version: [e.g. v2.0.2] + +**Additional context** +**其他** +Add any other context about the problem here. diff --git "a/.github/ISSUE_TEMPLATE/feature-request---\346\226\260\345\212\237\350\203\275\350\257\267\346\261\202.md" "b/.github/ISSUE_TEMPLATE/feature-request---\346\226\260\345\212\237\350\203\275\350\257\267\346\261\202.md" new file mode 100644 index 00000000..e406ed26 --- /dev/null +++ "b/.github/ISSUE_TEMPLATE/feature-request---\346\226\260\345\212\237\350\203\275\350\257\267\346\261\202.md" @@ -0,0 +1,20 @@ +--- +name: Feature request / 新功能请求 +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +**新功能是否与解决某个问题相关, 请描述** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +**你期望的新功能实现方案** +A clear and concise description of what you want to happen. + +**Additional context** +**其他** +Add any other context or screenshots about the feature request here. From 87c81ed637853ade5279210297dfb6df9bc8eacd Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 16 Mar 2023 22:11:21 +0800 Subject: [PATCH 18/69] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a0375c6d..25c40a77 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Integrating ChatGPT into your browser deeply, everything you need is here. [![Android][Android-image]][Android-url] [![Github][Github-image]][Github-url] -(Waiting for store review) +(Waiting for store review, [Firefox version][Firefox-url] is now available) [Guide](https://github.com/josStorer/chatGPTBox/wiki/Guide) | [Preview](https://github.com/josStorer/chatGPTBox#Preview) | @@ -53,7 +53,7 @@ Integrating ChatGPT into your browser deeply, everything you need is here. [Firefox-image]: https://img.shields.io/badge/-Firefox-orange?logo=firefox-browser&logoColor=white -[Firefox-url]: https://github.com/josStorer/chatGPTBox/wiki/Install +[Firefox-url]: https://addons.mozilla.org/zh-CN/firefox/addon/chatgptbox/ [Safari-image]: https://img.shields.io/badge/-Safari-blue?logo=safari&logoColor=white From 025e915c92b45c59d2bd38d54b79482fd2e95969 Mon Sep 17 00:00:00 2001 From: josc146 Date: Fri, 17 Mar 2023 10:32:32 +0800 Subject: [PATCH 19/69] chore: improve mobile selection --- src/components/FloatingToolbar/index.jsx | 18 ++++++++++++++++-- src/utils/is-mobile.mjs | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/components/FloatingToolbar/index.jsx b/src/components/FloatingToolbar/index.jsx index 43fcebc9..1c592f46 100644 --- a/src/components/FloatingToolbar/index.jsx +++ b/src/components/FloatingToolbar/index.jsx @@ -4,13 +4,14 @@ import ConversationCard from '../ConversationCard' import PropTypes from 'prop-types' import { defaultConfig, getUserConfig } from '../../config.mjs' import { config as toolsConfig } from '../../content-script/selection-tools' -import { setElementPositionInViewport } from '../../utils' +import { isMobile, setElementPositionInViewport } from '../../utils' import Draggable from 'react-draggable' import { useClampWindowSize } from '../../hooks/use-clamp-window-size' const logo = Browser.runtime.getURL('logo.png') function FloatingToolbar(props) { + const [selection, setSelection] = useState(props.selection) const [prompt, setPrompt] = useState(props.prompt) const [triggered, setTriggered] = useState(props.triggered) const [config, setConfig] = useState(defaultConfig) @@ -40,6 +41,19 @@ function FloatingToolbar(props) { } }, [config]) + useEffect(() => { + if (isMobile()) { + const selectionListener = () => { + const currentSelection = window.getSelection()?.toString() + if (currentSelection) setSelection(currentSelection) + } + document.addEventListener('selectionchange', selectionListener) + return () => { + document.removeEventListener('selectionchange', selectionListener) + } + } + }, []) + if (!render) return
if (triggered) { @@ -101,7 +115,7 @@ function FloatingToolbar(props) { className: 'gpt-selection-toolbar-button', title: toolConfig.label, onClick: async () => { - setPrompt(await toolConfig.genPrompt(props.selection)) + setPrompt(await toolConfig.genPrompt(selection)) setTriggered(true) }, }), diff --git a/src/utils/is-mobile.mjs b/src/utils/is-mobile.mjs index be3e1fac..a3c81703 100644 --- a/src/utils/is-mobile.mjs +++ b/src/utils/is-mobile.mjs @@ -1,6 +1,6 @@ // https://stackoverflow.com/questions/11381673/detecting-a-mobile-browser -export async function isMobile() { +export function isMobile() { if (navigator.userAgentData) return navigator.userAgentData.mobile let check = false ;(function (a) { From d8e02d17106eb7c0a5890e9a6498558ef959783e Mon Sep 17 00:00:00 2001 From: josc146 Date: Fri, 17 Mar 2023 10:47:34 +0800 Subject: [PATCH 20/69] chore: improve for reddit --- src/content-script/site-adapters/index.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content-script/site-adapters/index.mjs b/src/content-script/site-adapters/index.mjs index 82023ac4..125f1475 100644 --- a/src/content-script/site-adapters/index.mjs +++ b/src/content-script/site-adapters/index.mjs @@ -150,9 +150,9 @@ export const config = { }, reddit: { inputQuery: reddit.inputQuery, - sidebarContainerQuery: ['.side .spacer .linkinfo'], + sidebarContainerQuery: ['.side'], appendContainerQuery: [], - resultsContainerQuery: ['.side .spacer .linkinfo'], + resultsContainerQuery: ['.side'], }, quora: { inputQuery: quora.inputQuery, From 97a853f6b5f922dd36565e13ae1ffc9f93346b76 Mon Sep 17 00:00:00 2001 From: josc146 Date: Fri, 17 Mar 2023 11:04:25 +0800 Subject: [PATCH 21/69] chore: improve for youtube --- src/content-script/site-adapters/index.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content-script/site-adapters/index.mjs b/src/content-script/site-adapters/index.mjs index 125f1475..fe3165c8 100644 --- a/src/content-script/site-adapters/index.mjs +++ b/src/content-script/site-adapters/index.mjs @@ -120,9 +120,9 @@ export const config = { }, youtube: { inputQuery: youtube.inputQuery, - sidebarContainerQuery: ['#secondary'], + sidebarContainerQuery: ['#secondary:not([style*="display: none"])'], appendContainerQuery: [], - resultsContainerQuery: ['#secondary'], + resultsContainerQuery: ['#secondary:not([style*="display: none"])'], action: { init: youtube.init, }, From a1e36fec8025ecb085a88e3949f169440a9ee08d Mon Sep 17 00:00:00 2001 From: josc146 Date: Fri, 17 Mar 2023 11:10:02 +0800 Subject: [PATCH 22/69] chore: improve for youtube --- src/content-script/site-adapters/index.mjs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/content-script/site-adapters/index.mjs b/src/content-script/site-adapters/index.mjs index fe3165c8..5a14b300 100644 --- a/src/content-script/site-adapters/index.mjs +++ b/src/content-script/site-adapters/index.mjs @@ -120,9 +120,13 @@ export const config = { }, youtube: { inputQuery: youtube.inputQuery, - sidebarContainerQuery: ['#secondary:not([style*="display: none"])'], + sidebarContainerQuery: [ + '#secondary:not([style*="display: none"]):not(.ytd-two-column-browse-results-renderer)', + ], appendContainerQuery: [], - resultsContainerQuery: ['#secondary:not([style*="display: none"])'], + resultsContainerQuery: [ + '#secondary:not([style*="display: none"]):not(.ytd-two-column-browse-results-renderer)', + ], action: { init: youtube.init, }, From 9f8403c760da8f6d1142d122fead216c41d3a913 Mon Sep 17 00:00:00 2001 From: josc146 Date: Fri, 17 Mar 2023 11:55:51 +0800 Subject: [PATCH 23/69] chore: inline svg to save traffic --- build.mjs | 2 +- src/popup/Popup.jsx | 7 ++----- src/popup/donation/bugmeacoffee.svg | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 src/popup/donation/bugmeacoffee.svg diff --git a/build.mjs b/build.mjs index 2c4ed6ce..d118bed7 100644 --- a/build.mjs +++ b/build.mjs @@ -169,7 +169,7 @@ async function runWebpack(isWithoutKatex, callback) { type: 'asset/inline', }, { - test: /\.jpg$/, + test: /\.(jpg|svg)$/, type: 'asset/inline', }, ], diff --git a/src/popup/Popup.jsx b/src/popup/Popup.jsx index 879f171c..68a3170b 100644 --- a/src/popup/Popup.jsx +++ b/src/popup/Popup.jsx @@ -18,6 +18,7 @@ import Browser from 'webextension-polyfill' import PropTypes from 'prop-types' import { config as toolsConfig } from '../content-script/selection-tools' import wechatpay from './donation/wechatpay.jpg' +import bugmeacoffee from './donation/bugmeacoffee.svg' function GeneralPart({ config, updateConfig }) { const [balance, setBalance] = useState(null) @@ -336,11 +337,7 @@ function Donation() { target="_blank" rel="nofollow noopener noreferrer" > - buymeacoffee + buymeacoffee
<> diff --git a/src/popup/donation/bugmeacoffee.svg b/src/popup/donation/bugmeacoffee.svg new file mode 100644 index 00000000..ef9943ea --- /dev/null +++ b/src/popup/donation/bugmeacoffee.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + From 79a1628b4a26255a19ce5e30a26875dbe0373b50 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 17 Mar 2023 04:13:50 +0000 Subject: [PATCH 24/69] release v2.0.4 --- src/manifest.json | 2 +- src/manifest.v2.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/manifest.json b/src/manifest.json index a4e940a5..b6a7dabc 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,7 +1,7 @@ { "name": "ChatGPTBox", "description": "Integrating ChatGPT into your browser deeply, everything you need is here", - "version": "2.0.3", + "version": "2.0.4", "manifest_version": 3, "icons": { "16": "logo.png", diff --git a/src/manifest.v2.json b/src/manifest.v2.json index 6231b20c..25c8391d 100644 --- a/src/manifest.v2.json +++ b/src/manifest.v2.json @@ -1,7 +1,7 @@ { "name": "ChatGPTBox", "description": "Integrating ChatGPT into your browser deeply, everything you need is here", - "version": "2.0.3", + "version": "2.0.4", "manifest_version": 2, "icons": { "16": "logo.png", From 0a0299c5fcc60a15a198a30ae25fc90b62b2dce1 Mon Sep 17 00:00:00 2001 From: josc146 Date: Fri, 17 Mar 2023 21:59:33 +0800 Subject: [PATCH 25/69] style: fix markdown ol item style (#12) --- src/content-script/styles.scss | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/content-script/styles.scss b/src/content-script/styles.scss index 29bd2517..541c0d96 100644 --- a/src/content-script/styles.scss +++ b/src/content-script/styles.scss @@ -80,9 +80,8 @@ li { counter-increment: item; - &:before { + &::marker { content: counter(item) '. '; - margin-left: -0.75em; } } } From 45f48ee0496c3ef63c7c9525dedfcad1549684cb Mon Sep 17 00:00:00 2001 From: josc146 Date: Fri, 17 Mar 2023 22:11:08 +0800 Subject: [PATCH 26/69] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 25c40a77..5874c3ba 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ Integrating ChatGPT into your browser deeply, everything you need is here. [Donation](https://www.buymeacoffee.com/josStorer) | [Credit](https://github.com/josStorer/chatGPTBox#Credit) +[Video Demonstration](https://www.youtube.com/watch?v=E1smDxJvTRs) + [dev-url]: https://github.com/josStorer/chatGPTBox/wiki/Development&Contributing [license-image]: http://img.shields.io/badge/license-MIT-blue.svg From eb9eaddaa58cf7d329d66ed8d7453e26515e62ed Mon Sep 17 00:00:00 2001 From: josc146 Date: Sat, 18 Mar 2023 13:23:02 +0800 Subject: [PATCH 27/69] docu: readme in zh --- README.md | 8 ++- README_ZH.md | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 README_ZH.md diff --git a/README.md b/README.md index 5874c3ba..36c612ef 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ Integrating ChatGPT into your browser deeply, everything you need is here. [![release][release-image]][release-url] [![verfiy][verify-image]][verify-url] +English | [简体中文](README_ZH.md) + ### Install [![Chrome][Chrome-image]][Chrome-url] @@ -24,10 +26,10 @@ Integrating ChatGPT into your browser deeply, everything you need is here. (Waiting for store review, [Firefox version][Firefox-url] is now available) [Guide](https://github.com/josStorer/chatGPTBox/wiki/Guide) | -[Preview](https://github.com/josStorer/chatGPTBox#Preview) | +[Preview](#Preview) | [Development&Contributing][dev-url] | [Donation](https://www.buymeacoffee.com/josStorer) | -[Credit](https://github.com/josStorer/chatGPTBox#Credit) +[Credit](#Credit) [Video Demonstration](https://www.youtube.com/watch?v=E1smDxJvTRs) @@ -55,7 +57,7 @@ Integrating ChatGPT into your browser deeply, everything you need is here. [Firefox-image]: https://img.shields.io/badge/-Firefox-orange?logo=firefox-browser&logoColor=white -[Firefox-url]: https://addons.mozilla.org/zh-CN/firefox/addon/chatgptbox/ +[Firefox-url]: https://addons.mozilla.org/firefox/addon/chatgptbox/ [Safari-image]: https://img.shields.io/badge/-Safari-blue?logo=safari&logoColor=white diff --git a/README_ZH.md b/README_ZH.md new file mode 100644 index 00000000..ea8280fc --- /dev/null +++ b/README_ZH.md @@ -0,0 +1,160 @@ +

+ +

+ +

ChatGPT Box

+ +
+ +将ChatGPT深度集成到浏览器中, 你所需要的一切均在于此 + +[![license][license-image]][license-url] +[![release][release-image]][release-url] +[![verfiy][verify-image]][verify-url] + +[English](README.md) | 简体中文 + +### 安装链接 + +[![Chrome][Chrome-image]][Chrome-url] +[![Edge][Edge-image]][Edge-url] +[![Firefox][Firefox-image]][Firefox-url] +[![Safari][Safari-image]][Safari-url] +[![Android][Android-image]][Android-url] +[![Github][Github-image]][Github-url] + +(目前正在等待商店审核, [Firefox][Firefox-url]版本已过审) + +[使用指南](https://github.com/josStorer/chatGPTBox/wiki/Guide) | +[效果预览](#Preview) | +[开发&贡献][dev-url] | +[捐助](https://www.buymeacoffee.com/josStorer) | +[鸣谢](#Credit) + +[视频演示](https://www.bilibili.com/video/BV1524y1x7io) + +[dev-url]: https://github.com/josStorer/chatGPTBox/wiki/Development&Contributing + +[license-image]: http://img.shields.io/badge/license-MIT-blue.svg + +[license-url]: https://github.com/josStorer/chatGPTBox/blob/master/LICENSE + +[release-image]: https://img.shields.io/github/release/josStorer/chatGPTBox.svg + +[release-url]: https://github.com/josStorer/chatGPTBox/releases/latest + +[verify-image]: https://github.com/josStorer/chatGPTBox/workflows/verify-configs/badge.svg + +[verify-url]: https://github.com/josStorer/chatGPTBox/actions/workflows/verify-configs.yml + +[Chrome-image]: https://img.shields.io/badge/-Chrome-brightgreen?logo=google-chrome&logoColor=white + +[Chrome-url]: https://github.com/josStorer/chatGPTBox/wiki/Install + +[Edge-image]: https://img.shields.io/badge/-Edge-blue?logo=microsoft-edge&logoColor=white + +[Edge-url]: https://github.com/josStorer/chatGPTBox/wiki/Install + +[Firefox-image]: https://img.shields.io/badge/-Firefox-orange?logo=firefox-browser&logoColor=white + +[Firefox-url]: https://addons.mozilla.org/firefox/addon/chatgptbox/ + +[Safari-image]: https://img.shields.io/badge/-Safari-blue?logo=safari&logoColor=white + +[Safari-url]: https://github.com/josStorer/chatGPTBox/wiki/Install + +[Android-image]: https://img.shields.io/badge/-Android-brightgreen?logo=android&logoColor=white + +[Android-url]: https://github.com/josStorer/chatGPTBox/wiki/Install#install-to-android + +[Github-image]: https://img.shields.io/badge/-Github-black?logo=github&logoColor=white + +[Github-url]: https://github.com/josStorer/chatGPTBox/releases/latest + +
+ +## ✨ Features + +- 🌈 在任何页面随时呼出聊天对话框 +- 🔗 多种API支持 (免费用户和Plus用户可用Web API, 此外还有GPT-3, GPT-3.5等) +- 📦 对各种常用网站的集成适配 (reddit, quora, youtube, github, gitlab, zhihu, bilibili) +- 🔍 对所有主流搜索引擎的适配, 并支持自定义查询以支持额外的站点 +- 🧰 框选工具与右键菜单, 执行各种你的需求, 如翻译, 总结, 润色, 情感分析, 段落划分, 代码解释, 问询 +- 🗂️ 静态卡片支持浮出聊天框, 进行多分支对话 +- 🖨️ 随意保存你的完整对话记录, 或进行局部复制 +- 🎨 强大的渲染支持, 不论是代码高亮, 还是复杂数学公式 +- 🌍 多语言偏好支持 +- 📝 [自定义API地址](https://github.com/Ice-Hazymoon/openai-scf-proxy)支持 +- ⚙️ 所有站点适配与工具均可自由开关, 随时停用你不需要的模块 +- 💡 工具与站点适配开发易于扩展, 对于开发人员易于自定义, 请查看[开发&贡献][dev-url]部分 +- 😉 此外, 如果回答有任何不足, 直接聊天解决! + +## Preview + +
+ +**搜索引擎适配, 浮动窗口, 对话分支** + +![preview_google_floatingwindow_conversationbranch](screenshots/preview_google_floatingwindow_conversationbranch.jpg) + +**常用站点集成, 选择浮动工具** + +![preview_reddit_selectiontools](screenshots/preview_reddit_selectiontools.jpg) + +**Git分析, 右键菜单** + +![preview_github_rightclickmenu](screenshots/preview_github_rightclickmenu.jpg) + +**视频总结** + +![preview_youtube](screenshots/preview_youtube.jpg) + +**移动端效果** + +![image](https://user-images.githubusercontent.com/13366013/225529110-9221c8ce-ad41-423e-b6ec-097981e74b66.png) + +**设置界面** + +![preview_settings](screenshots/preview_settings.jpg) + +
+ +## Credit + +该项目基于我的另一个项目 [josStorer/chatGPT-search-engine-extension](https://github.com/josStorer/chatGPT-search-engine-extension) + +[josStorer/chatGPT-search-engine-extension](https://github.com/josStorer/chatGPT-search-engine-extension) +fork自 [wong2/chat-gpt-google-extension](https://github.com/wong2/chat-gpt-google-extension)(我从中学到很多) +并在2022年12月14日与上游分离 + +[wong2/chat-gpt-google-extension](https://github.com/wong2/chat-gpt-google-extension) 的想法源于 +[ZohaibAhmed/ChatGPT-Google](https://github.com/ZohaibAhmed/ChatGPT-Google) ([upstream-c54528b](https://github.com/wong2/chatgpt-google-extension/commit/c54528b0e13058ab78bfb433c92603db017d1b6b)) + +### 额外声明 + +#### 这个声明主要针对可能的道德问题指责 + +该项目最终可追溯至chatGPT刚刚爆火时出现的一个明星项目 [wong2/chat-gpt-google-extension](https://github.com/wong2/chat-gpt-google-extension), +一开始我为其添加了各种市面上主流搜索引擎的支持, 后续我也进一步改进了兼容性, 并提交了自动化构建支持等. +起初我更倾向于贡献到原始项目, 你可以查看我的[PR记录](https://github.com/wong2/chatgpt-google-extension/pulls?q=is%3Apr+author%3AjosStorer+). +我也在原始项目中的许多Issue中参与解决问题, 例如[该问题](https://github.com/wong2/chatgpt-google-extension/issues/110#issuecomment-1399831569)中, +我提及了我解决Safari构建的方式, 在[该PR中](https://github.com/wong2/chatgpt-google-extension/pull/187), 我尝试解决挂载点的检测问题, +又比如对于一些赤裸裸的[抄袭现象](https://github.com/wong2/chatgpt-google-extension/issues/197#issuecomment-1399824044), 我也深感不满. + +但是, 在一些问题上, 我与原作者的理念不合, 例如像[Katex渲染](https://github.com/wong2/chatgpt-google-extension/pull/75)的支持, 原作者在持续要求发起者改进后, +却又以体积问题为由拒绝了, 又比如[交互模式](https://github.com/wong2/chatgpt-google-extension/pull/103)的支持, 原作者同样拒绝了, 但是同时却一直把连续对话的Issue, Pin在顶部, +又一直不提供任何支持, 直至被其他团队收购后, 由其他团队进行了实现, +实际上早期我在贡献多搜索引擎支持时, 我认为这是个优先级比较高的功能, 但我觉得原作者推进有些缓慢, 而在执行一些我觉得优先级不高的事情, 并且其在合并搜索引擎支持后, +又刻意删除了几个引擎的支持, 并发起了一个请求的讨论, 导致用户重新前去提出, 而直至项目被收购, 讨论被关闭的几个月时间里, 原项目接收到大量的请求, 却全部被忽视了, +这意味着这个讨论一开始就是没有意义的, 我对诸如此类的做事风格深感不满. + +而原项目中也有一些有创意的想法, 许多都早于现在的一些独立项目, 例如[视频总结](https://github.com/wong2/chatgpt-google-extension/issues/140)请求, +很早就有人提出了, 但原作者同样拒绝了. + +出于种种原因, 我决定与上游分离, 并独立维护各种功能更新, 一直以来, 我维护的分支都始终覆盖了原项目所有功能, 并一直提供大量的额外功能支持, 也就是这个项目的[前身](https://github.com/josStorer/chatGPT-search-engine-extension). +但是, 我一直不愿意上架应用商店, 因为我认为这有违道德, 我不希望与原项目构成竞争. + +直至2023年2月份, 原作者宣布项目被收购, 代码将闭源, 我最终决定将一些比较好的社区提出的Issue, 但是被原作者拒绝的, 进行整合, 并上架商店, 最终诞生了这个项目. + +我仍想特别强调, 我只是对事不对人, 原作者是行业的前辈了, 而我只是个初出茅庐的菜鸡, 我不希望任何人因此对原作者进行任何攻击, 做开源的, 没有谁的时间是免费的, +原作者并没有做错任何事, 并且他的项目启发了大量的社区独立项目, 我也从中学到了很多, 而原作者的成功变现, 及运营过程也是非常值得学习的, 我仍然对其贡献表示尊敬. From fa13ace5b149f0560a77ba6644ccd89fa371e06d Mon Sep 17 00:00:00 2001 From: josc146 Date: Sat, 18 Mar 2023 13:37:37 +0800 Subject: [PATCH 28/69] docu: readme in zh --- README_ZH.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_ZH.md b/README_ZH.md index ea8280fc..9ca4af71 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -145,7 +145,7 @@ fork自 [wong2/chat-gpt-google-extension](https://github.com/wong2/chat-gpt-goog 却又以体积问题为由拒绝了, 又比如[交互模式](https://github.com/wong2/chatgpt-google-extension/pull/103)的支持, 原作者同样拒绝了, 但是同时却一直把连续对话的Issue, Pin在顶部, 又一直不提供任何支持, 直至被其他团队收购后, 由其他团队进行了实现, 实际上早期我在贡献多搜索引擎支持时, 我认为这是个优先级比较高的功能, 但我觉得原作者推进有些缓慢, 而在执行一些我觉得优先级不高的事情, 并且其在合并搜索引擎支持后, -又刻意删除了几个引擎的支持, 并发起了一个请求的讨论, 导致用户重新前去提出, 而直至项目被收购, 讨论被关闭的几个月时间里, 原项目接收到大量的请求, 却全部被忽视了, +又刻意删除了几个引擎的支持, 并发起了一个请求的[讨论](https://github.com/wong2/chatgpt-google-extension/issues/109), 导致用户重新前去提出, 而直至项目被收购, 讨论被关闭的几个月时间里, 原项目接收到大量的请求, 却全部被忽视了, 这意味着这个讨论一开始就是没有意义的, 我对诸如此类的做事风格深感不满. 而原项目中也有一些有创意的想法, 许多都早于现在的一些独立项目, 例如[视频总结](https://github.com/wong2/chatgpt-google-extension/issues/140)请求, From 8777140a9a8720a500fb44475b65add6bb775727 Mon Sep 17 00:00:00 2001 From: josc146 Date: Sat, 18 Mar 2023 13:58:08 +0800 Subject: [PATCH 29/69] docu: readme in zh --- README_ZH.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README_ZH.md b/README_ZH.md index 9ca4af71..bdf4f454 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -132,7 +132,8 @@ fork自 [wong2/chat-gpt-google-extension](https://github.com/wong2/chat-gpt-goog ### 额外声明 -#### 这个声明主要针对可能的道德问题指责 +
+谨慎展开该声明! 这个声明主要针对可能的道德问题指责, 因为我收到了一些攻击性言论, 因而我在此进行解释 该项目最终可追溯至chatGPT刚刚爆火时出现的一个明星项目 [wong2/chat-gpt-google-extension](https://github.com/wong2/chat-gpt-google-extension), 一开始我为其添加了各种市面上主流搜索引擎的支持, 后续我也进一步改进了兼容性, 并提交了自动化构建支持等. @@ -158,3 +159,5 @@ fork自 [wong2/chat-gpt-google-extension](https://github.com/wong2/chat-gpt-goog 我仍想特别强调, 我只是对事不对人, 原作者是行业的前辈了, 而我只是个初出茅庐的菜鸡, 我不希望任何人因此对原作者进行任何攻击, 做开源的, 没有谁的时间是免费的, 原作者并没有做错任何事, 并且他的项目启发了大量的社区独立项目, 我也从中学到了很多, 而原作者的成功变现, 及运营过程也是非常值得学习的, 我仍然对其贡献表示尊敬. + +
From 699d36ad3e08e54f290295e130c3b9d6cbb2c7bb Mon Sep 17 00:00:00 2001 From: josc146 Date: Sat, 18 Mar 2023 23:42:31 +0800 Subject: [PATCH 30/69] feat: support RTL text (#6) --- build.mjs | 1 + src/components/InputBox/index.jsx | 1 + .../MarkdownRender/markdown-without-katex.jsx | 50 +++++++++--------- src/components/MarkdownRender/markdown.jsx | 52 ++++++++++--------- 4 files changed, 55 insertions(+), 49 deletions(-) diff --git a/build.mjs b/build.mjs index d118bed7..5e20e707 100644 --- a/build.mjs +++ b/build.mjs @@ -246,6 +246,7 @@ async function build() { true, generateWebpackCallback(() => finishOutput('-without-katex')), ) + await new Promise((r) => setTimeout(r, 2000)) await runWebpack( false, generateWebpackCallback(() => finishOutput('')), diff --git a/src/components/InputBox/index.jsx b/src/components/InputBox/index.jsx index ff3502c1..12276284 100644 --- a/src/components/InputBox/index.jsx +++ b/src/components/InputBox/index.jsx @@ -21,6 +21,7 @@ export function InputBox({ onSubmit, enabled }) { return (