From 50b1f7db12fce10eeab7a83d25a9abe423f21809 Mon Sep 17 00:00:00 2001 From: Yidadaa <yidadaa@qq.com> Date: Sat, 24 Jun 2023 22:32:46 +0800 Subject: [PATCH 1/4] feat: right-click to copy message to user input --- app/components/chat.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 35f280466..d4e1dcd84 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -605,6 +605,10 @@ export function Chat() { const onRightClick = (e: any, message: ChatMessage) => { // copy to clipboard if (selectOrCopy(e.currentTarget, message.content)) { + if (userInput.length === 0) { + setUserInput(message.content); + } + e.preventDefault(); } }; From 5d06fa217cfde63439ef2c5b09cc71703e7d7f90 Mon Sep 17 00:00:00 2001 From: Yidadaa <yidadaa@qq.com> Date: Sat, 24 Jun 2023 22:41:13 +0800 Subject: [PATCH 2/4] feat: close #2013 add switch model button to chat actions --- app/components/chat.tsx | 21 +++++++++++++++++++++ app/icons/robot.svg | 1 + 2 files changed, 22 insertions(+) create mode 100644 app/icons/robot.svg diff --git a/app/components/chat.tsx b/app/components/chat.tsx index d4e1dcd84..505af77da 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -27,6 +27,7 @@ import DarkIcon from "../icons/dark.svg"; import AutoIcon from "../icons/auto.svg"; import BottomIcon from "../icons/bottom.svg"; import StopIcon from "../icons/pause.svg"; +import RobotIcon from "../icons/robot.svg"; import { ChatMessage, @@ -38,6 +39,7 @@ import { Theme, useAppConfig, DEFAULT_TOPIC, + ALL_MODELS, } from "../store"; import { @@ -385,6 +387,19 @@ export function ChatActions(props: { const couldStop = ChatControllerPool.hasPending(); const stopAll = () => ChatControllerPool.stopAll(); + // switch model + const currentModel = chatStore.currentSession().mask.modelConfig.model; + function nextModel() { + const models = ALL_MODELS.filter((m) => m.available).map((m) => m.name); + const modelIndex = models.indexOf(currentModel); + const nextIndex = (modelIndex + 1) % models.length; + const nextModel = models[nextIndex]; + chatStore.updateCurrentSession((session) => { + session.mask.modelConfig.model = nextModel; + session.mask.syncGlobalConfig = false; + }); + } + return ( <div className={chatStyle["chat-input-actions"]}> {couldStop && ( @@ -453,6 +468,12 @@ export function ChatActions(props: { }); }} /> + + <ChatAction + onClick={nextModel} + text={currentModel} + icon={<RobotIcon />} + /> </div> ); } diff --git a/app/icons/robot.svg b/app/icons/robot.svg new file mode 100644 index 000000000..62dd9dc8d --- /dev/null +++ b/app/icons/robot.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16" fill="none"><g opacity="1" transform="translate(0 0) rotate(0)"><mask id="bg-mask-0" fill="white"><use xlink:href="#path_0"></use></mask><g mask="url(#bg-mask-0)" ><path id="路径 1" style="fill:#333333; opacity:1;" d="M3.67,13.67h8.66c0.0022,0 0.0033,-0.00113 0.0033,-0.0034v-7.32997c0,-0.00091 -0.00033,-0.00169 -0.001,-0.00235c-0.0006,-0.00066 -0.00137,-0.00099 -0.0023,-0.00099h-8.66c-0.00222,0 -0.00333,0.00111 -0.00333,0.00334v7.32997c0,0.00227 0.00111,0.0034 0.00333,0.0034zM3.67,15.0033c-0.36909,0 -0.68414,-0.1305 -0.94515,-0.3915c-0.26101,-0.261 -0.39152,-0.57607 -0.39152,-0.9452v-7.32997c0,-0.3691 0.13051,-0.68415 0.39152,-0.94516c0.26101,-0.26101 0.57606,-0.39151 0.94515,-0.39151h8.66c0.36907,0 0.68413,0.1305 0.9452,0.39151c0.261,0.26101 0.3915,0.57606 0.3915,0.94516v7.32997c0,0.36913 -0.1305,0.6842 -0.3915,0.9452c-0.26107,0.261 -0.57613,0.3915 -0.9452,0.3915z"></path><path id="路径 2" style="fill:#333333; opacity:1;" d="M9.81876,6.127c-0.03001,0.03187 -0.06284,0.0605 -0.09849,0.08591c-0.03565,0.02541 -0.07343,0.04709 -0.11335,0.06505c-0.03992,0.01796 -0.08121,0.03185 -0.12386,0.04168c-0.04265,0.00983 -0.08586,0.01541 -0.12962,0.01672c-0.04375,0.00132 -0.08721,-0.00164 -0.13038,-0.00888c-0.04317,-0.00725 -0.08522,-0.01863 -0.12615,-0.03416c-0.04093,-0.01553 -0.07995,-0.0349 -0.11706,-0.05811c-0.07495,-0.04688 -0.13808,-0.10632 -0.18939,-0.17831c-0.05131,-0.07199 -0.08688,-0.15106 -0.10673,-0.23721c-0.01985,-0.08615 -0.02246,-0.17282 -0.00783,-0.26c0.01463,-0.08719 0.04538,-0.16826 0.09226,-0.24321l1.67004,-2.67c0.0232,-0.03711 0.0498,-0.07161 0.0798,-0.10348c0.03,-0.03187 0.06283,-0.0605 0.0985,-0.08591c0.0356,-0.02541 0.07337,-0.04709 0.1133,-0.06505c0.03993,-0.01796 0.08123,-0.03185 0.1239,-0.04168c0.04267,-0.00983 0.08587,-0.01541 0.1296,-0.01672c0.04373,-0.00132 0.0872,0.00164 0.1304,0.00888c0.04313,0.00725 0.08517,0.01863 0.1261,0.03416c0.04093,0.01553 0.07997,0.0349 0.1171,0.05811c0.03713,0.02321 0.07163,0.04982 0.1035,0.07983c0.03187,0.03001 0.0605,0.06283 0.0859,0.09848c0.0254,0.03565 0.04707,0.07343 0.065,0.11335c0.018,0.03992 0.0319,0.08121 0.0417,0.12386c0.00987,0.04266 0.01543,0.08587 0.0167,0.12962c0.00133,0.04375 -0.00163,0.08721 -0.0089,0.13038c-0.0072,0.04317 -0.01857,0.08522 -0.0341,0.12615c-0.01553,0.04093 -0.0349,0.07995 -0.0581,0.11706l-1.67001,2.67c-0.02321,0.03711 -0.04982,0.07161 -0.07983,0.10348z"></path><path id="路径 3" style="fill:#333333; opacity:1;" d="M7.29332,5.43354c0.01553,0.04093 0.02691,0.08297 0.03416,0.12614c0.00724,0.04317 0.0102,0.08664 0.00888,0.13039c-0.00131,0.04375 -0.00689,0.08696 -0.01672,0.12962c-0.00983,0.04265 -0.02372,0.08394 -0.04168,0.12386c-0.01796,0.03992 -0.03964,0.0777 -0.06505,0.11335c-0.02541,0.03565 -0.05404,0.06847 -0.08591,0.09848c-0.03187,0.03001 -0.06637,0.05662 -0.10348,0.07983c-0.03711,0.02321 -0.07613,0.04258 -0.11706,0.05811c-0.04093,0.01553 -0.08298,0.02691 -0.12615,0.03416c-0.04317,0.00724 -0.08663,0.0102 -0.13038,0.00888c-0.04375,-0.00131 -0.08696,-0.00689 -0.12962,-0.01672c-0.04265,-0.00983 -0.08394,-0.02372 -0.12386,-0.04168c-0.03992,-0.01796 -0.0777,-0.03964 -0.11335,-0.06505c-0.03565,-0.02541 -0.06847,-0.05404 -0.09848,-0.08591c-0.03001,-0.03187 -0.05662,-0.06637 -0.07983,-0.10348l-1.67,-2.67c-0.02321,-0.03711 -0.04258,-0.07613 -0.05811,-0.11706c-0.01553,-0.04093 -0.02691,-0.08298 -0.03416,-0.12615c-0.00724,-0.04317 -0.0102,-0.08663 -0.00888,-0.13038c0.00131,-0.04375 0.00689,-0.08696 0.01672,-0.12962c0.00983,-0.04265 0.02372,-0.08394 0.04168,-0.12386c0.01796,-0.03992 0.03964,-0.0777 0.06505,-0.11335c0.02541,-0.03565 0.05404,-0.06847 0.08591,-0.09848c0.03187,-0.03001 0.06637,-0.05662 0.10348,-0.07983c0.03711,-0.02321 0.07613,-0.04258 0.11706,-0.05811c0.04093,-0.01553 0.08297,-0.02691 0.12614,-0.03416c0.04317,-0.00724 0.08664,-0.0102 0.13039,-0.00888c0.04375,0.00131 0.08696,0.00689 0.12962,0.01672c0.04265,0.00983 0.08394,0.02372 0.12386,0.04168c0.03992,0.01796 0.0777,0.03964 0.11335,0.06505c0.03565,0.02541 0.06847,0.05404 0.09848,0.08591c0.03001,0.03187 0.05662,0.06637 0.07983,0.10348l1.67,2.67c0.02321,0.03711 0.04258,0.07613 0.05811,0.11706z"></path><path id="路径 4" style="fill:#333333; opacity:1;" d="M11.3366,2.33329c-0.0022,0 -0.0033,0.00111 -0.0033,0.00334c0,-0.00493 -0.0005,-0.00788 -0.0015,-0.00884c0.00147,0.00145 0.00307,0.00217 0.0048,0.00217c-0.00407,0 -0.0062,0.00009 -0.0064,0.00026c-0.00013,0.00017 -0.0002,0.00231 -0.0002,0.00641c0,-0.00173 -0.00073,-0.00333 -0.0022,-0.0048c0.00093,0.00097 0.00387,0.00146 0.0088,0.00146zM11.3366,0.99996c0.366,0 0.67897,0.13132 0.9389,0.39396c0.25853,0.26125 0.3878,0.57548 0.3878,0.94271c0,0.36409 -0.1301,0.67623 -0.3903,0.9364c-0.26013,0.26017 -0.57227,0.39026 -0.9364,0.39026c-0.3672,0 -0.68143,-0.12927 -0.9427,-0.38782c-0.26263,-0.25993 -0.39394,-0.57288 -0.39394,-0.93884c0,-0.3691 0.13051,-0.68415 0.39154,-0.94516c0.261,-0.26101 0.57603,-0.39151 0.9451,-0.39151z"></path><path id="路径 5" style="fill:#333333; opacity:1;" d="M4.67,2.33329c-0.00222,0 -0.00333,0.00111 -0.00333,0.00334c0,-0.00493 -0.00049,-0.00788 -0.00146,-0.00884c0.00146,0.00145 0.00306,0.00217 0.00479,0.00217c-0.00409,0 -0.00623,0.00009 -0.0064,0.00026c-0.00018,0.00017 -0.00027,0.00231 -0.00027,0.00641c0,-0.00173 -0.00072,-0.00333 -0.00217,-0.0048c0.00097,0.00097 0.00391,0.00146 0.00884,0.00146zM4.67,0.99996c0.36596,0 0.67891,0.13132 0.93884,0.39396c0.25855,0.26125 0.38783,0.57548 0.38783,0.94271c0,0.36409 -0.13009,0.67623 -0.39027,0.9364c-0.26017,0.26017 -0.57231,0.39026 -0.9364,0.39026c-0.36723,0 -0.68146,-0.12927 -0.94271,-0.38782c-0.26264,-0.25993 -0.39396,-0.57288 -0.39396,-0.93884c0,-0.3691 0.13051,-0.68415 0.39152,-0.94516c0.26101,-0.26101 0.57606,-0.39151 0.94515,-0.39151z"></path><path id="路径 6" style="fill:#333333; opacity:1;" d="M6.66337,10.0033h2.67c0.18392,0 0.34014,-0.06492 0.46866,-0.19476c0.12979,-0.13113 0.19468,-0.29065 0.19468,-0.47854c0,-0.18091 -0.06533,-0.33669 -0.19599,-0.46735c-0.13066,-0.13065 -0.28644,-0.19598 -0.46735,-0.19598h-2.67c-0.1809,0 -0.33668,0.06533 -0.46734,0.19598c-0.13066,0.13066 -0.19599,0.28644 -0.19599,0.46735c0,0.18789 0.06489,0.34741 0.19467,0.47854c0.12853,0.12984 0.28475,0.19476 0.46866,0.19476zM6.66337,11.3367c-0.27228,0 -0.53262,-0.05287 -0.78101,-0.1586c-0.23965,-0.10193 -0.45143,-0.2458 -0.63533,-0.4316c-0.18317,-0.18513 -0.3249,-0.3979 -0.42518,-0.6383c-0.10343,-0.24791 -0.15514,-0.50731 -0.15514,-0.7782c0,-0.26987 0.05281,-0.52885 0.15843,-0.77694c0.1014,-0.23816 0.24409,-0.44923 0.42808,-0.63321c0.18398,-0.18399 0.39505,-0.32668 0.63322,-0.42808c0.24808,-0.10563 0.50706,-0.15844 0.77693,-0.15844h2.67c0.26987,0 0.52885,0.05281 0.77693,0.15844c0.2382,0.1014 0.44927,0.24409 0.6332,0.42808c0.184,0.18398 0.3267,0.39505 0.4281,0.63321c0.1056,0.24809 0.1584,0.50707 0.1584,0.77694c0,0.27089 -0.0517,0.53029 -0.1551,0.7782c-0.10027,0.2404 -0.242,0.45317 -0.4252,0.6383c-0.18387,0.1858 -0.39563,0.32967 -0.6353,0.4316c-0.2484,0.10573 -0.50874,0.1586 -0.78103,0.1586z"></path><path id="路径 7" style="fill:#333333; opacity:1;" d="M2.00004,10.6633h1.00333c0.04377,0 0.08713,0.00427 0.13006,0.0128c0.04293,0.0086 0.08462,0.02127 0.12507,0.038c0.04044,0.01673 0.07886,0.03727 0.11525,0.0616c0.0364,0.02433 0.07008,0.05197 0.10103,0.0829c0.03095,0.03093 0.05859,0.0646 0.08291,0.101c0.02432,0.0364 0.04485,0.07483 0.0616,0.1153c0.01675,0.0404 0.0294,0.08207 0.03794,0.125c0.00854,0.04293 0.01281,0.0863 0.01281,0.1301c0,0.0438 -0.00427,0.08717 -0.01281,0.1301c-0.00854,0.04293 -0.02119,0.0846 -0.03794,0.125c-0.01675,0.04047 -0.03728,0.0789 -0.0616,0.1153c-0.02432,0.0364 -0.05196,0.07007 -0.08291,0.101c-0.03095,0.03093 -0.06463,0.05857 -0.10103,0.0829c-0.03639,0.02433 -0.07481,0.04487 -0.11525,0.0616c-0.04045,0.01673 -0.08214,0.0294 -0.12507,0.038c-0.04293,0.00853 -0.08629,0.0128 -0.13006,0.0128h-1.67c-0.04377,0 -0.08713,-0.00427 -0.13006,-0.0128c-0.04293,-0.0086 -0.08462,-0.02127 -0.12506,-0.038c-0.04044,-0.01673 -0.07886,-0.03727 -0.11526,-0.0616c-0.0364,-0.02433 -0.07007,-0.05197 -0.10103,-0.0829c-0.03095,-0.03093 -0.05859,-0.0646 -0.08291,-0.101c-0.02432,-0.0364 -0.04485,-0.07483 -0.06161,-0.1153c-0.01675,-0.0404 -0.0294,-0.08207 -0.03794,-0.125c-0.00854,-0.04293 -0.01281,-0.0863 -0.01281,-0.1301v-3.33c0,-0.04377 0.00427,-0.08713 0.01281,-0.13006c0.00854,-0.04293 0.02119,-0.08462 0.03794,-0.12506c0.01675,-0.04045 0.03729,-0.07887 0.06161,-0.11526c0.02432,-0.0364 0.05196,-0.07008 0.08291,-0.10103c0.03095,-0.03095 0.06463,-0.05858 0.10103,-0.0829c0.0364,-0.02432 0.07482,-0.04486 0.11526,-0.06161c0.04044,-0.01675 0.08213,-0.0294 0.12506,-0.03794c0.04293,-0.00854 0.08629,-0.01281 0.13006,-0.01281h1.67c0.04377,0 0.08713,0.00427 0.13006,0.01281c0.04293,0.00854 0.08462,0.02119 0.12507,0.03794c0.04044,0.01675 0.07886,0.03729 0.11525,0.06161c0.0364,0.02432 0.07008,0.05195 0.10103,0.0829c0.03095,0.03095 0.05859,0.06463 0.08291,0.10103c0.02432,0.03639 0.04485,0.07481 0.0616,0.11526c0.01675,0.04044 0.0294,0.08213 0.03794,0.12506c0.00854,0.04293 0.01281,0.08629 0.01281,0.13006c0,0.04377 -0.00427,0.08713 -0.01281,0.13006c-0.00854,0.04293 -0.02119,0.08462 -0.03794,0.12506c-0.01675,0.04044 -0.03728,0.07886 -0.0616,0.11526c-0.02432,0.03639 -0.05196,0.07007 -0.08291,0.10102c-0.03095,0.03095 -0.06463,0.05859 -0.10103,0.08291c-0.03639,0.02432 -0.07481,0.04486 -0.11525,0.06161c-0.04045,0.01675 -0.08214,0.0294 -0.12507,0.03794c-0.04293,0.00854 -0.08629,0.01281 -0.13006,0.01281h-1.00333z"></path><path id="路径 8" style="fill:#333333; opacity:1;" d="M14.8001,7.34614c0.04293,0.00854 0.0846,0.02119 0.125,0.03794c0.04047,0.01675 0.0789,0.03729 0.1153,0.06161c0.0364,0.02432 0.07007,0.05195 0.101,0.0829c0.03093,0.03095 0.05857,0.06463 0.0829,0.10103c0.02433,0.03639 0.04487,0.07481 0.0616,0.11526c0.01673,0.04044 0.0294,0.08213 0.038,0.12506c0.00853,0.04293 0.0128,0.08629 0.0128,0.13006v3.33c0,0.0438 -0.00427,0.08717 -0.0128,0.1301c-0.0086,0.04293 -0.02127,0.0846 -0.038,0.125c-0.01673,0.04047 -0.03727,0.0789 -0.0616,0.1153c-0.02433,0.0364 -0.05197,0.07007 -0.0829,0.101c-0.03093,0.03093 -0.0646,0.05857 -0.101,0.0829c-0.0364,0.02433 -0.07483,0.04487 -0.1153,0.0616c-0.0404,0.01673 -0.08207,0.0294 -0.125,0.038c-0.04293,0.00853 -0.0863,0.0128 -0.1301,0.0128h-1.67c-0.0438,0 -0.08717,-0.00427 -0.1301,-0.0128c-0.04293,-0.0086 -0.0846,-0.02127 -0.125,-0.038c-0.04047,-0.01673 -0.0789,-0.03727 -0.1153,-0.0616c-0.0364,-0.02433 -0.07007,-0.05197 -0.101,-0.0829c-0.03093,-0.03093 -0.05857,-0.0646 -0.0829,-0.101c-0.02433,-0.0364 -0.04487,-0.07483 -0.0616,-0.1153c-0.01673,-0.0404 -0.0294,-0.08207 -0.038,-0.125c-0.00853,-0.04293 -0.0128,-0.0863 -0.0128,-0.1301c0,-0.0438 0.00427,-0.08717 0.0128,-0.1301c0.0086,-0.04293 0.02127,-0.0846 0.038,-0.125c0.01673,-0.04047 0.03727,-0.0789 0.0616,-0.1153c0.02433,-0.0364 0.05197,-0.07007 0.0829,-0.101c0.03093,-0.03093 0.0646,-0.05857 0.101,-0.0829c0.0364,-0.02433 0.07483,-0.04487 0.1153,-0.0616c0.0404,-0.01673 0.08207,-0.0294 0.125,-0.038c0.04293,-0.00853 0.0863,-0.0128 0.1301,-0.0128h1.0033v-1.99663h-1.0033c-0.0438,0 -0.08717,-0.00427 -0.1301,-0.01281c-0.04293,-0.00854 -0.0846,-0.02119 -0.125,-0.03794c-0.04047,-0.01675 -0.0789,-0.03729 -0.1153,-0.06161c-0.0364,-0.02432 -0.07007,-0.05196 -0.101,-0.08291c-0.03093,-0.03095 -0.05857,-0.06463 -0.0829,-0.10102c-0.02433,-0.0364 -0.04487,-0.07482 -0.0616,-0.11526c-0.01673,-0.04044 -0.0294,-0.08213 -0.038,-0.12506c-0.00853,-0.04293 -0.0128,-0.08629 -0.0128,-0.13006c0,-0.04377 0.00427,-0.08713 0.0128,-0.13006c0.0086,-0.04293 0.02127,-0.08462 0.038,-0.12506c0.01673,-0.04045 0.03727,-0.07887 0.0616,-0.11526c0.02433,-0.0364 0.05197,-0.07008 0.0829,-0.10103c0.03093,-0.03095 0.0646,-0.05858 0.101,-0.0829c0.0364,-0.02432 0.07483,-0.04486 0.1153,-0.06161c0.0404,-0.01675 0.08207,-0.0294 0.125,-0.03794c0.04293,-0.00854 0.0863,-0.01281 0.1301,-0.01281h1.67c0.0438,0 0.08717,0.00427 0.1301,0.01281z"></path></g></g><defs><rect id="path_0" x="0" y="0" width="16" height="16" /></defs></svg> From ae1ef3215b45ae373044f0cba370307279d1ff7a Mon Sep 17 00:00:00 2001 From: Yidadaa <yidadaa@qq.com> Date: Sat, 24 Jun 2023 23:38:11 +0800 Subject: [PATCH 3/4] feat: close #628 add chat commands --- app/command.ts | 43 ++++++++++++++++++++++++++++++++++++++ app/components/chat.tsx | 38 ++++++++++++++++++++++++++------- app/components/sidebar.tsx | 7 ++----- app/locales/cn.ts | 10 ++++++++- app/locales/en.ts | 10 ++++++++- app/store/chat.ts | 8 +++++++ 6 files changed, 102 insertions(+), 14 deletions(-) diff --git a/app/command.ts b/app/command.ts index 40bad92b3..ba3bb6538 100644 --- a/app/command.ts +++ b/app/command.ts @@ -1,4 +1,5 @@ import { useSearchParams } from "react-router-dom"; +import Locale from "./locales"; type Command = (param: string) => void; interface Commands { @@ -26,3 +27,45 @@ export function useCommand(commands: Commands = {}) { setSearchParams(searchParams); } } + +interface ChatCommands { + new?: Command; + newm?: Command; + next?: Command; + prev?: Command; + clear?: Command; + del?: Command; +} + +export const ChatCommandPrefix = ":"; + +export function useChatCommand(commands: ChatCommands = {}) { + function extract(userInput: string) { + return ( + userInput.startsWith(ChatCommandPrefix) ? userInput.slice(1) : userInput + ) as keyof ChatCommands; + } + + function search(userInput: string) { + const input = extract(userInput); + const desc = Locale.Chat.Commands; + return Object.keys(commands) + .filter((c) => c.startsWith(input)) + .map((c) => ({ + title: desc[c as keyof ChatCommands], + content: ChatCommandPrefix + c, + })); + } + + function match(userInput: string) { + const command = extract(userInput); + const matched = typeof commands[command] === "function"; + + return { + matched, + invoke: () => matched && commands[command]!(userInput), + }; + } + + return { match, search }; +} diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 505af77da..e1011e422 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -66,7 +66,7 @@ import { LAST_INPUT_KEY, Path, REQUEST_TIMEOUT_MS } from "../constant"; import { Avatar } from "./emoji"; import { MaskAvatar, MaskConfig } from "./mask"; import { useMaskStore } from "../store/mask"; -import { useCommand } from "../command"; +import { ChatCommandPrefix, useChatCommand, useCommand } from "../command"; import { prettyObject } from "../utils/format"; import { ExportMessageModal } from "./exporter"; import { getClientConfig } from "../config/client"; @@ -208,8 +208,7 @@ export function PromptHints(props: { useEffect(() => { const onKeyDown = (e: KeyboardEvent) => { - if (noPrompts) return; - if (e.metaKey || e.altKey || e.ctrlKey) { + if (noPrompts || e.metaKey || e.altKey || e.ctrlKey) { return; } // arrow up / down to select prompt @@ -510,16 +509,19 @@ export function Chat() { const [promptHints, setPromptHints] = useState<Prompt[]>([]); const onSearch = useDebouncedCallback( (text: string) => { - setPromptHints(promptStore.search(text)); + const matchedPrompts = promptStore.search(text); + setPromptHints(matchedPrompts); }, 100, { leading: true, trailing: true }, ); const onPromptSelect = (prompt: Prompt) => { - setPromptHints([]); - inputRef.current?.focus(); - setTimeout(() => setUserInput(prompt.content), 60); + setTimeout(() => { + setPromptHints([]); + setUserInput(prompt.content); + inputRef.current?.focus(); + }, 30); }; // auto grow input @@ -543,6 +545,19 @@ export function Chat() { // eslint-disable-next-line react-hooks/exhaustive-deps useEffect(measure, [userInput]); + // chat commands shortcuts + const chatCommands = useChatCommand({ + new: () => chatStore.newSession(), + newm: () => navigate(Path.NewChat), + prev: () => chatStore.nextSession(-1), + next: () => chatStore.nextSession(1), + clear: () => + chatStore.updateCurrentSession( + (session) => (session.clearContextIndex = session.messages.length), + ), + del: () => chatStore.deleteSession(chatStore.currentSessionIndex), + }); + // only search prompts when user input is short const SEARCH_TEXT_LIMIT = 30; const onInput = (text: string) => { @@ -552,6 +567,8 @@ export function Chat() { // clear search results if (n === 0) { setPromptHints([]); + } else if (text.startsWith(ChatCommandPrefix)) { + setPromptHints(chatCommands.search(text)); } else if (!config.disablePromptHint && n < SEARCH_TEXT_LIMIT) { // check if need to trigger auto completion if (text.startsWith("/")) { @@ -563,6 +580,13 @@ export function Chat() { const doSubmit = (userInput: string) => { if (userInput.trim() === "") return; + const matchCommand = chatCommands.match(userInput); + if (matchCommand.matched) { + setUserInput(""); + setPromptHints([]); + matchCommand.invoke(); + return; + } setIsLoading(true); chatStore.onUserInput(userInput).then(() => setIsLoading(false)); localStorage.setItem(LAST_INPUT_KEY, userInput); diff --git a/app/components/sidebar.tsx b/app/components/sidebar.tsx index a43daedef..6392b962a 100644 --- a/app/components/sidebar.tsx +++ b/app/components/sidebar.tsx @@ -38,13 +38,10 @@ function useHotKey() { useEffect(() => { const onKeyDown = (e: KeyboardEvent) => { if (e.metaKey || e.altKey || e.ctrlKey) { - const n = chatStore.sessions.length; - const limit = (x: number) => (x + n) % n; - const i = chatStore.currentSessionIndex; if (e.key === "ArrowUp") { - chatStore.selectSession(limit(i - 1)); + chatStore.nextSession(-1); } else if (e.key === "ArrowDown") { - chatStore.selectSession(limit(i + 1)); + chatStore.nextSession(1); } } }; diff --git a/app/locales/cn.ts b/app/locales/cn.ts index e94c0332e..14ee7ec99 100644 --- a/app/locales/cn.ts +++ b/app/locales/cn.ts @@ -27,6 +27,14 @@ const cn = { Retry: "重试", Delete: "删除", }, + Commands: { + new: "新建聊天", + newm: "从面具新建聊天", + next: "下一个聊天", + prev: "上一个聊天", + clear: "清除上下文", + del: "删除聊天", + }, InputActions: { Stop: "停止响应", ToBottom: "滚到最新", @@ -47,7 +55,7 @@ const cn = { if (submitKey === String(SubmitKey.Enter)) { inputHints += ",Shift + Enter 换行"; } - return inputHints + ",/ 触发补全"; + return inputHints + ",/ 触发补全,: 触发命令"; }, Send: "发送", Config: { diff --git a/app/locales/en.ts b/app/locales/en.ts index 8e56147c8..1659ddb1f 100644 --- a/app/locales/en.ts +++ b/app/locales/en.ts @@ -28,6 +28,14 @@ const en: LocaleType = { Retry: "Retry", Delete: "Delete", }, + Commands: { + new: "Start a new chat", + newm: "Start a new chat with mask", + next: "Next Chat", + prev: "Previous Chat", + clear: "Clear Context", + del: "Delete Chat", + }, InputActions: { Stop: "Stop", ToBottom: "To Latest", @@ -48,7 +56,7 @@ const en: LocaleType = { if (submitKey === String(SubmitKey.Enter)) { inputHints += ", Shift + Enter to wrap"; } - return inputHints + ", / to search prompts"; + return inputHints + ", / to search prompts, : to use commands"; }, Send: "Send", Config: { diff --git a/app/store/chat.ts b/app/store/chat.ts index d42031005..fa6296811 100644 --- a/app/store/chat.ts +++ b/app/store/chat.ts @@ -85,6 +85,7 @@ interface ChatStore { newSession: (mask?: Mask) => void; deleteSession: (index: number) => void; currentSession: () => ChatSession; + nextSession: (delta: number) => void; onNewMessage: (message: ChatMessage) => void; onUserInput: (content: string) => Promise<void>; summarizeSession: () => void; @@ -200,6 +201,13 @@ export const useChatStore = create<ChatStore>()( })); }, + nextSession(delta) { + const n = get().sessions.length; + const limit = (x: number) => (x + n) % n; + const i = get().currentSessionIndex; + get().selectSession(limit(i + delta)); + }, + deleteSession(index) { const deletingLastSession = get().sessions.length === 1; const deletedSession = get().sessions.at(index); From 8915af9b6d7150f128e9fb99052300e20f9af311 Mon Sep 17 00:00:00 2001 From: Yidadaa <yidadaa@qq.com> Date: Sat, 24 Jun 2023 23:39:38 +0800 Subject: [PATCH 4/4] fixup --- app/locales/ar.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/locales/ar.ts b/app/locales/ar.ts index 70bfb0ceb..7a3eaa2b2 100644 --- a/app/locales/ar.ts +++ b/app/locales/ar.ts @@ -1,7 +1,7 @@ import { SubmitKey } from "../store/config"; -import { LocaleType } from "./index"; +import type { PartialLocaleType } from "./index"; -const ar: LocaleType = { +const ar: PartialLocaleType = { WIP: "قريبًا...", Error: { Unauthorized: