From 4cad8761735deeb6a0a2686ea3ca718b0fb5ea9d Mon Sep 17 00:00:00 2001 From: Alf Eaton Date: Fri, 28 Jan 2022 09:26:32 +0000 Subject: [PATCH] [web] CodeMirror 6 track changes extension (#6455) GitOrigin-RevId: 038f375c40e7bc8009ee423016b711a2252f52fa --- .../controllers/ReviewPanelController.js | 74 +++++++++++++++++-- .../directives/reviewPanelSorted.js | 20 +++++ 2 files changed, 89 insertions(+), 5 deletions(-) diff --git a/services/web/frontend/js/ide/review-panel/controllers/ReviewPanelController.js b/services/web/frontend/js/ide/review-panel/controllers/ReviewPanelController.js index a12e0e0a4e..3729959f3e 100644 --- a/services/web/frontend/js/ide/review-panel/controllers/ReviewPanelController.js +++ b/services/web/frontend/js/ide/review-panel/controllers/ReviewPanelController.js @@ -134,6 +134,7 @@ export default App.controller( $timeout(() => $scope.$broadcast('review-panel:layout')) ) + // TODO: unused? $scope.$on('review-panel:sizes', (e, sizes) => $scope.$broadcast('editor:set-scroll-size', sizes) ) @@ -203,6 +204,7 @@ export default App.controller( getChangeTracker(doc_id).removeChangeIds(change_ids) } else { $scope.$broadcast('changes:accept', change_ids) + dispatchReviewPanelEvent('changes:accept', change_ids) } updateEntries(doc_id) return $scope.$apply(function () {}) @@ -529,6 +531,11 @@ export default App.controller( // For now, not worrying about entry panels for rich text if (!$scope.editor.showRichText) { $scope.$broadcast('review-panel:recalculate-screen-positions') + dispatchReviewPanelEvent( + 'recalculate-screen-positions', + getDocEntries($scope.editor.open_doc_id) + ) + return $scope.$broadcast('review-panel:layout') } }) @@ -607,6 +614,9 @@ export default App.controller( } $scope.$broadcast('review-panel:recalculate-screen-positions') + + dispatchReviewPanelEvent('recalculate-screen-positions', entries) + return $scope.$broadcast('review-panel:layout') } ) @@ -630,11 +640,14 @@ export default App.controller( `/project/${$scope.project_id}/doc/${$scope.editor.open_doc_id}/changes/accept`, { change_ids, _csrf: window.csrfToken } ) - return $scope.$broadcast('changes:accept', change_ids) + $scope.$broadcast('changes:accept', change_ids) + dispatchReviewPanelEvent('changes:accept', change_ids) } - const _doRejectChanges = change_ids => + const _doRejectChanges = change_ids => { $scope.$broadcast('changes:reject', change_ids) + dispatchReviewPanelEvent('changes:reject', change_ids) + } const bulkAccept = function () { _doAcceptChanges($scope.reviewPanel.selectedEntryIds.slice()) @@ -694,6 +707,8 @@ export default App.controller( return } $scope.$broadcast('comment:select_line') + dispatchReviewPanelEvent('comment:select_line') + if (!$scope.ui.reviewPanelOpen) { $scope.toggleReviewPanel() } @@ -705,6 +720,7 @@ export default App.controller( $scope.startNewComment = function () { $scope.$broadcast('comment:select_line') + dispatchReviewPanelEvent('comment:select_line') return $timeout(() => $scope.$broadcast('review-panel:layout')) } @@ -722,6 +738,11 @@ export default App.controller( const thread = getThread(thread_id) thread.submitting = true $scope.$broadcast('comment:add', thread_id, offset, length) + dispatchReviewPanelEvent('comment:add', { + threadId: thread_id, + offset, + length, + }) $http .post(`/project/${$scope.project_id}/thread/${thread_id}/messages`, { content, @@ -733,6 +754,7 @@ export default App.controller( 'Sorry, there was a problem submitting your comment' ) ) + // TODO: unused? $scope.$broadcast('editor:clearSelection') $timeout(() => $scope.$broadcast('review-panel:layout')) eventTracking.sendMB('rp-new-comment', { size: content.length }) @@ -810,7 +832,8 @@ export default App.controller( thread.resolved_by_user = formatUser(user) thread.resolved_at = new Date().toISOString() $scope.reviewPanel.resolvedThreadIds[thread_id] = true - return $scope.$broadcast('comment:resolve_threads', [thread_id]) + $scope.$broadcast('comment:resolve_threads', [thread_id]) + dispatchReviewPanelEvent('comment:resolve_threads', [thread_id]) } function _onCommentReopened(thread_id) { @@ -822,13 +845,15 @@ export default App.controller( delete thread.resolved_by_user delete thread.resolved_at delete $scope.reviewPanel.resolvedThreadIds[thread_id] - return $scope.$broadcast('comment:unresolve_thread', thread_id) + $scope.$broadcast('comment:unresolve_thread', thread_id) + dispatchReviewPanelEvent('comment:unresolve_thread', thread_id) } function _onThreadDeleted(thread_id) { delete $scope.reviewPanel.resolvedThreadIds[thread_id] delete $scope.reviewPanel.commentThreads[thread_id] - return $scope.$broadcast('comment:remove', thread_id) + $scope.$broadcast('comment:remove', thread_id) + dispatchReviewPanelEvent('comment:remove', thread_id) } function _onCommentEdited(thread_id, comment_id, content) { @@ -1167,6 +1192,7 @@ export default App.controller( thread.resolved_by_user = formatUser(thread.resolved_by_user) $scope.reviewPanel.resolvedThreadIds[thread_id] = true $scope.$broadcast('comment:resolve_threads', [thread_id]) + dispatchReviewPanelEvent('comment:resolve_threads', [thread_id]) } } $scope.reviewPanel.commentThreads = threads @@ -1228,5 +1254,43 @@ export default App.controller( controller: 'TrackChangesUpgradeModalController', scope: $scope.$new(), }) + + // listen for events from the CodeMirror 6 track changes extension + window.addEventListener('editor:event', event => { + const { type, payload } = event.detail + + switch (type) { + case 'line-height': { + $scope.reviewPanel.rendererData.lineHeight = payload + $scope.$broadcast('review-panel:layout') + break + } + + case 'track-changes:changed': { + $scope.$broadcast('editor:track-changes:changed') + break + } + + case 'track-changes:visibility_changed': { + $scope.$broadcast('editor:track-changes:visibility_changed') + break + } + + case 'focus:changed': { + const { from, to, empty } = payload + $scope.$broadcast('editor:focus:changed', from, to, !empty) + break + } + } + }) } ) + +// send events to the CodeMirror 6 track changes extension +const dispatchReviewPanelEvent = (type, payload) => { + window.dispatchEvent( + new CustomEvent('review-panel:event', { + detail: { type, payload }, + }) + ) +} diff --git a/services/web/frontend/js/ide/review-panel/directives/reviewPanelSorted.js b/services/web/frontend/js/ide/review-panel/directives/reviewPanelSorted.js index 0be3c3847e..f0a0e293f4 100644 --- a/services/web/frontend/js/ide/review-panel/directives/reviewPanelSorted.js +++ b/services/web/frontend/js/ide/review-panel/directives/reviewPanelSorted.js @@ -169,6 +169,8 @@ export default App.directive('reviewPanelSorted', $timeout => ({ } else { overflowTop = 0 } + + // TODO: unused? return scope.$emit('review-panel:sizes', { overflowTop, height: previousBottom + OVERVIEW_TOGGLE_HEIGHT, @@ -203,6 +205,7 @@ export default App.directive('reviewPanelSorted', $timeout => ({ const old_top = parseInt(list.css('top')) const top = old_top - deltaY * 4 scrollAce(-top) + dispatchScrollEvent(-top) return e.preventDefault() }) @@ -215,6 +218,7 @@ export default App.directive('reviewPanelSorted', $timeout => ({ if (ignoreNextAceEvent) { return (ignoreNextAceEvent = false) } else { + // TODO: unused? const ignoreNextPanelEvent = true list.height(height) // console.log({height, scrollTop, top: height - scrollTop}) @@ -228,6 +232,22 @@ export default App.directive('reviewPanelSorted', $timeout => ({ scope.reviewPanelEventsBridge.on('aceScroll', scrollPanel) scope.$on('$destroy', () => scope.reviewPanelEventsBridge.off('aceScroll')) + // receive the scroll position from the CodeMirror 6 track changes extension + window.addEventListener('editor:scroll', event => { + const { scrollTop, height } = event.detail + + scrollPanel(scrollTop, height) + }) + + // send the scroll position to the CodeMirror 6 track changes extension + const dispatchScrollEvent = value => { + window.dispatchEvent( + new CustomEvent('review-panel:event', { + detail: { type: 'scroll', payload: value }, + }) + ) + } + return scope.reviewPanelEventsBridge.emit('refreshScrollPosition') }, }))