store annotations in db and sync with peers
This commit is contained in:
parent
131a6a3215
commit
e0cba14d6a
21 changed files with 385 additions and 63 deletions
|
|
@ -46,14 +46,22 @@ oml.ui.annotation = function(annotation, $iframe) {
|
|||
note.value = data.value
|
||||
note.modified = (new Date).toISOString()
|
||||
} else {
|
||||
annotation.notes.push({
|
||||
annotation.notes.push(note = {
|
||||
created: data.created || (new Date).toISOString(),
|
||||
modified: (new Date).toISOString(),
|
||||
id: data.id,
|
||||
user: '',
|
||||
value: data.value
|
||||
})
|
||||
}
|
||||
oml.api.editNote({
|
||||
item: oml.user.ui.item,
|
||||
annotation: annotation.id,
|
||||
notes: {
|
||||
created: note.created,
|
||||
modified: note.modified,
|
||||
value: note.value
|
||||
}
|
||||
})
|
||||
that.triggerEvent('change')
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
oml.ui.annotationPanel = function() {
|
||||
var ui = oml.user.ui;
|
||||
|
||||
var ui = oml.user.ui;
|
||||
|
||||
|
|
@ -28,6 +29,7 @@ oml.ui.annotationPanel = function() {
|
|||
click: function() {
|
||||
var $annotation = oml.$ui.annotationFolder.find('.OMLAnnotation.selected')
|
||||
$annotation.length && $annotation.delete()
|
||||
$deleteQuote.options({disabled: true})
|
||||
}
|
||||
}).appendTo($bar);
|
||||
|
||||
|
|
@ -80,6 +82,21 @@ oml.ui.annotationPanel = function() {
|
|||
}, function(result) {
|
||||
oml.ui.exportAnnotationsDialog(result.data).open()
|
||||
})
|
||||
} else {
|
||||
console.log('click', id, data)
|
||||
}
|
||||
},
|
||||
change: function(data) {
|
||||
var id = data.id;
|
||||
console.log('change', data)
|
||||
if (id == 'show') {
|
||||
console.log('show', data)
|
||||
oml.UI.set({annotationsShow: data.checked[0].id});
|
||||
} else if (id == 'sort') {
|
||||
console.log('sort', data)
|
||||
oml.UI.set({annotationsSort: data.checked[0].id});
|
||||
} else {
|
||||
console.log('change', id, data)
|
||||
}
|
||||
}
|
||||
}).appendTo($bar);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ oml.ui.exportAnnotationsDialog = function(data) {
|
|||
var annotations = oml.$ui.viewer.getAnnotations()
|
||||
var text = 'Annotations for ' + data.title + ' (' + data.author.join(', ') + ')\n\n\n\n'
|
||||
text += annotations.map(function(annotation) {
|
||||
var text = 'Quote:\n\n' + annotation.text
|
||||
var page = annotation.pageLabel || annotation.page
|
||||
var text = 'Quote' + (page ? ' Page ' + page : '' )+ ':\n\n' + annotation.text
|
||||
if (annotation.notes.length) {
|
||||
text += '\n\nNotes:\n' + annotation.notes.map(function(note) {
|
||||
return note.value
|
||||
|
|
|
|||
|
|
@ -15,6 +15,12 @@ oml.ui.viewer = function() {
|
|||
},
|
||||
oml_showannotations: function() {
|
||||
panel.toggleElement(1);
|
||||
},
|
||||
oml_sortannotations: function(data) {
|
||||
that.renderAnnotations()
|
||||
},
|
||||
oml_annotationusers: function(data) {
|
||||
that.renderAnnotations()
|
||||
}
|
||||
}),
|
||||
panel = Ox.SplitPanel({
|
||||
|
|
@ -40,38 +46,81 @@ oml.ui.viewer = function() {
|
|||
$iframe, item;
|
||||
|
||||
function loadAnnotations(callback) {
|
||||
annotations = JSON.parse(localStorage[item + '.annotations'] || '[]')
|
||||
annotations.forEach(function(data) {
|
||||
if (data.comments && !data.notes) {
|
||||
data.notes = data.comments
|
||||
delete data.comments
|
||||
}
|
||||
data.notes = data.notes || [];
|
||||
})
|
||||
callback && callback(annotations)
|
||||
}
|
||||
function saveAnnotations(data) {
|
||||
if (data) {
|
||||
data.created = data.created || (new Date).toISOString();
|
||||
if (data.comments && !data.notes) {
|
||||
data.notes = data.comments
|
||||
delete data.comments
|
||||
}
|
||||
data.notes = data.notes || [];
|
||||
annotations.push(data);
|
||||
if (localStorage[item + '.annotations']) {
|
||||
annotations = JSON.parse(localStorage[item + '.annotations'] || '[]')
|
||||
var ids = []
|
||||
annotations.forEach(function(data) {
|
||||
if (data.comments && !data.notes) {
|
||||
data.notes = data.comments
|
||||
delete data.comments
|
||||
}
|
||||
if (!Ox.contains(ids, data.id)) {
|
||||
ids.push(data.id)
|
||||
var note
|
||||
if (data.notes && data.notes.length) {
|
||||
note = data.notes[0]
|
||||
delete data.notes
|
||||
}
|
||||
addAnnotation(data, false)
|
||||
if (note) {
|
||||
data.notes = [note]
|
||||
} else {
|
||||
data.notes = []
|
||||
}
|
||||
if (data.notes.length) {
|
||||
var note = data.notes[0]
|
||||
oml.api.editNote({
|
||||
item: ui.item,
|
||||
annotation: data.id,
|
||||
notes: {
|
||||
created: note.created,
|
||||
modified: note.modified,
|
||||
value: note.value
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
console.log('ignore second time', data)
|
||||
}
|
||||
})
|
||||
localStorage[oml.user.ui.item + '.annotations_'] = localStorage[oml.user.ui.item + '.annotations']
|
||||
delete localStorage[oml.user.ui.item + '.annotations']
|
||||
callback && callback(annotations)
|
||||
} else {
|
||||
oml.api.getAnnotations({
|
||||
id: ui.item
|
||||
}, function(result) {
|
||||
console.log(result)
|
||||
annotations = result.data.annotations
|
||||
callback && callback(annotations)
|
||||
})
|
||||
}
|
||||
localStorage[item + '.annotations'] = JSON.stringify(annotations)
|
||||
}
|
||||
function addAnnotation(data, save) {
|
||||
var a = Ox.extend({}, data)
|
||||
a.created = a.created || (new Date).toISOString();
|
||||
a.item = ui.item
|
||||
if (save !== false) {
|
||||
oml.api.addAnnotation(a)
|
||||
}
|
||||
data.notes = data.notes || [];
|
||||
annotations.push(data);
|
||||
}
|
||||
|
||||
function removeAnnotation(id) {
|
||||
annotations = annotations.filter(function(annotation) {
|
||||
return annotation.id != id
|
||||
oml.api.removeAnnotation({
|
||||
item: ui.item,
|
||||
annotation: id
|
||||
}, function(result) {
|
||||
annotations = annotations.filter(function(annotation) {
|
||||
return annotation.id != id
|
||||
})
|
||||
})
|
||||
saveAnnotations()
|
||||
}
|
||||
|
||||
var annotationEvents = {
|
||||
change: function() {
|
||||
saveAnnotations()
|
||||
change: function(data) {
|
||||
// console.log('change', data)
|
||||
},
|
||||
'delete': function(data) {
|
||||
oml.$ui.annotationFolder.find('#a-' + data.id).remove()
|
||||
|
|
@ -95,14 +144,14 @@ oml.ui.viewer = function() {
|
|||
}).onMessage(function(data, event) {
|
||||
console.log('got', event, data)
|
||||
if (event == 'addAnnotation') {
|
||||
saveAnnotations(data);
|
||||
addAnnotation(data);
|
||||
var $annotation = oml.ui.annotation(data, $iframe).bindEvent(annotationEvents)
|
||||
oml.$ui.annotationFolder.append($annotation);
|
||||
$annotation.annotate();
|
||||
oml.$ui.annotationPanel.updateSelection(false)
|
||||
} else if (event == 'removeAnnotation') {
|
||||
oml.$ui.annotationFolder.find('#a-' + data.id).remove()
|
||||
removeAnnotation(data.id)
|
||||
data.id && removeAnnotation(data.id)
|
||||
} else if (event == 'selectAnnotation') {
|
||||
if (data.id) {
|
||||
var $annotation = oml.$ui.annotationFolder.find('#a-' + data.id)
|
||||
|
|
@ -115,18 +164,13 @@ oml.ui.viewer = function() {
|
|||
} else if (event == 'selectText') {
|
||||
oml.$ui.annotationPanel.updateSelection(data)
|
||||
} else {
|
||||
console.log('trigger unknwon event', event, data)
|
||||
that.triggerEvent(event, data);
|
||||
}
|
||||
}).bindEvent({
|
||||
init: function() {
|
||||
loadAnnotations(function(annotations) {
|
||||
that.renderAnnotations()
|
||||
// fixme: trigger loaded event from reader instead?
|
||||
setTimeout(function() {
|
||||
that.postMessage('addAnnotations', {
|
||||
annotations: annotations
|
||||
})
|
||||
}, 500)
|
||||
})
|
||||
}
|
||||
}).appendTo(frame);
|
||||
|
|
@ -145,12 +189,34 @@ oml.ui.viewer = function() {
|
|||
return annotations;
|
||||
}
|
||||
that.renderAnnotations = function() {
|
||||
var sortKey = ui.sortAnnotations
|
||||
if (sortKey == 'date') {
|
||||
sortKey = 'created'
|
||||
}
|
||||
if (sortKey == 'date') {
|
||||
sortKey = 'created'
|
||||
}
|
||||
if (sortKey == 'quote') {
|
||||
sortKey = 'text'
|
||||
}
|
||||
annotations = Ox.sortBy(annotations, sortKey)
|
||||
oml.$ui.annotationFolder.empty();
|
||||
Ox.sortBy(annotations, ui.sortAnnotations);
|
||||
var visibleAnnotations = [];
|
||||
annotations.forEach(function(data) {
|
||||
var $annotation = oml.ui.annotation(data, $iframe).bindEvent(annotationEvents)
|
||||
oml.$ui.annotationFolder.append($annotation);
|
||||
//that.postMessage('removeAnnotation', {id: data.id})
|
||||
if (ui.showAnnotationUsers == 'all' || data.user == oml.user.id) {
|
||||
var $annotation = oml.ui.annotation(data, $iframe).bindEvent(annotationEvents)
|
||||
oml.$ui.annotationFolder.append($annotation);
|
||||
visibleAnnotations.push(data)
|
||||
}
|
||||
})
|
||||
// fixme: trigger loaded event from reader instead?
|
||||
setTimeout(function() {
|
||||
that.postMessage('addAnnotations', {
|
||||
annotations: visibleAnnotations,
|
||||
replace: true
|
||||
})
|
||||
}, 500)
|
||||
}
|
||||
return that.updateElement();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,6 +22,12 @@ Ox.load({
|
|||
} else if (event == 'addAnnotation') {
|
||||
createAnnotation()
|
||||
} else if (event == 'addAnnotations') {
|
||||
if (data.replace) {
|
||||
annotations.forEach(function(a) {
|
||||
reader.rendition.annotations.remove(a.cfiRange)
|
||||
})
|
||||
annotations = []
|
||||
}
|
||||
data.annotations.forEach(function(annotation) {
|
||||
annotations.push(annotation)
|
||||
renderAnnotation(annotation)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ Ox.load({
|
|||
}
|
||||
}, function() {
|
||||
Ox.$parent.bindMessage(function(data, event) {
|
||||
console.log('got', event, 'data', data)
|
||||
if (event == 'selectAnnotation') {
|
||||
var annotation = annotations.filter(function(a) { return a.id == data.id })[0]
|
||||
var delay = 0
|
||||
|
|
@ -20,7 +19,7 @@ Ox.load({
|
|||
PDFViewerApplication.pdfViewer.currentPageNumber = annotation.page;
|
||||
delay = 250
|
||||
}
|
||||
setTimeout(function() {
|
||||
annotation && setTimeout(function() {
|
||||
var el = document.querySelector('.a' + annotation.id);
|
||||
if (el && !isInView(el)) {
|
||||
document.querySelector('#viewerContainer').scrollTop = el.offsetTop + el.parentElement.offsetTop - 64;
|
||||
|
|
@ -30,12 +29,20 @@ Ox.load({
|
|||
} else if (event == 'addAnnotation') {
|
||||
createAnnotation()
|
||||
} else if (event == 'addAnnotations') {
|
||||
if (data.replace) {
|
||||
document.querySelectorAll('.oml-annotation').forEach(function(a) {
|
||||
a.remove()
|
||||
})
|
||||
annotations = []
|
||||
}
|
||||
data.annotations.forEach(function(annotation) {
|
||||
annotations.push(annotation)
|
||||
renderAnnotation(annotation)
|
||||
})
|
||||
} else if (event == 'removeAnnotation') {
|
||||
removeAnnotation(data.id)
|
||||
} else {
|
||||
console.log('got', event, 'data', data)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
@ -96,6 +103,7 @@ function getHighlight() {
|
|||
var position = [pageNumber].concat(Ox.sort(selected.map(function(c) { return [c[1], c[0]]}))[0]);
|
||||
return {
|
||||
page: pageNumber,
|
||||
pageLabel: PDFViewerApplication.pdfViewer.currentPageLabel,
|
||||
position: position,
|
||||
coords: selected,
|
||||
text: text,
|
||||
|
|
@ -176,7 +184,7 @@ function deselectAllAnnotations() {
|
|||
g.classList.remove('selected')
|
||||
g.style.backgroundColor = 'yellow'
|
||||
var id = $(g).parents('.oml-annotation').data('id')
|
||||
console.log('deselect', g, id)
|
||||
//console.log('deselect', g, id)
|
||||
if (!Ox.contains(ids, id)) {
|
||||
ids.push(id)
|
||||
Ox.$parent.postMessage('selectAnnotation', {id: null})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue