Przeglądaj źródła

Merge pull request #358 from sharelatex/pr-latex-linter-onboarding

Code-checker onboarding
Paulo Jorge Reis 10 lat temu
rodzic
commit
74d8fb103b

+ 1 - 0
services/web/app/coffee/Features/User/UserCreator.coffee

@@ -17,6 +17,7 @@ module.exports =
 		user = new User()
 		user.email = opts.email
 		user.holdingAccount = opts.holdingAccount
+		user.ace.syntaxValidation = true
 
 		username = opts.email.match(/^[^@]*/)
 		if opts.first_name? and opts.first_name.length != 0

+ 1 - 1
services/web/app/coffee/models/User.coffee

@@ -26,7 +26,7 @@ UserSchema = new Schema
 							autoComplete:   {type : Boolean, default: true}
 							spellCheckLanguage :   {type : String, default: "en"}
 							pdfViewer   :   {type : String, default: "pdfjs"}
-							syntaxValidation   :   {type : Boolean, default: true}
+							syntaxValidation   :   {type : Boolean}
 						}
 	features		  : {
 							collaborators: { type:Number,  default: Settings.defaultFeatures.collaborators }

+ 4 - 6
services/web/app/views/project/editor.jade

@@ -15,7 +15,8 @@ block content
 				p.text-center.text-danger(ng-if="state.error").ng-cloak 
 					span(ng-bind-html="state.error")
 
-
+		include ./editor/feature-onboarding
+		
 		.global-alerts(ng-cloak)
 			.alert.alert-danger.small(ng-if="connection.forced_disconnect")
 				strong #{translate("disconnected")}
@@ -88,7 +89,8 @@ block content
 block requirejs
 	script(type="text/javascript" src='/socket.io/socket.io.js')
 
-	//- don't use cdn for worker
+	//- don't use cdn for workers
+	- var aceWorkerPath = buildJsPath(lib('ace'), {cdn:false,fingerprint:false})
 	- var pdfWorkerPath = buildJsPath('/libs/' + lib('pdfjs') + '/pdf.worker', {cdn:false,fingerprint:false})
 
 	//- We need to do .replace(/\//g, '\\/') do that '</script>' -> '<\/script>'
@@ -132,10 +134,6 @@ block requirejs
 			}
 		};
 		window.aceFingerprint = "#{fingerprint(jsPath + lib('ace') + '/ace.js')}"
-
-	- var aceWorkerPath = user.betaProgram ? buildJsPath(lib('ace'), {cdn:false,fingerprint:false}) : "" // don't use cdn for worker
-
-	script(type='text/javascript').
 		window.aceWorkerPath = "#{aceWorkerPath}";
 
 	script(

+ 54 - 0
services/web/app/views/project/editor/feature-onboarding.jade

@@ -0,0 +1,54 @@
+.feat-onboard(
+	ng-controller="FeatureOnboardingController"
+	ng-class="('feat-onboard-step' + innerStep)"
+	ng-if="!state.loading && ui.showCodeCheckerOnboarding"
+	ng-cloak
+)
+	.feat-onboard-wrapper
+		h1.feat-onboard-title
+			| Introducing&nbsp;
+			span.feat-onboard-title-name Code check
+		div(ng-if="innerStep === 1;")
+			p.feat-onboard-description
+				span.feat-onboard-description-name Code check&nbsp;
+				| will highlight potential problems in your LaTeX code, allowing you to handle errors earlier and become more productive.
+			.row
+				video.feat-onboard-video(autoplay, loop)
+					source(src="/img/teasers/code-checker/code-checker.mp4", type="video/mp4")
+					img(src="/img/teasers/code-checker/code-checker.gif")
+			.row.feat-onboard-adv-wrapper
+				.col-xs-4
+					h2.feat-onboard-adv-title 
+						| Missing&nbsp;
+						span.feat-onboard-adv-title-highlight brackets
+					p Forgot to place a closing bracket? We'll warn you.
+				.col-xs-4
+					h2.feat-onboard-adv-title 
+						| Unclosed&nbsp;
+						span.feat-onboard-adv-title-highlight environments
+					p 
+						| Know when you are missing an&nbsp;
+						code \end{...}
+						| &nbsp;command.
+				.col-xs-4
+					h2.feat-onboard-adv-title 
+						| Incorrect&nbsp;
+						span.feat-onboard-adv-title-highlight nesting
+					p 
+						| Order matters. Get notified when you use an&nbsp;
+						code \end{...}
+						| &nbsp; too soon.
+			.feat-onboard-btn-wrapper
+				button.btn.btn-primary(ng-click="turnCodeCheckOn();") Yes, turn Code check on
+			.feat-onboard-btn-wrapper
+				button.btn.btn-default(ng-click="turnCodeCheckOff();") No, disable it for now
+		div(ng-if="innerStep === 2;")
+			p.feat-onboard-description
+				| Remember: you can always turn&nbsp;
+				span.feat-onboard-description-name Code check&nbsp;
+				em on&nbsp;
+				| or&nbsp;
+				em off&nbsp;
+				|, in the settings menu.
+			.feat-onboard-btn-wrapper
+				button.btn.btn-primary(ng-click="dismiss();") OK, got it

+ 7 - 8
services/web/app/views/project/editor/left-menu.jade

@@ -105,14 +105,13 @@ aside#left-menu.full-size(
 					ng-options="o.v as o.n for o in [{ n: 'On', v: true }, { n: 'Off', v: false }]"
 				)
 
