From f0c635bd3b4c3f4b6a7b3824947982feaa04fe6b Mon Sep 17 00:00:00 2001 From: lencx Date: Sun, 15 Jan 2023 16:14:37 +0800 Subject: [PATCH] fix: slash command does not work (#207) --- UPDATE_LOG.md | 4 + src-tauri/src/scripts/cmd.js | 319 +++++++++++++++------------- src-tauri/src/scripts/export.js | 5 +- src-tauri/src/scripts/popup.core.js | 7 +- src/hooks/useColumns.tsx | 10 +- src/view/download/index.tsx | 2 +- src/view/notes/index.tsx | 3 +- 7 files changed, 184 insertions(+), 166 deletions(-) diff --git a/UPDATE_LOG.md b/UPDATE_LOG.md index b40ac36..09d75cf 100644 --- a/UPDATE_LOG.md +++ b/UPDATE_LOG.md @@ -1,5 +1,9 @@ # UPDATE LOG +## v0.9.1 + +fix: slash command does not work + ## v0.9.0 fix: diff --git a/src-tauri/src/scripts/cmd.js b/src-tauri/src/scripts/cmd.js index b390d0a..d4bcb53 100644 --- a/src-tauri/src/scripts/cmd.js +++ b/src-tauri/src/scripts/cmd.js @@ -87,185 +87,198 @@ $(function() { clearInterval(window.formInterval); } window.formInterval = setInterval(() => { - const form = document.querySelector("form"); + const form = document.querySelector("form textarea"); if (!form) return; clearInterval(window.formInterval); cmdTip(); - }, 200); + new MutationObserver(function (mutationsList) { + for (const mutation of mutationsList) { + if (mutation.target.getAttribute('id') === '__next') { + cmdTip(); + } + if (mutation.target.getAttribute('class') === 'chat-model-cmd-list') { + // The `chatgpt prompt` fill can be done by clicking on the event. + const searchDom = document.querySelector("form .chat-model-cmd-list>div"); + const searchInput = document.querySelector('form textarea'); + if (!searchDom) return; + searchDom.addEventListener('click', (event) => { + const item = event.target.closest("div"); + if (item) { + const val = decodeURIComponent(item.getAttribute('data-prompt')); + searchInput.value = val; + document.querySelector('form textarea').focus(); + initDom(); + } + }); + } + } + }).observe(document.body, { + childList: true, + subtree: true, + }); + }, 300); }); async function cmdTip() { + initDom(); const chatModelJson = await invoke('get_chat_model_cmd') || {}; const data = chatModelJson.data; if (data.length <= 0) return; - const modelDom = document.createElement('div'); - modelDom.classList.add('chat-model-cmd-list'); + let modelDom = document.querySelector('.chat-model-cmd-list'); + if (!modelDom) { + const dom = document.createElement('div'); + dom.classList.add('chat-model-cmd-list'); + document.querySelector('form').appendChild(dom); + modelDom = document.querySelector('.chat-model-cmd-list'); - // fix: tray window - if (__TAURI_METADATA__.__currentWindow.label === 'tray') { - modelDom.style.bottom = '54px'; - } - - document.querySelector('form').appendChild(modelDom); - const itemDom = (v) => `
/${v.cmd}${v.act}
`; - const renderList = (v) => { - modelDom.innerHTML = `
${v.map(itemDom).join('')}
`; - window.__CHAT_MODEL_CMD_PROMPT__ = v[0]?.prompt.trim(); - window.__CHAT_MODEL_CMD__ = v[0]?.cmd.trim(); - window.__list = modelDom.querySelectorAll('.cmd-item'); - window.__index = 0; - window.__list[window.__index].classList.add('selected'); - }; - const setPrompt = (v = '') => { - if (v.trim()) { - window.__CHAT_MODEL_CMD_PROMPT__ = window.__CHAT_MODEL_CMD_PROMPT__?.replace(/\{([^{}]*)\}/, `{${v.trim()}}`); - } - } - const searchInput = document.querySelector('form textarea'); - - // Enter a command starting with `/` and press a space to automatically fill `chatgpt prompt`. - // If more than one command appears in the search results, the first one will be used by default. - searchInput.addEventListener('keydown', (event) => { - if (!window.__CHAT_MODEL_CMD_PROMPT__) { - return; + // fix: tray window + if (__TAURI_METADATA__.__currentWindow.label === 'tray') { + modelDom.style.bottom = '54px'; } - // ------------------ Keyboard scrolling (ArrowUp | ArrowDown) -------------------------- - if (event.keyCode === 38 && window.__index > 0) { // ArrowUp - window.__list[window.__index].classList.remove('selected'); - window.__index = window.__index - 1; + const itemDom = (v) => `
/${v.cmd}${v.act}
`; + const renderList = (v) => { + initDom(); + modelDom.innerHTML = `
${v.map(itemDom).join('')}
`; + window.__CHAT_MODEL_CMD_PROMPT__ = v[0]?.prompt.trim(); + window.__CHAT_MODEL_CMD__ = v[0]?.cmd.trim(); + window.__list = modelDom.querySelectorAll('.cmd-item'); + window.__index = 0; window.__list[window.__index].classList.add('selected'); - window.__CHAT_MODEL_CMD_PROMPT__ = decodeURIComponent(window.__list[window.__index].getAttribute('data-prompt')); - searchInput.value = `/${window.__list[window.__index].getAttribute('data-cmd')}`; - event.preventDefault(); - } - - if (event.keyCode === 40 && window.__index < window.__list.length - 1) { // ArrowDown - window.__list[window.__index].classList.remove('selected'); - window.__index = window.__index + 1; - window.__list[window.__index].classList.add('selected'); - window.__CHAT_MODEL_CMD_PROMPT__ = decodeURIComponent(window.__list[window.__index].getAttribute('data-prompt')); - searchInput.value = `/${window.__list[window.__index].getAttribute('data-cmd')}`; - event.preventDefault(); - } - - const containerHeight = modelDom.offsetHeight; - const itemHeight = window.__list[0].offsetHeight + 1; - - const itemTop = window.__list[window.__index].offsetTop; - const itemBottom = itemTop + itemHeight; - if (itemTop < modelDom.scrollTop || itemBottom > modelDom.scrollTop + containerHeight) { - modelDom.scrollTop = itemTop; - } - - // ------------------ TAB key replaces `{q}` tag content ------------------------------- - // feat: https://github.com/lencx/ChatGPT/issues/54 - if (event.keyCode === 9 && !window.__CHAT_MODEL_STATUS__) { - const strGroup = window.__CHAT_MODEL_CMD_PROMPT__.match(/\{([^{}]*)\}/) || []; - - if (strGroup[1]) { - searchInput.value = `/${window.__CHAT_MODEL_CMD__}` + ` {${strGroup[1]}}` + ' |-> '; - window.__CHAT_MODEL_STATUS__ = 1; + }; + const setPrompt = (v = '') => { + if (v.trim()) { + window.__CHAT_MODEL_CMD_PROMPT__ = window.__CHAT_MODEL_CMD_PROMPT__?.replace(/\{([^{}]*)\}/, `{${v.trim()}}`); } - event.preventDefault(); } + const searchInput = document.querySelector('form textarea'); - if (window.__CHAT_MODEL_STATUS__ === 1 && event.keyCode === 9) { // TAB - const data = searchInput.value.split('|->'); - if (data[1]?.trim()) { - setPrompt(data[1]); - window.__CHAT_MODEL_STATUS__ = 2; + // Enter a command starting with `/` and press a space to automatically fill `chatgpt prompt`. + // If more than one command appears in the search results, the first one will be used by default. + function cmdKeydown(event) { + if (!window.__CHAT_MODEL_CMD_PROMPT__) { + return; } - event.preventDefault(); - } - // input text - if (window.__CHAT_MODEL_STATUS__ === 2 && event.keyCode === 9) { // TAB - searchInput.value = window.__CHAT_MODEL_CMD_PROMPT__; - modelDom.innerHTML = ''; - delete window.__CHAT_MODEL_STATUS__; - event.preventDefault(); - } + // ------------------ Keyboard scrolling (ArrowUp | ArrowDown) -------------------------- + if (event.keyCode === 38 && window.__index > 0) { // ArrowUp + window.__list[window.__index].classList.remove('selected'); + window.__index = window.__index - 1; + window.__list[window.__index].classList.add('selected'); + window.__CHAT_MODEL_CMD_PROMPT__ = decodeURIComponent(window.__list[window.__index].getAttribute('data-prompt')); + searchInput.value = `/${window.__list[window.__index].getAttribute('data-cmd')}`; + event.preventDefault(); + } - // ------------------ type in a space to complete the fill ------------------------------------ - if (event.keyCode === 32) { - searchInput.value = window.__CHAT_MODEL_CMD_PROMPT__; - modelDom.innerHTML = ''; - delete window.__CHAT_MODEL_CMD_PROMPT__; - } + if (event.keyCode === 40 && window.__index < window.__list.length - 1) { // ArrowDown + window.__list[window.__index].classList.remove('selected'); + window.__index = window.__index + 1; + window.__list[window.__index].classList.add('selected'); + window.__CHAT_MODEL_CMD_PROMPT__ = decodeURIComponent(window.__list[window.__index].getAttribute('data-prompt')); + searchInput.value = `/${window.__list[window.__index].getAttribute('data-cmd')}`; + event.preventDefault(); + } - // ------------------ send -------------------------------------------------------------------- - if (event.keyCode === 13 && window.__CHAT_MODEL_CMD_PROMPT__) { // Enter - const data = searchInput.value.split('|->'); - setPrompt(data[1]); + const containerHeight = modelDom.offsetHeight; + const itemHeight = window.__list[0].offsetHeight + 1; - searchInput.value = window.__CHAT_MODEL_CMD_PROMPT__; - modelDom.innerHTML = ''; - delete window.__CHAT_MODEL_CMD_PROMPT__; - delete window.__CHAT_MODEL_CMD__; - delete window.__CHAT_MODEL_STATUS__; - event.preventDefault(); - } - }); + const itemTop = window.__list[window.__index].offsetTop; + const itemBottom = itemTop + itemHeight; + if (itemTop < modelDom.scrollTop || itemBottom > modelDom.scrollTop + containerHeight) { + modelDom.scrollTop = itemTop; + } - searchInput.addEventListener('input', () => { - if (searchInput.value === '') { - delete window.__CHAT_MODEL_CMD_PROMPT__; - delete window.__CHAT_MODEL_CMD__; - delete window.__CHAT_MODEL_STATUS__; - } + // ------------------ TAB key replaces `{q}` tag content ------------------------------- + // feat: https://github.com/lencx/ChatGPT/issues/54 + if (event.keyCode === 9 && !window.__CHAT_MODEL_STATUS__) { + const strGroup = window.__CHAT_MODEL_CMD_PROMPT__.match(/\{([^{}]*)\}/) || []; - if (window.__CHAT_MODEL_STATUS__) return; + if (strGroup[1]) { + searchInput.value = `/${window.__CHAT_MODEL_CMD__}` + ` {${strGroup[1]}}` + ' |-> '; + window.__CHAT_MODEL_STATUS__ = 1; + } else { + searchInput.value = window.__CHAT_MODEL_CMD_PROMPT__; + initDom(); + } + event.preventDefault(); + } - const query = searchInput.value; - if (!query || !/^\//.test(query)) { - modelDom.innerHTML = ''; - return; - } + if (window.__CHAT_MODEL_STATUS__ === 1 && event.keyCode === 9) { // TAB + const data = searchInput.value.split('|->'); + if (data[1]?.trim()) { + setPrompt(data[1]); + window.__CHAT_MODEL_STATUS__ = 2; + } + event.preventDefault(); + } - // all cmd result - if (query === '/') { - renderList(data); - return; - } - - const result = data.filter(i => new RegExp(query.substring(1)).test(i.cmd)); - if (result.length > 0) { - renderList(result); - } else { - modelDom.innerHTML = ''; - delete window.__CHAT_MODEL_CMD_PROMPT__; - delete window.__CHAT_MODEL_CMD__; - delete window.__CHAT_MODEL_STATUS__; - } - }, { - capture: false, - passive: true, - once: false - }); - - if (window.searchInterval) { - clearInterval(window.searchInterval); - } - window.searchInterval = setInterval(() => { - // The `chatgpt prompt` fill can be done by clicking on the event. - const searchDom = document.querySelector("form .chat-model-cmd-list>div"); - if (!searchDom) return; - searchDom.addEventListener('click', (event) => { - // .cmd-item - const item = event.target.closest("div"); - if (item) { - const val = decodeURIComponent(item.getAttribute('data-prompt')); - searchInput.value = val; - document.querySelector('form textarea').focus(); - window.__CHAT_MODEL_CMD_PROMPT__ = val; + // input text + if (window.__CHAT_MODEL_STATUS__ === 2 && event.keyCode === 9) { // TAB + searchInput.value = window.__CHAT_MODEL_CMD_PROMPT__; modelDom.innerHTML = ''; + delete window.__CHAT_MODEL_STATUS__; + event.preventDefault(); } - }, { - capture: false, - passive: true, - once: false - }); - }, 200); + + // ------------------ type in a space to complete the fill ------------------------------------ + if (event.keyCode === 32) { + searchInput.value = window.__CHAT_MODEL_CMD_PROMPT__; + modelDom.innerHTML = ''; + delete window.__CHAT_MODEL_CMD_PROMPT__; + } + + // ------------------ send -------------------------------------------------------------------- + if (event.keyCode === 13 && window.__CHAT_MODEL_CMD_PROMPT__) { // Enter + const data = searchInput.value.split('|->'); + setPrompt(data[1]); + + searchInput.value = window.__CHAT_MODEL_CMD_PROMPT__; + + initDom(); + event.preventDefault(); + } + } + searchInput.removeEventListener('keydown', cmdKeydown); + searchInput.addEventListener('keydown', cmdKeydown); + + function cmdInput() { + if (searchInput.value === '') { + initDom(); + } + + if (window.__CHAT_MODEL_STATUS__) return; + + const query = searchInput.value; + if (!query || !/^\//.test(query)) { + initDom(); + return; + } + + // all cmd result + if (query === '/') { + renderList(data); + return; + } + + const result = data.filter(i => new RegExp(query.substring(1)).test(i.cmd)); + if (result.length > 0) { + renderList(result); + } else { + initDom(); + } + } + searchInput.removeEventListener('input', cmdInput); + searchInput.addEventListener('input', cmdInput); + } +} + +function initDom() { + const modelDom = document.querySelector('.chat-model-cmd-list'); + if (modelDom) { + modelDom.innerHTML = ''; + delete window.__CHAT_MODEL_CMD_PROMPT__; + delete window.__CHAT_MODEL_CMD__; + delete window.__CHAT_MODEL_STATUS__; + } } diff --git a/src-tauri/src/scripts/export.js b/src-tauri/src/scripts/export.js index a5539d5..fe60c35 100644 --- a/src-tauri/src/scripts/export.js +++ b/src-tauri/src/scripts/export.js @@ -1,8 +1,7 @@ // *** Core Script - Export *** -const buttonOuterHTMLFallback = ``; - $(async function () { + const buttonOuterHTMLFallback = ``; if (window.innerWidth < 767) return; const chatConf = await invoke('get_chat_conf') || {}; if (window.buttonsInterval) { @@ -190,7 +189,7 @@ async function handlePdf(imgData, canvas, pixelRatio) { } function getName() { - const id = uid().toString(36); + const id = window.crypto.getRandomValues(new Uint32Array(1))[0].toString(36); const name = document.querySelector('nav .overflow-y-auto a.hover\\:bg-gray-800')?.innerText?.trim() || ''; return { filename: name ? name : id, id, pathname: 'chat.download.json' }; } diff --git a/src-tauri/src/scripts/popup.core.js b/src-tauri/src/scripts/popup.core.js index 953420a..7e8f5fc 100644 --- a/src-tauri/src/scripts/popup.core.js +++ b/src-tauri/src/scripts/popup.core.js @@ -16,9 +16,9 @@ $(async function () { background: #4a4a4a; color: white; font-weight: bold; - padding: 5px 8px; - border-radius: 4px; - font-size: 12px; + padding: 3px 5px; + border-radius: 2px; + font-size: 10px; cursor: pointer; } `; @@ -31,6 +31,7 @@ $(async function () { const { computePosition, flip, offset, shift } = window.FloatingUIDOM; document.body.addEventListener('mousedown', async (e) => { + selectionMenu.style.display = 'none'; if (e.target.id === 'chagpt-selection-menu') { await invoke('dalle2_window', { query: encodeURIComponent(window.__DALLE2_CONTENT__) }); } else { diff --git a/src/hooks/useColumns.tsx b/src/hooks/useColumns.tsx index acc0dfa..d5562ff 100644 --- a/src/hooks/useColumns.tsx +++ b/src/hooks/useColumns.tsx @@ -53,25 +53,25 @@ interface EditRowProps { } export const EditRow: FC = ({ rowKey, row, actions }) => { const [isEdit, setEdit] = useState(false); - const [val, setVal] = useState(row[rowKey]); + const [val, setVal] = useState(row[rowKey] || ''); const handleEdit = () => { setEdit(true); }; - const handleChange = (e: React.ChangeEvent) => { + const handleChange = (e: React.ChangeEvent) => { setVal(e.target.value) }; const handleSave = () => { setEdit(false); - row[rowKey] = val; + row[rowKey] = val?.trim(); actions?.setRecord(row, 'rowedit') }; return isEdit ? ( - { await invoke('download_list', { pathname: CHAT_DOWNLOAD_JSON, dir: 'download' }); + rowReset(); const data = await refreshJson(); opInit(data); }; diff --git a/src/view/notes/index.tsx b/src/view/notes/index.tsx index b93bd35..38f0ab0 100644 --- a/src/view/notes/index.tsx +++ b/src/view/notes/index.tsx @@ -65,7 +65,6 @@ export default function Notes() { const notesDir = await path.join(await chatRoot(), 'notes'); await fs.removeDir(notesDir, { recursive: true }); await handleRefresh(); - rowReset(); message.success('All files have been cleared!'); return; } @@ -83,6 +82,7 @@ export default function Notes() { const handleRefresh = async () => { await invoke('download_list', { pathname: CHAT_NOTES_JSON, dir: 'notes' }); + rowReset(); const data = await refreshJson(); opInit(data); }; @@ -135,6 +135,7 @@ export default function Notes() { >