mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #6628 from overleaf/jk-heartbeat-editor-type-metadata
Add editor metadata to editing-session pings GitOrigin-RevId: f42be772c13f71380d59bae7c447645fe0e16a17
This commit is contained in:
parent
0edd4b7899
commit
9702346edc
8 changed files with 62 additions and 10 deletions
|
@ -4,6 +4,20 @@ const SessionManager = require('../Authentication/SessionManager')
|
||||||
const GeoIpLookup = require('../../infrastructure/GeoIpLookup')
|
const GeoIpLookup = require('../../infrastructure/GeoIpLookup')
|
||||||
const Features = require('../../infrastructure/Features')
|
const Features = require('../../infrastructure/Features')
|
||||||
|
|
||||||
|
const getSegmentation = req => {
|
||||||
|
const segmentation = req.body ? req.body.segmentation : null
|
||||||
|
const cleanedSegmentation = {}
|
||||||
|
if (
|
||||||
|
segmentation &&
|
||||||
|
segmentation.editorType &&
|
||||||
|
typeof segmentation.editorType === 'string' &&
|
||||||
|
segmentation.editorType.length < 100
|
||||||
|
) {
|
||||||
|
cleanedSegmentation.editorType = segmentation.editorType
|
||||||
|
}
|
||||||
|
return cleanedSegmentation
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
updateEditingSession(req, res, next) {
|
updateEditingSession(req, res, next) {
|
||||||
if (!Features.hasFeature('analytics')) {
|
if (!Features.hasFeature('analytics')) {
|
||||||
|
@ -11,6 +25,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
const userId = SessionManager.getLoggedInUserId(req.session)
|
const userId = SessionManager.getLoggedInUserId(req.session)
|
||||||
const { projectId } = req.params
|
const { projectId } = req.params
|
||||||
|
const segmentation = getSegmentation(req)
|
||||||
let countryCode = null
|
let countryCode = null
|
||||||
|
|
||||||
if (userId) {
|
if (userId) {
|
||||||
|
@ -20,7 +35,12 @@ module.exports = {
|
||||||
} else if (geoDetails && geoDetails.country_code) {
|
} else if (geoDetails && geoDetails.country_code) {
|
||||||
countryCode = geoDetails.country_code
|
countryCode = geoDetails.country_code
|
||||||
}
|
}
|
||||||
AnalyticsManager.updateEditingSession(userId, projectId, countryCode)
|
AnalyticsManager.updateEditingSession(
|
||||||
|
userId,
|
||||||
|
projectId,
|
||||||
|
countryCode,
|
||||||
|
segmentation
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
res.sendStatus(202)
|
res.sendStatus(202)
|
||||||
|
|
|
@ -123,7 +123,7 @@ async function setUserPropertyForSession(session, propertyName, propertyValue) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateEditingSession(userId, projectId, countryCode) {
|
function updateEditingSession(userId, projectId, countryCode, segmentation) {
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -139,6 +139,7 @@ function updateEditingSession(userId, projectId, countryCode) {
|
||||||
userId,
|
userId,
|
||||||
projectId,
|
projectId,
|
||||||
countryCode,
|
countryCode,
|
||||||
|
segmentation,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
|
@ -259,7 +259,10 @@ If the project has been renamed please look in your project list for a new proje
|
||||||
})
|
})
|
||||||
|
|
||||||
ide.editingSessionHeartbeat = () => {
|
ide.editingSessionHeartbeat = () => {
|
||||||
eventTracking.editingSessionHeartbeat()
|
const segmentation = {
|
||||||
|
editorType: ide.editorManager.getEditorType(),
|
||||||
|
}
|
||||||
|
eventTracking.editingSessionHeartbeat(segmentation)
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.$on('cursor:editor:update', () => {
|
$scope.$on('cursor:editor:update', () => {
|
||||||
|
|
|
@ -91,6 +91,18 @@ export default Document = (function () {
|
||||||
this._bindToSocketEvents()
|
this._bindToSocketEvents()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
editorType() {
|
||||||
|
if (this.ace) {
|
||||||
|
return 'ace'
|
||||||
|
} else if (this.cm6) {
|
||||||
|
return 'cm6'
|
||||||
|
} else if (this.cm) {
|
||||||
|
return 'cm-rich-text'
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
attachToAce(ace) {
|
attachToAce(ace) {
|
||||||
this.ace = ace
|
this.ace = ace
|
||||||
if (this.doc != null) {
|
if (this.doc != null) {
|
||||||
|
|
|
@ -132,6 +132,13 @@ export default EditorManager = (function () {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getEditorType() {
|
||||||
|
if (!this.$scope.editor.sharejs_doc) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return this.$scope.editor.sharejs_doc.editorType()
|
||||||
|
}
|
||||||
|
|
||||||
showRichText() {
|
showRichText() {
|
||||||
return (
|
return (
|
||||||
this.localStorage(`editor.mode.${this.$scope.project_id}`) ===
|
this.localStorage(`editor.mode.${this.$scope.project_id}`) ===
|
||||||
|
|
|
@ -48,10 +48,11 @@ App.factory('eventTracking', function ($http, localStorage) {
|
||||||
return localStorage(CACHE_KEY, curCache)
|
return localStorage(CACHE_KEY, curCache)
|
||||||
}
|
}
|
||||||
|
|
||||||
const _sendEditingSessionHeartbeat = () =>
|
const _sendEditingSessionHeartbeat = segmentation =>
|
||||||
$http({
|
$http({
|
||||||
url: `/editingSession/${window.project_id}`,
|
url: `/editingSession/${window.project_id}`,
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
|
data: { segmentation },
|
||||||
headers: {
|
headers: {
|
||||||
'X-CSRF-Token': window.csrfToken,
|
'X-CSRF-Token': window.csrfToken,
|
||||||
},
|
},
|
||||||
|
@ -69,14 +70,14 @@ App.factory('eventTracking', function ($http, localStorage) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
editingSessionHeartbeat() {
|
editingSessionHeartbeat(segmentation) {
|
||||||
sl_console.log('[Event] heartbeat trigger')
|
sl_console.log('[Event] heartbeat trigger', segmentation)
|
||||||
if (!(nextHeartbeat <= new Date())) {
|
if (!(nextHeartbeat <= new Date())) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sl_console.log('[Event] send heartbeat request')
|
sl_console.log('[Event] send heartbeat request', segmentation)
|
||||||
_sendEditingSessionHeartbeat()
|
_sendEditingSessionHeartbeat(segmentation)
|
||||||
|
|
||||||
heartbeatsSent++
|
heartbeatsSent++
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,11 @@ describe('AnalyticsController', function () {
|
||||||
projectId: 'a project id',
|
projectId: 'a project id',
|
||||||
},
|
},
|
||||||
session: {},
|
session: {},
|
||||||
|
body: {
|
||||||
|
segmentation: {
|
||||||
|
editorType: 'abc',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
this.GeoIpLookup.getDetails = sinon
|
this.GeoIpLookup.getDetails = sinon
|
||||||
.stub()
|
.stub()
|
||||||
|
@ -54,7 +59,7 @@ describe('AnalyticsController', function () {
|
||||||
this.controller.updateEditingSession(this.req, this.res)
|
this.controller.updateEditingSession(this.req, this.res)
|
||||||
|
|
||||||
this.AnalyticsManager.updateEditingSession
|
this.AnalyticsManager.updateEditingSession
|
||||||
.calledWith('1234', 'a project id', 'XY')
|
.calledWith('1234', 'a project id', 'XY', { editorType: 'abc' })
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
|
|
@ -146,10 +146,12 @@ describe('AnalyticsManager', function () {
|
||||||
it('updateEditingSession', function () {
|
it('updateEditingSession', function () {
|
||||||
const projectId = '789ghi'
|
const projectId = '789ghi'
|
||||||
const countryCode = 'fr'
|
const countryCode = 'fr'
|
||||||
|
const segmentation = { editorType: 'abc' }
|
||||||
this.AnalyticsManager.updateEditingSession(
|
this.AnalyticsManager.updateEditingSession(
|
||||||
this.fakeUserId,
|
this.fakeUserId,
|
||||||
projectId,
|
projectId,
|
||||||
countryCode
|
countryCode,
|
||||||
|
segmentation
|
||||||
)
|
)
|
||||||
sinon.assert.calledWithMatch(
|
sinon.assert.calledWithMatch(
|
||||||
this.analyticsEditingSessionQueue.add,
|
this.analyticsEditingSessionQueue.add,
|
||||||
|
@ -158,6 +160,7 @@ describe('AnalyticsManager', function () {
|
||||||
userId: this.fakeUserId,
|
userId: this.fakeUserId,
|
||||||
projectId,
|
projectId,
|
||||||
countryCode,
|
countryCode,
|
||||||
|
segmentation,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue