Просмотр исходного кода

Show animated bar while auto-compile is pending

James Allen 8 лет назад
Родитель
Сommit
5bf2ff0a47

+ 13 - 1
services/web/app/views/project/editor/pdf.pug

@@ -1,5 +1,5 @@
 div.full-size.pdf(ng-controller="PdfController")
-	.toolbar.toolbar-pdf
+	.toolbar.toolbar-pdf(ng-class="{ 'uncompiled-changes': uncompiledChanges && !autoCompileLintingError }")
 		.btn-group.btn-recompile-group#recompile(
 			dropdown,
 			tooltip-html="'"+translate('recompile_pdf')+" <span class=\"keyboard-shortcut\">({{modifierKey}} + Enter)</span>'"
@@ -92,6 +92,18 @@ div.full-size.pdf(ng-controller="PdfController")
 			i.fa.fa-download
 			
 		.toolbar-right
+			span.auto-compile-status.small(
+				ng-show="uncompiledChanges && !compiling && !autoCompileLintingError"
+			) #{translate('uncompiled_changes')}
+			span.auto-compile-status.auto-compile-error.small(
+				ng-show="autoCompileLintingError"
+				tooltip-placement="bottom"
+				tooltip=translate("code_check_failed_explanation")
+				tooltip-append-to-body="true"
+			)
+				i.fa.fa-fw.fa-exclamation-triangle
+				|
+				| #{translate("code_check_failed")}
 			a(
 				href,
 				ng-click="switchToFlatLayout()"

+ 5 - 0
services/web/public/coffee/ide/editor/Document.coffee

@@ -340,8 +340,13 @@ define [
 					v: version
 			@doc.on "change", (ops, oldSnapshot, msg) =>
 				@_applyOpsToRanges(ops, oldSnapshot, msg)
+				@ide.$scope.$emit "doc:changed",
+					doc_id: @doc_id
 			@doc.on "flipped_pending_to_inflight", () =>
 				@trigger "flipped_pending_to_inflight"
+			@doc.on "saved", () =>
+				@ide.$scope.$emit "doc:saved",
+					doc_id: @doc_id
 
 		_onError: (error, meta = {}) ->
 			meta.doc_id = @doc_id

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

@@ -46,6 +46,8 @@ define [
 				@trigger "remoteop", args...
 			@_doc.on "flipped_pending_to_inflight", () =>
 				@trigger "flipped_pending_to_inflight"
+			@_doc.on "saved", () =>
+				@trigger "saved"
 			@_doc.on "error", (e) =>
 				@_handleError(e)
 

+ 3 - 0
services/web/public/coffee/ide/editor/sharejs/vendor/client/doc.coffee

@@ -164,6 +164,9 @@ class Doc
       @inflightOp = null
       @inflightSubmittedIds.length = 0
 
+      if @pendingOp == null # All ops are acked
+        @emit 'saved'
+
       error = msg.error
       if error
         # The server has rejected an op from the client for some reason.

+ 31 - 4
services/web/public/coffee/ide/pdf/controllers/PdfController.coffee

@@ -93,6 +93,9 @@ define [
 					$scope.recompile(isAutoCompileOnChange: true) # compile if no linting errors
 				else if !ide.$scope.settings.syntaxValidation
 					$scope.recompile(isAutoCompileOnChange: true) # always recompile
+				else
+					$scope.$apply () ->
+						$scope.autoCompileLintingError = true
 			else
 				# Extend remainder of timeout
 				autoCompileTimeout = setTimeout () ->
@@ -100,13 +103,37 @@ define [
 					triggerAutoCompile()
 				, AUTO_COMPILE_TIMEOUT - timeSinceLastCompile
 
-		autoCompileListener = null
+		$scope.uncompiledChanges = false
+		recalculateUncompiledChanges = () ->
+			if $scope.docLastChanged > $scope.projectLastCompiled
+				$scope.uncompiledChanges = true
+			else
+				$scope.uncompiledChanges = false
+
+		onDocChanged = () ->
+			$scope.autoCompileLintingError = false
+			$scope.docLastChanged = Date.now()
+			recalculateUncompiledChanges()
+
+		onCompilingStateChanged = (compiling) ->
+			if compiling
+				$scope.projectLastCompiled = Date.now()
+				recalculateUncompiledChanges()
+
+		autoCompileListeners = []
 		toggleAutoCompile = (enabling) ->
 			if enabling
-				autoCompileListener = ide.$scope.$on "ide:opAcknowledged", _.debounce(triggerAutoCompile, OP_ACKNOWLEDGEMENT_TIMEOUT)
+				autoCompileListeners = [
+					ide.$scope.$on "doc:changed", onDocChanged
+					ide.$scope.$on "doc:saved", onDocChanged
+					$scope.$watch "pdf.compiling", onCompilingStateChanged
+					ide.$scope.$on "ide:opAcknowledged", _.debounce(triggerAutoCompile, OP_ACKNOWLEDGEMENT_TIMEOUT)
+				]
 			else
-				autoCompileListener() if autoCompileListener
-				autoCompileListener = null
+				for unbind in autoCompileListeners
+					unbind()
+				autoCompileListeners = []
+				$scope.autoCompileLintingError = false
 
 		$scope.autocompile_enabled = localStorage("autocompile_enabled:#{$scope.project_id}") or false
 		$scope.$watch "autocompile_enabled", (newValue, oldValue) ->

+ 42 - 16
services/web/public/stylesheets/app/editor/pdf.less

@@ -1,13 +1,38 @@
+@stripe-width: 20px;
+@-webkit-keyframes pdf-toolbar-stripes {
+  from  { background-position: 0 0; }
+  to    { background-position: @stripe-width 0; }
+}
+@keyframes pdf-toolbar-stripes {
+  from  { background-position: 0 0; }
+  to    { background-position: @stripe-width 0; }
+}
+
 .pdf .toolbar.toolbar-pdf when (@is-overleaf = true) {
 	.toolbar-small-mixin;
 	.toolbar-alt-mixin;
 	border-bottom: 0;
 	padding-right: 5px;
+	&.uncompiled-changes {
+		#gradient > .striped(@color: rgba(255,255,255,.10), @angle: -45deg);
+		background-size: @stripe-width @stripe-width;
+		.animation(pdf-toolbar-stripes 2s linear infinite);
+	}
+	.auto-compile-status {
+		color: white;
+		margin-right: (@line-height-computed / 2);
+		i {
+			color: @brand-danger;
+		}
+	}
 }
 
 .pdf .toolbar.toolbar-pdf when (@is-overleaf = false) {
 	.toolbar-tall-mixin;
 	padding: 0 (@line-height-computed / 2);
+	.auto-compile-status {
+		display: none;
+	}
 }
 
 .pdf {
@@ -31,29 +56,30 @@
 
 .btn-recompile-group when (@is-overleaf = true) {
 	align-self: stretch;
-	margin-right: 5px;
+	margin-right: 6px;
+	.btn-recompile {
+		height: 100%;
+		.btn-primary;
+		padding-top: 3px;
+		padding-bottom: 3px;
+		&:first-child {
+			border-top-left-radius: 0;
+			border-bottom-left-radius: 0;
+		}
+		&[disabled] {
+			background-color: mix(@btn-primary-bg, @toolbar-alt-bg-color, 65%);
+			.opacity(1.0);
+		}
+	}
 }
 
 .btn-recompile-group when (@is-overleaf = false) {
 	margin-right: (@line-height-computed / 2);
-}
-
-
-.btn-recompile when (@is-overleaf = true) {
-	height: 100%;
-	.btn-primary;
-	padding-top: 3px;
-	padding-bottom: 3px;
-	&:first-child {
-		border-top-left-radius: 0;
-		border-bottom-left-radius: 0;
+	.btn-recompile {
+		.btn-info;
 	}
 }
 
-.btn-recompile when (@is-overleaf = false) {
-	.btn-info;
-}
-
 .btn-split-screen when (@is-overleaf = false) {
 	.fa {
 		display: none;