copilot ui and sync with settings

pull/5370/head
lianahus 1 year ago
parent c209b5acb8
commit 05f8166b6c
  1. 2
      apps/remix-ide/src/app/plugins/openaigpt.tsx
  2. 6
      apps/remix-ide/src/app/plugins/solcoderAI.tsx
  3. 7
      apps/remix-ide/src/app/tabs/locales/en/remixUiTabs.json
  4. 4
      apps/remix-ide/src/assets/css/themes/bootstrap-cerulean.min.css
  5. 4
      apps/remix-ide/src/assets/css/themes/bootstrap-cyborg.min.css
  6. 6
      apps/remix-ide/src/assets/css/themes/bootstrap-flatly.min.css
  7. 4
      apps/remix-ide/src/assets/css/themes/bootstrap-spacelab.min.css
  8. 4
      apps/remix-ide/src/assets/css/themes/remix-black_undtds.css
  9. 5
      apps/remix-ide/src/assets/css/themes/remix-candy_ikhg4m.css
  10. 4
      apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css
  11. 4
      apps/remix-ide/src/assets/css/themes/remix-hacker_owl.css
  12. 5
      apps/remix-ide/src/assets/css/themes/remix-light_powaqg.css
  13. 5
      apps/remix-ide/src/assets/css/themes/remix-midcentury_hrzph3.css
  14. 5
      apps/remix-ide/src/assets/css/themes/remix-unicorn.css
  15. 5
      apps/remix-ide/src/assets/css/themes/remix-violet.css
  16. 15
      libs/remix-ui/renderer/src/lib/renderer.tsx
  17. 6
      libs/remix-ui/settings/src/lib/remix-ui-settings.tsx
  18. 23
      libs/remix-ui/tabs/src/lib/remix-ui-tabs.css
  19. 191
      libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx
  20. 2
      libs/remix-ui/terminal/src/lib/reducers/terminalReducer.ts
  21. 14
      libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx

