diff --git a/apps/noir-compiler/src/app/app.tsx b/apps/noir-compiler/src/app/app.tsx index 5fae7839e59..bcb69ddf334 100644 --- a/apps/noir-compiler/src/app/app.tsx +++ b/apps/noir-compiler/src/app/app.tsx @@ -23,6 +23,20 @@ function App() { plugin.on('locale', 'localeChanged', (locale: any) => { setLocale(locale) }) + plugin.on('fileManager', 'currentFileChanged', (filePath) => { + if (filePath.endsWith('.nr')) { + dispatch({ type: 'SET_FILE_PATH', payload: filePath }) + plugin.parse(filePath) + } + }) + // @ts-ignore + plugin.on('editor', 'contentChanged', async (path: string, content: string) => { + setIsContentChanged(true) + // check if autoCompile is enabled + // if (path.endsWith('.nr')) { + // plugin.parse(path, content) + // } + }) setIsPluginActivated(true) }) }, []) diff --git a/apps/noir-compiler/src/app/components/container.tsx b/apps/noir-compiler/src/app/components/container.tsx index 886b5255591..0fe4ffc8e84 100644 --- a/apps/noir-compiler/src/app/components/container.tsx +++ b/apps/noir-compiler/src/app/components/container.tsx @@ -21,22 +21,17 @@ export function Container () { } } - // const handleOpenErrorLocation = async (location: string, startRange: string) => { - // if (location) { - // const fullPathLocation = await circuitApp.plugin.resolveReportPath(location) + const handleOpenErrorLocation = async (location: string, startRange: string) => { + if (location) { + const fullPathLocation = await circuitApp.plugin.resolveReportPath(location) - // await circuitApp.plugin.call('fileManager', 'open', fullPathLocation) - // // @ts-ignore - // const startPosition: { lineNumber: number; column: number } = await circuitApp.plugin.call('editor', 'getPositionAt', startRange) - // // @ts-ignore - // await circuitApp.plugin.call('editor', 'gotoLine', startPosition.lineNumber - 1, startPosition.column) - // } - // } - - // const handlePrimeChange = (value: PrimeValue) => { - // circuitApp.plugin.compilerPrime = value - // circuitApp.dispatch({ type: 'SET_PRIME_VALUE', payload: value as PrimeValue }) - // } + await circuitApp.plugin.call('fileManager', 'open', fullPathLocation) + // @ts-ignore + const startPosition: { lineNumber: number; column: number } = await circuitApp.plugin.call('editor', 'getPositionAt', startRange) + // @ts-ignore + await circuitApp.plugin.call('editor', 'gotoLine', startPosition.lineNumber - 1, startPosition.column) + } + } const handleCircuitAutoCompile = (value: boolean) => { noirApp.dispatch({ type: 'SET_AUTO_COMPILE', payload: value }) @@ -46,48 +41,48 @@ export function Container () { noirApp.dispatch({ type: 'SET_HIDE_WARNINGS', payload: value }) } - // const askGPT = async (report: CompilerReport) => { - // if (report.labels.length > 0) { - // const location = circuitApp.appState.filePathToId[report.labels[0].file_id] - // const error = report.labels[0].message + const askGPT = async (report: CompilerReport) => { + if (report.labels.length > 0) { + const location = circuitApp.appState.filePathToId[report.labels[0].file_id] + const error = report.labels[0].message - // if (location) { - // const fullPathLocation = await circuitApp.plugin.resolveReportPath(location) - // const content = await circuitApp.plugin.call('fileManager', 'readFile', fullPathLocation) - // const message = ` - // circom code: ${content} - // error message: ${error} - // full circom error: ${JSON.stringify(report, null, 2)} - // explain why the error occurred and how to fix it. - // ` - // await circuitApp.plugin.call('popupPanel' as any, 'showPopupPanel', true) - // setTimeout(async () => { - // await circuitApp.plugin.call('remixAI' as any, 'chatPipe', 'error_explaining', message) - // }, 500) - // } else { - // const message = ` - // error message: ${error} - // full circom error: ${JSON.stringify(report, null, 2)} - // explain why the error occurred and how to fix it. - // ` - // await circuitApp.plugin.call('popupPanel' as any, 'showPopupPanel', true) - // setTimeout(async () => { - // await circuitApp.plugin.call('remixAI' as any, 'chatPipe', 'error_explaining', message) - // }, 500) - // } - // } else { - // const error = report.message - // const message = ` - // error message: ${error} - // full circom error: ${JSON.stringify(report, null, 2)} - // explain why the error occurred and how to fix it. - // ` - // await circuitApp.plugin.call('popupPanel' as any, 'showPopupPanel', true) - // setTimeout(async () => { - // await circuitApp.plugin.call('remixAI' as any, 'chatPipe', 'error_explaining', message) - // }, 500) - // } - // } + if (location) { + const fullPathLocation = await circuitApp.plugin.resolveReportPath(location) + const content = await circuitApp.plugin.call('fileManager', 'readFile', fullPathLocation) + const message = ` + circom code: ${content} + error message: ${error} + full circom error: ${JSON.stringify(report, null, 2)} + explain why the error occurred and how to fix it. + ` + await circuitApp.plugin.call('popupPanel' as any, 'showPopupPanel', true) + setTimeout(async () => { + await circuitApp.plugin.call('remixAI' as any, 'chatPipe', 'error_explaining', message) + }, 500) + } else { + const message = ` + error message: ${error} + full circom error: ${JSON.stringify(report, null, 2)} + explain why the error occurred and how to fix it. + ` + await circuitApp.plugin.call('popupPanel' as any, 'showPopupPanel', true) + setTimeout(async () => { + await circuitApp.plugin.call('remixAI' as any, 'chatPipe', 'error_explaining', message) + }, 500) + } + } else { + const error = report.message + const message = ` + error message: ${error} + full circom error: ${JSON.stringify(report, null, 2)} + explain why the error occurred and how to fix it. + ` + await circuitApp.plugin.call('popupPanel' as any, 'showPopupPanel', true) + setTimeout(async () => { + await circuitApp.plugin.call('remixAI' as any, 'chatPipe', 'error_explaining', message) + }, 500) + } + } const handleCompileClick = () => { compileNoirCircuit(noirApp.plugin, noirApp.appState) @@ -113,9 +108,9 @@ export function Container () {
- {/* - - */} + + + diff --git a/apps/noir-compiler/src/app/reducers/state.ts b/apps/noir-compiler/src/app/reducers/state.ts index 3fd53e48f56..8230ade8200 100644 --- a/apps/noir-compiler/src/app/reducers/state.ts +++ b/apps/noir-compiler/src/app/reducers/state.ts @@ -1,10 +1,5 @@ import { Actions, AppState } from '../types' -export interface ActionPayloadTypes { - SET_AUTO_COMPILE: boolean, - SET_HIDE_WARNINGS: boolean -} - export const appInitialState: AppState = { filePath: '', filePathToId: {}, @@ -28,6 +23,12 @@ export const appReducer = (state = appInitialState, action: Actions): AppState = hideWarnings: action.payload } + case 'SET_FILE_PATH': + return { + ...state, + filePath: action.payload + } + default: throw new Error() } diff --git a/apps/noir-compiler/src/app/types/index.ts b/apps/noir-compiler/src/app/types/index.ts index 96a84cf241e..f927f9c31b0 100644 --- a/apps/noir-compiler/src/app/types/index.ts +++ b/apps/noir-compiler/src/app/types/index.ts @@ -1,7 +1,6 @@ import { compiler_list } from 'circom_wasm' import { Dispatch } from 'react' import type { NoirPluginClient } from '../services/noirPluginClient' -import { ActionPayloadTypes } from '../reducers/state' export type CompilerStatus = "compiling" | "idle" | "errored" | "warning" export interface INoirAppContext { @@ -18,6 +17,11 @@ export interface AppState { status: CompilerStatus } +export interface ActionPayloadTypes { + SET_AUTO_COMPILE: boolean, + SET_HIDE_WARNINGS: boolean, + SET_FILE_PATH: string +} export interface Action { type: T payload: ActionPayloadTypes[T] diff --git a/libs/remix-ui/helper/src/lib/components/feedback.tsx b/libs/remix-ui/helper/src/lib/components/feedback.tsx new file mode 100644 index 00000000000..af42b20d862 --- /dev/null +++ b/libs/remix-ui/helper/src/lib/components/feedback.tsx @@ -0,0 +1,72 @@ +import { useState } from 'react' +import { CompilerFeedbackProps, CompilerReport } from '../types' +import { RenderIf } from '@remix-ui/helper' +import { CopyToClipboard } from '@remix-ui/clipboard' +import { FeedbackAlert } from './feedbackAlert' + +export function CompilerFeedback ({ feedback, filePathToId, hideWarnings, openErrorLocation, askGPT }: CompilerFeedbackProps) { + const [showException, setShowException] = useState(true) + + const handleCloseException = () => { + setShowException(false) + } + + const handleOpenError = (report: CompilerReport) => { + if (report.labels.length > 0) { + openErrorLocation(filePathToId[report.labels[0].file_id], report.labels[0].range.start) + } + } + + const handleAskGPT = (report: CompilerReport) => { + askGPT(report) + } + + return ( +
+ { + (feedback && typeof feedback === 'string') || (Array.isArray(feedback) && feedback.length > 0) ? ( +
+ +
+ <>{ feedback } +
+ +
+
+ + + +
+
+
+ + <> + { + Array.isArray(feedback) && feedback.map((response, index) => ( +
handleOpenError(response)}> + +
+ handleAskGPT(response) } /> +
+
+ +
+ { handleAskGPT(response) }} /> +
+
+
+ ) + ) + } + +
+
+ ) : <> + } +
+ ) +} diff --git a/libs/remix-ui/helper/src/lib/components/feedbackAlert.tsx b/libs/remix-ui/helper/src/lib/components/feedbackAlert.tsx new file mode 100644 index 00000000000..c6328dd510a --- /dev/null +++ b/libs/remix-ui/helper/src/lib/components/feedbackAlert.tsx @@ -0,0 +1,32 @@ +import { useState } from 'react' +import { FeedbackAlertProps } from '../types' +import { RenderIf } from '@remix-ui/helper' +import {CopyToClipboard} from '@remix-ui/clipboard' + +export function FeedbackAlert ({ message, askGPT }: FeedbackAlertProps) { + const [ showAlert, setShowAlert] = useState(true) + + const handleCloseAlert = () => { + setShowAlert(false) + } + + return ( + + <> + { message } +
+ +
+
+ + + + { + e.stopPropagation() + askGPT() + }}>Ask RemixAI +
+ +
+ ) +} diff --git a/libs/remix-ui/helper/src/lib/remix-ui-helper.ts b/libs/remix-ui/helper/src/lib/remix-ui-helper.ts index 7657a3a7cfa..32e3947b822 100644 --- a/libs/remix-ui/helper/src/lib/remix-ui-helper.ts +++ b/libs/remix-ui/helper/src/lib/remix-ui-helper.ts @@ -82,7 +82,8 @@ export const getPathIcon = (path: string) => { ? 'fad fa-brackets-curly' : path.endsWith('.cairo') ? 'small fa-kit fa-cairo' : path.endsWith('.circom') ? 'fa-kit fa-circom' : path.endsWith('.nr') - ? 'fa-kit fa-noir' : 'far fa-file' + ? 'fa-kit fa-noir' : path.endsWith('.toml') + ? 'fad fa-cog': 'far fa-file' } export const isNumeric = (value) => {