diff --git a/services/web/app/views/project/editor/editor.pug b/services/web/app/views/project/editor/editor.pug index 98060725a7..d3a2e7fd8a 100644 --- a/services/web/app/views/project/editor/editor.pug +++ b/services/web/app/views/project/editor/editor.pug @@ -100,15 +100,19 @@ div.full-size( tooltip-placement="right" tooltip-append-to-body="true" ng-click="syncToPdf()" + ng-disabled="syncToPdfInFlight" ) - i.synctex-control-icon + i.synctex-control-icon(ng-show="!syncToPdfInFlight") + i.synctex-spin-icon.fa.fa-refresh.fa-spin(ng-show="syncToPdfInFlight") a.btn.btn-default.btn-xs.synctex-control.synctex-control-goto-code( tooltip-html="'"+translate('go_to_pdf_location_in_code', {}, true)+"'" tooltip-placement="right" tooltip-append-to-body="true" ng-click="syncToCode()" + ng-disabled="syncToCodeInFlight" ) - i.synctex-control-icon + i.synctex-control-icon(ng-show="!syncToCodeInFlight") + i.synctex-spin-icon.fa.fa-refresh.fa-spin(ng-show="syncToCodeInFlight") div.full-size( ng-if="ui.pdfLayout == 'flat'" diff --git a/services/web/app/views/project/editor/file-tree.pug b/services/web/app/views/project/editor/file-tree.pug index cac3f1e715..5117e27a2c 100644 --- a/services/web/app/views/project/editor/file-tree.pug +++ b/services/web/app/views/project/editor/file-tree.pug @@ -2,13 +2,13 @@ aside.editor-sidebar.full-size( ng-controller="FileTreeController" ng-class="{ 'multi-selected': multiSelectedCount > 0 }" ng-show="ui.view != 'history' || !history.isV2" - vertical-resizable-panes=user.betaProgram && "outline-resizer" - vertical-resizable-panes-toggled-externally-on=user.betaProgram && "outline-toggled" - vertical-resizable-panes-min-size=user.betaProgram && "32" - vertical-resizable-panes-max-size=user.betaProgram && "75%" + vertical-resizable-panes="outline-resizer" + vertical-resizable-panes-toggled-externally-on="outline-toggled" + vertical-resizable-panes-min-size="32" + vertical-resizable-panes-max-size="75%" ) .file-tree( - vertical-resizable-top=user.betaProgram + vertical-resizable-top ) .toolbar.toolbar-filetree(ng-if="permissions.write") a( @@ -99,20 +99,19 @@ aside.editor-sidebar.full-size( span {{ entity.name }} - if user.betaProgram - .outline-container( - vertical-resizable-bottom - ng-controller="OutlineController" + .outline-container( + vertical-resizable-bottom + ng-controller="OutlineController" + ) + outline-pane( + is-tex-file="isTexFile" + outline="outline" + project-id="project_id" + jump-to-line="jumpToLine" + on-toggle="onToggle" + event-tracking="eventTracking" + highlighted-line="highlightedLine" ) - outline-pane( - is-tex-file="isTexFile" - outline="outline" - project-id="project_id" - jump-to-line="jumpToLine" - on-toggle="onToggle" - event-tracking="eventTracking" - highlighted-line="highlightedLine" - ) script(type='text/ng-template', id='entityListItemTemplate') @@ -156,8 +155,7 @@ script(type='text/ng-template', id='entityListItemTemplate') dropdown, ng-if="permissions.write" ) - a.dropdown-toggle(href, dropdown-toggle, stop-propagation="click") - i.fa.fa-chevron-down + a.dropdown-toggle.file-tree-dropdown-toggle(href, dropdown-toggle, stop-propagation="click") ul.dropdown-menu.dropdown-menu-right li @@ -214,7 +212,7 @@ script(type='text/ng-template', id='entityListItemTemplate') ) i.fa.fa-fw.toggle( ng-if="entity.type == 'folder'" - ng-class="{'fa-chevron-right': !expanded, 'fa-chevron-down': expanded}" + ng-class="{'fa-angle-right': !expanded, 'fa-angle-down': expanded}" ng-click="toggleExpanded()" ) @@ -245,8 +243,7 @@ script(type='text/ng-template', id='entityListItemTemplate') dropdown, ng-if="permissions.write" ) - a.dropdown-toggle(href, dropdown-toggle, stop-propagation="click") - i.fa.fa-chevron-down + a.dropdown-toggle.file-tree-dropdown-toggle(href, dropdown-toggle, stop-propagation="click") ul.dropdown-menu.dropdown-menu-right li diff --git a/services/web/frontend/js/ide/editor/EditorManager.js b/services/web/frontend/js/ide/editor/EditorManager.js index f2daefac9d..8efc0f644c 100644 --- a/services/web/frontend/js/ide/editor/EditorManager.js +++ b/services/web/frontend/js/ide/editor/EditorManager.js @@ -139,8 +139,8 @@ export default (EditorManager = (function() { sl_console.log(`[openDoc] Opening ${doc.id}`) this.$scope.ui.view = 'editor' - const done = () => { - this.$scope.$broadcast('doc:after-opened') + const done = isNewDoc => { + this.$scope.$broadcast('doc:after-opened', { isNewDoc }) if (options.gotoLine != null) { // allow Ace to display document before moving, delay until next tick // added delay to make this happen later that gotoStoredPosition in @@ -163,7 +163,7 @@ export default (EditorManager = (function() { // automatically update the file tree whenever the file is opened this.ide.fileTreeManager.selectEntity(doc) this.$scope.$apply(() => { - return done() + return done(false) }) return } @@ -192,7 +192,7 @@ export default (EditorManager = (function() { return this.$scope.$apply(() => { this.$scope.editor.opening = false this.$scope.editor.sharejs_doc = sharejs_doc - return done() + return done(true) }) }) } diff --git a/services/web/frontend/js/ide/outline/OutlineManager.js b/services/web/frontend/js/ide/outline/OutlineManager.js index 4369a3f77a..440bcd192b 100644 --- a/services/web/frontend/js/ide/outline/OutlineManager.js +++ b/services/web/frontend/js/ide/outline/OutlineManager.js @@ -18,9 +18,17 @@ class OutlineManager { this.ignoreNextScroll = false this.ignoreNextCursorUpdate = false - scope.$on('doc:after-opened', () => { + scope.$on('doc:after-opened', (ev, { isNewDoc }) => { + if (isNewDoc) { + // if a new doc is opened a cursor updates will be triggered before the + // content is loaded. We have to ignore it or the outline highlight + // will be incorrect. This doesn't happen when `doc:after-opened` is + // fired without a new doc opened. + this.ignoreNextCursorUpdate = true + } + // always ignore the next scroll update so the cursor update takes + // precedence this.ignoreNextScroll = true - this.ignoreNextCursorUpdate = true this.shareJsDoc = scope.editor.sharejs_doc this.isTexFile = isValidTeXFile(scope.editor.open_doc_name) this.updateOutline() diff --git a/services/web/frontend/js/ide/outline/components/OutlineItem.js b/services/web/frontend/js/ide/outline/components/OutlineItem.js index 42a8f8b2d6..48548bb70d 100644 --- a/services/web/frontend/js/ide/outline/components/OutlineItem.js +++ b/services/web/frontend/js/ide/outline/components/OutlineItem.js @@ -3,6 +3,14 @@ import PropTypes from 'prop-types' import classNames from 'classnames' import OutlineList from './OutlineList' +function getChildrenLines(children) { + return (children || []) + .map(child => { + return getChildrenLines(child.children).concat(child.line) + }) + .flat() +} + function OutlineItem({ outlineItem, jumpToLine, highlightedLine }) { const [expanded, setExpanded] = useState(true) const titleElementRef = createRef() @@ -17,8 +25,13 @@ function OutlineItem({ outlineItem, jumpToLine, highlightedLine }) { 'fa-angle-right': !expanded }) + const hasHighlightedChild = + !expanded && + getChildrenLines(outlineItem.children).includes(highlightedLine) + const itemLinkClasses = classNames('outline-item-link', { - 'outline-item-link-highlight': highlightedLine === outlineItem.line + 'outline-item-link-highlight': + highlightedLine === outlineItem.line || hasHighlightedChild }) function handleExpandCollapseClick() { diff --git a/services/web/frontend/js/ide/outline/components/OutlinePane.js b/services/web/frontend/js/ide/outline/components/OutlinePane.js index b29ac7263f..e4750ab1e2 100644 --- a/services/web/frontend/js/ide/outline/components/OutlinePane.js +++ b/services/web/frontend/js/ide/outline/components/OutlinePane.js @@ -55,19 +55,19 @@ function OutlinePane({ >