Add annotationAuthorName property to annotation items

And pass both `authorName` and `lastCreatedByUser` to the PDF reader.
The former can either come from `createdByUser` or be set directly on
the item (for group annotations dragged to personal libraries).
This commit is contained in:
Dan Stillman 2022-02-08 04:33:33 -05:00
parent 60f9a0417f
commit 67451dffd5
6 changed files with 67 additions and 12 deletions

View file

@ -118,9 +118,16 @@ Zotero.Annotations = new function () {
o.type = item.annotationType;
o.isExternal = item.annotationIsExternal;
var isAuthor = !item.createdByUserID || item.createdByUserID == Zotero.Users.getCurrentUserID();
if (!o.isExternal && item.library.libraryType == 'group') {
var isGroup = item.library.libraryType == 'group';
if (item.annotationAuthorName) {
o.authorName = item.annotationAuthorName;
}
else if (!o.isExternal && isGroup) {
o.authorName = Zotero.Users.getName(item.createdByUserID);
}
if (o.authorName && isGroup) {
o.lastModifiedByUser = Zotero.Users.getName(item.lastModifiedByUserID)
}
o.readOnly = o.isExternal || !isAuthor;
if (o.type == 'highlight') {
o.text = item.annotationText;
@ -197,6 +204,7 @@ Zotero.Annotations = new function () {
item._requireData('annotation');
item._requireData('annotationDeferred');
item.annotationType = json.type;
item.annotationAuthorName = json.authorName || '';
if (json.type == 'highlight') {
item.annotationText = json.text;
}

View file

@ -67,6 +67,7 @@ Zotero.Item = function(itemTypeOrID) {
// loadAnnotation
this._annotationType = null;
this._annotationAuthorName = null;
this._annotationText = null;
this._annotationImage = null;
this._annotationComment = null;
@ -1847,6 +1848,7 @@ Zotero.Item.prototype._saveData = Zotero.Promise.coroutine(function* (env) {
throw new Error(`Invalid annotation type '${type}'`);
}
let authorName = this._getLatestField('annotationAuthorName');
let text = this._getLatestField('annotationText');
let comment = this._getLatestField('annotationComment');
let color = this._getLatestField('annotationColor');
@ -1856,14 +1858,15 @@ Zotero.Item.prototype._saveData = Zotero.Promise.coroutine(function* (env) {
let isExternal = this._getLatestField('annotationIsExternal');
let sql = "REPLACE INTO itemAnnotations "
+ "(itemID, parentItemID, type, text, comment, color, pageLabel, sortIndex, position, isExternal) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+ "(itemID, parentItemID, type, authorName, text, comment, color, pageLabel, sortIndex, position, isExternal) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
yield Zotero.DB.queryAsync(
sql,
[
itemID,
parentItemID,
typeID,
authorName || null,
text || null,
comment || null,
color || null,
@ -3706,7 +3709,7 @@ Zotero.Item.prototype.clearBestAttachmentState = function () {
////////////////////////////////////////////////////////
// Main annotation properties (required for items list display)
for (let name of ['type', 'text', 'comment', 'color', 'pageLabel', 'sortIndex', 'isExternal']) {
for (let name of ['type', 'authorName', 'text', 'comment', 'color', 'pageLabel', 'sortIndex', 'isExternal']) {
let field = 'annotation' + name[0].toUpperCase() + name.substr(1);
Zotero.defineProperty(Zotero.Item.prototype, field, {
get: function () {
@ -4948,6 +4951,7 @@ Zotero.Item.prototype.fromJSON = function (json, options = {}) {
//
case 'annotationType':
case 'annotationType':
case 'annotationAuthorName':
case 'annotationText':
case 'annotationComment':
case 'annotationColor':
@ -5224,6 +5228,7 @@ Zotero.Item.prototype.toJSON = function (options = {}) {
if (this.isAnnotation()) {
let type = this.annotationType;
obj.annotationType = type;
obj.annotationAuthorName = this.annotationAuthorName || '';
if (type == 'highlight') {
obj.annotationText = this.annotationText || '';
}

View file

@ -495,8 +495,8 @@ Zotero.Items = function() {
this._loadAnnotations = async function (libraryID, ids, idSQL) {
var sql = "SELECT itemID, IA.parentItemID, IA.type, IA.text, IA.comment, IA.color, "
+ "IA.sortIndex, IA.isExternal "
var sql = "SELECT itemID, IA.parentItemID, IA.type, IA.authorName, IA.text, IA.comment, "
+ "IA.color, IA.sortIndex, IA.isExternal "
+ "FROM items JOIN itemAnnotations IA USING (itemID) "
+ "WHERE libraryID=?" + idSQL;
var params = [libraryID];
@ -537,11 +537,12 @@ Zotero.Items = function() {
throw new Error(`Unknown annotation type id ${typeID}`);
}
item._annotationType = type;
item._annotationText = row.getResultByIndex(3);
item._annotationComment = row.getResultByIndex(4);
item._annotationColor = row.getResultByIndex(5);
item._annotationSortIndex = row.getResultByIndex(6);
item._annotationIsExternal = !!row.getResultByIndex(7);
item._annotationAuthorName = row.getResultByIndex(3);
item._annotationText = row.getResultByIndex(4);
item._annotationComment = row.getResultByIndex(5);
item._annotationColor = row.getResultByIndex(6);
item._annotationSortIndex = row.getResultByIndex(7);
item._annotationIsExternal = !!row.getResultByIndex(8);
item._loaded.annotation = true;
item._clearChanged('annotation');

View file

@ -3422,6 +3422,14 @@ Zotero.Schema = new function(){
yield Zotero.DB.queryAsync("PRAGMA legacy_alter_table=OFF");
}
else if (i == 119) {
yield Zotero.DB.queryAsync("CREATE TABLE itemAnnotationsTemp (\n itemID INTEGER PRIMARY KEY,\n parentItemID INT NOT NULL,\n type INTEGER NOT NULL,\n authorName TEXT,\n text TEXT,\n comment TEXT,\n color TEXT,\n pageLabel TEXT,\n sortIndex TEXT NOT NULL,\n position TEXT NOT NULL,\n isExternal INT NOT NULL,\n FOREIGN KEY (itemID) REFERENCES items(itemID) ON DELETE CASCADE,\n FOREIGN KEY (parentItemID) REFERENCES itemAttachments(itemID)\n)");
yield Zotero.DB.queryAsync("INSERT INTO itemAnnotationsTemp SELECT itemID, parentItemID, type, '', text, comment, color, pageLabel, sortIndex, position, isExternal FROM itemAnnotations");
yield Zotero.DB.queryAsync("DROP TABLE itemAnnotations");
yield Zotero.DB.queryAsync("ALTER TABLE itemAnnotationsTemp RENAME TO itemAnnotations");
yield Zotero.DB.queryAsync("CREATE INDEX itemAnnotations_parentItemID ON itemAnnotations(parentItemID)");
}
// If breaking compatibility or doing anything dangerous, clear minorUpdateFrom
}

View file

@ -1,4 +1,4 @@
-- 117
-- 119
-- Copyright (c) 2009 Center for History and New Media
-- George Mason University, Fairfax, Virginia, USA
@ -224,6 +224,7 @@ CREATE TABLE itemAnnotations (
itemID INTEGER PRIMARY KEY,
parentItemID INT NOT NULL,
type INTEGER NOT NULL,
authorName TEXT,
text TEXT,
comment TEXT,
color TEXT,

View file

@ -256,6 +256,38 @@ describe("Zotero.Annotations", function() {
skipEditCheck: true
});
});
it("should generate an object for a highlight by another user modified by the current user in a group library", async function () {
await Zotero.Users.setName(1, 'My Name');
await Zotero.Users.setName(12345, 'Their Name');
var annotation = await createAnnotation('highlight', groupAttachment);
annotation.createdByUserID = 12345;
annotation.lastModifiedByUserID = 1;
await annotation.saveTx({
skipEditCheck: true
});
var json = await Zotero.Annotations.toJSON(annotation);
assert.equal(json.authorName, 'Their Name');
assert.equal(json.lastModifiedByUser, 'My Name');
await annotation.eraseTx({
skipEditCheck: true
});
});
it("should generate an object for an annotation by another user in a personal library", async function () {
var annotation = await createAnnotation('highlight', attachment);
annotation.annotationAuthorName = 'First Last';
await annotation.saveTx();
var json = await Zotero.Annotations.toJSON(annotation);
assert.equal(json.authorName, 'First Last');
await annotation.eraseTx();
});
});