mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Merge pull request #358 from sharelatex/pr-latex-linter-onboarding
Code-checker onboarding
This commit is contained in:
commit
74d8fb103b
14 changed files with 191 additions and 19 deletions
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
span.feat-onboard-title-name Code check
|
||||
div(ng-if="innerStep === 1;")
|
||||
p.feat-onboard-description
|
||||
span.feat-onboard-description-name Code check
|
||||
| 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
|
||||
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
|
||||
span.feat-onboard-adv-title-highlight environments
|
||||
p
|
||||
| Know when you are missing an
|
||||
code \end{...}
|
||||
| command.
|
||||
.col-xs-4
|
||||
h2.feat-onboard-adv-title
|
||||
| Incorrect
|
||||
span.feat-onboard-adv-title-highlight nesting
|
||||
p
|
||||
| Order matters. Get notified when you use an
|
||||
code \end{...}
|
||||
| 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
|
||||
span.feat-onboard-description-name Code check
|
||||
em on
|
||||
| or
|
||||
em off
|
||||
|, in the settings menu.
|
||||
.feat-onboard-btn-wrapper
|
||||
button.btn.btn-primary(ng-click="dismiss();") OK, got it
|
|
@ -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")}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
Normal file
BIN
services/web/public/img/teasers/code-checker/code-checker.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 111 KiB |
BIN
services/web/public/img/teasers/code-checker/code-checker.mp4
Normal file
BIN
services/web/public/img/teasers/code-checker/code-checker.mp4
Normal file
Binary file not shown.
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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: ->
|
||||
|
|
Loading…
Reference in a new issue