diff --git a/src/_locales/de/main.json b/src/_locales/de/main.json index 01c38fa..a5eb555 100644 --- a/src/_locales/de/main.json +++ b/src/_locales/de/main.json @@ -143,7 +143,5 @@ "Prompt Template": "Vorlagen-Template", "Explain this: {{selection}}": "Erkläre das: {{selection}}", "New": "Neu", - "DisplayMode": "Anzeigemodus", - "Display in sidebar": "In der Seitenleiste anzeigen", - "Display in floating toolbar": "In der schwebenden Symbolleiste anzeigen" + "Always display floating window, disable sidebar for all site adapters": "Immer das schwebende Fenster anzeigen, die Seitenleiste für alle Website-Adapter deaktivieren" } diff --git a/src/_locales/en/main.json b/src/_locales/en/main.json index bedacff..26dd94b 100644 --- a/src/_locales/en/main.json +++ b/src/_locales/en/main.json @@ -143,7 +143,5 @@ "Prompt Template": "Prompt Template", "Explain this: {{selection}}": "Explain this: {{selection}}", "New": "New", - "DisplayMode": "DisplayMode", - "Display in sidebar": "Display in sidebar", - "Display in floating toolbar": "Display in floating toolbar" + "Always display floating window, disable sidebar for all site adapters": "Always display floating window, disable sidebar for all site adapters" } diff --git a/src/_locales/es/main.json b/src/_locales/es/main.json index c8f38b8..0ae0028 100644 --- a/src/_locales/es/main.json +++ b/src/_locales/es/main.json @@ -143,7 +143,5 @@ "Prompt Template": "Plantilla de sugerencias", "Explain this: {{selection}}": "Explicar esto: {{selection}}", "New": "Nuevo", - "DisplayMode": "Modo de visualización", - "Display in sidebar": "Mostrar en la barra lateral", - "Display in floating toolbar": "Mostrar en la barra de herramientas flotante" + "Always display floating window, disable sidebar for all site adapters": "Mostrar siempre la ventana flotante, desactivar la barra lateral para todos los adaptadores de sitios" } diff --git a/src/_locales/fr/main.json b/src/_locales/fr/main.json index c2b94d4..0019d2c 100644 --- a/src/_locales/fr/main.json +++ b/src/_locales/fr/main.json @@ -143,7 +143,5 @@ "Prompt Template": "Modèle de suggestion", "Explain this: {{selection}}": "Expliquer ceci : {{selection}}", "New": "Nouveau", - "DisplayMode": "Mode d'affichage", - "Display in sidebar": "Afficher dans la barre latérale", - "Display in floating toolbar": "Afficher dans la barre d'outils flottante" + "Always display floating window, disable sidebar for all site adapters": "Toujours afficher la fenêtre flottante, désactiver la barre latérale pour tous les adaptateurs de site" } diff --git a/src/_locales/in/main.json b/src/_locales/in/main.json index e84463e..0650e9b 100644 --- a/src/_locales/in/main.json +++ b/src/_locales/in/main.json @@ -143,7 +143,5 @@ "Prompt Template": "Template Prompt", "Explain this: {{selection}}": "Jelaskan ini: {{selection}}", "New": "Baru", - "DisplayMode": "Mode Tampilan", - "Display in sidebar": "Tampilkan di bilah sisi", - "Display in floating toolbar": "Tampilkan di bilah alat mengambang" + "Always display floating window, disable sidebar for all site adapters": "Selalu tampilkan jendela mengambang, nonaktifkan sidebar untuk semua adapter situs" } diff --git a/src/_locales/it/main.json b/src/_locales/it/main.json index 70ce1d9..594ff70 100644 --- a/src/_locales/it/main.json +++ b/src/_locales/it/main.json @@ -143,7 +143,5 @@ "Prompt Template": "Modello di prompt", "Explain this: {{selection}}": "Spiega questo: {{selection}}", "New": "Nuovo", - "DisplayMode": "Modalità di visualizzazione", - "Display in sidebar": "Visualizza nella barra laterale", - "Display in floating toolbar": "Visualizza nella barra degli strumenti flottante" + "Always display floating window, disable sidebar for all site adapters": "Mostra sempre la finestra flottante, disabilita la barra laterale per tutti gli adattatori del sito" } diff --git a/src/_locales/ja/main.json b/src/_locales/ja/main.json index 73203ef..5697909 100644 --- a/src/_locales/ja/main.json +++ b/src/_locales/ja/main.json @@ -143,7 +143,5 @@ "Prompt Template": "プロンプトテンプレート", "Explain this: {{selection}}": "これを説明する: {{selection}}", "New": "新規", - "DisplayMode": "表示モード", - "Display in sidebar": "サイドバーに表示", - "Display in floating toolbar": "フローティングツールバーに表示" + "Always display floating window, disable sidebar for all site adapters": "常にフローティングウィンドウを表示し、すべてのサイトアダプターでサイドバーを無効にします" } diff --git a/src/_locales/ko/main.json b/src/_locales/ko/main.json index 675d252..e0a39a4 100644 --- a/src/_locales/ko/main.json +++ b/src/_locales/ko/main.json @@ -143,7 +143,5 @@ "Prompt Template": "프롬프트 템플릿", "Explain this: {{selection}}": "이것을 설명하세요: {{selection}}", "New": "새로 만들기", - "DisplayMode": "디스플레이 모드", - "Display in sidebar": "사이드바에 표시", - "Display in floating toolbar": "떠다니는 도구 모음에 표시" + "Always display floating window, disable sidebar for all site adapters": "항상 떠다니는 창을 표시하고 모든 사이트 어댑터의 사이드바를 비활성화합니다" } diff --git a/src/_locales/pt/main.json b/src/_locales/pt/main.json index 229703c..d4b62e2 100644 --- a/src/_locales/pt/main.json +++ b/src/_locales/pt/main.json @@ -143,7 +143,5 @@ "Prompt Template": "Modelo de Prompt", "Explain this: {{selection}}": "Explique isso: {{selection}}", "New": "Novo", - "DisplayMode": "Modo de Exibição", - "Display in sidebar": "Exibir na barra lateral", - "Display in floating toolbar": "Exibir na barra de ferramentas flutuante" + "Always display floating window, disable sidebar for all site adapters": "Sempre exibir janela flutuante, desativar barra lateral para todos os adaptadores de site" } diff --git a/src/_locales/ru/main.json b/src/_locales/ru/main.json index 7e3ab39..e5d1f75 100644 --- a/src/_locales/ru/main.json +++ b/src/_locales/ru/main.json @@ -143,7 +143,5 @@ "Prompt Template": "Шаблон запроса", "Explain this: {{selection}}": "Объяснить это: {{selection}}", "New": "Новый", - "DisplayMode": "Режим отображения", - "Display in sidebar": "Отображать в боковой панели", - "Display in floating toolbar": "Отображать в плавающей панели инструментов" + "Always display floating window, disable sidebar for all site adapters": "Всегда отображать плавающее окно, отключить боковую панель для всех адаптеров сайтов" } diff --git a/src/_locales/tr/main.json b/src/_locales/tr/main.json index 58d9320..77d4fba 100644 --- a/src/_locales/tr/main.json +++ b/src/_locales/tr/main.json @@ -143,7 +143,5 @@ "Prompt Template": "Prompt Şablonu", "Explain this: {{selection}}": "Bunu açıkla: {{selection}}", "New": "Yeni", - "DisplayMode": "Görüntüleme Modu", - "Display in sidebar": "Kenar çubuğunda görüntüle", - "Display in floating toolbar": "Kayan araç çubuğunda görüntüle" + "Always display floating window, disable sidebar for all site adapters": "Her zaman kayan pencereyi görüntüle, tüm site adaptörleri için kenar çubuğunu devre dışı bırak" } diff --git a/src/_locales/zh-hans/main.json b/src/_locales/zh-hans/main.json index 0a1282d..f713173 100644 --- a/src/_locales/zh-hans/main.json +++ b/src/_locales/zh-hans/main.json @@ -144,9 +144,7 @@ "Prompt Template": "提示模板", "Explain this: {{selection}}": "解释这个: {{selection}}", "New": "新建", - "DisplayMode": "显示方式", - "Display in sidebar": "在侧边栏显示", - "Display in floating toolbar": "在浮动工具栏显示", + "Always display floating window, disable sidebar for all site adapters": "总是显示浮动窗口, 禁用所有站点适配器的侧边栏", "Temperature": "温度", "keep-alive Time": "保活时间", "5m": "5分钟", diff --git a/src/_locales/zh-hant/main.json b/src/_locales/zh-hant/main.json index 5e95440..21a4089 100644 --- a/src/_locales/zh-hant/main.json +++ b/src/_locales/zh-hant/main.json @@ -143,7 +143,5 @@ "Prompt Template": "提示範本", "Explain this: {{selection}}": "解釋這個: {{selection}}", "New": "新增", - "DisplayMode": "顯示模式", - "Display in sidebar": "在側邊欄顯示", - "Display in floating toolbar": "在浮動工具列顯示" + "Always display floating window, disable sidebar for all site adapters": "總是顯示浮動視窗,停用所有網站適配器的側邊欄" } diff --git a/src/components/ConversationCard/index.jsx b/src/components/ConversationCard/index.jsx index 57a0ca5..58d2ece 100644 --- a/src/components/ConversationCard/index.jsx +++ b/src/components/ConversationCard/index.jsx @@ -9,6 +9,7 @@ import { DesktopDownloadIcon, LinkExternalIcon, MoveToBottomIcon, + SearchIcon, } from '@primer/octicons-react' import { Pin, WindowDesktop, XLg } from 'react-bootstrap-icons' import FileSaver from 'file-saver' @@ -46,6 +47,7 @@ function ConversationCard(props) { const { t } = useTranslation() const [isReady, setIsReady] = useState(!props.question) const [port, setPort] = useState(() => Browser.runtime.connect()) + const [triggered, setTriggered] = useState(!props.waitForTrigger) const [session, setSession] = useState(props.session) const windowSize = useClampWindowSize([750, 1500], [250, 1100]) const bodyRef = useRef(null) @@ -59,7 +61,7 @@ function ConversationCard(props) { const [conversationItemData, setConversationItemData] = useState( (() => { if (session.conversationRecords.length === 0) - if (props.question) + if (props.question && triggered) return [ new ConversationItemData( 'answer', @@ -102,12 +104,12 @@ function ConversationCard(props) { useEffect(async () => { // 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) { + if (props.question && triggered) { const newSession = initSession({ ...session, question: props.question }) setSession(newSession) await postMessage({ session: newSession }) } - }, [props.question]) // usually only triggered once + }, [props.question, triggered]) // usually only triggered once /** * @param {string} value @@ -516,32 +518,53 @@ function ConversationCard(props) { /> ))} - { - const newQuestion = new ConversationItemData('question', question) - const newAnswer = new ConversationItemData( - 'answer', - `

${t('Waiting for response...')}

`, - ) - setConversationItemData([...conversationItemData, newQuestion, newAnswer]) - setIsReady(false) + {props.waitForTrigger && !triggered ? ( +

{ + setConversationItemData([ + new ConversationItemData( + 'answer', + `

${t(`Waiting for response...`)}

`, + ), + ]) + setTriggered(true) + setIsReady(false) + }} + > + + {t('Ask ChatGPT')} + +

+ ) : ( + { + const newQuestion = new ConversationItemData('question', question) + const newAnswer = new ConversationItemData( + 'answer', + `

${t('Waiting for response...')}

`, + ) + setConversationItemData([...conversationItemData, newQuestion, newAnswer]) + setIsReady(false) - const newSession = { ...session, question, isRetry: false } - setSession(newSession) - try { - await postMessage({ session: newSession }) - } catch (e) { - updateAnswer(e, false, 'error') - } - bodyRef.current.scrollTo({ - top: bodyRef.current.scrollHeight, - behavior: 'instant', - }) - }} - /> + const newSession = { ...session, question, isRetry: false } + setSession(newSession) + try { + await postMessage({ session: newSession }) + } catch (e) { + updateAnswer(e, false, 'error') + } + bodyRef.current.scrollTo({ + top: bodyRef.current.scrollHeight, + behavior: 'instant', + }) + }} + /> + )} ) } @@ -557,6 +580,7 @@ ConversationCard.propTypes = { onDock: PropTypes.func, notClampSize: PropTypes.bool, pageMode: PropTypes.bool, + waitForTrigger: PropTypes.bool, } export default memo(ConversationCard) diff --git a/src/components/ConversationItem/index.jsx b/src/components/ConversationItem/index.jsx index 4079276..44a5ec2 100644 --- a/src/components/ConversationItem/index.jsx +++ b/src/components/ConversationItem/index.jsx @@ -5,7 +5,7 @@ import ReadButton from '../ReadButton' import PropTypes from 'prop-types' import MarkdownRender from '../MarkdownRender/markdown.jsx' import { useTranslation } from 'react-i18next' -import { isUsingCustomModel, isUsingOllamaModel } from '../../config/index.mjs' +import { isUsingCustomModel } from '../../config/index.mjs' import { useConfig } from '../../hooks/use-config.mjs' function AnswerTitle({ descName, modelName }) { diff --git a/src/components/FloatingToolbar/index.jsx b/src/components/FloatingToolbar/index.jsx index e0705bd..e44665e 100644 --- a/src/components/FloatingToolbar/index.jsx +++ b/src/components/FloatingToolbar/index.jsx @@ -22,7 +22,7 @@ function FloatingToolbar(props) { const windowSize = useClampWindowSize([750, 1500], [0, Infinity]) const config = useConfig(() => { setRender(true) - if (!triggered) { + if (!triggered && selection) { props.container.style.position = 'absolute' setTimeout(() => { const left = Math.min( @@ -49,7 +49,7 @@ function FloatingToolbar(props) { if (!render) return
- if (triggered) { + if (triggered || (prompt && !selection)) { const updatePosition = () => { const newPosition = setElementPositionInViewport(props.container, position.x, position.y) if (position.x !== newPosition.x || position.y !== newPosition.y) setPosition(newPosition) // clear extra virtual position offset @@ -106,6 +106,7 @@ function FloatingToolbar(props) { dockable={props.dockable} onDock={onDock} onUpdate={onUpdate} + waitForTrigger={prompt && !triggered && !selection} />
diff --git a/src/config/index.mjs b/src/config/index.mjs index b595f28..1b5b86c 100644 --- a/src/config/index.mjs +++ b/src/config/index.mjs @@ -8,11 +8,6 @@ export const TriggerMode = { manually: 'Manually', } -export const DisplayMode = { - sidebar: 'Display in sidebar', - floatingToolbar: 'Display in floating toolbar', -} - export const ThemeMode = { light: 'Light', dark: 'Dark', @@ -213,8 +208,6 @@ export const defaultConfig = { /** @type {keyof TriggerMode}*/ triggerMode: 'manually', - /** @type {keyof DisplayMode}*/ - displayMode: 'sidebar', /** @type {keyof ThemeMode}*/ themeMode: 'auto', /** @type {keyof Models}*/ @@ -223,6 +216,7 @@ export const defaultConfig = { preferredLanguage: getNavigatorLanguage(), clickIconAction: 'popup', insertAtTop: isMobile(), + alwaysFloatingSidebar: false, lockWhenAnswer: true, answerScrollMargin: 200, autoRegenAfterSwitchModel: false, diff --git a/src/content-script/index.jsx b/src/content-script/index.jsx index 7962d26..713dd07 100644 --- a/src/content-script/index.jsx +++ b/src/content-script/index.jsx @@ -15,6 +15,7 @@ import { import { createElementAtPosition, cropText, + endsWithQuestionMark, getClientPosition, getPossibleElementByQuerySelector, } from '../utils' @@ -33,28 +34,30 @@ import NotificationForChatGPTWeb from '../components/NotificationForChatGPTWeb' * @param {UserConfig} userConfig */ async function mountComponent(siteConfig, userConfig) { - const retry = 10 - let oldUrl = location.href - for (let i = 1; i <= retry; i++) { - if (location.href !== oldUrl) { - console.log(`SiteAdapters Retry ${i}/${retry}: stop`) - return - } - const e = - (siteConfig && - (getPossibleElementByQuerySelector(siteConfig.sidebarContainerQuery) || - getPossibleElementByQuerySelector(siteConfig.appendContainerQuery) || - getPossibleElementByQuerySelector(siteConfig.resultsContainerQuery))) || - getPossibleElementByQuerySelector([userConfig.prependQuery]) || - getPossibleElementByQuerySelector([userConfig.appendQuery]) - if (e) { - console.log(`SiteAdapters Retry ${i}/${retry}: found`) - console.log(e) - break - } else { - console.log(`SiteAdapters Retry ${i}/${retry}: not found`) - if (i === retry) return - else await new Promise((r) => setTimeout(r, 500)) + if (!userConfig.alwaysFloatingSidebar) { + const retry = 10 + let oldUrl = location.href + for (let i = 1; i <= retry; i++) { + if (location.href !== oldUrl) { + console.log(`SiteAdapters Retry ${i}/${retry}: stop`) + return + } + const e = + (siteConfig && + (getPossibleElementByQuerySelector(siteConfig.sidebarContainerQuery) || + getPossibleElementByQuerySelector(siteConfig.appendContainerQuery) || + getPossibleElementByQuerySelector(siteConfig.resultsContainerQuery))) || + getPossibleElementByQuerySelector([userConfig.prependQuery]) || + getPossibleElementByQuerySelector([userConfig.appendQuery]) + if (e) { + console.log(`SiteAdapters Retry ${i}/${retry}: found`) + console.log(e) + break + } else { + console.log(`SiteAdapters Retry ${i}/${retry}: not found`) + if (i === retry) return + else await new Promise((r) => setTimeout(r, 500)) + } } } document.querySelectorAll('.chatgptbox-container,#chatgptbox-container').forEach((e) => { @@ -77,14 +80,17 @@ async function mountComponent(siteConfig, userConfig) { } const toolbarContainer = createElementAtPosition(position.x, position.y) toolbarContainer.className = 'chatgptbox-toolbar-container-not-queryable' - if (userConfig.displayMode === 'floatingToolbar') { + if (userConfig.alwaysFloatingSidebar && question) { + let triggered = false + if (userConfig.triggerMode === 'always') triggered = true + else if (userConfig.triggerMode === 'questionMark' && endsWithQuestionMark(question.trim())) + triggered = true render( , diff --git a/src/manifest.json b/src/manifest.json index 4acc2ac..95a23b3 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.5.7", + "version": "2.5.6", "manifest_version": 3, "icons": { "16": "logo.png", diff --git a/src/manifest.v2.json b/src/manifest.v2.json index 8f2c496..80fd9a3 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.5.7", + "version": "2.5.6", "manifest_version": 2, "icons": { "16": "logo.png", diff --git a/src/popup/sections/GeneralPart.jsx b/src/popup/sections/GeneralPart.jsx index 045a9a9..2cf8b3a 100644 --- a/src/popup/sections/GeneralPart.jsx +++ b/src/popup/sections/GeneralPart.jsx @@ -15,7 +15,6 @@ import { Models, ThemeMode, TriggerMode, - DisplayMode, isUsingMoonshotApi, } from '../../config/index.mjs' import Browser from 'webextension-polyfill' @@ -120,24 +119,6 @@ export function GeneralPart({ config, updateConfig }) { })} -