mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Removed Angular chat (#3553)
GitOrigin-RevId: dd9f6b3adff13d28ef251f61c7a2b54fff2d9ae7
This commit is contained in:
parent
7e7beffa59
commit
846510b2e6
9 changed files with 4 additions and 378 deletions
|
@ -774,9 +774,6 @@ const ProjectController = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const wantsOldChatUI =
|
|
||||||
req.query && req.query.new_chat_ui === 'false'
|
|
||||||
|
|
||||||
const wantsOldLogsUI =
|
const wantsOldLogsUI =
|
||||||
req.query && req.query.new_logs_ui === 'false'
|
req.query && req.query.new_logs_ui === 'false'
|
||||||
|
|
||||||
|
@ -836,7 +833,6 @@ const ProjectController = {
|
||||||
wsUrl,
|
wsUrl,
|
||||||
showSupport: Features.hasFeature('support'),
|
showSupport: Features.hasFeature('support'),
|
||||||
showNewLogsUI: user.alphaProgram && !wantsOldLogsUI,
|
showNewLogsUI: user.alphaProgram && !wantsOldLogsUI,
|
||||||
showNewChatUI: user.betaProgram && !wantsOldChatUI,
|
|
||||||
showReactFileTree: user.betaProgram && !wantsOldFileTreeUI
|
showReactFileTree: user.betaProgram && !wantsOldFileTreeUI
|
||||||
})
|
})
|
||||||
timer.done()
|
timer.done()
|
||||||
|
|
|
@ -107,10 +107,10 @@ block content
|
||||||
|
|
||||||
if !isRestrictedTokenMember
|
if !isRestrictedTokenMember
|
||||||
.ui-layout-east
|
.ui-layout-east
|
||||||
if showNewChatUI
|
aside.chat(
|
||||||
include ./editor/chat-react
|
ng-controller="ReactChatController"
|
||||||
else
|
)
|
||||||
include ./editor/chat
|
chat(reset-unread-messages="resetUnreadMessages" chat-is-open="chatIsOpen")
|
||||||
|
|
||||||
script(type="text/ng-template", id="genericMessageModalTemplate")
|
script(type="text/ng-template", id="genericMessageModalTemplate")
|
||||||
.modal-header
|
.modal-header
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
aside.chat(
|
|
||||||
ng-controller="ReactChatController"
|
|
||||||
)
|
|
||||||
chat(reset-unread-messages="resetUnreadMessages" chat-is-open="chatIsOpen")
|
|
|
@ -1,53 +0,0 @@
|
||||||
aside.chat(
|
|
||||||
ng-controller="ChatController",
|
|
||||||
ng-if="!anonymous"
|
|
||||||
)
|
|
||||||
.messages(
|
|
||||||
infinite-scroll="loadMoreMessages()"
|
|
||||||
infinite-scroll-disabled="chat.loading || chat.atEnd || chat.errored"
|
|
||||||
infinite-scroll-initialize="ui.chatOpen"
|
|
||||||
infinite-scroll-upwards="true"
|
|
||||||
update-scroll-bottom-on="updateScrollPosition"
|
|
||||||
)
|
|
||||||
.infinite-scroll-inner
|
|
||||||
.loading(ng-show="chat.loading")
|
|
||||||
i.fa.fa-fw.fa-spin.fa-refresh
|
|
||||||
| #{translate("loading")}…
|
|
||||||
.no-messages.text-center.small(ng-show='!chat.loading && chat.messages.length == 0')
|
|
||||||
| #{translate("no_messages")}
|
|
||||||
.first-message.text-center(ng-show='!chat.loading && chat.messages.length == 0')
|
|
||||||
| #{translate("send_first_message")}
|
|
||||||
br
|
|
||||||
i.fa.fa-arrow-down
|
|
||||||
ul.list-unstyled(
|
|
||||||
ng-click="resetUnreadMessages()"
|
|
||||||
)
|
|
||||||
li.message(
|
|
||||||
ng-repeat="message in chat.messages"
|
|
||||||
ng-controller="ChatMessageController"
|
|
||||||
ng-class="{'self': message.user.id == user.id }"
|
|
||||||
)
|
|
||||||
div.date(ng-if="$index == 0 || (message.timestamp - chat.messages[$index - 1].timestamp) > 5 * 60 * 1000") {{ message.timestamp | formatDate:'h:mm a' }} {{ message.timestamp | relativeDate }}
|
|
||||||
div.message-wrapper
|
|
||||||
.name(ng-if="message.user.id != user.id")
|
|
||||||
span(ng-if="message.user.first_name") {{ message.user.first_name }}
|
|
||||||
span(ng-if="!message.user.first_name") {{ message.user.email }}
|
|
||||||
.message(
|
|
||||||
ng-style="getMessageStyle(message.user);"
|
|
||||||
)
|
|
||||||
.arrow(ng-if="message.user.id != user.id" ng-style="getArrowStyle(message.user)")
|
|
||||||
.message-content
|
|
||||||
p(
|
|
||||||
mathjax,
|
|
||||||
mathjax-allow-html="true",
|
|
||||||
ng-repeat="content in message.contents track by $index"
|
|
||||||
)
|
|
||||||
span(ng-bind-html="content | linky:'_blank':{rel: 'noreferrer noopener'}")
|
|
||||||
|
|
||||||
.new-message
|
|
||||||
textarea(
|
|
||||||
placeholder=translate('your_message')+"…",
|
|
||||||
on-enter="sendMessage()",
|
|
||||||
ng-model="newMessageContent",
|
|
||||||
ng-click="resetUnreadMessages()"
|
|
||||||
)
|
|
|
@ -1,37 +0,0 @@
|
||||||
/* eslint-disable
|
|
||||||
max-len,
|
|
||||||
no-return-assign,
|
|
||||||
no-unused-vars,
|
|
||||||
no-useless-escape,
|
|
||||||
*/
|
|
||||||
// TODO: This file was created by bulk-decaffeinate.
|
|
||||||
// Fix any style issues and re-enable lint.
|
|
||||||
/*
|
|
||||||
* decaffeinate suggestions:
|
|
||||||
* DS101: Remove unnecessary use of Array.from
|
|
||||||
* DS102: Remove unnecessary code created because of implicit returns
|
|
||||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
||||||
*/
|
|
||||||
import App from '../base'
|
|
||||||
const DEF_MIN_LENGTH = 20
|
|
||||||
|
|
||||||
const _decodeHTMLEntities = str =>
|
|
||||||
str.replace(/&#(\d+);/g, (match, dec) => String.fromCharCode(dec))
|
|
||||||
|
|
||||||
const _getWrappedWordsString = function(baseStr, wrapperElName, minLength) {
|
|
||||||
let outputStr
|
|
||||||
minLength = minLength || DEF_MIN_LENGTH
|
|
||||||
const words = baseStr.split(' ')
|
|
||||||
|
|
||||||
const wordsWrapped = Array.from(words).map(word =>
|
|
||||||
_decodeHTMLEntities(word).length >= minLength
|
|
||||||
? `<${wrapperElName} class=\"break-word\">${word}</${wrapperElName}>`
|
|
||||||
: word
|
|
||||||
)
|
|
||||||
|
|
||||||
return (outputStr = wordsWrapped.join(' '))
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App.filter('wrapLongWords', () => (input, minLength) =>
|
|
||||||
_getWrappedWordsString(input, 'span', minLength)
|
|
||||||
)
|
|
|
@ -1,52 +0,0 @@
|
||||||
/* eslint-disable
|
|
||||||
max-len,
|
|
||||||
no-return-assign,
|
|
||||||
*/
|
|
||||||
// TODO: This file was created by bulk-decaffeinate.
|
|
||||||
// Fix any style issues and re-enable lint.
|
|
||||||
/*
|
|
||||||
* decaffeinate suggestions:
|
|
||||||
* DS102: Remove unnecessary code created because of implicit returns
|
|
||||||
* DS207: Consider shorter variations of null checks
|
|
||||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
||||||
*/
|
|
||||||
import App from '../../../base'
|
|
||||||
import '../services/chatMessages'
|
|
||||||
|
|
||||||
export default App.controller('ChatController', function(
|
|
||||||
$scope,
|
|
||||||
chatMessages,
|
|
||||||
ide,
|
|
||||||
$location
|
|
||||||
) {
|
|
||||||
$scope.chat = chatMessages.state
|
|
||||||
|
|
||||||
$scope.$watch(
|
|
||||||
'chat.messages',
|
|
||||||
function(messages) {
|
|
||||||
if (messages != null) {
|
|
||||||
return $scope.$emit('updateScrollPosition')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
true
|
|
||||||
) // Deep watch
|
|
||||||
|
|
||||||
$scope.$on('layout:chat:resize', () => $scope.$emit('updateScrollPosition'))
|
|
||||||
|
|
||||||
$scope.$watch('chat.newMessage', function(message) {
|
|
||||||
if (message != null) {
|
|
||||||
return ide.$scope.$broadcast('chat:newMessage', message)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
$scope.resetUnreadMessages = () =>
|
|
||||||
ide.$scope.$broadcast('chat:resetUnreadMessages')
|
|
||||||
|
|
||||||
$scope.sendMessage = function() {
|
|
||||||
const message = $scope.newMessageContent
|
|
||||||
$scope.newMessageContent = ''
|
|
||||||
return chatMessages.sendMessage(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ($scope.loadMoreMessages = () => chatMessages.loadMoreMessages())
|
|
||||||
})
|
|
|
@ -1,58 +0,0 @@
|
||||||
/* eslint-disable
|
|
||||||
max-len,
|
|
||||||
no-return-assign,
|
|
||||||
*/
|
|
||||||
// TODO: This file was created by bulk-decaffeinate.
|
|
||||||
// Fix any style issues and re-enable lint.
|
|
||||||
/*
|
|
||||||
* decaffeinate suggestions:
|
|
||||||
* DS102: Remove unnecessary code created because of implicit returns
|
|
||||||
* DS207: Consider shorter variations of null checks
|
|
||||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
||||||
*/
|
|
||||||
import App from '../../../base'
|
|
||||||
import ColorManager from '../../colors/ColorManager'
|
|
||||||
|
|
||||||
export default App.controller('ChatMessageController', function($scope, ide) {
|
|
||||||
const hslColorConfigs = {
|
|
||||||
borderSaturation:
|
|
||||||
(window.uiConfig != null
|
|
||||||
? window.uiConfig.chatMessageBorderSaturation
|
|
||||||
: undefined) || '70%',
|
|
||||||
borderLightness:
|
|
||||||
(window.uiConfig != null
|
|
||||||
? window.uiConfig.chatMessageBorderLightness
|
|
||||||
: undefined) || '70%',
|
|
||||||
bgSaturation:
|
|
||||||
(window.uiConfig != null
|
|
||||||
? window.uiConfig.chatMessageBgSaturation
|
|
||||||
: undefined) || '60%',
|
|
||||||
bgLightness:
|
|
||||||
(window.uiConfig != null
|
|
||||||
? window.uiConfig.chatMessageBgLightness
|
|
||||||
: undefined) || '97%'
|
|
||||||
}
|
|
||||||
|
|
||||||
const hue = function(user) {
|
|
||||||
if (user == null) {
|
|
||||||
return 0
|
|
||||||
} else {
|
|
||||||
return ColorManager.getHueForUserId(user.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.getMessageStyle = user => ({
|
|
||||||
'border-color': `hsl(${hue(user)}, ${hslColorConfigs.borderSaturation}, ${
|
|
||||||
hslColorConfigs.borderLightness
|
|
||||||
})`,
|
|
||||||
'background-color': `hsl(${hue(user)}, ${hslColorConfigs.bgSaturation}, ${
|
|
||||||
hslColorConfigs.bgLightness
|
|
||||||
})`
|
|
||||||
})
|
|
||||||
|
|
||||||
return ($scope.getArrowStyle = user => ({
|
|
||||||
'border-color': `hsl(${hue(user)}, ${hslColorConfigs.borderSaturation}, ${
|
|
||||||
hslColorConfigs.borderLightness
|
|
||||||
})`
|
|
||||||
}))
|
|
||||||
})
|
|
|
@ -1,6 +1,2 @@
|
||||||
import './controllers/ChatButtonController'
|
import './controllers/ChatButtonController'
|
||||||
import './controllers/ChatController'
|
|
||||||
import './controllers/ChatMessageController'
|
|
||||||
import '../../directives/mathjax'
|
|
||||||
import '../../filters/wrapLongWords'
|
|
||||||
import '../../features/chat/controllers/chat-controller'
|
import '../../features/chat/controllers/chat-controller'
|
||||||
|
|
|
@ -1,162 +0,0 @@
|
||||||
/* eslint-disable
|
|
||||||
max-len,
|
|
||||||
no-return-assign,
|
|
||||||
no-unused-vars,
|
|
||||||
*/
|
|
||||||
// TODO: This file was created by bulk-decaffeinate.
|
|
||||||
// Fix any style issues and re-enable lint.
|
|
||||||
/*
|
|
||||||
* decaffeinate suggestions:
|
|
||||||
* DS101: Remove unnecessary use of Array.from
|
|
||||||
* DS102: Remove unnecessary code created because of implicit returns
|
|
||||||
* DS103: Rewrite code to no longer use __guard__
|
|
||||||
* DS207: Consider shorter variations of null checks
|
|
||||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
||||||
*/
|
|
||||||
import App from '../../../base'
|
|
||||||
import { captureException } from '../../../infrastructure/error-reporter'
|
|
||||||
|
|
||||||
export default App.factory('chatMessages', function($http, ide) {
|
|
||||||
const MESSAGES_URL = `/project/${ide.project_id}/messages`
|
|
||||||
const MESSAGE_LIMIT = 50
|
|
||||||
const CONNECTED_USER_URL = `/project/${ide.project_id}/connected_users`
|
|
||||||
|
|
||||||
const chat = {
|
|
||||||
state: {
|
|
||||||
messages: [],
|
|
||||||
loading: false,
|
|
||||||
atEnd: false,
|
|
||||||
errored: false,
|
|
||||||
nextBeforeTimestamp: null,
|
|
||||||
newMessage: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let justSent = false
|
|
||||||
ide.socket.on('new-chat-message', message => {
|
|
||||||
if (
|
|
||||||
__guard__(message != null ? message.user : undefined, x => x.id) ===
|
|
||||||
ide.$scope.user.id &&
|
|
||||||
justSent
|
|
||||||
) {
|
|
||||||
// Nothing to do
|
|
||||||
} else {
|
|
||||||
ide.$scope.$apply(() => appendMessage(message))
|
|
||||||
}
|
|
||||||
return (justSent = false)
|
|
||||||
})
|
|
||||||
|
|
||||||
chat.sendMessage = function(message) {
|
|
||||||
const body = {
|
|
||||||
content: message,
|
|
||||||
_csrf: window.csrfToken
|
|
||||||
}
|
|
||||||
justSent = true
|
|
||||||
appendMessage({
|
|
||||||
user: ide.$scope.user,
|
|
||||||
content: message,
|
|
||||||
timestamp: Date.now()
|
|
||||||
})
|
|
||||||
return $http.post(MESSAGES_URL, body)
|
|
||||||
}
|
|
||||||
|
|
||||||
chat.loadMoreMessages = function() {
|
|
||||||
if (chat.state.atEnd) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (chat.state.errored) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let url = MESSAGES_URL + `?limit=${MESSAGE_LIMIT}`
|
|
||||||
if (chat.state.nextBeforeTimestamp != null) {
|
|
||||||
url += `&before=${chat.state.nextBeforeTimestamp}`
|
|
||||||
}
|
|
||||||
chat.state.loading = true
|
|
||||||
ide.$scope.$broadcast('chat:more-messages-loading', chat)
|
|
||||||
return $http.get(url).then(function(response) {
|
|
||||||
const messages = response.data != null ? response.data : []
|
|
||||||
chat.state.loading = false
|
|
||||||
if (messages.length < MESSAGE_LIMIT) {
|
|
||||||
chat.state.atEnd = true
|
|
||||||
}
|
|
||||||
if (messages.reverse == null) {
|
|
||||||
captureException(
|
|
||||||
new Error(`messages has no reverse property ${typeof messages}`)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (typeof messages.reverse !== 'function') {
|
|
||||||
captureException(
|
|
||||||
new Error(
|
|
||||||
`messages.reverse not a function ${typeof messages.reverse} ${typeof messages}`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
chat.state.errored = true
|
|
||||||
} else {
|
|
||||||
messages.reverse()
|
|
||||||
prependMessages(messages)
|
|
||||||
chat.state.nextBeforeTimestamp =
|
|
||||||
chat.state.messages[0] != null
|
|
||||||
? chat.state.messages[0].timestamp
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
ide.$scope.$broadcast('chat:more-messages-loaded', chat)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const TIMESTAMP_GROUP_SIZE = 5 * 60 * 1000 // 5 minutes
|
|
||||||
|
|
||||||
const prependMessage = function(message) {
|
|
||||||
const firstMessage = chat.state.messages[0]
|
|
||||||
const shouldGroup =
|
|
||||||
firstMessage != null &&
|
|
||||||
firstMessage.user.id ===
|
|
||||||
__guard__(message != null ? message.user : undefined, x => x.id) &&
|
|
||||||
firstMessage.timestamp - message.timestamp < TIMESTAMP_GROUP_SIZE
|
|
||||||
if (shouldGroup) {
|
|
||||||
firstMessage.timestamp = message.timestamp
|
|
||||||
return firstMessage.contents.unshift(message.content)
|
|
||||||
} else {
|
|
||||||
return chat.state.messages.unshift({
|
|
||||||
user: message.user,
|
|
||||||
timestamp: message.timestamp,
|
|
||||||
contents: [message.content]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var prependMessages = messages =>
|
|
||||||
Array.from(messages.slice(0).reverse()).map(message =>
|
|
||||||
prependMessage(message)
|
|
||||||
)
|
|
||||||
|
|
||||||
var appendMessage = function(message) {
|
|
||||||
chat.state.newMessage = message
|
|
||||||
|
|
||||||
const lastMessage = chat.state.messages[chat.state.messages.length - 1]
|
|
||||||
const shouldGroup =
|
|
||||||
lastMessage != null &&
|
|
||||||
lastMessage.user.id ===
|
|
||||||
__guard__(message != null ? message.user : undefined, x => x.id) &&
|
|
||||||
message.timestamp - lastMessage.timestamp < TIMESTAMP_GROUP_SIZE
|
|
||||||
if (shouldGroup) {
|
|
||||||
lastMessage.timestamp = message.timestamp
|
|
||||||
lastMessage.contents.push(message.content)
|
|
||||||
} else {
|
|
||||||
chat.state.messages.push({
|
|
||||||
user: message.user,
|
|
||||||
timestamp: message.timestamp,
|
|
||||||
contents: [message.content]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
ide.$scope.$broadcast('chat:more-messages-loaded', chat)
|
|
||||||
}
|
|
||||||
|
|
||||||
return chat
|
|
||||||
})
|
|
||||||
|
|
||||||
function __guard__(value, transform) {
|
|
||||||
return typeof value !== 'undefined' && value !== null
|
|
||||||
? transform(value)
|
|
||||||
: undefined
|
|
||||||
}
|
|
Loading…
Reference in a new issue