Ver Fonte

Merge branch 'master' of github.com:sharelatex/web-sharelatex

Henry Oswald há 12 anos atrás
pai
commit
63a5f2bf44

+ 1 - 1
services/web/app/coffee/router.coffee

@@ -124,7 +124,7 @@ module.exports = class Router
 		app.get  '/Project/:Project_id/version', SecutiryManager.requestCanAccessProject, versioningController.listVersions
 		app.get  '/Project/:Project_id/version/:Version_id', SecutiryManager.requestCanAccessProject, versioningController.getVersion
 
-		app.get  "/project/:Project_id/doc/:doc_id/updates", SecutiryManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi
+		app.get  "/project/:Project_id/updates", SecutiryManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi
 		app.get  "/project/:Project_id/doc/:doc_id/diff", SecutiryManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi
 		app.post "/project/:Project_id/doc/:doc_id/version/:version_id/restore", SecutiryManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi
 

+ 2 - 1
services/web/app/views/templates.jade

@@ -443,7 +443,8 @@
 			input(type="radio",name="toVersion").change-selector-to
 
 		div(class='change-description')
-			div(class='change-date') {{date}}
+			div.changed-docs {{docs}}
+			div.change-date {{date}}
 			div {{{users}}}
 
 		div(class='restore')

+ 11 - 5
services/web/public/coffee/editor/Editor.coffee

