diff --git a/services/web/app/coffee/infrastructure/ExpressLocals.coffee b/services/web/app/coffee/infrastructure/ExpressLocals.coffee index 2fdf219962..b126819f56 100644 --- a/services/web/app/coffee/infrastructure/ExpressLocals.coffee +++ b/services/web/app/coffee/infrastructure/ExpressLocals.coffee @@ -292,3 +292,14 @@ module.exports = (app, webRouter, privateApiRouter, publicApiRouter)-> res.locals.moduleIncludes = Modules.moduleIncludes res.locals.moduleIncludesAvailable = Modules.moduleIncludesAvailable next() + + webRouter.use (req, res, next) -> + isOl = (Settings.brandPrefix == 'ol-') + res.locals.uiConfig = + defaultResizerSizeOpen : if isOl then 2 else 24 + defaultResizerSizeClosed : if isOl then 2 else 24 + eastResizerCursor : if isOl then "ew-resize" else null + westResizerCursor : if isOl then "ew-resize" else null + chatResizerSizeOpen : if isOl then 2 else 12 + chatResizerSizeClosed : 0 + next() diff --git a/services/web/app/views/project/editor.pug b/services/web/app/views/project/editor.pug index 625bea883d..ec1d129714 100644 --- a/services/web/app/views/project/editor.pug +++ b/services/web/app/views/project/editor.pug @@ -43,8 +43,8 @@ block content #chat-wrapper.full-size( layout="chat", - spacing-open="12", - spacing-closed="0", + spacing-open="{{ui.chatResizerSizeOpen}}", + spacing-closed="{{ui.chatResizerSizeClosed}}", initial-size-east="250", init-closed-east="true", open-east="ui.chatOpen", @@ -158,6 +158,7 @@ block requirejs window.aceFingerprint = "#{fingerprint(jsPath + lib('ace') + '/ace.js')}" window.aceWorkerPath = "#{aceWorkerPath}"; window.pdfCMapsPath = "#{pdfCMapsPath}" + window.uiConfig = JSON.parse('!{JSON.stringify(uiConfig).replace(/\//g, "\\/")}'); script( data-main=buildJsPath("ide.js", {fingerprint:false}), diff --git a/services/web/app/views/project/editor/editor.pug b/services/web/app/views/project/editor/editor.pug index d1c6fa8156..ad06b6b6ba 100644 --- a/services/web/app/views/project/editor/editor.pug +++ b/services/web/app/views/project/editor/editor.pug @@ -73,21 +73,20 @@ div.full-size( ng-show="!!pdf.url && settings.pdfViewer == 'pdfjs'" ng-controller="PdfSynctexController" ) - a.btn.btn-default.btn-xs( + a.synctex-control.synctex-control-goto-pdf( tooltip=translate('go_to_code_location_in_pdf') tooltip-placement="right" tooltip-append-to-body="true" ng-click="syncToPdf()" ) - i.fa.fa-long-arrow-right - br - a.btn.btn-default.btn-xs( + i.synctex-control-icon + a.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()" ) - i.fa.fa-long-arrow-left + i.synctex-control-icon div.full-size( ng-if="ui.pdfLayout == 'flat'" diff --git a/services/web/public/coffee/ide.coffee b/services/web/public/coffee/ide.coffee index e31985ec8a..dbf6a2724e 100644 --- a/services/web/public/coffee/ide.coffee +++ b/services/web/public/coffee/ide.coffee @@ -77,6 +77,8 @@ define [ pdfWidth: 0 reviewPanelOpen: localStorage("ui.reviewPanelOpen.#{window.project_id}") miniReviewPanelVisible: false + chatResizerSizeOpen: window.uiConfig.chatResizerSizeOpen + chatResizerSizeClosed: window.uiConfig.chatResizerSizeClosed } $scope.onboarding = { autoCompile: if window.showAutoCompileOnboarding then 'unseen' else 'dismissed' diff --git a/services/web/public/coffee/ide/directives/layout.coffee b/services/web/public/coffee/ide/directives/layout.coffee index 21d9230b52..fcc75b29a1 100644 --- a/services/web/public/coffee/ide/directives/layout.coffee +++ b/services/web/public/coffee/ide/directives/layout.coffee @@ -11,12 +11,12 @@ define [ if attrs.spacingOpen? spacingOpen = parseInt(attrs.spacingOpen, 10) else - spacingOpen = 24 + spacingOpen = window.uiConfig.defaultResizerSizeOpen if attrs.spacingClosed? spacingClosed = parseInt(attrs.spacingClosed, 10) else - spacingClosed = 24 + spacingClosed = window.uiConfig.defaultResizerSizeClosed options = spacing_open: spacingOpen @@ -44,6 +44,12 @@ define [ if !attrs.minimumRestoreSizeWest? or (state.west.size >= attrs.minimumRestoreSizeWest and !state.west.initClosed) options.west = state.west + if window.uiConfig.eastResizerCursor? + options.east.resizerCursor = window.uiConfig.eastResizerCursor + + if window.uiConfig.westResizerCursor? + options.west.resizerCursor = window.uiConfig.westResizerCursor + repositionControls = () -> state = element.layout().readState() if state.east? @@ -53,9 +59,7 @@ define [ else controls.show() controls.css({ - position: "absolute" right: state.east.size - "z-index": 3 }) resetOpenStates = () -> @@ -112,7 +116,7 @@ define [ # Set the panel as overflowing (gives it higher z-index and sets overflow rules) layoutObj.allowOverflow overflowPane # Read the given z-index value and increment it, so that it's higher than synctex controls. - overflowPaneZVal = overflowPaneEl.css "z-index" + overflowPaneZVal = overflowPaneEl.zIndex() overflowPaneEl.css "z-index", overflowPaneZVal + 1 resetOpenStates() diff --git a/services/web/public/stylesheets/app/editor.less b/services/web/public/stylesheets/app/editor.less index e37d829710..9224dbe181 100644 --- a/services/web/public/stylesheets/app/editor.less +++ b/services/web/public/stylesheets/app/editor.less @@ -14,6 +14,9 @@ @import "./editor/review-panel.less"; @import "./editor/feature-onboarding.less"; +@ui-layout-toggler-def-height: 50px; +@ui-resizer-extra-hit-area: 8px; + @keyframes blink { 0% { opacity: 0.2; @@ -261,9 +264,9 @@ } } -.ui-layout-resizer { +.ui-layout-resizer when (@is-overleaf = false) { width: 6px; - background-color: #f4f4f4; + background-color: @editor-resizer-bg-color; border-left: 1px solid @editor-border-color; border-right: 1px solid @editor-border-color; .ui-layout-toggler { @@ -276,28 +279,117 @@ -moz-osx-font-smoothing: grayscale; font-size: 16px !important; line-height: 50px; + background-color: @editor-toggler-bg-color; &:hover { - background-color: #ddd; + background-color: @editor-toggler-hover-bg-color; color: #333; } } } -.ui-layout-resizer-west.ui-layout-resizer-open, .ui-layout-resizer-east.ui-layout-resizer-closed { + +.ui-layout-resizer when (@is-overleaf = true) { + margin-left: -(@ui-resizer-extra-hit-area) !important; + margin-right: -(@ui-resizer-extra-hit-area - 1px) !important; + padding-left: @ui-resizer-extra-hit-area !important; + padding-right: @ui-resizer-extra-hit-area !important; + z-index: 5 !important; + box-sizing: content-box; + background-image: linear-gradient(90deg, + transparent, + transparent (@ui-resizer-extra-hit-area - 1px), + @editor-resizer-bg-color (@ui-resizer-extra-hit-area - 1px), + @editor-resizer-bg-color (@ui-resizer-extra-hit-area + 1px), + transparent (@ui-resizer-extra-hit-area + 1px), + transparent); + .ui-layout-toggler { + padding: 0 @ui-resizer-extra-hit-area !important; + background-image: linear-gradient(90deg, + transparent, + transparent (@ui-resizer-extra-hit-area - 1px), + @editor-toggler-bg-color (@ui-resizer-extra-hit-area - 1px), + @editor-toggler-bg-color (@ui-resizer-extra-hit-area + 1px), + transparent (@ui-resizer-extra-hit-area + 1px), + transparent); + + &:hover { + background-image: linear-gradient(90deg, + transparent, + transparent (@ui-resizer-extra-hit-area - 2px), + @editor-toggler-hover-bg-color (@ui-resizer-extra-hit-area - 2px), + @editor-toggler-hover-bg-color (@ui-resizer-extra-hit-area + 2px), + transparent (@ui-resizer-extra-hit-area + 2px), + transparent); + } + } +} + +.ui-layout-resizer-west.ui-layout-resizer-open, .ui-layout-resizer-east.ui-layout-resizer-closed { + .ui-layout-toggler when (@is-overleaf = false) { &:before { content: "\f104" } } } .ui-layout-resizer-east.ui-layout-resizer-open, .ui-layout-resizer-west.ui-layout-resizer-closed { - .ui-layout-toggler { + .ui-layout-toggler when (@is-overleaf = false) { &:before { content: "\f105" } } } + +.ui-layout-toggler.ui-layout-toggler-closed when (@is-overleaf = true) { + background-color: @editor-resizer-bg-color; + background-image: none; + line-height: @ui-layout-toggler-def-height; + + &::before { + content: "\22EE"; // Vertical ellipsis + display: block; + color: #FFF; + font-weight: 700; + font-size: @font-size-h2; + width: @ui-resizer-extra-hit-area / 2; + } + &:hover { + background-color: @editor-toggler-hover-bg-color; + background-image: none; + } + .ui-layout-resizer-west > & { + border-radius: 0 @border-radius-base @border-radius-base 0; + &::before { + margin-left: -2px; + } + } + .ui-layout-resizer-east > & { + border-radius: @border-radius-base 0 0 @border-radius-base; + &::before { + margin-left: (-1 - @ui-resizer-extra-hit-area); + } + } +} + +.ui-layout-toggler-east when (@is-overleaf = true) { + &.ui-layout-toggler-open { + cursor: e-resize !important + } + &.ui-layout-toggler-closed { + cursor: w-resize !important + } +} + +.ui-layout-toggler-west when (@is-overleaf = true) { + &.ui-layout-toggler-open { + cursor: w-resize !important + } + &.ui-layout-toggler-closed { + cursor: e-resize !important + } +} + .ui-layout-resizer-dragging { - background-color: #ddd; + background-color: @editor-resizer-bg-color-dragging; } .context-menu { diff --git a/services/web/public/stylesheets/app/editor/pdf.less b/services/web/public/stylesheets/app/editor/pdf.less index a873cd5e8f..b8ddfc5efd 100644 --- a/services/web/public/stylesheets/app/editor/pdf.less +++ b/services/web/public/stylesheets/app/editor/pdf.less @@ -229,14 +229,72 @@ } .synctex-controls { + position: absolute; + z-index: @synctex-controls-z-index; + padding: @synctex-controls-padding; top: 68px; - padding: 0px 2px; - .btn-xs { - line-height: 1.3; - padding: 0 2px 0; - } } +.synctex-controls when (@is-overleaf = true) { + margin-right: -11px; +} + .synctex-control { + .btn; + .btn-default; + .btn-xs; + display: block; + margin-bottom: 3px; + + > .synctex-control-icon { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + } + + .synctex-control when (@is-overleaf = true) { + @ol-synctex-control-size: 24px; + display: flex; + align-items: center; + justify-content: center; + font-size: 1em; + width: @ol-synctex-control-size; + height: @ol-synctex-control-size; + border-radius: @ol-synctex-control-size / 2; + padding: 0 0 2px; + background-color: fade(@btn-default-bg, 80%); + transition: background 0.15s ease; + margin-bottom: @ol-synctex-control-size / 2; + } + + .synctex-control when (@is-overleaf = false) { + line-height: 1.3; + padding: 0 2px; + } + + .synctex-control-goto-pdf > .synctex-control-icon when (@is-overleaf = true) { + text-indent: 1px; // "Optical" adjustment. + &::before { + content: "\f061"; + } + } + .synctex-control-goto-code > .synctex-control-icon when (@is-overleaf = true) { + text-indent: -1px; // "Optical" adjustment. + &::before { + content: "\f060"; + } + } + + .synctex-control-goto-pdf > .synctex-control-icon::before when (@is-overleaf = false) { + content: "\f178"; + } + .synctex-control-goto-code > .synctex-control-icon::before when (@is-overleaf = false) { + content: "\f177"; + } + .editor-dark { .pdf-logs { background-color: lighten(@editor-dark-background-color, 10%); diff --git a/services/web/public/stylesheets/core/_common-variables.less b/services/web/public/stylesheets/core/_common-variables.less index acf6bcc91f..ab3ef2ccc9 100644 --- a/services/web/public/stylesheets/core/_common-variables.less +++ b/services/web/public/stylesheets/core/_common-variables.less @@ -889,34 +889,42 @@ @footer-padding : 2em; // Editor header -@toolbar-header-bg-color : transparent; -@toolbar-header-shadow : 0 0 2px #ccc; -@toolbar-btn-color : @link-color; -@toolbar-btn-hover-color : @link-hover-color; -@toolbar-btn-hover-bg-color : darken(white, 10%); -@toolbar-btn-hover-text-shadow : 0 1px 0 rgba(0, 0, 0, 0.15); -@toolbar-btn-active-color : white; -@toolbar-btn-active-bg-color : @link-color; -@toolbar-btn-active-shadow : inset 0 3px 5px rgba(0, 0, 0, 0.225); -@toolbar-alt-bg-color : #fafafa; -@toolbar-icon-btn-color : @gray-light; -@toolbar-icon-btn-hover-color : @gray-dark; -@toolbar-icon-btn-hover-shadow : 0 1px 0 rgba(0, 0, 0, 0.25); +@toolbar-header-bg-color : transparent; +@toolbar-header-shadow : 0 0 2px #ccc; +@toolbar-btn-color : @link-color; +@toolbar-btn-hover-color : @link-hover-color; +@toolbar-btn-hover-bg-color : darken(white, 10%); +@toolbar-btn-hover-text-shadow : 0 1px 0 rgba(0, 0, 0, 0.15); +@toolbar-btn-active-color : white; +@toolbar-btn-active-bg-color : @link-color; +@toolbar-btn-active-shadow : inset 0 3px 5px rgba(0, 0, 0, 0.225); +@toolbar-alt-bg-color : #fafafa; +@toolbar-icon-btn-color : @gray-light; +@toolbar-icon-btn-hover-color : @gray-dark; +@toolbar-icon-btn-hover-shadow : 0 1px 0 rgba(0, 0, 0, 0.25); @toolbar-icon-btn-hover-boxshadow : inset 0 3px 5px rgba(0, 0, 0, 0.225); -@toolbar-border-bottom : 1px solid @toolbar-border-color; +@toolbar-border-bottom : 1px solid @toolbar-border-color; // Editor file-tree -@file-tree-bg : transparent; -@file-tree-line-height : 2.6; -@file-tree-item-color : @gray-darker; -@file-tree-item-toggle-color : @gray; -@file-tree-item-icon-color : @gray-light; -@file-tree-item-input-color : inherit; -@file-tree-item-folder-color : lighten(desaturate(@link-color, 10%), 5%); -@file-tree-item-hover-bg : @gray-lightest; -@file-tree-item-selected-bg : transparent; -@file-tree-multiselect-bg : lighten(@brand-info, 40%); -@file-tree-multiselect-hover-bg : lighten(@brand-info, 30%); +@file-tree-bg : transparent; +@file-tree-line-height : 2.6; +@file-tree-item-color : @gray-darker; +@file-tree-item-toggle-color : @gray; +@file-tree-item-icon-color : @gray-light; +@file-tree-item-input-color : inherit; +@file-tree-item-folder-color : lighten(desaturate(@link-color, 10%), 5%); +@file-tree-item-hover-bg : @gray-lightest; +@file-tree-item-selected-bg : transparent; +@file-tree-multiselect-bg : lighten(@brand-info, 40%); +@file-tree-multiselect-hover-bg : lighten(@brand-info, 30%); + +// Editor resizers +@editor-resizer-bg-color : #F4F4F4; +@editor-resizer-bg-color-dragging : #ddd; +@editor-toggler-bg-color : transparent; +@editor-toggler-hover-bg-color : #DDD; +@synctex-controls-z-index : 3; +@synctex-controls-padding : 0 2px; // Tags @tag-border-radius : 0.25em; @tag-bg-color : @label-default-bg; diff --git a/services/web/public/stylesheets/core/ol-variables.less b/services/web/public/stylesheets/core/ol-variables.less index 5c15ad2d3d..004bc343d8 100644 --- a/services/web/public/stylesheets/core/ol-variables.less +++ b/services/web/public/stylesheets/core/ol-variables.less @@ -171,23 +171,28 @@ @toolbar-icon-btn-color : #FFF; @toolbar-icon-btn-hover-color : #FFF; @toolbar-icon-btn-hover-shadow : none; -@toolbar-icon-btn-hover-boxshadow : none; @toolbar-border-bottom : 1px solid @toolbar-border-color; +@toolbar-icon-btn-hover-boxshadow : none; // Editor file-tree -@file-tree-bg : @ol-blue-gray-4; -@file-tree-line-height : 2.05; -@file-tree-item-color : #FFF; -@file-tree-item-input-color : @ol-blue-gray-5; -@file-tree-item-toggle-color : @ol-blue-gray-2; -@file-tree-item-icon-color : @ol-blue-gray-2; -@file-tree-item-folder-color : @ol-blue-gray-2; -@file-tree-item-hover-bg : @ol-blue-gray-5; -@file-tree-item-selected-bg : @ol-green; -@file-tree-multiselect-bg : @ol-blue; -@file-tree-multiselect-hover-bg : @ol-dark-blue; -@file-tree-droppable-bg-color : tint(@ol-green, 5%); -//== Colors -// +@file-tree-bg : @ol-blue-gray-4; +@file-tree-line-height : 2.05; +@file-tree-item-color : #FFF; +@file-tree-item-input-color : @ol-blue-gray-5; +@file-tree-item-toggle-color : @ol-blue-gray-2; +@file-tree-item-icon-color : @ol-blue-gray-2; +@file-tree-item-folder-color : @ol-blue-gray-2; +@file-tree-item-hover-bg : @ol-blue-gray-5; +@file-tree-item-selected-bg : @ol-green; +@file-tree-multiselect-bg : @ol-blue; +@file-tree-multiselect-hover-bg : @ol-dark-blue; +@file-tree-droppable-bg-color : tint(@ol-green, 5%); +// Editor resizers +@editor-resizer-bg-color : @ol-blue-gray-6; +@editor-resizer-bg-color-dragging : transparent; +@editor-toggler-bg-color : @ol-blue-gray-2; +@editor-toggler-hover-bg-color : @ol-green; +@synctex-controls-z-index : 6; +@synctex-controls-padding : 0; //## Gray and brand colors for use across Bootstrap. @gray-darker: #252525; @gray-dark: #505050;