Skip to content

Commit 975ea37

Browse files
author
Ives van Hoorne
committed
More live updates
1 parent e0fce9a commit 975ea37

File tree

1 file changed

+67
-28
lines changed
  • packages/app/src/app/components/CodeEditor/Monaco

1 file changed

+67
-28
lines changed

packages/app/src/app/components/CodeEditor/Monaco/index.js

Lines changed: 67 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ const fadeIn = css.keyframes('fadeIn', {
5555
'100%': { opacity: 1 },
5656
});
5757

58+
const fadeOut = css.keyframes('fadeOut', {
59+
// optional name
60+
'0%': { opacity: 1 },
61+
'100%': { opacity: 0 },
62+
});
63+
5864
function lineAndColumnToIndex(lines, lineNumber, column) {
5965
let currentLine = 0;
6066
let index = 0;
@@ -145,6 +151,10 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
145151

146152
this.resizeEditor = debounce(this.resizeEditor, 500);
147153
this.commitLibChanges = debounce(this.commitLibChanges, 300);
154+
this.onSelectionChangedDebounced = debounce(
155+
this.onSelectionChangedDebounced,
156+
500
157+
);
148158
}
149159

150160
shouldComponentUpdate(nextProps: Props) {
@@ -270,36 +280,45 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
270280
});
271281

272282
editor.onDidChangeModelContent(({ changes }) => {
273-
const { isLive, sendTransforms, onCodeReceived } = this.props;
283+
const { isLive, sendTransforms } = this.props;
274284

275285
if (isLive && sendTransforms && !this.receivingCode) {
276286
this.addChangesOperation(changes);
277287
}
278288
});
279289

280290
editor.onDidChangeCursorSelection(selectionChange => {
291+
// TODO: add another debounced action to send the current data. So we can
292+
// have the correct cursor pos no matter what
281293
const { onSelectionChanged, isLive } = this.props;
282294
// Reason 3 is update by mouse or arrow keys
283-
if (
284-
isLive &&
285-
(selectionChange.reason === 3 ||
286-
/* alt + shift + arrow keys */ selectionChange.source ===
287-
'moveWordCommand' ||
288-
/* click inside a selection */ selectionChange.source === 'api') &&
289-
onSelectionChanged
290-
) {
295+
if (isLive) {
291296
const lines = editor.getModel().getLinesContent();
292297
const data = {
293298
primary: getSelection(lines, selectionChange.selection),
294299
secondary: selectionChange.secondarySelections.map(s =>
295300
getSelection(lines, s)
296301
),
297302
};
298-
299-
onSelectionChanged({
300-
selection: data,
301-
moduleShortid: this.currentModule.shortid,
302-
});
303+
if (
304+
(selectionChange.reason === 3 ||
305+
/* alt + shift + arrow keys */ selectionChange.source ===
306+
'moveWordCommand' ||
307+
/* click inside a selection */ selectionChange.source === 'api') &&
308+
onSelectionChanged
309+
) {
310+
onSelectionChanged({
311+
selection: data,
312+
moduleShortid: this.currentModule.shortid,
313+
});
314+
} else {
315+
// This is just on typing, we send a debounced selection update as a
316+
// safeguard to make sure we are in sync
317+
this.onSelectionChangedDebounced({
318+
selection: data,
319+
moduleShortid: this.currentModule.shortid,
320+
});
321+
}
303322
}
304323
});
305324

@@ -390,6 +409,12 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
390409
});
391410
};
392411

412+
onSelectionChangedDebounced = data => {
413+
if (this.props.onSelectionChanged) {
414+
this.props.onSelectionChanged(data);
415+
}
416+
};
417+
393418
changes = { code: '', changes: [] };
394419
changeTimeout: ?TimeoutID;
395420
/**
@@ -519,30 +544,41 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
519544
const secondarySelectionClassName = userId + '-secondary-selection';
520545

521546
if (!this.userClassesGenerated[cursorClassName]) {
547+
const nameStyles = {
548+
content: name,
549+
position: 'absolute',
550+
top: -17,
551+
backgroundColor: `rgb(${color[0]}, ${color[1]}, ${color[2]})`,
552+
zIndex: 20,
553+
color:
554+
color[0] + color[1] + color[2] > 500
555+
? 'rgba(0, 0, 0, 0.8)'
556+
: 'white',
557+
padding: '2px 4px',
558+
borderRadius: 2,
559+
borderBottomLeftRadius: 0,
560+
fontSize: '.75rem',
561+
fontWeight: 600,
562+
};
522563
this.userClassesGenerated[cursorClassName] = `${css({
523564
backgroundColor: `rgba(${color[0]}, ${color[1]}, ${color[2]}, 0.8)`,
524565
width: '2px !important',
566+
marginLeft: -1,
525567
cursor: 'text',
526568
zIndex: 30,
569+
':before': {
570+
animation: `${fadeOut} 0.3s`,
571+
animationDelay: '1s',
572+
animationFillMode: 'forwards',
573+
opacity: 1,
574+
...nameStyles,
575+
},
527576
':hover': {
528577
':before': {
529578
animation: `${fadeIn} 0.3s`,
530579
animationFillMode: 'forwards',
531580
opacity: 0,
532-
content: name,
533-
position: 'absolute',
534-
top: -20,
535-
backgroundColor: `rgb(${color[0]}, ${color[1]}, ${color[2]})`,
536-
zIndex: 20,
537-
color:
538-
color[0] + color[1] + color[2] > 500
539-
? 'rgba(0, 0, 0, 0.8)'
540-
: 'white',
541-
padding: '2px 6px',
542-
borderRadius: 2,
543-
borderBottomLeftRadius: 0,
544-
fontSize: '.875rem',
545-
fontWeight: 800,
581+
...nameStyles,
546582
},
547583
},
548584
})}`;
@@ -552,20 +588,23 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
552588
this.userClassesGenerated[secondaryCursorClassName] = `${css({
553589
backgroundColor: `rgba(${color[0]}, ${color[1]}, ${color[2]}, 0.6)`,
554590
width: '2px !important',
591+
marginLeft: -1,
555592
})}`;
556593
}
557594

558595
if (!this.userClassesGenerated[selectionClassName]) {
559596
this.userClassesGenerated[selectionClassName] = `${css({
560597
backgroundColor: `rgba(${color[0]}, ${color[1]}, ${color[2]}, 0.3)`,
561598
borderRadius: '3px',
599+
minWidth: 7.6,
562600
})}`;
563601
}
564602

565603
if (!this.userClassesGenerated[secondarySelectionClassName]) {
566604
this.userClassesGenerated[secondarySelectionClassName] = `${css({
567605
backgroundColor: `rgba(${color[0]}, ${color[1]}, ${color[2]}, 0.2)`,
568606
borderRadius: '3px',
607+
minWidth: 7.6,
569608
})}`;
570609
}
571610

0 commit comments

Comments
 (0)