Get basic cursor updating going on

This commit is contained in:
James Allen 2014-06-25 18:17:17 +01:00
parent 703a4faa0e
commit c14774bedd
7 changed files with 143 additions and 4 deletions

View file

@ -142,9 +142,11 @@ block content
font-size="settings.fontSize", font-size="settings.fontSize",
auto-complete="settings.autoComplete", auto-complete="settings.autoComplete",
spell-check-language="project.spellCheckLanguage", spell-check-language="project.spellCheckLanguage",
annotations="onlineUserCursorAnnotations[editor.open_doc_id]"
show-print-margin="false", show-print-margin="false",
sharejs-doc="editor.sharejs_doc", sharejs-doc="editor.sharejs_doc",
last-updated="editor.last_updated" last-updated="editor.last_updated",
cursor-position="editor.cursorPosition"
) )
//- #loadingScreen //- #loadingScreen

View file

@ -4,6 +4,7 @@ define [
"ide/connection/ConnectionManager" "ide/connection/ConnectionManager"
"ide/editor/EditorManager" "ide/editor/EditorManager"
"ide/settings/SettingsManager" "ide/settings/SettingsManager"
"ide/online-users/OnlineUsersManager"
"ide/directives/layout" "ide/directives/layout"
"ide/services/ide" "ide/services/ide"
"directives/focus" "directives/focus"
@ -15,6 +16,7 @@ define [
ConnectionManager ConnectionManager
EditorManager EditorManager
SettingsManager SettingsManager
OnlineUsersManager
) -> ) ->
App.controller "IdeController", ["$scope", "$timeout", "ide", ($scope, $timeout, ide) -> App.controller "IdeController", ["$scope", "$timeout", "ide", ($scope, $timeout, ide) ->
# Don't freak out if we're already in an apply callback # Don't freak out if we're already in an apply callback
@ -43,6 +45,7 @@ define [
ide.fileTreeManager = new FileTreeManager(ide, $scope) ide.fileTreeManager = new FileTreeManager(ide, $scope)
ide.editorManager = new EditorManager(ide, $scope) ide.editorManager = new EditorManager(ide, $scope)
ide.settingsManager = new SettingsManager(ide, $scope) ide.settingsManager = new SettingsManager(ide, $scope)
ide.onlineUsersManager = new OnlineUsersManager(ide, $scope)
] ]
angular.bootstrap(document.body, ["SharelatexApp"]) angular.bootstrap(document.body, ["SharelatexApp"])

View file

@ -9,6 +9,7 @@ define [
last_updated: null last_updated: null
open_doc_id: null open_doc_id: null
opening: true opening: true
cursorPosition: null
} }
@$scope.$on "entity:selected", (event, entity) => @$scope.$on "entity:selected", (event, entity) =>
@ -32,8 +33,8 @@ define [
openDoc: (doc, options = {}) -> openDoc: (doc, options = {}) ->
console.log "Trying to open doc", doc.id console.log "Trying to open doc", doc.id
return if doc.id == @$scope.open_doc_id and !options.forceReopen return if doc.id == @$scope.editor.open_doc_id and !options.forceReopen
@$scope.open_doc_id = doc.id @$scope.editor.open_doc_id = doc.id
console.log "Actually opening doc", doc.id console.log "Actually opening doc", doc.id
$.localStorage "doc.open_id.#{@$scope.project_id}", doc.id $.localStorage "doc.open_id.#{@$scope.project_id}", doc.id

View file

@ -0,0 +1,37 @@
define [
"ace/range"
], () ->
Range = require("ace/range").Range
class AnnotationsManager
constructor: (@$scope, @editor) ->
@markerIds = []
@$scope.$watch "annotations", (value) =>
if value?
@redrawAnnotations()
redrawAnnotations: () ->
console.log "REDRAWING ANNOTATIONS"
for marker_id in @markerIds
@editor.getSession().removeMarker(marker_id)
@markerIds = []
for annotation in @$scope.annotations or []
do (annotation) =>
console.log "DRAWING ANNOTATION", annotation
@markerIds.push @editor.getSession().addMarker new Range(
annotation.cursor.row, annotation.cursor.column,
annotation.cursor.row, annotation.cursor.column + 1
), "remote-cursor", (html, range, left, top, config) ->
div = """
<div
class='remote-cursor custom ace_start'
style='height: #{config.lineHeight}px; top:#{top}px; left:#{left}px;'
>
<div class="nubbin" style="bottom: #{config.lineHeight - 2}px"></div>
<div class="name" style="display: none; bottom: #{config.lineHeight - 2}px">#{$('<div/>').text(annotation.text).html()}</div>
</div>
"""
html.push div
, true

View file

@ -4,11 +4,12 @@ define [
"ide/editor/undo/UndoManager" "ide/editor/undo/UndoManager"
"ide/editor/auto-complete/AutoCompleteManager" "ide/editor/auto-complete/AutoCompleteManager"
"ide/editor/spell-check/SpellCheckManager" "ide/editor/spell-check/SpellCheckManager"
"ide/editor/annotations/AnnotationsManager"
"ace/keyboard/vim" "ace/keyboard/vim"
"ace/keyboard/emacs" "ace/keyboard/emacs"
"ace/mode/latex" "ace/mode/latex"
"ace/edit_session" "ace/edit_session"
], (App, Ace, UndoManager, AutoCompleteManager, SpellCheckManager) -> ], (App, Ace, UndoManager, AutoCompleteManager, SpellCheckManager, AnnotationsManager) ->
LatexMode = require("ace/mode/latex").Mode LatexMode = require("ace/mode/latex").Mode
EditSession = require('ace/edit_session').EditSession EditSession = require('ace/edit_session').EditSession
@ -23,13 +24,25 @@ define [
sharejsDoc: "=" sharejsDoc: "="
lastUpdated: "=" lastUpdated: "="
spellCheckLanguage: "=" spellCheckLanguage: "="
cursorPosition: "="
annotations: "="
} }
link: (scope, element, attrs) -> link: (scope, element, attrs) ->
# Don't freak out if we're already in an apply callback
scope.$originalApply = scope.$apply
scope.$apply = (fn = () ->) ->
phase = @$root.$$phase
if (phase == '$apply' || phase == '$digest')
fn()
else
@$originalApply(fn);
editor = Ace.edit(element.find(".ace-editor-body")[0]) editor = Ace.edit(element.find(".ace-editor-body")[0])
autoCompleteManager = new AutoCompleteManager(scope, editor) autoCompleteManager = new AutoCompleteManager(scope, editor)
spellCheckManager = new SpellCheckManager(scope, editor, element) spellCheckManager = new SpellCheckManager(scope, editor, element)
undoManager = new UndoManager(scope, editor) undoManager = new UndoManager(scope, editor)
annotationsManagaer = new AnnotationsManager(scope, editor)
# Prevert Ctrl|Cmd-S from triggering save dialog # Prevert Ctrl|Cmd-S from triggering save dialog
editor.commands.addCommand editor.commands.addCommand
@ -41,6 +54,11 @@ define [
editor.commands.removeCommand "showSettingsMenu" editor.commands.removeCommand "showSettingsMenu"
editor.commands.removeCommand "foldall" editor.commands.removeCommand "foldall"
editor.on "changeSelection", () ->
cursor = editor.getCursorPosition()
scope.$apply () ->
scope.cursorPosition = cursor
scope.$watch "theme", (value) -> scope.$watch "theme", (value) ->
editor.setTheme("ace/theme/#{value}") editor.setTheme("ace/theme/#{value}")

View file

@ -0,0 +1,56 @@
define [], () ->
class OnlineUsersManager
constructor: (@ide, @$scope) ->
@$scope.onlineUsers = {}
@$scope.onlineUserCursorAnnotations = {}
@$scope.$watch "editor.cursorPosition", (position) =>
console.log "CURSOR POSITION UPDATE", position
if position?
@sendCursorPositionUpdate()
@ide.socket.on "clientTracking.clientUpdated", (client) =>
console.log "REMOTE CURSOR POSITION UPDATE", client
if client.id != @ide.socket.socket.sessionid # Check it's not me!
@$scope.$apply () =>
@$scope.onlineUsers[client.id] = client
@updateCursorHighlights()
@ide.socket.on "clientTracking.clientDisconnected", (client_id) =>
@$scope.$apply () =>
delete @$scope.onlineUsers[client_id]
@updateCursorHighlights()
updateCursorHighlights: () ->
console.log "UPDATING CURSOR HIGHLIGHTS"
@$scope.onlineUserCursorAnnotations = {}
for client_id, client of @$scope.onlineUsers
doc_id = client.doc_id
@$scope.onlineUserCursorAnnotations[doc_id] ||= []
@$scope.onlineUserCursorAnnotations[doc_id].push {
text: client.name
cursor:
row: client.row
column: client.column
}
UPDATE_INTERVAL: 500
sendCursorPositionUpdate: () ->
if !@cursorUpdateTimeout?
console.log "CREATING DELAYED UPDATED"
@cursorUpdateTimeout = setTimeout ()=>
position = @$scope.editor.cursorPosition
doc_id = @$scope.editor.open_doc_id
@ide.socket.emit "clientTracking.updatePosition", {
row: position.row
column: position.column
doc_id: doc_id
}
delete @cursorUpdateTimeout
, @UPDATE_INTERVAL
else
console.log "NOT UPDATING"

View file

@ -193,6 +193,28 @@
background-repeat: repeat-x; background-repeat: repeat-x;
background-position: bottom left; background-position: bottom left;
} }
@cursor-color: rgb(14, 158, 0);
.remote-cursor {
position: absolute;
z-index: 2;
border-left: 2px solid @cursor-color;
.name {
font-size: 0.8em;
background-color: @cursor-color;
color: white;
padding: 2px 6px;
border-radius: 3px 3px 3px 0;
position: absolute;
left: -4px;
}
.nubbin {
height: 6px;
width: 6px;
background-color: @cursor-color;
position: absolute;
left: -4px;
}
}
} }
.ui-layout-resizer { .ui-layout-resizer {