@ -19,7 +19,7 @@ export class OpenAIGpt extends Plugin {
async message(prompt): Promise<CreateChatCompletionResponse> { async message(prompt): Promise<CreateChatCompletionResponse> {
this.call('layout', 'maximizeTerminal') this.call('layout', 'maximizeTerminal')
this.call('terminal', 'log', 'Waiting for GPT answer...') this.call('terminal', 'log', { type: 'typewriterwarning', value: 'Waiting for GPT answer...'})
let result let result
try { try {
result = await ( result = await (

@ -22,7 +22,7 @@ export class SolCoder extends Plugin {
async code_generation(prompt): Promise<any> { async code_generation(prompt): Promise<any> {
this.emit("aiInfering") this.emit("aiInfering")
this.call('layout', 'maximizeTerminal') this.call('layout', 'maximizeTerminal')
this.call('terminal', 'log', 'Waiting for Solcoder answer...') this.call('terminal', 'log', { type: 'typewriterwarning', value: 'Waiting for Solcoder answer...'})
let result let result
try { try {
result = await( result = await(
@ -47,7 +47,7 @@ export class SolCoder extends Plugin {
async solidity_answer(prompt): Promise<any> { async solidity_answer(prompt): Promise<any> {
this.emit("aiInfering") this.emit("aiInfering")
this.call('layout', 'maximizeTerminal') this.call('layout', 'maximizeTerminal')
this.call('terminal', 'log', 'Waiting for Solcoder answer...') this.call('terminal', 'log', { type: 'typewriterwarning', value: 'Waiting for Solcoder answer...'})
let result let result
try { try {
result = await( result = await(
@ -77,7 +77,7 @@ export class SolCoder extends Plugin {
async code_explaining(prompt): Promise<any> { async code_explaining(prompt): Promise<any> {
this.emit("aiInfering") this.emit("aiInfering")
this.call('layout', 'maximizeTerminal') this.call('layout', 'maximizeTerminal')
this.call('terminal', 'log', 'Waiting for Solcoder answer...') this.call('terminal', 'log', { type: 'typewriterwarning', value: 'Waiting for Solcoder answer...'})
let result let result
try { try {
result = await( result = await(

@ -2,9 +2,10 @@
"remixUiTabs.tooltipText1": "Run script (CTRL + SHIFT + S)", "remixUiTabs.tooltipText1": "Run script (CTRL + SHIFT + S)",
"remixUiTabs.tooltipText2": "Compile CTRL + S", "remixUiTabs.tooltipText2": "Compile CTRL + S",
"remixUiTabs.tooltipText3": "Select .sol or .yul file to compile or a .ts or .js file and run it", "remixUiTabs.tooltipText3": "Select .sol or .yul file to compile or a .ts or .js file and run it",
"remixUiTabs.tooltipText4": "Select .sol file to explain with AI [BETA]", "remixUiTabs.tooltipText4": "Select .sol file to use AI tools [BETA]",
"remixUiTabs.tooltipText5": "Explain the contract/s in current file [BETA]", "remixUiTabs.tooltipText5": "Explain the contract(s) in current file [BETA]",
"remixUiTabs.tooltipText6": "AI Copilot [BETA]", "remixUiTabs.tooltipText6": "Enable AI Copilot [BETA]. Note that the AI model is downloaded once to your browser's memory - approximately 50MB.",
"remixUiTabs.tooltipText7": "Disable AI Copilot [BETA]",
"remixUiTabs.zoomOut": "Zoom out", "remixUiTabs.zoomOut": "Zoom out",
"remixUiTabs.zoomIn": "Zoom in" "remixUiTabs.zoomIn": "Zoom in"
} }

@ -10,6 +10,7 @@
* Copyright 2011-2020 Twitter, Inc. * Copyright 2011-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/:root { */:root {
--ai: #da2de4;
--blue:#033c73; --blue:#033c73;
--indigo:#6610f2; --indigo:#6610f2;
--purple:#6f42c1; --purple:#6f42c1;
@ -8373,6 +8374,9 @@ a.text-danger:focus,a.text-danger:hover {
a.text-light:focus,a.text-light:hover { a.text-light:focus,a.text-light:hover {
color:#cbd3da!important color:#cbd3da!important
} }
.text-ai {
color: #da2de4 !important;
}
.text-dark { .text-dark {
color:#343a40!important color:#343a40!important
} }

@ -11,6 +11,7 @@
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/@import url(https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap); */@import url(https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap);
:root { :root {
--ai: #2de7f3;
--blue:#2a9fd6; --blue:#2a9fd6;
--indigo:#6610f2; --indigo:#6610f2;
--purple:#6f42c1; --purple:#6f42c1;
@ -8375,6 +8376,9 @@ a.text-danger:focus,a.text-danger:hover {
a.text-light:focus,a.text-light:hover { a.text-light:focus,a.text-light:hover {
color:#000!important color:#000!important
} }
.text-dark {
color: #babbcc !important;
}
.text-dark { .text-dark {
color:#adafae!important color:#adafae!important
} }

@ -10,7 +10,8 @@
* Copyright 2011-2020 Twitter, Inc. * Copyright 2011-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/@import url(https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap);:root { */@import url(https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap);:root {
--blue:#2c3e50; --ai: #da2de4;
--blue:#2c3e50;
--indigo:#6610f2; --indigo:#6610f2;
--purple:#6f42c1; --purple:#6f42c1;
--pink:#e83e8c; --pink:#e83e8c;
@ -7004,6 +7005,9 @@ a.text-danger:focus,a.text-danger:hover {
a.text-light:focus,a.text-light:hover { a.text-light:focus,a.text-light:hover {
color:#c0cdd1!important color:#c0cdd1!important
} }
.text-ai {
color: #da2de4 !important;
}
.text-dark { .text-dark {
color:#7b8a8b!important color:#7b8a8b!important
} }

@ -11,6 +11,7 @@
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/@import url(https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap); */@import url(https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap);
:root { :root {
--ai: #da2de4;
--blue:#446e9b; --blue:#446e9b;
--indigo:#6610f2; --indigo:#6610f2;
--purple:#6f42c1; --purple:#6f42c1;
@ -8375,6 +8376,9 @@ a.text-danger:focus,a.text-danger:hover {
a.text-light:focus,a.text-light:hover { a.text-light:focus,a.text-light:hover {
color:#c8c8c8!important color:#c8c8c8!important
} }
.text-ai {
color: #da2de4 !important;
}
.text-dark { .text-dark {
color:#333!important color:#333!important
} }

@ -1,5 +1,6 @@
@import url('https://fonts.googleapis.com/css?family=Nunito+Sans:400,600&display=swap'); @import url('https://fonts.googleapis.com/css?family=Nunito+Sans:400,600&display=swap');
:root { :root {
--ai: #2de7f3;
--blue: #90c3f6; --blue: #90c3f6;
--indigo: #6610f2; --indigo: #6610f2;
--purple: #9e77f6; --purple: #9e77f6;
@ -8590,6 +8591,9 @@ a.text-light:hover {
.text-dark { .text-dark {
color: #babbcc !important; color: #babbcc !important;
} }
.text-ai {
color: #2de7f3 !important;
}
a.text-dark:focus, a.text-dark:focus,
a.text-dark:hover { a.text-dark:hover {
color: #6f7087 !important; color: #6f7087 !important;

@ -1,4 +1,5 @@
:root { :root {
--ai: #da2de4;
--blue: #007bff; --blue: #007bff;
--indigo: #6610f2; --indigo: #6610f2;
--purple: #6f42c1; --purple: #6f42c1;
@ -9364,7 +9365,9 @@ a.text-light:hover,
a.text-light:focus { a.text-light:focus {
color: #d9d9d9 !important; color: #d9d9d9 !important;
} }
.text-ai {
color: #da2de4 !important;
}
.text-dark { .text-dark {
color: #11556c !important; color: #11556c !important;
} }

@ -1,4 +1,5 @@
:root { :root {
--ai: #2de7f3;
--blue: #007aa6; --blue: #007aa6;
--indigo: #6610f2; --indigo: #6610f2;
--purple: #9e77f6; --purple: #9e77f6;
@ -8570,6 +8571,9 @@ a.text-info:hover {
.text-warning { .text-warning {
color: #c97539 !important; color: #c97539 !important;
} }
.text-ai {
color: #2de7f3 !important;
}
a.text-warning:focus, a.text-warning:focus,
a.text-warning:hover { a.text-warning:hover {
color: #8f5227 !important; color: #8f5227 !important;

@ -1,6 +1,7 @@
@import url('https://fonts.googleapis.com/css2?family=Saira:ital,wght@0,300;0,400;0,500;1,300;1,400&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Saira:ital,wght@0,300;0,400;0,500;1,300;1,400&display=swap');
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,700;1,400&display=swap'); @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,700;1,400&display=swap');
:root { :root {
--ai: #2de7f3;
--blue: #2cc1f7; --blue: #2cc1f7;
--indigo: #6610f2; --indigo: #6610f2;
--purple: #6f42c1; --purple: #6f42c1;
@ -8604,6 +8605,9 @@ a.text-light:hover {
.text-dark { .text-dark {
color: #babbcc !important; color: #babbcc !important;
} }
.text-ai {
color: #2de7f3 !important;
}
a.text-dark:focus, a.text-dark:focus,
a.text-dark:hover { a.text-dark:hover {
color: #6f7087 !important; color: #6f7087 !important;

@ -1,4 +1,5 @@
:root { :root {
--ai: #da2de4;
--blue: #007bff; --blue: #007bff;
--indigo: #6610f2; --indigo: #6610f2;
--purple: #7c47b9; --purple: #7c47b9;
@ -9360,7 +9361,9 @@ a.text-light:hover,
a.text-light:focus { a.text-light:focus {
color: #d9d9d9 !important; color: #d9d9d9 !important;
} }
.text-ai {
color: #da2de4 !important;
}
.text-dark { .text-dark {
color: #747B90 !important; color: #747B90 !important;
} }

@ -1,4 +1,5 @@
:root { :root {
--ai: #da2de4;
--blue: #007bff; --blue: #007bff;
--indigo: #6610f2; --indigo: #6610f2;
--purple: #6f42c1; --purple: #6f42c1;
@ -9366,7 +9367,9 @@ a.text-light:hover,
a.text-light:focus { a.text-light:focus {
color: #d9d9d9 !important; color: #d9d9d9 !important;
} }
.text-ai {
color: #da2de4 !important;
}
.text-dark { .text-dark {
color: #11556c !important; color: #11556c !important;
} }

@ -1,4 +1,5 @@
:root { :root {
--ai: #da2de4;
--blue: #007bff; --blue: #007bff;
--indigo: #6610f2; --indigo: #6610f2;
--purple: #7c47b9; --purple: #7c47b9;
@ -9360,7 +9361,9 @@ a.text-light:hover,
a.text-light:focus { a.text-light:focus {
color: #d9d9d9 !important; color: #d9d9d9 !important;
} }
.text-ai {
color: #da2de4 !important;
}
.text-dark { .text-dark {
color: #747B90 !important; color: #747B90 !important;
} }

@ -1,4 +1,5 @@
:root { :root {
--ai: #da2de4;
--blue: #007bff; --blue: #007bff;
--indigo: #6610f2; --indigo: #6610f2;
--purple: #7c47b9; --purple: #7c47b9;
@ -9356,7 +9357,9 @@ a.text-light:hover,
a.text-light:focus { a.text-light:focus {
color: #d9d9d9 !important; color: #d9d9d9 !important;
} }
.text-ai {
color: #da2de4 !important;
}
.text-dark { .text-dark {
color: #747B90 !important; color: #747B90 !important;
} }

@ -101,7 +101,20 @@ export const Renderer = ({message, opt = {}, plugin}: RendererProps) => {
<span className="ml-3 pt-1 py-1" > <span className="ml-3 pt-1 py-1" >
<CopyToClipboard content={messageText} className={` p-0 m-0 far fa-copy ${classList}`} direction={'top'} /> <CopyToClipboard content={messageText} className={` p-0 m-0 far fa-copy ${classList}`} direction={'top'} />
</span> </span>
<span className="border border-success text-success btn-sm" onClick={() => { askGtp() }}>ASK GPT</span> <span
className="position-relative text-ai text-sm pl-0 pr-2"
style={{fontSize: "x-small", alignSelf: "end"}}
>
AI
</span>
<span
className="button border text-ai btn-sm"
onClick={() => { askGtp() }}
style={{borderColor: "var(--ai)"}}
>
ASK GPT
</span>
</div> </div>
</div> </div>
)} )}

@ -120,7 +120,11 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
useEffect(() => { useEffect(() => {
if (props.useMatomoAnalytics !== null) useMatomoAnalytics(props.config, props.useMatomoAnalytics, dispatch) if (props.useMatomoAnalytics !== null) useMatomoAnalytics(props.config, props.useMatomoAnalytics, dispatch)
}, [props.useMatomoAnalytics]) }, [props.useMatomoAnalytics])
useEffect(() => {
if (props.useCopilot !== null) copilotActivate(props.config, props.useCopilot, dispatch)
}, [props.useCopilot])
const onchangeGenerateContractMetadata = (event) => { const onchangeGenerateContractMetadata = (event) => {
generateContractMetadat(props.config, event.target.checked, dispatch) generateContractMetadat(props.config, event.target.checked, dispatch)

@ -56,3 +56,26 @@
-ms-overflow-style: none; /* IE and Edge */ -ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */ scrollbar-width: none; /* Firefox */
} }
.loadingExplanation {
animation: fancy-spin 2000ms;
animation-iteration-count: infinite;
}
@keyframes fancy-spin {
0% {
transform: scale(1);
}
25% {
transform: scale(1);
}
50% {
transform: scale(1.3);
}
75% {
transform: scale(1.3);
}
100% {
transform: scale(1);
}
}

@ -60,6 +60,7 @@ const tabsReducer = (state: ITabsState, action: ITabsAction) => {
export const TabsUI = (props: TabsUIProps) => { export const TabsUI = (props: TabsUIProps) => {
const [tabsState, dispatch] = useReducer(tabsReducer, initialTabsState) const [tabsState, dispatch] = useReducer(tabsReducer, initialTabsState)
const currentIndexRef = useRef(-1) const currentIndexRef = useRef(-1)
const [explaining, setExplaining] = useState<boolean>(false)
const tabsRef = useRef({}) const tabsRef = useRef({})
const tabsElement = useRef(null) const tabsElement = useRef(null)
const [ai_switch, setAI_switch] = useState<boolean>(false) const [ai_switch, setAI_switch] = useState<boolean>(false)
@ -167,101 +168,119 @@ export const TabsUI = (props: TabsUIProps) => {
<div className="remix-ui-tabs d-flex justify-content-between border-0 header nav-tabs" data-id="tabs-component"> <div className="remix-ui-tabs d-flex justify-content-between border-0 header nav-tabs" data-id="tabs-component">
<div className="d-flex flex-row" style={{maxWidth: 'fit-content', width: '99%'}}> <div className="d-flex flex-row" style={{maxWidth: 'fit-content', width: '99%'}}>
<div className="d-flex flex-row justify-content-center align-items-center m-1 mt-1"> <div className="d-flex flex-row justify-content-center align-items-center m-1 mt-1">
<button <CustomTooltip
data-id="play-editor" placement="bottom"
className="btn text-success py-0" tooltipId="overlay-tooltip-run-script"
disabled={!(tabsState.currentExt === 'js' || tabsState.currentExt === 'ts' || tabsState.currentExt === 'sol' || tabsState.currentExt === 'circom')} tooltipText={
onClick={async () => { <span>
const path = active().substr(active().indexOf('/') + 1, active().length) {tabsState.currentExt === 'js' || tabsState.currentExt === 'ts' ? (
const content = await props.plugin.call('fileManager', 'readFile', path) <FormattedMessage id="remixUiTabs.tooltipText1" />
if (tabsState.currentExt === 'js' || tabsState.currentExt === 'ts') { ) : tabsState.currentExt === 'sol' || tabsState.currentExt === 'yul' || tabsState.currentExt === 'circom' ? (
await props.plugin.call('scriptRunner', 'execute', content, path) <FormattedMessage id="remixUiTabs.tooltipText2" />
_paq.push(['trackEvent', 'editor', 'clickRunFromEditor', tabsState.currentExt]) ) : (
} else if (tabsState.currentExt === 'sol' || tabsState.currentExt === 'yul') { <FormattedMessage id="remixUiTabs.tooltipText3" />
await props.plugin.call('solidity', 'compile', path) )}
_paq.push(['trackEvent', 'editor', 'clickRunFromEditor', tabsState.currentExt]) </span>
} else if (tabsState.currentExt === 'circom') { }
await props.plugin.call('circuit-compiler', 'compile', path)
_paq.push(['trackEvent', 'editor', 'clickRunFromEditor', tabsState.currentExt])
}
}}
> >
<CustomTooltip <button
placement="bottom" data-id="play-editor"
tooltipId="overlay-tooltip-run-script" className="btn text-success py-0"
tooltipText={ disabled={!(tabsState.currentExt === 'js' || tabsState.currentExt === 'ts' || tabsState.currentExt === 'sol' || tabsState.currentExt === 'circom')}
<span> onClick={async () => {
{tabsState.currentExt === 'js' || tabsState.currentExt === 'ts' ? ( const path = active().substr(active().indexOf('/') + 1, active().length)
<FormattedMessage id="remixUiTabs.tooltipText1" /> const content = await props.plugin.call('fileManager', 'readFile', path)
) : tabsState.currentExt === 'sol' || tabsState.currentExt === 'yul' || tabsState.currentExt === 'circom' ? ( if (tabsState.currentExt === 'js' || tabsState.currentExt === 'ts') {
<FormattedMessage id="remixUiTabs.tooltipText2" /> await props.plugin.call('scriptRunner', 'execute', content, path)
) : ( _paq.push(['trackEvent', 'editor', 'clickRunFromEditor', tabsState.currentExt])
<FormattedMessage id="remixUiTabs.tooltipText3" /> } else if (tabsState.currentExt === 'sol' || tabsState.currentExt === 'yul') {
)} await props.plugin.call('solidity', 'compile', path)
</span> _paq.push(['trackEvent', 'editor', 'clickRunFromEditor', tabsState.currentExt])
} } else if (tabsState.currentExt === 'circom') {
await props.plugin.call('circuit-compiler', 'compile', path)
_paq.push(['trackEvent', 'editor', 'clickRunFromEditor', tabsState.currentExt])
}
}}
> >
<i className="fad fa-play"></i> <i className="fad fa-play"></i>
</CustomTooltip> </button>
</button> </CustomTooltip>
<button <CustomTooltip
data-id="explain-editor" placement="bottom"
id='explain_btn' tooltipId="overlay-tooltip-explaination"
className="btn py-0" tooltipText={
disabled={!(tabsState.currentExt === 'sol' )} <span>
onClick={async () => { {tabsState.currentExt === 'sol'? (
const path = active().substr(active().indexOf('/') + 1, active().length) <FormattedMessage id="remixUiTabs.tooltipText5" />
const content = await props.plugin.call('fileManager', 'readFile', path) ) : (
if (tabsState.currentExt === 'sol') { <FormattedMessage id="remixUiTabs.tooltipText4" />
(document.getElementById('explain_btn') as HTMLButtonElement).disabled = true; )}
const result = await props.plugin.call('solcoder', 'code_explaining', content) </span>
_paq.push(['trackEvent', 'ai', 'solcoder', 'explain_file']) }
}
(document.getElementById('explain_btn') as HTMLButtonElement).disabled = false;
}}
> >
<CustomTooltip <button
placement="bottom" data-id="explain-editor"
tooltipId="overlay-tooltip-explaination" id='explain_btn'
tooltipText={ className='btn py-0 text-ai px-0 d-flex'
<span> disabled={!(tabsState.currentExt === 'sol') || explaining}
{tabsState.currentExt === 'sol'? ( onClick={async () => {
<FormattedMessage id="remixUiTabs.tooltipText5" /> const path = active().substr(active().indexOf('/') + 1, active().length)
) : ( const content = await props.plugin.call('fileManager', 'readFile', path)
<FormattedMessage id="remixUiTabs.tooltipText4" /> if (tabsState.currentExt === 'sol') {
)} setExplaining(true)
</span> await props.plugin.call('solcoder', 'code_explaining', content)
} setExplaining(false)
_paq.push(['trackEvent', 'ai', 'solcoder', 'explain_file'])
}
}}
> >
<i className="fa-solid text-dark fa-message-exclamation"></i> <i className={`fa-solid fa-user-robot ${explaining ? 'loadingExplanation' : ''}`}></i>
</CustomTooltip> <span
</button> className="position-relative text-ai text-sm pl-1"
<button style={{fontSize: "x-small", alignSelf: "end"}}
data-id="remix_ai_switch" >
id='remix_ai_switch' AI
className="btn ai-switch py-0" </span>
disabled={!(tabsState.currentExt === 'sol' )} </button>
onClick={async () => { </CustomTooltip>
await props.plugin.call('settings', 'updateCopilotChoice', ai_switch) <CustomTooltip
setAI_switch(!ai_switch) placement="bottom"
}} tooltipId="overlay-tooltip-copilot"
tooltipText={
<span>
{ tabsState.currentExt === 'sol'? (
!ai_switch ? (
<FormattedMessage id="remixUiTabs.tooltipText6" />
) : (<FormattedMessage id="remixUiTabs.tooltipText7" />)
) : (
<FormattedMessage id="remixUiTabs.tooltipText4" />
)}
</span>
}
> >
<CustomTooltip <button
placement="bottom" data-id="remix_ai_switch"
tooltipId="overlay-tooltip-copilot" id='remix_ai_switch'
tooltipText={ className="btn ai-switch text-ai pl-2 pr-0 py-0 d-flex"
<span> disabled={!(tabsState.currentExt === 'sol' )}
<FormattedMessage id="remixUiTabs.tooltipText6" /> onClick={async () => {
</span> await props.plugin.call('settings', 'updateCopilotChoice', ai_switch)
} setAI_switch(!ai_switch)
}}
> >
<i className= {ai_switch ? "fa-solid text-success fa-toggle-on" :"fa-solid text-dark fa-toggle-off"}></i> <i
</CustomTooltip> className={ai_switch ? "fa-solid fa-toggle-on" : "fa-solid fa-toggle-off"}
</button> ></i>
<span
className="position-relative text-ai text-sm pl-1"
style={{fontSize: "x-small", alignSelf: "end"}}
>
AI
</span>
</button>
</CustomTooltip>
<script> <script>
const button = document.querySelector('#button'); const button = document.querySelector('#button');
</script> </script>
<CustomTooltip placement="bottom" tooltipId="overlay-tooltip-zoom-out" tooltipText={<FormattedMessage id="remixUiTabs.zoomOut" />}> <CustomTooltip placement="bottom" tooltipId="overlay-tooltip-zoom-out" tooltipText={<FormattedMessage id="remixUiTabs.zoomOut" />}>
<span data-id="tabProxyZoomOut" className="btn btn-sm px-2 fas fa-search-minus text-dark" onClick={() => props.onZoomOut()}></span> <span data-id="tabProxyZoomOut" className="btn btn-sm px-2 fas fa-search-minus text-dark" onClick={() => props.onZoomOut()}></span>

@ -159,7 +159,7 @@ export const registerScriptRunnerReducer = (state, action) => {
case TYPEWRITERWARNING: case TYPEWRITERWARNING:
return { return {
...state, ...state,
journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, typewriter: true, style: 'text-warning', provider: action.payload.provider }) journalBlocks: initialState.journalBlocks.push({ message: action.payload.message, typewriter: true, style: 'text-ai', provider: action.payload.provider })
} }
case TYPEWRITERSUCCESS: case TYPEWRITERSUCCESS:
return { return {

@ -44,7 +44,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState) const [cmdHistory, cmdHistoryDispatch] = useReducer(addCommandHistoryReducer, initialState)
const [, scriptRunnerDispatch] = useReducer(registerScriptRunnerReducer, initialState) const [, scriptRunnerDispatch] = useReducer(registerScriptRunnerReducer, initialState)
const [toaster, setToaster] = useState(false) const [toaster, setToaster] = useState(false)
const [aiLoading, setAILoading] = useState(false)
const [toastProvider, setToastProvider] = useState({ const [toastProvider, setToastProvider] = useState({
show: false, show: false,
fileName: '', fileName: '',
@ -104,14 +103,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
setIsVM(provider.startsWith('vm-')) setIsVM(provider.startsWith('vm-'))
}) })
props.plugin.on('solcoder', 'aiInfering', () => {
setAILoading(true)
})
props.plugin.on('solcoder', 'aiInferingDone', () => {
setAILoading(false)
})
props.onReady({ props.onReady({
logHtml: (html) => { logHtml: (html) => {
scriptRunnerDispatch({ scriptRunnerDispatch({
@ -658,11 +649,6 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
data-id="terminalInputSearch" data-id="terminalInputSearch"
/> />
</div> </div>
{aiLoading && <div className="text-center py-5 ml-5">
<i className="fas fa-spinner fa-pulse fa-2x"></i>
<span> AI Running ...</span>
</div>}
</div> </div>
</div> </div>
<div tabIndex={-1} className="remix_ui_terminal_container d-flex h-100 m-0 flex-column" data-id="terminalContainer"> <div tabIndex={-1} className="remix_ui_terminal_container d-flex h-100 m-0 flex-column" data-id="terminalContainer">

Loading…
Cancel
Save