@@ -35,6 +35,8 @@ define [
 				identifier: "editor"
 				element: @editorPanel
 			@initializeEditor()
+			@bindToFileTreeEvents()
+			@enable()
 			@loadingIndicator = $(@templates.loadingIndicator)
 			@editorPanel.find("#editor").append(@loadingIndicator)
 			@leftPanel = @editorPanel.find("#leftEditorPanel")
@@ -42,6 +44,11 @@ define [
 			@initSplitView()
 			@switchToFlatView()
 
+		bindToFileTreeEvents: () ->
+			@ide.fileTreeManager.on "open:doc", (doc_id, options = {}) =>
+				if @enabled
+					@openDoc doc_id, options
+
 		initSplitView: () ->
 			splitter = @editorPanel.find("#editorSplitter")
 			options =
@@ -352,9 +359,8 @@ define [
 		getCurrentDocId: () ->
 			@current_doc_id
 
-		show: () ->
-			$("#editor").show()
-
-		hide: () ->
-			$("#editor").hide()
+		enable: () ->
+			@enabled = true
 
+		disable: () ->
+			@enabled = false

+ 2 - 3
services/web/public/coffee/file-tree/FileTreeManager.coffee

@@ -76,7 +76,7 @@ define [
 
 		openDoc: (doc, line) ->
 			doc_id = doc.id or doc
-			@ide.editor.openDoc(doc_id, line: line)
+			@trigger "open:doc", doc_id, line: line
 			@selectEntity(doc_id)
 			$.localStorage "doc.open_id.#{@project_id}", doc_id
 
@@ -86,8 +86,7 @@ define [
 			@openDoc(doc_id, line)
 
 		openFile: (file) ->
-			@ide.mainAreaManager.change('file')
-			@ide.fileViewManager.showFile(file)
+			@trigger "open:file", file
 			@selectEntity(file.id)
 
 		openFolder: (folder) ->

+ 15 - 0
services/web/public/coffee/file-view/FileViewManager.coffee

@@ -13,5 +13,20 @@ define [
 			@ide.layoutManager.on "resize", () => @view.onResize()
 			@view.onResize()
 
+			@bindToFileTreeEvents()
+			@enable()
+
+		bindToFileTreeEvents: () ->
+			@ide.fileTreeManager.on "open:file", (file) =>
+				if @enabled
+					@showFile(file)
+
 		showFile: (file) ->
+			@ide.mainAreaManager.change('file')
 			@view.setModel(file)
+
+		enable: () ->
+			@enabled = true
+
+		disable: () ->
+			@enabled = false

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

@@ -106,12 +106,12 @@ define [
 			@sideBarView = new SideBarManager(@, $("#sections"))
 			selectElement = @sideBarView.selectElement
 			mainAreaManager = @mainAreaManager = new MainAreaManager(@, $("#content"))
+			@fileTreeManager = new FileTreeManager(@)
 			@editor = new Editor(@)
 			@pdfManager = new PdfManager(@)
 			if @userSettings.autoComplete
 				@autoCompleteManager = new AutoCompleteManager(@)
 			@spellingManager = new SpellingManager(@)
-			@fileTreeManager = new FileTreeManager(@)
 			@fileUploadManager = new FileUploadManager(@)
 			@searchManager = new SearchManager(@)
 			@cursorManager = new CursorManager(@)
@@ -119,6 +119,8 @@ define [
 			@analyticsManager = new AnalyticsManager(@)
 			if @userSettings.trackChanges
 				@trackChangesManager = new TrackChangesManager(@)
+			else
+				@historyManager = new HistoryManager(@)
 
 			@setLoadingMessage("Connecting")
 			firstConnect = true
@@ -186,7 +188,6 @@ define [
 
 	_.extend(Ide::, Backbone.Events)
 	window.ide = ide = new Ide()
-	ide.historyManager = new HistoryManager ide
 	ide.projectMembersManager = new ProjectMembersManager ide
 	ide.settingsManager = new SettingsManager ide
 	ide.helpManager = new HelpManager ide

+ 18 - 4
services/web/public/coffee/ide/TabManager.coffee

@@ -12,26 +12,39 @@ define [
 			@state = "closed"
 			$("#toolbar").on "mouseenter", () => @onMouseOver()
 			$("#toolbar").on "mouseleave", (e) => @onMouseOut(e)
+			@tabs = []
 
 		addTab: (options) ->
+			@tabs.push options
+
 			tabEl = $(Mustache.to_html @templates.tab, options)
 			tabEl.find("a").attr("href", "#" + options.id)
-			contentEl = $(Mustache.to_html @templates.content, options)
-			contentEl.append(options.content)
+
+			if options.content?
+				contentEl = $(Mustache.to_html @templates.content, options)
+				contentEl.append(options.content)
+				$("#tab-content").append(contentEl)
 
 			if options.active
 				tabEl.addClass("active")
-				contentEl.addClass("active")
+				contentEl?.addClass("active")
 
 			if options.after?
 				tabEl.insertAfter($("##{options.after}-tab-li"))
 			else
 				$("#tabs").append(tabEl)
-			$("#tab-content").append(contentEl)
+
 			$("body").scrollTop(0)
 			tabEl.on "shown", () =>
 				$("body").scrollTop(0)
+
 				options.onShown() if options.onShown?
+				for other_tab in @tabs
+					if other_tab.id != options.id and other_tab.active and other_tab.onHidden?
+						other_tab.onHidden()
+					other_tab.active = false
+				options.active = true
+
 				if options.lock
 					@lockOpen()
 				else
@@ -40,6 +53,7 @@ define [
 				if options.contract
 					@contract()
 
+
 		lockOpen: () ->
 			@locked_open = true
 			$("#toolbar").css({

+ 19 - 12
services/web/public/coffee/track-changes/ChangeListView.coffee

@@ -112,7 +112,7 @@ define [
 					view.setHoverUnselected()
 
 		triggerChangeDiff: () ->
-			@trigger "change_diff", @collection.models[@selectedFromIndex], @collection.models[@selectedToIndex]
+			@trigger "change_diff", @selectedFromIndex, @selectedToIndex
 
 		listShorterThanContainer: ->
 			@$el.height() > @$(".change-list").height()
@@ -131,12 +131,12 @@ define [
 						callback(error)
 					success: (collection, response) =>
 						@hideLoading()
-						if response.updates.length == @collection.batchSize
-							@loadUntilFull(callback)
-						else
+						if @collection.isAtEnd()
 							@atEndOfCollection = true
 							@showEmptyMessageIfCollectionEmpty()
 							callback()
+						else
+							@loadUntilFull(callback)
 							
 			else
 				callback() if callback?
@@ -189,9 +189,16 @@ define [
 					hue:  user.hue()
 					name: user.name()
 				}
+			docNames = []
+			for doc in @model.get("docs")
+				if doc.entity?
+					docNames.push doc.entity.get("name")
+				else
+					docNames.push "deleted"
 			data = {
 				date: moment(parseInt(@model.get("end_ts"), 10)).calendar()
 				users: userHtml.join("")
+				docs: docNames.join(", ")
 			}
 
 			@$el.html Mustache.to_html(@templates.item, data)
@@ -236,20 +243,20 @@ define [
 			@$(".change-selector-to").prop("checked", checked)
 
 		setSelected: (first, last) ->
-			@$el.addClass("selected")
+			@$el.addClass("selected-change")
 			if first
-				@$el.addClass("selected-to")
+				@$el.addClass("selected-change-to")
 			else
-				@$el.removeClass("selected-to")
+				@$el.removeClass("selected-change-to")
 			if last
-				@$el.addClass("selected-from")
+				@$el.addClass("selected-change-from")
 			else
-				@$el.removeClass("selected-from")
+				@$el.removeClass("selected-change-from")
 
 		setUnselected: () ->
-			@$el.removeClass("selected-to")
-			@$el.removeClass("selected-from")
-			@$el.removeClass("selected")
+			@$el.removeClass("selected-change-to")
+			@$el.removeClass("selected-change-from")
+			@$el.removeClass("selected-change")
 
 		setHoverSelected: (first, last) ->
 			@$el.addClass("hover-selected")

+ 84 - 32
services/web/public/coffee/track-changes/TrackChangesManager.coffee

@@ -13,11 +13,17 @@ define [
 		constructor: (@ide) ->
 			@project_id = window.userSettings.project_id
 			@$el = $(@template)
-			$("#editorWrapper").append(@$el)
-			@hideEl()
-
-			@ide.editor.on "change:doc", () =>
-				@hideEl()
+			@ide.mainAreaManager.addArea
+				identifier: "trackChanges"
+				element: @$el
+
+			@ide.tabManager.addTab
+				id: "history"
+				name: "History"
+				after: "code"
+				contract: true
+				onShown: () => @show()
+				onHidden: () => @hide()
 
 			@ide.editor.on "resize", () =>
 				@diffView?.resize()
@@ -26,20 +32,18 @@ define [
 				e.preventDefault
 				@hide()
 
-			@ide.fileTreeManager.on "contextmenu:beforeshow", (entity, entries) =>
-				if entity instanceof Doc
-					entries.push {
-						divider: true
-					}, {
-						text: "History"
-						onClick: () =>
-							@show(entity.id)
-					}
-
-		show: (@doc_id) ->
-			@ide.fileTreeManager.selectEntity(@doc_id)
+			@bindToFileTreeEvents()
+
+			@disable()
 
-			@changes = new ChangeList([], doc_id: @doc_id, project_id: @project_id)
+		bindToFileTreeEvents: () ->
+			@ide.fileTreeManager.on "open:doc", (doc_id) =>
+				if @enabled
+					@doc_id = doc_id
+					@updateDiff()
+
+		show: () ->
+			@changes = new ChangeList([], project_id: @project_id, ide: @ide)
 
 			@changeListView = new ChangeListView(
 				collection : @changes,
@@ -49,8 +53,8 @@ define [
 			@changeListView.loadUntilFull (error) =>
 				@autoSelectDiff()
 
-			@changeListView.on "change_diff", (fromModel, toModel) =>
-				@showDiff(fromModel, toModel)
+			@changeListView.on "change_diff", (fromIndex, toIndex) =>
+				@selectDocAndUpdateDiff(fromIndex, toIndex)
 
 			@changeListView.on "restore", (change) =>
 				@restore(change)
@@ -58,11 +62,17 @@ define [
 			if @diffView?
 				@diffView.destroy()
 
-			@showEl()
+			@ide.mainAreaManager.change "trackChanges"
+			@ide.editor.disable()
+			@ide.fileViewManager.disable()
+			@enable()
 
 		hide: () ->
-			@hideEl()
+			@ide.editor.enable()
+			@ide.fileViewManager.enable()
+			@disable()
 			@ide.fileTreeManager.openDoc(@doc_id)
+			@ide.mainAreaManager.change "editor"
 
 		autoSelectDiff: () ->
 			if @changes.models.length == 0
@@ -81,15 +91,39 @@ define [
 
 			toChange = @changes.models[0]
 			fromChange = @changes.models[fromIndex]
-			@showDiff(fromChange, toChange)
 			@changeListView.setSelectionRange(fromIndex, 0)
+			@updateDiff()
+
+		selectDocAndUpdateDiff: (fromIndex, toIndex) ->
+			doc_ids = []
+			for change in @changes.models.slice(toIndex, fromIndex + 1)
+				for doc in change.get("docs") or []
+					doc_ids.push doc.id if doc.id not in doc_ids
+
+			if !@doc_id? or @doc_id not in doc_ids
+				@doc_id = doc_ids[0]
+
+			@updateDiff()
+
+		updateDiff: () ->
+			fromIndex = @changeListView.selectedFromIndex
+			toIndex   = @changeListView.selectedToIndex
+
+			if !toIndex? or !fromIndex?
+				console.log "No selection - what should we do!?"
+				return
+
+			{from, to} = @_findDocVersionsRangeInSelection(@doc_id, fromIndex, toIndex)
+
+			if !from? or !to?
+				console.log "No diff, should probably just show latest version"
+				return
 
-		showDiff: (fromModel, toModel) ->
 			@diff = new Diff({
 				project_id: @project_id
 				doc_id: @doc_id
-				from: fromModel.get("fromVersion")
-				to:   toModel.get("toVersion")
+				from: from
+				to:   to
 			})
 
 			if @diffView?
@@ -100,13 +134,25 @@ define [
 			)
 			@diff.fetch()
 
-		showEl: ->
-			@ide.editor.hide()
-			@$el.show()
+			@ide.fileTreeManager.selectEntity(@doc_id)
+
 
-		hideEl: () ->
-			@ide.editor.show()
-			@$el.hide()
+		_findDocVersionsRangeInSelection: (doc_id, fromIndex, toIndex) ->
+			from = null
+			to = null
+
+			for change in @changes.models.slice(toIndex, fromIndex + 1)
+				for doc in change.get("docs")
+					if doc.id == doc_id
+						if from? and to?
+							from = Math.min(from, doc.fromV)
+							to = Math.max(to, doc.toV)
+						else
+							from = doc.fromV
+							to = doc.toV
+						break
+
+			return {from, to}
 
 		restore: (change) ->
 			name = @ide.fileTreeManager.getNameOfEntityId(@doc_id)
@@ -141,4 +187,10 @@ define [
 					callback(error)
 			}
 
+		enable: () ->
+			@enabled = true
+
+		disable: () ->
+			@enabled = false
+
 	return TrackChangesManager

+ 10 - 2
services/web/public/coffee/track-changes/models/Change.coffee

@@ -7,12 +7,20 @@ define [
 			model = {
 				start_ts: change.meta.start_ts
 				end_ts: change.meta.end_ts
-				fromVersion: change.fromV
-				toVersion: change.toV
 			}
 			model.users = []
 			for user in change.meta.users or []
 				model.users.push User.findOrBuild(user.id, user)
 			if model.users.length == 0
 				model.users.push User.getAnonymousUser()
+			model.docs = []
+			for doc_id, data of change.docs
+				model.docs.push
+					id: doc_id
+					fromV: data.fromV
+					toV: data.toV
+					# TODO: We should not use a global reference here, but 
+					# it's hard to get @ide into Backbone at this point.
+					entity: ide.fileTreeManager.getEntity(doc_id)
+
 			return model

+ 13 - 5
services/web/public/coffee/track-changes/models/ChangeList.coffee

@@ -4,21 +4,29 @@ define [
 ], (Change)->
 	ChangeList = Backbone.Collection.extend
 		model: Change
-		batchSize: 25
+		batchSize: 10
 
 		initialize: (models, @options) ->
+			@ide = @options.ide
+			@atEnd = false
 
 		url: () ->
-			url = "/project/#{@options.project_id}/doc/#{@options.doc_id}/updates?limit=#{@batchSize}"
-			if @models.length > 0
-				last = @models[@models.length - 1]
-				url += "&to=#{last.get("fromVersion") - 1}"
+			url = "/project/#{@options.project_id}/updates?min_count=#{@batchSize}"
+			if @nextBeforeTimestamp?
+				url += "&before=#{@nextBeforeTimestamp}"
 			return url
 
+		isAtEnd: () -> @atEnd
+
 		parse: (json) ->
+			@nextBeforeTimestamp = json.nextBeforeTimestamp
+			@atEnd = !@nextBeforeTimestamp
 			return json.updates
 
 		fetchNextBatch: (options = {}) ->
+			if @isAtEnd()
+				options.success?(@)
+				return
 			options.add = true
 			@fetch options
 

+ 12 - 5
services/web/public/stylesheets/less/trackchanges.less

@@ -126,10 +126,14 @@
 				min-height: 38px;
 			}
 			.change-name {
-				font-size: 0.9em;
+				font-size: 11px;
 				color: #666;
 				text-transform: capitalize;
 			}
+			.change-date {
+				margin-top: 2px;
+				font-size: 12px;
+			}
 			.color-square {
 				display: inline-block;
 				height: 10px;
@@ -137,6 +141,9 @@
 				margin-right: 4px;
 				margin-bottom: -1px;
 			}
+			.changed-docs {
+				font-weight: bold;
+			}
 			.restore {
 				a {
 					display: block;
@@ -153,7 +160,7 @@
 		li.loading-changes, li.empty-message {
 			padding: 6px;
 		}
-		li.selected {
+		li.selected-change {
 			background-color: #eaeaea;
 			.change-selectors {
 				.range {
@@ -161,7 +168,7 @@
 				}
 			}
 		}
-		li.selected-to {
+		li.selected-change-to {
 			.change-selectors {
 				.range {
 					top: 10px;
@@ -171,7 +178,7 @@
 				}
 			}
 		}
-		li.selected-from {
+		li.selected-change-from {
 			.change-selectors {
 				.range {
 					bottom: 37px;
@@ -223,7 +230,7 @@
 				}
 			}
 		}
-		li.selected-from.hover-selected-from {
+		li.selected-change-from.hover-selected-from {
 			.change-selectors {
 				.range {
 					bottom: 37px;