diff --git a/services/web/Jenkinsfile b/services/web/Jenkinsfile index 93f0a31008..6421174e68 100644 --- a/services/web/Jenkinsfile +++ b/services/web/Jenkinsfile @@ -74,6 +74,8 @@ pipeline { } steps { sh 'node_modules/.bin/grunt compile --verbose' + // replace the build number placeholder for sentry + sh 'node_modules/.bin/grunt version' } } diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index 84fa89ea37..17adeae4c1 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -248,6 +248,24 @@ module.exports = ProjectController = return cb(null, false) else return cb(null, true) + showAutoCompileOnboarding: (cb) -> + cb = underscore.once(cb) + if !user_id? + return cb() + timestamp = user_id.toString().substring(0,8) + userSignupDate = new Date( parseInt( timestamp, 16 ) * 1000 ) + if userSignupDate > new Date("2017-10-03") + # Don't show for users who registered after it was released + return cb(null, false) + timeout = setTimeout cb, 500 + AnalyticsManager.getLastOccurance user_id, "shown-autocompile-onboarding", (error, event) -> + clearTimeout timeout + if error? + return cb(null, false) + else if event? + return cb(null, false) + else + return cb(null, true) }, (err, results)-> if err? logger.err err:err, "error getting details for project page" @@ -255,9 +273,9 @@ module.exports = ProjectController = project = results.project user = results.user subscription = results.subscription - { showTrackChangesOnboarding, showPerUserTCNotice } = results + { showTrackChangesOnboarding, showPerUserTCNotice, showAutoCompileOnboarding } = results - daysSinceLastUpdated = (new Date() - project.lastUpdated) /86400000 + daysSinceLastUpdated = (new Date() - project.lastUpdated) / 86400000 logger.log project_id:project_id, daysSinceLastUpdated:daysSinceLastUpdated, "got db results for loading editor" AuthorizationManager.getPrivilegeLevelForProject user_id, project_id, (error, privilegeLevel)-> @@ -300,6 +318,7 @@ module.exports = ProjectController = trackChangesState: project.track_changes showTrackChangesOnboarding: !!showTrackChangesOnboarding showPerUserTCNotice: !!showPerUserTCNotice + showAutoCompileOnboarding: !!showAutoCompileOnboarding privilegeLevel: privilegeLevel chatUrl: Settings.apis.chat.url anonymous: anonymous diff --git a/services/web/app/views/project/editor.pug b/services/web/app/views/project/editor.pug index fb92510917..1065941815 100644 --- a/services/web/app/views/project/editor.pug +++ b/services/web/app/views/project/editor.pug @@ -122,6 +122,7 @@ block requirejs window.trackChangesState = data.trackChangesState; window.showTrackChangesOnboarding = #{!!showTrackChangesOnboarding}; window.showPerUserTCNotice = #{!!showPerUserTCNotice}; + window.showAutoCompileOnboarding = #{!!showAutoCompileOnboarding} window.wikiEnabled = #{!!(settings.apis.wiki && settings.apis.wiki.url)}; window.requirejs = { "paths" : { diff --git a/services/web/app/views/project/editor/editor.pug b/services/web/app/views/project/editor/editor.pug index 6007f2e0be..89ec5c7828 100644 --- a/services/web/app/views/project/editor/editor.pug +++ b/services/web/app/views/project/editor/editor.pug @@ -94,4 +94,19 @@ div.full-size( ng-show="ui.view == 'pdf'" ) include ./pdf - + +#onboarding-autocompile.onboarding-autocompile.popover( + ng-controller="AutoCompileOnboardingController" + ng-if="onboarding.autoCompile == 'show'" + ng-class="placement" +) + .popover-inner + h3.popover-title + | #{translate("auto_compile")} + span.beta-feature-badge + .popover-content + p #{translate("try_out_auto_compile_setting")} + img(src="/img/onboarding/autocompile/setting-dropdown.png" width="100%") + p #{translate("auto_compile_onboarding_description")} + button.btn.btn-default.btn-block(ng-click="dismiss()") + | #{translate("got_it")} diff --git a/services/web/app/views/project/editor/pdf.pug b/services/web/app/views/project/editor/pdf.pug index 377f09f71a..69fc28cc54 100644 --- a/services/web/app/views/project/editor/pdf.pug +++ b/services/web/app/views/project/editor/pdf.pug @@ -1,6 +1,6 @@ div.full-size.pdf(ng-controller="PdfController") .toolbar.toolbar-tall - .btn-group( + .btn-group#recompile( dropdown, tooltip-html="'"+translate('recompile_pdf')+" ({{modifierKey}} + Enter)'" tooltip-class="keyboard-tooltip" @@ -28,7 +28,9 @@ div.full-size.pdf(ng-controller="PdfController") ul.dropdown-menu.dropdown-menu-left // Only show on beta program? if user.betaProgram - li.dropdown-header #{translate("auto_compile")} + li.dropdown-header + | #{translate("auto_compile")} + span.beta-feature-badge li a(href, ng-click="autocompile_enabled = true") i.fa.fa-fw(ng-class="{'fa-check': autocompile_enabled}") diff --git a/services/web/public/coffee/ide.coffee b/services/web/public/coffee/ide.coffee index e317b355ef..4aaaecc53b 100644 --- a/services/web/public/coffee/ide.coffee +++ b/services/web/public/coffee/ide.coffee @@ -12,7 +12,8 @@ define [ "ide/labels/LabelsManager" "ide/review-panel/ReviewPanelManager" "ide/SafariScrollPatcher" - "ide/FeatureOnboardingController" + "ide/FeatureOnboardingController", + "ide/AutoCompileOnboardingController", "ide/settings/index" "ide/share/index" "ide/chat/index" @@ -72,8 +73,12 @@ define [ chatOpen: false pdfLayout: 'sideBySide' pdfHidden: false, - reviewPanelOpen: localStorage("ui.reviewPanelOpen.#{window.project_id}") - miniReviewPanelVisible: false + pdfWidth: 0, + reviewPanelOpen: localStorage("ui.reviewPanelOpen.#{window.project_id}"), + miniReviewPanelVisible: false, + } + $scope.onboarding = { + autoCompile: if window.user.betaProgram and window.showAutoCompileOnboarding then 'unseen' else 'dismissed' } $scope.user = window.user @@ -102,6 +107,7 @@ define [ $scope.$on "layout:pdf:resize", (_, layoutState) -> $scope.ui.pdfHidden = layoutState.east.initClosed + $scope.ui.pdfWidth = layoutState.east.size # Tracking code. $scope.$watch "ui.view", (newView, oldView) -> @@ -185,6 +191,20 @@ define [ if ide.browserIsSafari ide.safariScrollPatcher = new SafariScrollPatcher($scope) + # Fix Chrome 61 and 62 text-shadow rendering + browserIsChrome61or62 = false + try + chromeVersion = parseFloat(navigator.userAgent.split(" Chrome/")[1]) || null; + browserIsChrome61or62 = ( + chromeVersion? && + (chromeVersion == 61 || chromeVersion == 62) + ) + if browserIsChrome61or62 + document.styleSheets[0].insertRule(".ace_editor.ace_autocomplete .ace_completion-highlight { text-shadow: none !important; }", 1) + catch err + console.error err + + # User can append ?ft=somefeature to url to activate a feature toggle ide.featureToggle = location?.search?.match(/^\?ft=(\w+)$/)?[1] diff --git a/services/web/public/coffee/ide/AutoCompileOnboardingController.coffee b/services/web/public/coffee/ide/AutoCompileOnboardingController.coffee new file mode 100644 index 0000000000..a57575fb94 --- /dev/null +++ b/services/web/public/coffee/ide/AutoCompileOnboardingController.coffee @@ -0,0 +1,26 @@ +define [ + "base" +], (App) -> + App.controller "AutoCompileOnboardingController", ($scope, event_tracking) -> + recompileBtn = angular.element('#recompile') + popover = angular.element('#onboarding-autocompile') + { top, left } = recompileBtn.offset() + + # If pdf panel smaller than recompile button + popover, show to left. + # Otherwise show to right + if $scope.ui.pdfWidth < 475 + $scope.placement = 'left' + popover.offset({ + top: top, + left: left - popover.width() + }) + else + $scope.placement = 'right' + popover.offset({ + top: top, + left: left + recompileBtn.width() + }) + + $scope.dismiss = () -> + $scope.onboarding.autoCompile = 'dismissed' + event_tracking.sendMB "shown-autocompile-onboarding" diff --git a/services/web/public/coffee/ide/history/controllers/HistoryListController.coffee b/services/web/public/coffee/ide/history/controllers/HistoryListController.coffee index d3ca0c50f2..f6e7c724c3 100644 --- a/services/web/public/coffee/ide/history/controllers/HistoryListController.coffee +++ b/services/web/public/coffee/ide/history/controllers/HistoryListController.coffee @@ -115,7 +115,10 @@ define [ $scope.resetHoverState() $scope.displayName = (user) -> - full_name = "#{user.first_name} #{user.last_name}" + if user.name? + full_name = user.name + else + full_name = "#{user.first_name} #{user.last_name}" fallback_name = "Unknown" if !user? fallback_name diff --git a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee index 73ae9a4380..1e0403bb76 100644 --- a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee +++ b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee @@ -412,6 +412,9 @@ define [ $scope.recompile = (options = {}) -> return if $scope.pdf.compiling + if !options.isAutoCompile and $scope.onboarding.autoCompile == 'unseen' + $scope.onboarding.autoCompile = 'show' + event_tracking.sendMBSampled "editor-recompile-sampled", options $scope.pdf.compiling = true diff --git a/services/web/public/img/onboarding/autocompile/setting-dropdown.png b/services/web/public/img/onboarding/autocompile/setting-dropdown.png new file mode 100644 index 0000000000..cc0da8f7a5 Binary files /dev/null and b/services/web/public/img/onboarding/autocompile/setting-dropdown.png differ diff --git a/services/web/public/stylesheets/app/editor/feature-onboarding.less b/services/web/public/stylesheets/app/editor/feature-onboarding.less index 7289ed4fb7..475658f885 100644 --- a/services/web/public/stylesheets/app/editor/feature-onboarding.less +++ b/services/web/public/stylesheets/app/editor/feature-onboarding.less @@ -98,4 +98,48 @@ a.feat-onboard-dismiss { color: #FFF; opacity: 1; } -} \ No newline at end of file +} + +.onboarding-autocompile { + display: block; + top: 10px; + + img { + margin-bottom: 10px; + border: 1px solid @gray-lighter; + } + + &::before, &::after { + content: ''; + border-width: 11px; + border-style: solid; + border-color: transparent; + top: 7px; + display: block; + position: absolute; + } + + &.right::before { + border-left-width: 0; + border-right-color: rgba(0, 0, 0, .3); + left: -11px; + } + + &.right::after { + border-left-width: 0; + border-right-color: #f7f7f7; + left: -9.5px; + } + + &.left::before { + border-right-width: 0; + border-left-color: rgba(0, 0, 0, .3); + right: -11px + } + + &.left::after { + border-right-width: 0; + border-left-color: #f7f7f7; + right: -9.5px; + } +}