Merge branch 'master' into solgpt_chat

pull/5370/head
STetsing 6 months ago committed by GitHub
commit e414afcd1d
  1. 5
      apps/remix-ide/src/app/components/vertical-icons.tsx
  2. 1
      apps/remix-ide/src/app/plugins/solcoderAI.tsx
  3. 7
      apps/remix-ide/src/app/tabs/locales/en/remixUiTabs.json
  4. 8
      apps/remix-ide/src/app/tabs/settings-tab.tsx
  5. 12
      libs/remix-ui/run-tab/src/lib/components/environment.tsx
  6. 21
      libs/remix-ui/settings/src/lib/remix-ui-settings.tsx
  7. 181
      libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx

@ -73,7 +73,10 @@ export class VerticalIcons extends Plugin {
Object.keys(this.icons).map((o) => {
this.icons[o].active = false
})
this.icons[name].active = true
if (this.icons[name]) {
this.icons[name].active = true
}
this.renderComponent()
})
}

@ -81,7 +81,6 @@ export class SolCoder extends Plugin {
let result
try {
const main_prompt = this._build_solgpt_promt(prompt)
console.log(main_prompt.length)
result = await(
await fetch(this.api_url, {
method: 'POST',

@ -1,12 +1,13 @@
{
"remixUiTabs.tooltipText1": "Run script (CTRL + SHIFT + 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.tooltipText4": "Select .sol file to use AI tools [BETA]",
"remixUiTabs.tooltipText3": "Select .sol or .yul file to compile OR a .ts or .js file to run",
"remixUiTabs.tooltipText4": "To explain a contract, choose a .sol file",
"remixUiTabs.tooltipText5": "Explain the contract(s) in current file [BETA]",
"remixUiTabs.tooltipText6": "Enable Remix AI Copilot [BETA]",
"remixUiTabs.tooltipText7": "Disable Remix AI Copilot [BETA]",
"remixUiTabs.tooltipText8": "Remix AI Tools Documentation [BETA]",
"remixUiTabs.tooltipText8": "Remix AI Tools Documentation",
"remixUiTabs.tooltipTextDisabledCopilot": "To use Remix AI Copilot, choose a .sol file",
"remixUiTabs.zoomOut": "Zoom out",
"remixUiTabs.zoomIn": "Zoom in"
}

@ -15,7 +15,7 @@ const _paq = (window._paq = window._paq || [])
const profile = {
name: 'settings',
displayName: 'Settings',
methods: ['get', 'updateCopilotChoice'],
methods: ['get', 'updateCopilotChoice', 'getCopilotSetting'],
events: [],
icon: 'assets/img/settings.webp',
description: 'Remix-IDE settings',
@ -52,7 +52,7 @@ module.exports = class SettingsTab extends ViewPlugin {
this.element = document.createElement('div')
this.element.setAttribute('id', 'settingsTab')
this.useMatomoAnalytics = null
this.useCopilot = false
this.useCopilot = this.get('settings/copilot/suggest/activate')
}
setDispatch(dispatch: React.Dispatch<any>) {
@ -102,6 +102,10 @@ module.exports = class SettingsTab extends ViewPlugin {
})
}
getCopilotSetting(){
return this.useCopilot
}
updateMatomoAnalyticsChoice(isChecked) {
this.config.set('settings/matomo-analytics', isChecked)
this.useMatomoAnalytics = isChecked

@ -15,10 +15,10 @@ export function EnvironmentUI(props: EnvironmentProps) {
const currentProvider = props.providers.providerList.find((exEnv) => exEnv.name === props.selectedEnv)
const bridges = {
'L2 - Optimism': 'https://app.optimism.io/bridge/deposit',
'L2 - Arbitrum One': 'https://bridge.arbitrum.io/'
'L2 - Arbitrum': 'https://bridge.arbitrum.io/'
}
const isL2 = (providerDisplayName: string) => providerDisplayName === 'Optimism Provider' || providerDisplayName === 'Arbitrum One Provider'
const isL2 = (providerDisplayName: string) => providerDisplayName === 'L2 - Optimism' || providerDisplayName === 'L2 - Arbitrum'
return (
<div className="udapp_crow">
<label id="selectExEnv" className="udapp_settingsLabel">
@ -38,16 +38,16 @@ export function EnvironmentUI(props: EnvironmentProps) {
<div className="udapp_environment">
<Dropdown id="selectExEnvOptions" data-id="settingsSelectEnvOptions" className="udapp_selectExEnvOptions">
<Dropdown.Toggle as={CustomToggle} id="dropdown-custom-components" className="btn btn-light btn-block w-100 d-inline-block border border-dark form-control" icon={null}>
{isL2(currentProvider && currentProvider.displayName) && 'L2 - '}
{isL2(currentProvider && currentProvider.displayName)}
{currentProvider && currentProvider.displayName}
{currentProvider && bridges[currentProvider.name] && (
{currentProvider && bridges[currentProvider.displayName] && (
<CustomTooltip placement={'right'} tooltipClasses="text-nowrap" tooltipId="info-recorder" tooltipText={<FormattedMessage id="udapp.tooltipText3" />}>
<i
style={{ fontSize: 'medium' }}
className={'ml-2 fa fa-rocket-launch'}
aria-hidden="true"
onClick={() => {
window.open(bridges[currentProvider.name], '_blank')
window.open(bridges[currentProvider.displayName], '_blank')
}}
></i>
</CustomTooltip>
@ -63,7 +63,7 @@ export function EnvironmentUI(props: EnvironmentProps) {
data-id={`dropdown-item-${name}`}
>
<span className="">
{isL2(displayName) && 'L2 - '}
{isL2(displayName)}
{displayName}
</span>
</Dropdown.Item>

@ -1,5 +1,7 @@
import { ViewPlugin } from '@remixproject/engine-web'
import React, {useState, useRef, useReducer, useEffect, useCallback} from 'react' // eslint-disable-line
import { CustomTooltip } from '@remix-ui/helper'
const _paq = (window._paq = window._paq || [])
import { AppModal, AlertModal, ModalTypes } from '@remix-ui/app'
import { labels, textDark, textSecondary } from './constants'
@ -56,7 +58,6 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
const [ipfsProtocol, setipfsProtocol] = useState('')
const [ipfsProjectId, setipfsProjectId] = useState('')
const [ipfsProjectSecret, setipfsProjectSecret] = useState('')
const copilotDownload = useRef(null)
const intl = useIntl()
const initValue = () => {
@ -143,7 +144,7 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
}
const startCopilot = async () => {
copilotActivate(props.config, true, dispatch)
copilotActivate(props.config, props.useCopilot, dispatch)
props.plugin.call('terminal', 'log', { type: 'typewriterlog', value: `Solidity copilot activated!` })
}
@ -450,9 +451,23 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
const copilotSettings = () => (
<div className="border-top">
<div className="card-body pt-3 pb-2">
<h6 className="card-title">
<h6 className="card-title d-inline">
<FormattedMessage id="settings.copilot" />
</h6>
<CustomTooltip placement="bottom" tooltipId="overlay-tooltip-aiDocumentation" tooltipText={<FormattedMessage id="remixUiTabs.tooltipText8" />}>
<span
data-id="remix_ai_docs"
id="remix_ai_docs"
className="btn pl-2 pr-0 py-0 d-inline ai-docs"
role='link'
onClick={()=>{
window.open("https://remix-ide.readthedocs.io/en/latest/ai.html")
_paq.push(['trackEvent', 'ai', 'solcoder', 'documentation'])
}}
>
<i aria-hidden="true" className="fas fa-book"></i>
</span>
</CustomTooltip>
<div className="pt-2 mb-0">
<div className="text-secondary mb-0 h6">

@ -5,6 +5,7 @@ import React, {useState, useRef, useEffect, useReducer} from 'react' // eslint-d
import { FormattedMessage } from 'react-intl'
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'
import './remix-ui-tabs.css'
import { values } from 'lodash'
const _paq = (window._paq = window._paq || [])
/* eslint-disable-next-line */
@ -64,7 +65,6 @@ export const TabsUI = (props: TabsUIProps) => {
const tabsRef = useRef({})
const tabsElement = useRef(null)
const [ai_switch, setAI_switch] = useState<boolean>(false)
const tabs = useRef(props.tabs)
tabs.current = props.tabs // we do this to pass the tabs list to the onReady callbacks
@ -77,6 +77,14 @@ export const TabsUI = (props: TabsUIProps) => {
}
}, [tabsState.selectedIndex])
const getAI = async() => {
try {
return await props.plugin.call('settings', 'getCopilotSetting')
} catch (e){
return false
}
}
const getFileDecorationClasses = (tab: any) => {
const fileDecoration = tabsState.fileDecorations.find((fileDecoration: fileDecoration) => {
if (`${fileDecoration.workspace.name}/${fileDecoration.path}` === tab.name) return true
@ -92,7 +100,6 @@ export const TabsUI = (props: TabsUIProps) => {
const classNameImg = 'my-1 mr-1 text-dark ' + tab.iconClass
const classNameTab = 'nav-item nav-link d-flex justify-content-center align-items-center px-2 py-1 tab' + (index === currentIndexRef.current ? ' active' : '')
const invert = props.themeQuality === 'dark' ? 'invert(1)' : 'invert(0)'
return (
<CustomTooltip tooltipId="tabsActive" tooltipText={tab.tooltip} placement="bottom-start">
<div
@ -133,6 +140,7 @@ export const TabsUI = (props: TabsUIProps) => {
}
const setFileDecorations = (fileStates: fileDecoration[]) => {
getAI().then(value => setAI_switch(value)).catch(error => console.log(error))
dispatch({ type: 'SET_FILE_DECORATIONS', payload: fileStates })
}
@ -185,7 +193,7 @@ export const TabsUI = (props: TabsUIProps) => {
>
<button
data-id="play-editor"
className="btn text-success py-0"
className="btn text-success pr-0 py-0 d-flex"
disabled={!(tabsState.currentExt === 'js' || tabsState.currentExt === 'ts' || tabsState.currentExt === 'sol' || tabsState.currentExt === 'circom' || tabsState.currentExt === 'vy')}
onClick={async () => {
const path = active().substr(active().indexOf('/') + 1, active().length)
@ -205,111 +213,82 @@ export const TabsUI = (props: TabsUIProps) => {
}
}}
>
<i className="fad fa-play"></i>
</button>
</CustomTooltip>
<CustomTooltip
placement="bottom"
tooltipId="overlay-tooltip-explaination"
tooltipText={
<span>
{tabsState.currentExt === 'sol'? (
<FormattedMessage id="remixUiTabs.tooltipText5" />
) : (
<FormattedMessage id="remixUiTabs.tooltipText4" />
)}
</span>
}
>
<button
data-id="explain-editor"
id='explain_btn'
className='btn py-0 text-ai px-0 d-flex'
disabled={!(tabsState.currentExt === 'sol') || explaining}
onClick={async () => {
const path = active().substr(active().indexOf('/') + 1, active().length)
const content = await props.plugin.call('fileManager', 'readFile', path)
if (tabsState.currentExt === 'sol') {
setExplaining(true)
await props.plugin.call('solcoder', 'code_explaining', content)
setExplaining(false)
_paq.push(['trackEvent', 'ai', 'solcoder', 'explain_file'])
}
}}
>
<i className={`fa-solid fa-user-robot ${explaining ? 'loadingExplanation' : ''}`}></i>
<span
className="position-relative text-ai text-sm pl-1"
style={{ fontSize: "x-small", alignSelf: "end" }}
>
AI
</span>
<i className="fas fa-play"></i>
</button>
</CustomTooltip>
<CustomTooltip
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>
}
>
<button
data-id="remix_ai_switch"
id='remix_ai_switch'
className="btn ai-switch text-ai pl-2 pr-0 py-0 d-flex"
disabled={!(tabsState.currentExt === 'sol' )}
onClick={async () => {
await props.plugin.call('settings', 'updateCopilotChoice', !ai_switch)
setAI_switch(!ai_switch)
ai_switch ? _paq.push(['trackEvent', 'ai', 'solcoder', 'copilot_enabled']) : _paq.push(['trackEvent', 'ai', 'solcoder', 'copilot_disabled'])
}}
<div className= "d-flex border-left ml-2 align-items-center" style={{ height: "3em" }}>
<CustomTooltip
placement="bottom"
tooltipId="overlay-tooltip-explaination"
tooltipText={
<span>
{tabsState.currentExt === 'sol'? (
<FormattedMessage id="remixUiTabs.tooltipText5" />
) : (
<FormattedMessage id="remixUiTabs.tooltipText4" />
)}
</span>
}
>
<i
className={ai_switch ? "fa-solid fa-toggle-on" : "fa-solid fa-toggle-off"}
></i>
<span
className="position-relative text-ai text-sm pl-1"
style={{ fontSize: "x-small", alignSelf: "end" }}
<button
data-id="explain-editor"
id='explain_btn'
className='btn text-ai pl-2 pr-0 py-0 d-flex'
disabled={!(tabsState.currentExt === 'sol') || explaining}
onClick={async () => {
const path = active().substr(active().indexOf('/') + 1, active().length)
const content = await props.plugin.call('fileManager', 'readFile', path)
if (tabsState.currentExt === 'sol') {
setExplaining(true)
await props.plugin.call('solcoder', 'code_explaining', content)
setExplaining(false)
_paq.push(['trackEvent', 'ai', 'solcoder', 'explain_file'])
}
}}
>
AI
</span>
</button>
</CustomTooltip>
<CustomTooltip placement="bottom" tooltipId="overlay-tooltip-aiDocumentation" tooltipText={<FormattedMessage id="remixUiTabs.tooltipText8" />}>
<span
data-id="remix_ai_docs"
id="remix_ai_docs"
className="btn pl-2 pr-0 py-0 d-flex ai-docs"
role='link'
onClick={()=>{
window.open("https://remix-ide.readthedocs.io/en/latest/ai.html")
_paq.push(['trackEvent', 'ai', 'solcoder', 'documentation'])
}}
<i className={`fas fa-user-robot ${explaining ? 'loadingExplanation' : ''}`}></i>
</button>
</CustomTooltip>
<CustomTooltip
placement="bottom"
tooltipId="overlay-tooltip-copilot"
tooltipText={
<span>
{ tabsState.currentExt === 'sol'? (
!ai_switch ? (
<FormattedMessage id="remixUiTabs.tooltipText6" />
) : (<FormattedMessage id="remixUiTabs.tooltipText7" />)
) : (
<FormattedMessage id="remixUiTabs.tooltipTextDisabledCopilot" />
)}
</span>
}
>
<i className="fa-solid fa-book text-ai"></i>
<span
className="position-relative text-ai text-sm pl-1"
style={{ fontSize: "x-small", alignSelf: "end" }}
<button
data-id="remix_ai_switch"
id='remix_ai_switch'
className="btn ai-switch text-ai pl-2 pr-0 py-0 d-flex"
disabled={!(tabsState.currentExt === 'sol' )}
onClick={async () => {
await props.plugin.call('settings', 'updateCopilotChoice', !ai_switch)
setAI_switch(!ai_switch)
ai_switch ? _paq.push(['trackEvent', 'ai', 'solcoder', 'copilot_enabled']) : _paq.push(['trackEvent', 'ai', 'solcoder', 'copilot_disabled'])
}}
>
AI
</span>
</span>
</CustomTooltip>
<i className={ai_switch ? "fas fa-toggle-on fa-lg" : "fas fa-toggle-off fa-lg"}></i>
</button>
</CustomTooltip>
</div>
<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>
</CustomTooltip>
<CustomTooltip placement="bottom" tooltipId="overlay-tooltip-run-zoom-in" tooltipText={<FormattedMessage id="remixUiTabs.zoomIn" />}>
<span data-id="tabProxyZoomIn" className="btn btn-sm px-2 fas fa-search-plus text-dark" onClick={() => props.onZoomIn()}></span>
</CustomTooltip>
<div className= "d-flex border-left ml-2 align-items-center" style={{ height: "3em" }}>
<CustomTooltip placement="bottom" tooltipId="overlay-tooltip-zoom-out" tooltipText={<FormattedMessage id="remixUiTabs.zoomOut" />}>
<span data-id="tabProxyZoomOut" className="btn fas fa-search-minus text-dark pl-2 pr-0 py-0 d-flex" onClick={() => props.onZoomOut()}></span>
</CustomTooltip>
<CustomTooltip placement="bottom" tooltipId="overlay-tooltip-run-zoom-in" tooltipText={<FormattedMessage id="remixUiTabs.zoomIn" />}>
<span data-id="tabProxyZoomIn" className="btn fas fa-search-plus text-dark pl-2 pr-0 py-0 d-flex" onClick={() => props.onZoomIn()}></span>
</CustomTooltip>
</div>
</div>
<Tabs
className="tab-scroll"

Loading…
Cancel
Save