+ Giant update to multiple users editing notes.
- Edits are done per DOM element, making diffs smaller and faster - Multiple users can now edit the same note witheout it turning into a gaint mess - Caret position is saved better and wont jump around as much + Removed Active sessions text
This commit is contained in:
parent
c61f0c0198
commit
b5ef64485f
@ -592,6 +592,15 @@ padding-right: 10px;
|
|||||||
color: var(--main-accent);
|
color: var(--main-accent);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove indent line on mobile */
|
||||||
|
.note-card-text > ol > ol,
|
||||||
|
.squire-box > ol > ol,
|
||||||
|
.note-card-text > ul > ul,
|
||||||
|
.squire-box > ul > ul
|
||||||
|
{
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -173,7 +173,8 @@
|
|||||||
<span class="status-menu" v-on:click=" hash=0; save()">
|
<span class="status-menu" v-on:click=" hash=0; save()">
|
||||||
|
|
||||||
<span v-if="diffsApplied > 0">
|
<span v-if="diffsApplied > 0">
|
||||||
+{{ diffsApplied }} Unsaved Changes
|
<i class="blue wave square icon"></i>
|
||||||
|
+{{ diffsApplied }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span v-if="usersOnNote > 1" :data-tooltip="`Viewers`" data-position="left center">
|
<span v-if="usersOnNote > 1" :data-tooltip="`Viewers`" data-position="left center">
|
||||||
@ -359,6 +360,8 @@
|
|||||||
const dmp = new DiffMatchPatch.diff_match_patch()
|
const dmp = new DiffMatchPatch.diff_match_patch()
|
||||||
|
|
||||||
import SquireButtonFunctions from '@/mixins/SquireButtonFunctions.js'
|
import SquireButtonFunctions from '@/mixins/SquireButtonFunctions.js'
|
||||||
|
|
||||||
|
let rawNoteText = '' // Used for comparing and generating diffs
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NoteInputPanel',
|
name: 'NoteInputPanel',
|
||||||
@ -390,7 +393,6 @@
|
|||||||
created: '',
|
created: '',
|
||||||
updated: '',
|
updated: '',
|
||||||
shareUsername: null,
|
shareUsername: null,
|
||||||
// diffNoteText: '',
|
|
||||||
statusText: 'saved',
|
statusText: 'saved',
|
||||||
lastNoteHash: null,
|
lastNoteHash: null,
|
||||||
saveDebounce: null, //Prevent save from being called numerous times quickly
|
saveDebounce: null, //Prevent save from being called numerous times quickly
|
||||||
@ -428,6 +430,7 @@
|
|||||||
//Used to restore caret position
|
//Used to restore caret position
|
||||||
lastRange: null,
|
lastRange: null,
|
||||||
startOffset: 0,
|
startOffset: 0,
|
||||||
|
childIndex: null,
|
||||||
|
|
||||||
//Tag Display
|
//Tag Display
|
||||||
allTags: [],
|
allTags: [],
|
||||||
@ -570,33 +573,31 @@
|
|||||||
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
initSquire(){
|
initSquireEvents(){
|
||||||
|
|
||||||
//Set up squire and load note text
|
//Set up squire and load note text
|
||||||
this.setText(this.noteText)
|
this.setText(this.noteText)
|
||||||
|
|
||||||
|
// Use squire box HTML for diff/patch changes
|
||||||
|
rawNoteText = document.getElementById('squire-id').innerHTML
|
||||||
|
|
||||||
//focus on open, not on mobile, it causes the keyboard to pop up, thats annoying
|
//focus on open, not on mobile, it causes the keyboard to pop up, thats annoying
|
||||||
if(!this.$store.getters.getIsUserOnMobile){
|
if(!this.$store.getters.getIsUserOnMobile){
|
||||||
this.editor.focus()
|
this.editor.focus()
|
||||||
this.editor.moveCursorToEnd()
|
this.editor.moveCursorToEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set up websockets after squire is set up
|
|
||||||
setTimeout(() => {
|
|
||||||
this.setupWebSockets()
|
|
||||||
}, 500)
|
|
||||||
|
|
||||||
this.editor.addEventListener('cursor', e => {
|
this.editor.addEventListener('cursor', e => {
|
||||||
|
|
||||||
//Save range to replace cursor if someone else makes an update
|
this.saveCaretPosition(e)
|
||||||
this.lastRange = e.range
|
|
||||||
this.startOffset = parseInt(e.range.startOffset)
|
|
||||||
return
|
|
||||||
})
|
})
|
||||||
|
|
||||||
//Change button states on editor when element is active
|
//Change button states on editor when element is active
|
||||||
//eg; Bold button turns green when on bold text
|
//eg; Bold button turns green when on bold text
|
||||||
this.editor.addEventListener('pathChange', e => this.pathChangeEvent(e))
|
this.editor.addEventListener('pathChange', e => {
|
||||||
|
this.pathChangeEvent(e)
|
||||||
|
this.diffText(e)
|
||||||
|
})
|
||||||
|
|
||||||
//Click Event - Open links when clicked in editor or toggle checks
|
//Click Event - Open links when clicked in editor or toggle checks
|
||||||
this.editor.addEventListener('click', e => {
|
this.editor.addEventListener('click', e => {
|
||||||
@ -681,10 +682,17 @@
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
//Bind event handlers
|
|
||||||
this.editor.addEventListener('keyup', event => {
|
this.editor.addEventListener('keyup', event => {
|
||||||
|
|
||||||
this.onKeyup(event)
|
this.onKeyup(event)
|
||||||
|
this.diffText(event)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.editor.addEventListener('focus', e => {
|
||||||
|
// this.diffText(e)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.editor.addEventListener('blur', e => {
|
||||||
|
this.diffText(e)
|
||||||
})
|
})
|
||||||
|
|
||||||
// this.editor.addEventListener("dragstart", e => {
|
// this.editor.addEventListener("dragstart", e => {
|
||||||
@ -692,12 +700,6 @@
|
|||||||
// console.log(e)
|
// console.log(e)
|
||||||
// if(){}
|
// if(){}
|
||||||
// });
|
// });
|
||||||
|
|
||||||
//Show and hide additional toolbars
|
|
||||||
// this.editor.addEventListener('focus', e => {
|
|
||||||
// })
|
|
||||||
// this.editor.addEventListener('blur', e => {
|
|
||||||
// })
|
|
||||||
},
|
},
|
||||||
openEditAttachment(){
|
openEditAttachment(){
|
||||||
|
|
||||||
@ -760,13 +762,18 @@
|
|||||||
//Setup all responsive vue data
|
//Setup all responsive vue data
|
||||||
this.setupLoadedNoteData(response)
|
this.setupLoadedNoteData(response)
|
||||||
|
|
||||||
this.loading = false
|
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
|
||||||
//Adjust note title size after load
|
//Adjust note title size after load
|
||||||
this.titleResize()
|
this.titleResize()
|
||||||
this.initSquire()
|
this.initSquireEvents()
|
||||||
|
|
||||||
|
//Set up websockets after squire is set up
|
||||||
|
setTimeout(() => {
|
||||||
|
this.initWebsocketEvents()
|
||||||
|
|
||||||
|
this.loading = false
|
||||||
|
}, 500)
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
@ -786,14 +793,11 @@
|
|||||||
this.created = response.data.created
|
this.created = response.data.created
|
||||||
this.updated = response.data.updated
|
this.updated = response.data.updated
|
||||||
this.lastInteractionTimestamp = +new Date
|
this.lastInteractionTimestamp = +new Date
|
||||||
this.noteTitle = ''
|
this.noteTitle = response.data.title || ''
|
||||||
if(response.data.title){
|
|
||||||
this.noteTitle = response.data.title
|
|
||||||
}
|
|
||||||
|
|
||||||
this.noteText = response.data.text
|
this.noteText = response.data.text
|
||||||
this.lastNoteHash = this.hashString( response.data.text )
|
this.lastNoteHash = this.hashString( response.data.text )
|
||||||
// this.diffNoteText = response.data.text
|
|
||||||
|
|
||||||
//Setup note tags
|
//Setup note tags
|
||||||
this.allTags = response.data.tags ? response.data.tags.split(','):[]
|
this.allTags = response.data.tags ? response.data.tags.split(','):[]
|
||||||
@ -811,77 +815,167 @@
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
},
|
||||||
|
generateSelector(el){
|
||||||
|
|
||||||
|
if (!(el instanceof Element))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var path = [];
|
||||||
|
while (el.nodeType === Node.ELEMENT_NODE) {
|
||||||
|
var selector = el.nodeName.toLowerCase();
|
||||||
|
if (el.id) {
|
||||||
|
selector += '#' + el.id;
|
||||||
|
path.unshift(selector);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
var sib = el, nth = 1;
|
||||||
|
while (sib = sib.previousElementSibling) {
|
||||||
|
if (sib.nodeName.toLowerCase() == selector)
|
||||||
|
nth++;
|
||||||
|
}
|
||||||
|
if (nth != 1)
|
||||||
|
selector += ":nth-of-type("+nth+")";
|
||||||
|
}
|
||||||
|
path.unshift(selector);
|
||||||
|
el = el.parentNode;
|
||||||
|
}
|
||||||
|
return path.join(" > ");
|
||||||
},
|
},
|
||||||
//Called on squire event for keyup
|
//Called on squire event for keyup
|
||||||
diffText(event){
|
diffText(event){
|
||||||
|
// console.log(event.type)
|
||||||
|
|
||||||
//Diff the changed lines only
|
const diffEvents = ['keyup','pathChange', 'click']
|
||||||
|
|
||||||
let oldText = this.noteText
|
// only process changes on certain events
|
||||||
// let newText = this.getText()
|
if( !diffEvents.includes(event?.type) ){
|
||||||
let newText = document.getElementById('squire-id').innerHTML
|
return
|
||||||
|
|
||||||
const diff = dmp.diff_main(oldText, newText)
|
|
||||||
// dmp.diff_cleanupSemantic(diff)
|
|
||||||
const patch_list = dmp.patch_make(oldText, newText, diff);
|
|
||||||
const patch_text = dmp.patch_toText(patch_list);
|
|
||||||
|
|
||||||
if(patch_text == ''){ return }
|
|
||||||
|
|
||||||
//Save computed diff text
|
|
||||||
this.noteText = newText
|
|
||||||
|
|
||||||
let newPatch = {
|
|
||||||
id: this.rawTextId,
|
|
||||||
diff: patch_text,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$io.emit('note_diff', newPatch)
|
clearTimeout(this.diffTextTimeout)
|
||||||
},
|
this.diffTextTimeout = setTimeout(() => {
|
||||||
patchText(incomingPatchs){
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
|
|
||||||
if(incomingPatchs == null){ return resolve(true) }
|
// Current Editor Text
|
||||||
if(incomingPatchs.length == 0){ return resolve(true) }
|
const liveEditorElm = document.getElementById('squire-id')
|
||||||
|
|
||||||
// let currentText = this.getText()
|
// virtual element for selecting div
|
||||||
let currentText = document.getElementById('squire-id').innerHTML
|
let virtualEditorElm = document.createElement('div')
|
||||||
|
virtualEditorElm.innerHTML = rawNoteText
|
||||||
|
|
||||||
//Convert text of all new patches into patches array
|
// element at cursor
|
||||||
let patches = []
|
const elmAtCaret = window.getSelection().getRangeAt(0).startContainer.parentNode
|
||||||
incomingPatchs.forEach(patch => {
|
|
||||||
|
|
||||||
if(patch.time <= this.updated){
|
// Remove beginngin selector from path, make it more generic
|
||||||
return
|
const path = this.generateSelector(elmAtCaret).replace('div#squire-id > ','')
|
||||||
|
let workingPath = ''
|
||||||
|
|
||||||
|
// default to entire note text, select down if path
|
||||||
|
let selectedDivText = virtualEditorElm
|
||||||
|
let newSelectedDivText = liveEditorElm
|
||||||
|
|
||||||
|
if( path != ''){
|
||||||
|
|
||||||
|
const pathParts = path.split(' > ')
|
||||||
|
let testedPathParts = []
|
||||||
|
let workingPathParts = []
|
||||||
|
|
||||||
|
for (var i = 0; i < pathParts.length; i++) {
|
||||||
|
|
||||||
|
testedPathParts.push(pathParts[i])
|
||||||
|
let currentTestPath = testedPathParts.join(' > ')
|
||||||
|
// console.log('elm test ',i,currentTestPath)
|
||||||
|
let elmTest = virtualEditorElm.querySelector(currentTestPath)
|
||||||
|
|
||||||
|
if(!elmTest){
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
workingPathParts.push(pathParts[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
patches.push(...dmp.patch_fromText(patch.diff))
|
workingPath = workingPathParts.join(' > ')
|
||||||
})
|
|
||||||
|
if(workingPath){
|
||||||
if(patches.length == 0){
|
// Select text from virtual editor text
|
||||||
return resolve(true)
|
selectedDivText = selectedDivText.querySelector(workingPath)
|
||||||
|
// select text from current editor text
|
||||||
|
newSelectedDivText = newSelectedDivText.querySelector(workingPath)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var results = dmp.patch_apply(patches, currentText);
|
const oldDivText = selectedDivText.innerHTML
|
||||||
let newText = results[0]
|
const newDivText = newSelectedDivText.innerHTML
|
||||||
|
|
||||||
this.noteText = newText
|
if(oldDivText == newDivText){ return }
|
||||||
// this.editor.setHTML(newText)
|
|
||||||
document.getElementById('squire-id').innerHTML = newText
|
|
||||||
|
|
||||||
return resolve(true)
|
const diff = dmp.diff_main(oldDivText, newDivText)
|
||||||
|
const patch_list = dmp.patch_make(oldDivText, newDivText, diff)
|
||||||
|
const patch_text = dmp.patch_toText(patch_list)
|
||||||
|
|
||||||
|
// save raw text for future diffs
|
||||||
|
rawNoteText = liveEditorElm.innerHTML
|
||||||
|
|
||||||
|
let newPatch = {
|
||||||
|
id: this.rawTextId,
|
||||||
|
diff: patch_text,
|
||||||
|
path: path,
|
||||||
|
// testing metrics
|
||||||
|
'old text':oldDivText,
|
||||||
|
'new text':newDivText,
|
||||||
|
'starting path':path,
|
||||||
|
'working path':workingPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('Sending out patch', newPatch)
|
||||||
|
|
||||||
|
this.$io.emit('note_diff', newPatch)
|
||||||
|
}, 100)
|
||||||
|
|
||||||
|
},
|
||||||
|
patchText(incomingPatchs){
|
||||||
|
// console.log('incoming patches ', incomingPatchs)
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
const editorElement = document.getElementById('squire-id')
|
||||||
|
|
||||||
|
// iterate over incoming patches because they apply to specific divs
|
||||||
|
incomingPatchs.forEach(patch => {
|
||||||
|
|
||||||
|
// default to parent element, change to child if set
|
||||||
|
let editedElement = editorElement
|
||||||
|
if(patch.path){
|
||||||
|
editedElement = editorElement.querySelector(patch.path)
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !editedElement ){
|
||||||
|
editedElement = editorElement
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert patch from text and then apply to selected element
|
||||||
|
const patches = dmp.patch_fromText(patch.diff)
|
||||||
|
const patchResults = dmp.patch_apply(patches, editedElement.innerHTML)
|
||||||
|
|
||||||
|
// console.log('Patch results')
|
||||||
|
// console.log([patch.path, editedElement.innerHTML, patchResults[0]])
|
||||||
|
|
||||||
|
// patch changed directly into editor
|
||||||
|
editedElement.innerHTML = patchResults[0]
|
||||||
|
})
|
||||||
|
|
||||||
|
// save editor HTML after change for future comparisons
|
||||||
|
rawNoteText = editorElement.innerHTML
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
return resolve(true)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onKeyup(event){
|
onKeyup(event){
|
||||||
|
|
||||||
this.statusText = 'modified'
|
this.statusText = 'modified'
|
||||||
|
|
||||||
// Small debounce on diff generation
|
|
||||||
clearTimeout(this.diffTextTimeout)
|
|
||||||
this.diffTextTimeout = setTimeout(() => {
|
|
||||||
this.diffText()
|
|
||||||
}, 25)
|
|
||||||
|
|
||||||
//Save after x seconds
|
//Save after x seconds
|
||||||
clearTimeout(this.editDebounce)
|
clearTimeout(this.editDebounce)
|
||||||
this.editDebounce = setTimeout(() => {
|
this.editDebounce = setTimeout(() => {
|
||||||
@ -1030,11 +1124,11 @@
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
destroyWebSockets(){
|
destroyWebSockets(){
|
||||||
// this.$io.removeListener('past_diffs')
|
this.$io.removeListener('past_diffs')
|
||||||
// this.$io.removeListener('update_user_count')
|
this.$io.removeListener('update_user_count')
|
||||||
// this.$io.removeListener('incoming_diff')
|
this.$io.removeListener('incoming_diff')
|
||||||
},
|
},
|
||||||
setupWebSockets(){
|
initWebsocketEvents(){
|
||||||
|
|
||||||
//Tell server to push this note into a room
|
//Tell server to push this note into a room
|
||||||
this.$io.emit('join_room', this.rawTextId )
|
this.$io.emit('join_room', this.rawTextId )
|
||||||
@ -1050,37 +1144,55 @@
|
|||||||
this.diffsApplied = diffSinceLastUpdate.length
|
this.diffsApplied = diffSinceLastUpdate.length
|
||||||
// console.log('Got Diffs Total -> ', diffSinceLastUpdate)
|
// console.log('Got Diffs Total -> ', diffSinceLastUpdate)
|
||||||
}
|
}
|
||||||
|
// console.log(diffSinceLastUpdate)
|
||||||
this.patchText(diffSinceLastUpdate)
|
this.patchText(diffSinceLastUpdate)
|
||||||
|
.then(() => {
|
||||||
|
this.restoreCaretPosition()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
this.$io.on('incoming_diff', incomingDiff => {
|
this.$io.on('incoming_diff', incomingDiff => {
|
||||||
|
|
||||||
//Save current caret position
|
|
||||||
//Find index of child element based on past range
|
|
||||||
const element = window.getSelection().getRangeAt(0).startContainer.parentNode
|
|
||||||
const textLines = document.getElementById('squire-id').children
|
|
||||||
const childIndex = [...textLines].indexOf(element)
|
|
||||||
|
|
||||||
this.patchText([incomingDiff])
|
this.patchText([incomingDiff])
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
this.restoreCaretPosition()
|
||||||
if(childIndex == -1){
|
|
||||||
console.log('Cursor position lost. Div being updated was lost.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//Reset caret position
|
|
||||||
//Find child index of old range and create a new one
|
|
||||||
let allChildren = document.getElementById('squire-id').children
|
|
||||||
const newLine = allChildren[childIndex].firstChild
|
|
||||||
let range = document.createRange()
|
|
||||||
range.setStart(newLine, this.startOffset)
|
|
||||||
range.setEnd(newLine, this.startOffset)
|
|
||||||
this.editor.setSelection(range)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
},
|
},
|
||||||
|
saveCaretPosition(event){
|
||||||
|
|
||||||
|
//Find index of child element based on past range
|
||||||
|
const element = window.getSelection().getRangeAt(0).startContainer.parentNode
|
||||||
|
|
||||||
|
//Save range to replace cursor if someone else makes an update
|
||||||
|
this.lastRange = this.generateSelector(element)
|
||||||
|
this.startOffset = parseInt(event.range.startOffset) || 0
|
||||||
|
|
||||||
|
return
|
||||||
|
},
|
||||||
|
restoreCaretPosition(){
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// This code is intended to restore caret position to previous location
|
||||||
|
// when a third party updates the note.
|
||||||
|
|
||||||
|
if(!this.lastRange){ return resolve(true) }
|
||||||
|
|
||||||
|
const editorElement = document.getElementById('squire-id')
|
||||||
|
const lastElement = editorElement.querySelector(this.lastRange)
|
||||||
|
|
||||||
|
if( !lastElement ){ return resolve(true) }
|
||||||
|
|
||||||
|
let range = document.createRange()
|
||||||
|
range.setStart(lastElement.firstChild, this.startOffset)
|
||||||
|
range.setEnd(lastElement.firstChild, this.startOffset)
|
||||||
|
|
||||||
|
// Set range in editor element
|
||||||
|
this.editor.setSelection(range)
|
||||||
|
|
||||||
|
return resolve(true)
|
||||||
|
})
|
||||||
|
},
|
||||||
titleResize(){
|
titleResize(){
|
||||||
//Resize the title field
|
//Resize the title field
|
||||||
let element = this.$refs.titleTextarea
|
let element = this.$refs.titleTextarea
|
||||||
@ -1102,6 +1214,11 @@
|
|||||||
z-index: 1019;
|
z-index: 1019;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
.status-menu span + span {
|
||||||
|
border-left: 1px solid #ccc;
|
||||||
|
margin-left: 4px;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.font-color-bar {
|
.font-color-bar {
|
||||||
/*width: calc(100% - 8px);*/
|
/*width: calc(100% - 8px);*/
|
||||||
|
@ -36,10 +36,6 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<paste-button />
|
<paste-button />
|
||||||
|
|
||||||
<span class="ui grey text text-fix">
|
|
||||||
Active Sessions {{ $store.getters.getActiveSessions }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -571,7 +567,7 @@
|
|||||||
// @TODO Don't even trigger this if the note wasn't changed
|
// @TODO Don't even trigger this if the note wasn't changed
|
||||||
updateSingleNote(noteId, focuseAndAnimate = true){
|
updateSingleNote(noteId, focuseAndAnimate = true){
|
||||||
|
|
||||||
console.log('updating single note', noteId)
|
// console.log('updating single note', noteId)
|
||||||
|
|
||||||
noteId = parseInt(noteId)
|
noteId = parseInt(noteId)
|
||||||
|
|
||||||
|
@ -114,29 +114,12 @@ io.on('connection', function(socket){
|
|||||||
|
|
||||||
//Emit all sorted diffs to user
|
//Emit all sorted diffs to user
|
||||||
socket.emit('past_diffs', noteDiffs[rawTextId])
|
socket.emit('past_diffs', noteDiffs[rawTextId])
|
||||||
} else {
|
|
||||||
socket.emit('past_diffs', null)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const usersInRoom = io.sockets.adapter.rooms[rawTextId]
|
const usersInRoom = io.sockets.adapter.rooms[rawTextId]
|
||||||
if(usersInRoom){
|
if(usersInRoom){
|
||||||
//Update users in room count
|
//Update users in room count
|
||||||
io.to(rawTextId).emit('update_user_count', usersInRoom.length)
|
io.to(rawTextId).emit('update_user_count', usersInRoom.length)
|
||||||
|
|
||||||
//Debugging text - prints out notes in limbo
|
|
||||||
let noteDiffKeys = Object.keys(noteDiffs)
|
|
||||||
let totalDiffs = 0
|
|
||||||
noteDiffKeys.forEach(diffSetKey => {
|
|
||||||
if(noteDiffs[diffSetKey]){
|
|
||||||
totalDiffs += noteDiffs[diffSetKey].length
|
|
||||||
}
|
|
||||||
})
|
|
||||||
//Debugging Text
|
|
||||||
if(noteDiffKeys.length > 0){
|
|
||||||
console.log('Total notes in limbo -> ', noteDiffKeys.length)
|
|
||||||
console.log('Total Diffs for all notes -> ', totalDiffs)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -162,31 +145,13 @@ io.on('connection', function(socket){
|
|||||||
|
|
||||||
noteDiffs[noteId].push(data)
|
noteDiffs[noteId].push(data)
|
||||||
|
|
||||||
//Remove duplicate diffs if they exist
|
// Go over each user in this note-room
|
||||||
for (var i = noteDiffs[noteId].length - 1; i >= 0; i--) {
|
|
||||||
|
|
||||||
let pastDiff = noteDiffs[noteId][i]
|
|
||||||
|
|
||||||
for (var j = noteDiffs[noteId].length - 1; j >= 0; j--) {
|
|
||||||
let currentDiff = noteDiffs[noteId][j]
|
|
||||||
|
|
||||||
if(i == j){
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if(currentDiff.diff == pastDiff.diff || currentDiff.time == pastDiff.time){
|
|
||||||
console.log('Removing Duplicate')
|
|
||||||
noteDiffs[noteId].splice(i,1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Each user joins a room when they open the app.
|
|
||||||
io.in(noteId).clients((error, clients) => {
|
io.in(noteId).clients((error, clients) => {
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
|
|
||||||
//Go through each client in note room and send them the diff
|
//Go through each client in note-room and send them the diff
|
||||||
clients.forEach(socketId => {
|
clients.forEach(socketId => {
|
||||||
|
// only send off diff if user
|
||||||
if(socketId != socket.id){
|
if(socketId != socket.id){
|
||||||
io.to(socketId).emit('incoming_diff', data)
|
io.to(socketId).emit('incoming_diff', data)
|
||||||
}
|
}
|
||||||
@ -213,7 +178,6 @@ io.on('connection', function(socket){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
noteDiffs[checkpoint.rawTextId] = diffSet.slice(0, sliceTo)
|
noteDiffs[checkpoint.rawTextId] = diffSet.slice(0, sliceTo)
|
||||||
|
|
||||||
if(noteDiffs[checkpoint.rawTextId].length == 0){
|
if(noteDiffs[checkpoint.rawTextId].length == 0){
|
||||||
|
Loading…
Reference in New Issue
Block a user