-			if (user.betaProgram)
-				.form-controls
-					label(for="syntaxValidation") #{translate("syntax_validation")}
-					select(
-						name="syntaxValidation"
-						ng-model="settings.syntaxValidation"
-						ng-options="o.v as o.n for o in [{ n: 'On', v: true }, { n: 'Off', v: false }]"
-					)
+			.form-controls.code-check-setting
+				label(for="syntaxValidation") #{translate("syntax_validation")}
+				select(
+					name="syntaxValidation"
+					ng-model="settings.syntaxValidation"
+					ng-options="o.v as o.n for o in [{ n: 'On', v: true }, { n: 'Off', v: false }]"
+				)
 
 			.form-controls
 				label(for="theme") #{translate("theme")}

+ 2 - 0
services/web/public/coffee/ide.coffee

@@ -10,6 +10,7 @@ define [
 	"ide/binary-files/BinaryFilesManager"
 	"ide/references/ReferencesManager"
 	"ide/SafariScrollPatcher"
+	"ide/FeatureOnboardingController"
 	"ide/settings/index"
 	"ide/share/index"
 	"ide/chat/index"
@@ -64,6 +65,7 @@ define [
 			view: "editor"
 			chatOpen: false
 			pdfLayout: 'sideBySide'
+			showCodeCheckerOnboarding: !window.userSettings.syntaxValidation?
 		}
 		$scope.user = window.user
 

+ 35 - 0
services/web/public/coffee/ide/FeatureOnboardingController.coffee

@@ -0,0 +1,35 @@
+define [
+	"base"
+], (App) ->
+	App.controller "FeatureOnboardingController", ($scope, settings) ->
+		$scope.innerStep = 1
+
+		$scope.turnCodeCheckOn = () ->
+			settings.saveSettings({ syntaxValidation: true })
+			$scope.settings.syntaxValidation = true
+			navToInnerStep2()
+			
+		$scope.turnCodeCheckOff = () ->
+			settings.saveSettings({ syntaxValidation: false })
+			$scope.settings.syntaxValidation = false
+			navToInnerStep2()
+
+		$scope.dismiss = () ->
+			$scope.ui.leftMenuShown = false
+			$scope.ui.showCodeCheckerOnboarding = false
+
+		navToInnerStep2 = () ->
+			$scope.innerStep = 2
+			$scope.ui.leftMenuShown = true
+
+		handleKeypress = (e) ->
+			if e.keyCode == 13
+				if $scope.innerStep == 1
+					$scope.turnCodeCheckOn()
+				else
+					$scope.dismiss()
+
+		$(document).on "keypress", handleKeypress
+
+		$scope.$on "$destroy", () -> 
+			$(document).off "keypress", handleKeypress

BIN
services/web/public/img/teasers/code-checker/code-checker.gif


BIN
services/web/public/img/teasers/code-checker/code-checker.mp4


+ 1 - 0
services/web/public/stylesheets/app/editor.less

@@ -11,6 +11,7 @@
 @import "./editor/publish-template.less";
 @import "./editor/online-users.less";
 @import "./editor/hotkeys.less";
+@import "./editor/feature-onboarding.less";
 
 .full-size {
 	position: absolute;

+ 79 - 0
services/web/public/stylesheets/app/editor/feature-onboarding.less

@@ -0,0 +1,79 @@
+@feat-onboard-wrapper-width: 820px;
+@feat-onboard-max-text-width: 750px;
+
+.feat-onboard {
+	position: fixed;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	left: 0;
+	display: flex;
+ 	justify-content: center;
+ 	align-items: center;
+	background-image: linear-gradient(rgba(0, 0, 0, .85), rgba(0, 0, 0, .85));
+	background-repeat: no-repeat;
+	background-position-x: 0;
+	color: #FFF;
+	text-align: center;
+	z-index: 102;
+	transition: background-position ease-in-out @left-menu-animation-duration;
+	overflow: auto;
+}
+
+.feat-onboard-step2 {
+	background-position-x: @left-menu-width;
+
+	~ #left-menu {
+		pointer-events: none;
+
+		.code-check-setting {
+			box-shadow: 0 0 300px #000;
+		}
+	}
+}
+	.feat-onboard-wrapper {
+		width: @feat-onboard-wrapper-width;
+		text-shadow: 0 0 70px rgba(255, 255, 255, 0.5);
+	}
+		.feat-onboard-title {
+			color: @brand-primary;
+			margin-bottom: 40px;
+
+		}
+			.feat-onboard-title-name {
+				color: #FFF;
+				font-weight: bold;
+			}
+
+		.feat-onboard-description {
+			max-width: @feat-onboard-max-text-width;
+			margin: 0 auto 30px;
+			padding: 0 80px;
+		}
+			.feat-onboard-description-name {
+				font-weight: bold;
+			}
+
+	.feat-onboard-video {
+		box-shadow: 0 0 70px rgba(255, 255, 255, 0.3);
+	}
+
+	.feat-onboard-adv-wrapper {
+		text-align: left;
+		margin-bottom: 30px;
+	}
+		.feat-onboard-adv-title {
+			color: #FFF;
+			font-size: 23px;
+		}
+			.feat-onboard-adv-title-highlight {
+				font-weight: bold;
+			}
+
+	.feat-onboard-btn-wrapper {
+		margin-bottom: 10px;
+
+		> .btn {
+			box-shadow: 0 0 70px rgba(255, 255, 255, 0.3);
+		}
+	}

+ 3 - 3
services/web/public/stylesheets/app/editor/left-menu.less

@@ -1,6 +1,6 @@
 #left-menu {
 	position: absolute;
-	width: 260px;
+	width: @left-menu-width;
 	padding: (@line-height-computed / 2);
 	top: 0;
 	bottom: 0;
@@ -8,8 +8,8 @@
 	z-index: 100;
 	overflow-y: auto;
 	overflow-x: hidden;
-	-webkit-transition: left ease-in-out 0.35s;
-	transition: left ease-in-out 0.35s;
+	-webkit-transition: left ease-in-out @left-menu-animation-duration;
+	transition: left ease-in-out @left-menu-animation-duration;
 	font-size: 14px;
 
 	left: -280px;

+ 3 - 0
services/web/public/stylesheets/core/variables.less

@@ -820,6 +820,9 @@
 
 // Custom
 
+@left-menu-width: 260px;
+@left-menu-animation-duration: 0.35s;
+
 @toolbar-border-color: @gray-lighter;
 @file-tree-droppable-background-color: rgb(252, 231, 199);
 

+ 1 - 1
services/web/test/UnitTests/coffee/User/UserCreatorTests.coffee

@@ -9,7 +9,7 @@ describe "UserCreator", ->
 
 	beforeEach ->
 		self = @
-		@user = {_id:"12390i"}
+		@user = {_id:"12390i", ace: {}}
 		@user.save = sinon.stub().callsArgWith(0)
 		@UserModel = class Project
 			constructor: ->