mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-09 16:09:08 +00:00
- hooked up chat throughout the stack
- removed lots of console.logs - working on the auto scrol, doesn't quite work yet
This commit is contained in:
parent
34ac6b03cd
commit
581d9ec925
24 changed files with 106 additions and 98 deletions
|
@ -5,17 +5,24 @@ logger = require("logger-sharelatex")
|
|||
module.exports =
|
||||
|
||||
|
||||
sendMessage: (project_id, user_id, messageContent, callback)->
|
||||
sendMessage: (req, res)->
|
||||
{project_id} = req.params
|
||||
user_id = req.session.user._id
|
||||
messageContent = req.body.content
|
||||
ChatHandler.sendMessage project_id, user_id, messageContent, (err, builtMessge)->
|
||||
if err?
|
||||
logger.err err:err, project_id:project_id, user_id:user_id, messageContent:messageContent, "problem sending message to chat api"
|
||||
return callback(err)
|
||||
return res.send(500)
|
||||
EditorRealTimeController.emitToRoom project_id, "new-chat-message", builtMessge, (err)->
|
||||
callback(err)
|
||||
res.send()
|
||||
|
||||
getMessages: (project_id, query, callback)->
|
||||
ChatHandler.getMessages project_id, query, (err)->
|
||||
getMessages: (req, res)->
|
||||
{project_id} = req.params
|
||||
query = req.body
|
||||
logger.log project_id:project_id, query:query, "getting messages"
|
||||
ChatHandler.getMessages project_id, query, (err, messages)->
|
||||
if err?
|
||||
logger.err err:err, query:query, "problem getting messages from chat api"
|
||||
return callback(err)
|
||||
callback()
|
||||
return res.send 500
|
||||
logger.log messages:messages, "sending messages to client"
|
||||
res.send messages
|
||||
|
|
|
@ -35,6 +35,7 @@ TrackChangesController = require("./Features/TrackChanges/TrackChangesController
|
|||
DropboxUserController = require("./Features/Dropbox/DropboxUserController")
|
||||
PasswordResetRouter = require("./Features/PasswordReset/PasswordResetRouter")
|
||||
StaticPagesRouter = require("./Features/StaticPages/StaticPagesRouter")
|
||||
ChatController = require("./Features/Chat/ChatController")
|
||||
|
||||
logger = require("logger-sharelatex")
|
||||
_ = require("underscore")
|
||||
|
@ -152,6 +153,9 @@ module.exports = class Router
|
|||
app.post "/spelling/check", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi
|
||||
app.post "/spelling/learn", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi
|
||||
|
||||
app.get "/project/:project_id/messages", ChatController.getMessages
|
||||
app.post "/project/:project_id/messages", ChatController.sendMessage
|
||||
|
||||
#Admin Stuff
|
||||
app.get '/admin', SecurityManager.requestIsAdmin, AdminController.index
|
||||
app.post '/admin/closeEditor', SecurityManager.requestIsAdmin, AdminController.closeEditor
|
||||
|
@ -295,3 +299,4 @@ module.exports = class Router
|
|||
client.on "getPublishedDetails", (user_id, callback)->
|
||||
AuthorizationManager.ensureClientCanViewProject client, (error, project_id) =>
|
||||
TemplatesController.getTemplateDetails user_id, project_id, callback
|
||||
|
||||
|
|
|
@ -131,19 +131,3 @@ block content
|
|||
src=jsPath+'libs/require.js?fingerprint='+fingerprint(jsPath + 'libs/require.js')
|
||||
)
|
||||
|
||||
- if (!anonymous)
|
||||
script(type="text/javascript").
|
||||
var chatReq = require.config({
|
||||
context: "chat",
|
||||
baseUrl: "#{chatUrl}/chat"
|
||||
});
|
||||
chatReq(["require", "chat"], function(require, Chat) {
|
||||
new Chat({
|
||||
room: {
|
||||
project_id: window.userSettings.project_id
|
||||
},
|
||||
url: "#{chatUrl}"
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ aside.chat(
|
|||
infinite-scroll="loadMore()"
|
||||
infinite-scroll-disabled="chat.loading || chat.atEnd"
|
||||
infinite-scroll-initialize="ui.chatOpen"
|
||||
scroll-to-bottom-on="message:new"
|
||||
)
|
||||
.infinite-scroll-inner
|
||||
ul.list-unstyled
|
||||
|
@ -19,7 +20,7 @@ aside.chat(
|
|||
div.date(ng-if="$index == 0 || (message.timestamp - chat.groupedMessages[$index - 1].timestamp) > 5 * 60 * 1000")
|
||||
{{ message.timestamp | formatDate:'h:MMa' }} {{ message.timestamp | relativeDate }}
|
||||
span.avatar
|
||||
img(ng-src="{{gravatarUrl(message.user)}}")
|
||||
img(ng-src="{{message.user.gravatar_url}}")
|
||||
div.message-wrapper
|
||||
.name(ng-if="message.user.id != user.id") {{ message.user.first_name }}
|
||||
.message(
|
||||
|
@ -32,8 +33,6 @@ aside.chat(
|
|||
p(ng-repeat="content in message.contents") {{ content }}
|
||||
|
||||
.new-message
|
||||
textarea(
|
||||
placeholder="Your message..."
|
||||
)
|
||||
textarea(placeholder="Your message...", on-enter="sendMessage()", ng-model="newMessageContent")
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ define [
|
|||
"../../libs/fineuploader"
|
||||
], (App) ->
|
||||
App.directive 'fineUpload', ($timeout) ->
|
||||
console.log "7777777777"
|
||||
return {
|
||||
scope: {
|
||||
multiple: "="
|
||||
|
|
14
services/web/public/coffee/app/directives/scroll.coffee
Normal file
14
services/web/public/coffee/app/directives/scroll.coffee
Normal file
|
@ -0,0 +1,14 @@
|
|||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
App.directive 'scrollToBottomOn', () ->
|
||||
return {
|
||||
link: (scope, element, attrs) ->
|
||||
element = element[0]
|
||||
eventToScrollOn = attrs.scrollToBottomOn
|
||||
console.log eventToScrollOn
|
||||
scope.$on eventToScrollOn, ()->
|
||||
console.log element.scrollHeight, element.scrollTop
|
||||
element.scrollTop = element.scrollHeight*4
|
||||
console.log element.scrollHeight, element.scrollTop
|
||||
}
|
34
services/web/public/coffee/app/directives/scrollGlue.coffee
Normal file
34
services/web/public/coffee/app/directives/scrollGlue.coffee
Normal file
|
@ -0,0 +1,34 @@
|
|||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
|
||||
fakeNgModel = (initValue) ->
|
||||
$setViewValue: (value) ->
|
||||
@$viewValue = value
|
||||
return
|
||||
|
||||
$viewValue: initValue
|
||||
|
||||
App.directive "scrollGlue", ->
|
||||
return {
|
||||
|
||||
priority: 1
|
||||
require: ["?ngModel"]
|
||||
restrict: "A"
|
||||
|
||||
link: (scope, $el, attrs, ctrls) ->
|
||||
scrollToBottom = ->
|
||||
el.scrollTop = el.scrollHeight
|
||||
|
||||
shouldActivateAutoScroll = ->
|
||||
el.scrollTop + el.clientHeight + 1 >= el.scrollHeight
|
||||
|
||||
el = $el[0]
|
||||
ngModel = ctrls[0] or fakeNgModel(true)
|
||||
scope.$watch ->
|
||||
scrollToBottom() if ngModel.$viewValue
|
||||
|
||||
$el.bind "scroll", ->
|
||||
activate = shouldActivateAutoScroll()
|
||||
scope.$apply ngModel.$setViewValue.bind(ngModel, activate) if activate isnt ngModel.$viewValue
|
||||
}
|
|
@ -16,6 +16,7 @@ define [
|
|||
"directives/focus"
|
||||
"directives/fineUpload"
|
||||
"directives/onEnter"
|
||||
"directives/scroll"
|
||||
"filters/formatDate"
|
||||
], (
|
||||
App
|
||||
|
|
|
@ -1,48 +1,29 @@
|
|||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
App.controller "ChatController", ["$scope", ($scope) ->
|
||||
james = {
|
||||
id: $scope.user.id
|
||||
first_name: "James"
|
||||
last_name: "Allen"
|
||||
email: "james@sharelatex.com"
|
||||
}
|
||||
james2 = {
|
||||
id: "james2-id"
|
||||
first_name: "James"
|
||||
last_name: "Allen"
|
||||
email: "jamesallen0108@gmail.com"
|
||||
}
|
||||
henry = {
|
||||
id: "henry-id"
|
||||
first_name: "Henry"
|
||||
last_name: "Oswald"
|
||||
email: "henry.oswald@sharelatex.com"
|
||||
}
|
||||
$scope.chat.messages = [
|
||||
{ content: "Hello world", timestamp: Date.now() - 2000, user: james2 }
|
||||
{ content: "Hello, this is the new chat", timestamp: Date.now() - 4000, user: james }
|
||||
{ content: "Here are some longer messages to show what it looks like when I say a lot!", timestamp: Date.now() - 20000, user: henry }
|
||||
{ content: "What about some maths? $x^2 = 1$?", timestamp: Date.now() - 22000, user: james2 }
|
||||
{ content: "Nope, that doesn't work yet!", timestamp: Date.now() - 45000, user: henry }
|
||||
{ content: "I'm running out of things to say.", timestamp: Date.now() - 56000, user: henry }
|
||||
{ content: "Yep, me too", timestamp: Date.now() - 100000, user: james }
|
||||
{ content: "Hmm, looks like we've had this conversation backwards", timestamp: Date.now() - 120000, user: james }
|
||||
{ content: "Hello world", timestamp: Date.now() - 202000, user: james2 }
|
||||
{ content: "Hello, this is the new chat", timestamp: Date.now() - 204000, user: james }
|
||||
{ content: "Here are some longer messages to show what it looks like when I say a lot!", timestamp: Date.now() - 2020000, user: henry }
|
||||
{ content: "What about some maths? $x^2 = 1$?", timestamp: Date.now() - 12022000, user: james2 }
|
||||
{ content: "Nope, that doesn't work yet!", timestamp: Date.now() - 12045000, user: henry }
|
||||
{ content: "I'm running out of things to say.", timestamp: Date.now() - 22056000, user: henry }
|
||||
{ content: "Yep, me too", timestamp: Date.now() - 220100000, user: james }
|
||||
{ content: "Hmm, looks like we've had this conversation backwards", timestamp: Date.now() - 520120000, user: james }
|
||||
].reverse()
|
||||
App.controller "ChatController", ["$scope", "$http", "ide", "$location", ($scope, $http, @ide, $location) ->
|
||||
MESSAGES_URL = "/project/#{$scope.project_id}/messages"
|
||||
|
||||
$scope.$watch "chat.messages", (messages) ->
|
||||
$scope.$on "project:joined", =>
|
||||
@ide.socket.on "new-chat-message", (message) =>
|
||||
$scope.$emit "message:new"
|
||||
$scope.chat.messages.push(message)
|
||||
|
||||
$http.get(MESSAGES_URL).success (data, status, headers, config)->
|
||||
$scope.chat.messages = data
|
||||
|
||||
$scope.$watchCollection "chat.messages", (messages) ->
|
||||
if messages?
|
||||
console.log "grouping messages"
|
||||
$scope.chat.groupedMessages = groupMessages(messages)
|
||||
|
||||
$scope.sendMessage = ->
|
||||
body =
|
||||
content:$scope.newMessageContent
|
||||
_csrf : window.csrfToken
|
||||
$http.post(MESSAGES_URL, body).success (data, status, headers, config)->
|
||||
$scope.newMessageContent = ""
|
||||
|
||||
TIMESTAMP_GROUP_SIZE = 5 * 60 * 1000 # 5 minutes
|
||||
groupMessages = (messages) ->
|
||||
previousMessage = null
|
||||
|
|
|
@ -60,7 +60,7 @@ define [], () ->
|
|||
@$scope.permissionsLevel = permissionsLevel
|
||||
@$scope.state.load_progress = 100
|
||||
@$scope.state.loading = false
|
||||
@$scope.$emit "project:joined"
|
||||
@$scope.$broadcast "project:joined"
|
||||
|
||||
reconnectImmediately: () ->
|
||||
@disconnect()
|
||||
|
|
|
@ -48,7 +48,6 @@ define [
|
|||
oldWidth = element.width()
|
||||
# Something resized our parent element
|
||||
onExternalResize = () ->
|
||||
console.log "EXTERNAL RESIOZE", name, attrs.resizeProportionally
|
||||
if attrs.resizeProportionally? and scope.$eval(attrs.resizeProportionally)
|
||||
eastState = element.layout().readState().east
|
||||
if eastState?
|
||||
|
@ -86,7 +85,6 @@ define [
|
|||
|
||||
if attrs.openEast?
|
||||
scope.$watch attrs.openEast, (value, oldValue) ->
|
||||
console.log "Open East", value, oldValue
|
||||
if value? and value != oldValue
|
||||
if value
|
||||
element.layout().open("east")
|
||||
|
|
|
@ -38,7 +38,6 @@ define [
|
|||
range = new Range(pos.row, pos.column, pos.row, pos.column + 1)
|
||||
nextChar = editor.session.getTextRange(range)
|
||||
|
||||
console.log "INSERT MATCH", this
|
||||
|
||||
# If we are in \begin{it|}, then we need to remove the trailing }
|
||||
# since it will be adding in with the autocomplete of \begin{item}...
|
||||
|
@ -48,7 +47,6 @@ define [
|
|||
Autocomplete::_insertMatch.call this, data
|
||||
|
||||
@$scope.$watch "autoComplete", (autocomplete) =>
|
||||
console.log "autocomplete change", autocomplete
|
||||
if autocomplete
|
||||
@enable()
|
||||
else
|
||||
|
|
|
@ -18,7 +18,6 @@ define [], () ->
|
|||
@$scope.cursorPosition = cursor
|
||||
|
||||
@$scope.$watch "gotoLine", (value) =>
|
||||
console.log "Going to line", value
|
||||
if value?
|
||||
setTimeout () =>
|
||||
@gotoLine(value)
|
||||
|
|
|
@ -99,7 +99,6 @@ define [
|
|||
session.setMode(new LatexMode())
|
||||
|
||||
scope.$watch "annotations", (annotations) ->
|
||||
console.log "SETTING ANNOTATIONS", annotations
|
||||
if annotations?
|
||||
session = editor.getSession()
|
||||
session.setAnnotations annotations
|
||||
|
|
|
@ -39,7 +39,6 @@ define [
|
|||
@learnWord(highlight)
|
||||
|
||||
runFullCheck: () ->
|
||||
console.log "Running full check"
|
||||
@highlightedWordManager.clearRows()
|
||||
if @$scope.spellCheckLanguage and @$scope.spellCheckLanguage != ""
|
||||
@runSpellCheck()
|
||||
|
|
|
@ -16,7 +16,6 @@ define [
|
|||
@nextUpdateIsRemote = false
|
||||
|
||||
@editor.on "changeSession", (e) =>
|
||||
console.log "setting undo manager", e.session
|
||||
e.session.setUndoManager(@)
|
||||
|
||||
showUndoConflictWarning: () ->
|
||||
|
|
|
@ -2,12 +2,9 @@ define [
|
|||
"base"
|
||||
], (App) ->
|
||||
App.controller "FileTreeRootFolderController", ["$scope", "ide", ($scope, ide) ->
|
||||
console.log "CREATING FileTreeRootFolderController"
|
||||
rootFolder = $scope.rootFolder
|
||||
console.log "ROOT FOLDER", rootFolder
|
||||
$scope.onDrop = (events, ui) ->
|
||||
source = $(ui.draggable).scope().entity
|
||||
console.log "DROPPED INTO ROOT", source, rootFolder
|
||||
return if !source?
|
||||
ide.fileTreeManager.moveEntity(source, rootFolder)
|
||||
]
|
||||
|
|
|
@ -22,7 +22,6 @@ define [
|
|||
@updateCursorHighlights()
|
||||
|
||||
updateCursorHighlights: () ->
|
||||
console.log "UPDATING CURSOR HIGHLIGHTS"
|
||||
@$scope.onlineUserCursorHighlights = {}
|
||||
for client_id, client of @$scope.onlineUsers
|
||||
doc_id = client.doc_id
|
||||
|
@ -38,7 +37,6 @@ define [
|
|||
|
||||
UPDATE_INTERVAL: 500
|
||||
sendCursorPositionUpdate: () ->
|
||||
console.log "SENDING CURSOR POSITION UPDATE", @$scope.editor.cursorPosition
|
||||
if !@cursorUpdateTimeout?
|
||||
@cursorUpdateTimeout = setTimeout ()=>
|
||||
position = @$scope.editor.cursorPosition
|
||||
|
|
|
@ -94,7 +94,6 @@ define [
|
|||
return path
|
||||
|
||||
$scope.recompile = (options = {}) ->
|
||||
console.log "Recompiling", options
|
||||
return if $scope.pdf.compiling
|
||||
$scope.pdf.compiling = true
|
||||
|
||||
|
@ -140,7 +139,6 @@ define [
|
|||
)
|
||||
|
||||
$scope.syncToCode = (position) ->
|
||||
console.log "SYNCING VIA DBL CLICK", position
|
||||
synctex
|
||||
.syncToCode(position)
|
||||
.then (data) ->
|
||||
|
@ -246,13 +244,11 @@ define [
|
|||
.syncToCode($scope.pdf.position, includeVisualOffset: true)
|
||||
.then (data) ->
|
||||
{doc, line} = data
|
||||
console.log "OPENING DOC", doc, line
|
||||
ide.editorManager.openDoc(doc, gotoLine: line)
|
||||
]
|
||||
|
||||
App.controller "PdfLogEntryController", ["$scope", "ide", ($scope, ide) ->
|
||||
$scope.openInEditor = (entry) ->
|
||||
console.log "OPENING", entry.file, entry.line
|
||||
entity = ide.fileTreeManager.findEntityByPath(entry.file)
|
||||
return if !entity? or entity.type != "doc"
|
||||
if entry.line?
|
||||
|
|
|
@ -47,7 +47,6 @@ define [
|
|||
onProgress = (progress) ->
|
||||
scope.$apply () ->
|
||||
scope.progress = Math.floor(progress.loaded/progress.total*100)
|
||||
console.log "PROGRESS", scope.progress, progress.loaded, progress.total
|
||||
|
||||
initializedPosition = false
|
||||
initializePosition = () ->
|
||||
|
@ -78,7 +77,6 @@ define [
|
|||
, 1000
|
||||
|
||||
element.find(".pdfjs-viewer").scroll () ->
|
||||
console.log "UPDATING POSITION", pdfListView.getPdfPosition(true)
|
||||
scope.position = pdfListView.getPdfPosition(true)
|
||||
|
||||
onDoubleClick = (e) ->
|
||||
|
@ -99,7 +97,6 @@ define [
|
|||
flashControls()
|
||||
|
||||
scope.$watch "highlights", (areas) ->
|
||||
console.log "UPDATING HIGHLIGHTS", areas
|
||||
return if !areas?
|
||||
highlights = for area in areas or []
|
||||
{
|
||||
|
|
|
@ -8,7 +8,6 @@ define [
|
|||
ide.trackChangesManager.fetchNextBatchOfUpdates()
|
||||
|
||||
$scope.recalculateSelectedUpdates = () ->
|
||||
console.log "RECALCULATING UPDATES"
|
||||
beforeSelection = true
|
||||
afterSelection = false
|
||||
$scope.trackChanges.selection.updates = []
|
||||
|
@ -72,14 +71,12 @@ define [
|
|||
App.controller "TrackChangesListItemController", ["$scope", ($scope) ->
|
||||
$scope.$watch "update.selectedFrom", (selectedFrom, oldSelectedFrom) ->
|
||||
if selectedFrom
|
||||
console.log "SELECTED FROM CHANGED", $scope.update, selectedFrom, oldSelectedFrom
|
||||
for update in $scope.trackChanges.updates
|
||||
update.selectedFrom = false unless update == $scope.update
|
||||
$scope.recalculateSelectedUpdates()
|
||||
|
||||
$scope.$watch "update.selectedTo", (selectedTo, oldSelectedTo) ->
|
||||
if selectedTo
|
||||
console.log "SELECTED TO CHANGED", $scope.update, selectedTo, oldSelectedTo
|
||||
for update in $scope.trackChanges.updates
|
||||
update.selectedTo = false unless update == $scope.update
|
||||
$scope.recalculateSelectedUpdates()
|
||||
|
|
|
@ -8,18 +8,19 @@ define [
|
|||
element.css 'overflow-y': 'auto'
|
||||
|
||||
atEndOfListView = () ->
|
||||
element.scrollTop() + element.height() >= innerElement.height() - 30
|
||||
if element?
|
||||
element.scrollTop() + element.height() >= innerElement.height() - 30
|
||||
|
||||
listShorterThanContainer = () ->
|
||||
element.innerHeight() > @$(".change-list").outerHeight()
|
||||
if element?
|
||||
element.innerHeight() > @$(".change-list").outerHeight()
|
||||
|
||||
loadUntilFull = () ->
|
||||
if (listShorterThanContainer() or atEndOfListView()) and not scope.$eval(attrs.infiniteScrollDisabled)
|
||||
console.log "Loading more"
|
||||
promise = scope.$eval(attrs.infiniteScroll)
|
||||
console.log promise
|
||||
promise.then () ->
|
||||
loadUntilFull()
|
||||
# promise.then () ->
|
||||
# loadUntilFull()
|
||||
|
||||
# @collection.fetchNextBatch
|
||||
# error: (error) =>
|
||||
# @hideLoading()
|
||||
|
@ -38,7 +39,6 @@ define [
|
|||
loadUntilFull()
|
||||
|
||||
scope.$watch attrs.infiniteScrollInitialize, (value) ->
|
||||
console.log "INITIALIZE", value
|
||||
if value
|
||||
loadUntilFull()
|
||||
|
||||
|
|
|
@ -47,8 +47,6 @@ define [
|
|||
range = new Range(pos.row, pos.column, pos.row, pos.column + 1)
|
||||
nextChar = editor.session.getTextRange(range)
|
||||
|
||||
console.log "CALLING OLD"
|
||||
|
||||
# If we are in \begin{it|}, then we need to remove the trailing }
|
||||
# since it will be adding in with the autocomplete of \begin{item}...
|
||||
if this.completions.filterText.match(/^\\begin\{/) and nextChar == "}"
|
||||
|
|
|
@ -53,3 +53,10 @@ describe "ChatController", ->
|
|||
@ChatHandler.getMessages.calledWith(@project_id, @query).should.equal true
|
||||
done()
|
||||
|
||||
it "should return the messages", (done)->
|
||||
messages = [{content:"hello"}]
|
||||
@ChatHandler.getMessages.callsArgWith(2, null, messages)
|
||||
@ChatController.getMessages @project_id, @query, (err, passedMessages)=>
|
||||
passedMessages.should.deep.equal messages
|
||||
done()
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue