fix editor blinking

pull/2081/head^2
yann300 3 years ago
parent 7afc35ae40
commit 9dacd0ab34
  1. 43
      apps/remix-ide/src/app/editor/editor.js
  2. 4
      apps/remix-ide/src/app/tabs/settings-tab.tsx
  3. 160
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
  4. 438
      package-lock.json
  5. 4
      package.json

@ -28,8 +28,6 @@ class Editor extends Plugin {
// Init
this.event = new EventManager()
this.sessions = {}
this.sourceAnnotationsPerFile = {}
this.markerPerFile = {}
this.readOnlySessions = {}
this.previousInput = ''
this.saveTimeout = null
@ -74,8 +72,6 @@ class Editor extends Plugin {
editorAPI={state.api}
themeType={state.currentThemeType}
currentFile={state.currentFile}
sourceAnnotationsPerFile={state.sourceAnnotationsPerFile}
markerPerFile={state.markerPerFile}
events={state.events}
plugin={state.plugin}
/>
@ -108,6 +104,10 @@ class Editor extends Plugin {
}
this.ref.gotoLine = (line, column) => this.gotoLine(line, column || 0)
this.ref.getCursorPosition = () => this.getCursorPosition()
this.ref.addMarkerPerFile = (marker, filePath) => this.addMarkerPerFile(marker, filePath)
this.ref.addSourceAnnotationsPerFile = (annotation, filePath) => this.addSourceAnnotationsPerFile(annotation, filePath)
this.ref.clearDecorationsByPlugin = (filePath, plugin, typeOfDecoration) => this.clearDecorationsByPlugin(filePath, plugin, typeOfDecoration)
this.ref.keepDecorationsFor = (name, typeOfDecoration) => this.keepDecorationsFor(name, typeOfDecoration)
}} id='editorView'>
<PluginViewWrapper plugin={this} />
</div>
@ -118,8 +118,6 @@ class Editor extends Plugin {
api: this.api,
currentThemeType: this.currentThemeType,
currentFile: this.currentFile,
sourceAnnotationsPerFile: this.sourceAnnotationsPerFile,
markerPerFile: this.markerPerFile,
events: this.events,
plugin: this
})
@ -410,27 +408,12 @@ class Editor extends Plugin {
if (filePath && !this.sessions[filePath]) throw new Error('file not found' + filePath)
const path = filePath || this.currentFile
const currentAnnotations = this[typeOfDecoration][path]
if (!currentAnnotations) return
const newAnnotations = []
for (const annotation of currentAnnotations) {
if (annotation.from !== plugin) newAnnotations.push(annotation)
}
this[typeOfDecoration][path] = newAnnotations
this.renderComponent()
this.api.clearDecorationsByPlugin(path, plugin, typeOfDecoration)
}
keepDecorationsFor (name, typeOfDecoration) {
keepDecorationsFor (plugin, typeOfDecoration) {
if (!this.currentFile) return
if (!this[typeOfDecoration][this.currentFile]) return
const annotations = this[typeOfDecoration][this.currentFile]
for (const annotation of annotations) {
annotation.hide = annotation.from !== name
}
this.renderComponent()
this.api.keepDecorationsFor(this.currentFile, plugin, typeOfDecoration)
}
/**
@ -473,10 +456,16 @@ class Editor extends Plugin {
const path = filePath || this.currentFile
const { from } = this.currentRequest
if (!this[typeOfDecoration][path]) this[typeOfDecoration][path] = []
decoration.from = from
this[typeOfDecoration][path].push(decoration)
this.renderComponent()
if (typeOfDecoration === 'markerPerFile') {
this.api.addMarkerPerFile(decoration, path)
return
}
if (typeOfDecoration === 'sourceAnnotationsPerFile') {
this.api.addSourceAnnotationsPerFile(decoration, path)
return
}
}
/**

@ -47,11 +47,9 @@ module.exports = class SettingsTab extends ViewPlugin {
}
render() {
return (
<div id='settingsTab'>
return <div id='settingsTab'>
<PluginViewWrapper plugin={this} />
</div>
);
}
updateComponent(state: any){

@ -38,14 +38,6 @@ type sourceMarker = {
hide: boolean
}
type sourceAnnotationMap = {
[key: string]: [sourceAnnotation];
}
type sourceMarkerMap = {
[key: string]: [sourceMarker];
}
loader.config({ paths: { vs: 'assets/js/monaco-editor/dev/vs' } })
/* eslint-disable-next-line */
@ -54,8 +46,6 @@ export interface EditorUIProps {
activated: boolean
themeType: string
currentFile: string
sourceAnnotationsPerFile: sourceAnnotationMap
markerPerFile: sourceMarkerMap
events: {
onBreakPointAdded: (file: string, line: number) => void
onBreakPointCleared: (file: string, line: number) => void
@ -71,17 +61,21 @@ export interface EditorUIProps {
getFontSize: () => number,
getValue: (uri: string) => string
getCursorPosition: () => cursorPosition
addMarkerPerFile: (marker: sourceMarker, filePath: string) => void
addSourceAnnotationsPerFile: (annotations: sourceAnnotation, filePath: string) => void
clearDecorationsByPlugin: (filePath: string, plugin: string, typeOfDecoration: string) => void
keepDecorationsFor: (filePath: string, plugin: string, typeOfDecoration: string) => void
}
}
export const EditorUI = (props: EditorUIProps) => {
const [, setCurrentBreakpoints] = useState({})
const [currentAnnotations, setCurrentAnnotations] = useState({})
const [currentMarkers, setCurrentMarkers] = useState({})
const editorRef = useRef(null)
const monacoRef = useRef(null)
const currentFileRef = useRef('')
const currentDecorations = useRef({ sourceAnnotationsPerFile: {}, markerPerFile: {} }) // decorations that are currently in use by the editor
const registeredDecorations = useRef({}) // registered decorations
const [editorModelsState, dispatch] = useReducer(reducerActions, initialState)
const formatColor = (name) => {
@ -226,55 +220,6 @@ export const EditorUI = (props: EditorUIProps) => {
defineAndSetTheme(monacoRef.current)
})
const setAnnotationsbyFile = (uri) => {
if (props.sourceAnnotationsPerFile[uri]) {
const model = editorModelsState[uri]?.model
const newAnnotations = []
for (const annotation of props.sourceAnnotationsPerFile[uri]) {
if (!annotation.hide) {
newAnnotations.push({
range: new monacoRef.current.Range(annotation.row + 1, 1, annotation.row + 1, 1),
options: {
isWholeLine: false,
glyphMarginHoverMessage: { value: (annotation.from ? `from ${annotation.from}:\n` : '') + annotation.text },
glyphMarginClassName: `fal fa-exclamation-square text-${annotation.type === 'error' ? 'danger' : (annotation.type === 'warning' ? 'warning' : 'info')}`
}
})
}
}
setCurrentAnnotations(prevState => {
prevState[uri] = model.deltaDecorations(currentAnnotations[uri] || [], newAnnotations)
return prevState
})
}
}
const setMarkerbyFile = (uri) => {
if (props.markerPerFile[uri]) {
const model = editorModelsState[uri]?.model
const newMarkers = []
for (const marker of props.markerPerFile[uri]) {
if (!marker.hide) {
let isWholeLine = false
if (marker.position.start.line === marker.position.end.line && marker.position.end.column - marker.position.start.column < 3) {
// in this case we force highlighting the whole line (doesn't make sense to highlight 2 chars)
isWholeLine = true
}
newMarkers.push({
range: new monacoRef.current.Range(marker.position.start.line + 1, marker.position.start.column + 1, marker.position.end.line + 1, marker.position.end.column + 1),
options: {
isWholeLine,
inlineClassName: `alert-info border-0 highlightLine${marker.position.start.line + 1}`
}
})
}
}
setCurrentMarkers(prevState => {
prevState[uri] = model.deltaDecorations(currentMarkers[uri] || [], newMarkers)
return prevState
})
}
}
useEffect(() => {
if (!editorRef.current) return
@ -286,18 +231,91 @@ export const EditorUI = (props: EditorUIProps) => {
monacoRef.current.editor.setModelLanguage(file.model, 'remix-solidity')
} else if (file.language === 'cairo') {
monacoRef.current.editor.setModelLanguage(file.model, 'remix-cairo')
}
setAnnotationsbyFile(props.currentFile)
setMarkerbyFile(props.currentFile)
}
}, [props.currentFile])
useEffect(() => {
setAnnotationsbyFile(props.currentFile)
}, [JSON.stringify(props.sourceAnnotationsPerFile)])
const convertToMonacoDecoration = (decoration: sourceAnnotation | sourceMarker, typeOfDecoration: string) => {
if (typeOfDecoration === 'sourceAnnotationsPerFile') {
decoration = decoration as sourceAnnotation
return {
type: typeOfDecoration,
range: new monacoRef.current.Range(decoration.row + 1, 1, decoration.row + 1, 1),
options: {
isWholeLine: false,
glyphMarginHoverMessage: { value: (decoration.from ? `from ${decoration.from}:\n` : '') + decoration.text },
glyphMarginClassName: `fal fa-exclamation-square text-${decoration.type === 'error' ? 'danger' : (decoration.type === 'warning' ? 'warning' : 'info')}`
}
}
}
if (typeOfDecoration === 'markerPerFile') {
decoration = decoration as sourceMarker
let isWholeLine = false
if (decoration.position.start.line === decoration.position.end.line && decoration.position.end.column - decoration.position.start.column < 3) {
// in this case we force highlighting the whole line (doesn't make sense to highlight 2 chars)
isWholeLine = true
}
return {
type: typeOfDecoration,
range: new monacoRef.current.Range(decoration.position.start.line + 1, decoration.position.start.column + 1, decoration.position.end.line + 1, decoration.position.end.column + 1),
options: {
isWholeLine,
inlineClassName: `alert-info border-top border-bottom highlightLine${decoration.position.start.line + 1}`
}
}
}
}
props.editorAPI.clearDecorationsByPlugin = (filePath: string, plugin: string, typeOfDecoration: string) => {
const model = editorModelsState[filePath]?.model
if (!model) return
const decorations = []
const newRegisteredDecorations = []
if (registeredDecorations.current[filePath]) {
for (const decoration of registeredDecorations.current[filePath]) {
if (decoration.type === typeOfDecoration && decoration.value.from !== plugin) {
decorations.push(convertToMonacoDecoration(decoration.value, typeOfDecoration))
newRegisteredDecorations.push(decoration)
}
}
}
currentDecorations.current[typeOfDecoration][filePath] = model.deltaDecorations(currentDecorations.current[typeOfDecoration][filePath], decorations)
registeredDecorations.current[filePath] = newRegisteredDecorations
}
props.editorAPI.keepDecorationsFor = (filePath: string, plugin: string, typeOfDecoration: string) => {
const model = editorModelsState[filePath]?.model
if (!model) return
const decorations = []
if (registeredDecorations.current[filePath]) {
for (const decoration of registeredDecorations.current[filePath]) {
if (decoration.type === typeOfDecoration && decoration.value.from === plugin) {
decorations.push(convertToMonacoDecoration(decoration.value, typeOfDecoration))
}
}
}
currentDecorations.current[typeOfDecoration][filePath] = model.deltaDecorations(currentDecorations.current[typeOfDecoration][filePath], decorations)
}
const addDecoration = (decoration: sourceAnnotation | sourceMarker, filePath: string, typeOfDecoration: string) => {
const model = editorModelsState[filePath]?.model
if (!model) return
const monacoDecoration = convertToMonacoDecoration(decoration, typeOfDecoration)
if (!registeredDecorations.current[filePath]) registeredDecorations.current[filePath] = []
registeredDecorations.current[filePath].push({ value: decoration, type: typeOfDecoration })
if (!currentDecorations.current[typeOfDecoration][filePath]) currentDecorations.current[typeOfDecoration][filePath] = []
currentDecorations.current[typeOfDecoration][filePath].push(...model.deltaDecorations([], [monacoDecoration]))
}
props.editorAPI.addSourceAnnotationsPerFile = (annotation: sourceAnnotation, filePath: string) => {
addDecoration(annotation, filePath, 'sourceAnnotationsPerFile')
}
props.editorAPI.addMarkerPerFile = (marker: sourceMarker, filePath: string) => {
addDecoration(marker, filePath, 'markerPerFile')
}
useEffect(() => {
setMarkerbyFile(props.currentFile)
}, [JSON.stringify(props.markerPerFile)])
props.editorAPI.findMatches = (uri: string, value: string) => {
if (!editorRef.current) return

438
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -75,7 +75,7 @@
"nightwatch_local_staticAnalysis": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/staticAnalysis.test.js --env=chrome",
"nightwatch_local_signingMessage": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/signingMessage.test.js --env=chrome",
"nightwatch_local_specialFunctions": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/specialFunctions_*.test.js --env=chrome",
"nightwatch_local_solidityUnitTests": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/solidityUnittests_*.test.js --env=chrome",
"nightwatch_local_solidityUnitTests": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/solidityUnittests_*.test.js --env=firefoxDesktop",
"nightwatch_local_remixd": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/remixd.test.js --env=chrome",
"nightwatch_local_terminal": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/terminal_*.test.js --env=chrome",
"nightwatch_local_gist": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/gist.test.js --env=chrome",
@ -86,7 +86,7 @@
"nightwatch_local_generalSettings": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/generalSettings.test.js --env=chrome",
"nightwatch_local_fileExplorer": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/fileExplorer.test.js --env=chrome",
"nightwatch_local_debugger": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/debugger_*.test.js --env=chrome",
"nightwatch_local_editor": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/editor.test.js --env=chrome",
"nightwatch_local_editor": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/editor.test.js --env=firefoxDesktop",
"nightwatch_local_importFromGithub": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/importFromGithub.test.js --env=chrome",
"nightwatch_local_compiler": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/compiler_api.test.js --env=chrome",
"nightwatch_local_txListener": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/txListener.test.js --env=chrome",

Loading…
Cancel
Save