parent
8671e1edc9
commit
bff2067afd
|
|
@ -71,8 +71,11 @@ import {
|
|||
getLinesInNote,
|
||||
} from "./utils/note";
|
||||
import {
|
||||
getAnnotationByLinkTarget,
|
||||
getLinkTargetByAnnotation,
|
||||
getNoteLinkInboundRelation,
|
||||
getNoteLinkOutboundRelation,
|
||||
linkAnnotationToTarget,
|
||||
updateNoteLinkRelation,
|
||||
} from "./utils/relation";
|
||||
|
||||
|
|
@ -162,6 +165,9 @@ const relation = {
|
|||
getNoteLinkInboundRelation,
|
||||
getNoteLinkOutboundRelation,
|
||||
updateNoteLinkRelation,
|
||||
linkAnnotationToTarget,
|
||||
getLinkTargetByAnnotation,
|
||||
getAnnotationByLinkTarget,
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ import Dexie from "dexie";
|
|||
|
||||
const db = new Dexie("BN_Two_Way_Relation") as Dexie & {
|
||||
link: Dexie.Table<LinkModel>;
|
||||
annotation: Dexie.Table<AnnotationModel>;
|
||||
};
|
||||
|
||||
db.version(1).stores({
|
||||
db.version(2).stores({
|
||||
link: "++id, fromLibID, fromKey, toLibID, toKey, fromLine, toLine, toSection, url",
|
||||
annotation: "++id, fromLibID, fromKey, toLibID, toKey, url",
|
||||
});
|
||||
|
||||
console.log("Using Dexie v" + Dexie.semVer, db);
|
||||
|
|
@ -31,9 +33,9 @@ async function rebuildLinkForNote(
|
|||
|
||||
const collection = db.link.where({ fromLibID, fromKey });
|
||||
const oldOutboundLinks = await collection.toArray();
|
||||
collection.delete().then((deleteCount) => {
|
||||
await collection.delete().then((deleteCount) => {
|
||||
console.log("Deleted " + deleteCount + " objects");
|
||||
bulkAddLink(links);
|
||||
return bulkAddLink(links);
|
||||
});
|
||||
return {
|
||||
oldOutboundLinks,
|
||||
|
|
@ -50,6 +52,27 @@ async function getInboundLinks(toLibID: number, toKey: string) {
|
|||
return db.link.where({ toLibID, toKey }).toArray();
|
||||
}
|
||||
|
||||
async function linkAnnotationToTarget(model: AnnotationModel) {
|
||||
console.log("linkAnnotationToTarget", model);
|
||||
const collection = db.annotation.where({
|
||||
fromLibID: model.fromLibID,
|
||||
fromKey: model.fromKey,
|
||||
});
|
||||
await collection.delete().then(() => {
|
||||
return db.annotation.add(model);
|
||||
});
|
||||
}
|
||||
|
||||
async function getLinkTargetByAnnotation(fromLibID: number, fromKey: string) {
|
||||
console.log("getLinkTargetByAnnotation", fromLibID, fromKey);
|
||||
return db.annotation.get({ fromLibID, fromKey });
|
||||
}
|
||||
|
||||
async function getAnnotationByLinkTarget(toLibID: number, toKey: string) {
|
||||
console.log("getAnnotationByLinkTarget", toLibID, toKey);
|
||||
return db.annotation.get({ toLibID, toKey });
|
||||
}
|
||||
|
||||
interface LinkModel {
|
||||
fromLibID: number;
|
||||
fromKey: string;
|
||||
|
|
@ -61,6 +84,14 @@ interface LinkModel {
|
|||
url: string;
|
||||
}
|
||||
|
||||
interface AnnotationModel {
|
||||
fromLibID: number;
|
||||
fromKey: string;
|
||||
toLibID: number;
|
||||
toKey: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
// Handle messages from the main thread and send responses back for await
|
||||
onmessage = async (event) => {
|
||||
const { type, jobID, data } = event.data;
|
||||
|
|
@ -105,6 +136,27 @@ onmessage = async (event) => {
|
|||
result: await getInboundLinks(data.toLibID, data.toKey),
|
||||
});
|
||||
break;
|
||||
case "linkAnnotationToTarget":
|
||||
postMessage({
|
||||
type,
|
||||
jobID,
|
||||
result: await linkAnnotationToTarget(data),
|
||||
});
|
||||
break;
|
||||
case "getLinkTargetByAnnotation":
|
||||
postMessage({
|
||||
type,
|
||||
jobID,
|
||||
result: await getLinkTargetByAnnotation(data.fromLibID, data.fromKey),
|
||||
});
|
||||
break;
|
||||
case "getAnnotationByLinkTarget":
|
||||
postMessage({
|
||||
type,
|
||||
jobID,
|
||||
result: await getAnnotationByLinkTarget(data.toLibID, data.toKey),
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export function registerReaderAnnotationButton() {
|
|||
createNoteFromAnnotation(
|
||||
reader._item.libraryID,
|
||||
annotationData.id,
|
||||
(e as MouseEvent).shiftKey ? "builtin" : "auto",
|
||||
(e as MouseEvent).shiftKey ? "window" : "tab",
|
||||
);
|
||||
e.preventDefault();
|
||||
},
|
||||
|
|
@ -54,7 +54,7 @@ export function registerReaderAnnotationButton() {
|
|||
async function createNoteFromAnnotation(
|
||||
libraryID: number,
|
||||
itemKey: string,
|
||||
openMode: "builtin" | "auto" = "auto",
|
||||
openMode: "window" | "tab" | undefined,
|
||||
) {
|
||||
const annotationItem = Zotero.Items.getByLibraryAndKey(
|
||||
libraryID,
|
||||
|
|
@ -63,15 +63,27 @@ async function createNoteFromAnnotation(
|
|||
if (!annotationItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the annotation has a note link tag
|
||||
const annotationTags = annotationItem.getTags().map((_) => _.tag);
|
||||
const linkRegex = new RegExp("^zotero://note/(.*)$");
|
||||
for (const tag of annotationTags) {
|
||||
if (linkRegex.test(tag)) {
|
||||
const linkParams = getNoteLinkParams(tag);
|
||||
if (linkParams.noteItem) {
|
||||
addon.hooks.onOpenNote(linkParams.noteItem.id, openMode, {
|
||||
addon.hooks.onOpenNote(linkParams.noteItem.id, openMode || "tab", {
|
||||
lineIndex: linkParams.lineIndex || undefined,
|
||||
});
|
||||
// Remove deprecated link tag and create a link in IndexedDB
|
||||
await addon.api.relation.linkAnnotationToTarget({
|
||||
fromLibID: annotationItem.libraryID,
|
||||
fromKey: annotationItem.key,
|
||||
toLibID: linkParams.libraryID,
|
||||
toKey: linkParams.noteKey!,
|
||||
url: tag,
|
||||
});
|
||||
annotationItem.removeTag(tag);
|
||||
await annotationItem.saveTx();
|
||||
return;
|
||||
} else {
|
||||
annotationItem.removeTag(tag);
|
||||
|
|
@ -80,17 +92,31 @@ async function createNoteFromAnnotation(
|
|||
}
|
||||
}
|
||||
|
||||
const linkTarget = await addon.api.relation.getLinkTargetByAnnotation(
|
||||
annotationItem.libraryID,
|
||||
annotationItem.key,
|
||||
);
|
||||
if (linkTarget) {
|
||||
const targetItem = Zotero.Items.getByLibraryAndKey(
|
||||
linkTarget.toLibID,
|
||||
linkTarget.toKey,
|
||||
);
|
||||
if (targetItem)
|
||||
addon.hooks.onOpenNote(targetItem.id, openMode || "tab", {});
|
||||
return;
|
||||
}
|
||||
|
||||
const note: Zotero.Item = new Zotero.Item("note");
|
||||
note.libraryID = annotationItem.libraryID;
|
||||
note.parentID = annotationItem.parentItem!.parentID;
|
||||
await note.saveTx();
|
||||
|
||||
const renderredTemplate = await addon.api.template.runTemplate(
|
||||
const renderedTemplate = await addon.api.template.runTemplate(
|
||||
"[QuickNoteV5]",
|
||||
"annotationItem, topItem, noteItem",
|
||||
[annotationItem, annotationItem.parentItem!.parentItem, note],
|
||||
);
|
||||
await addLineToNote(note, renderredTemplate);
|
||||
await addLineToNote(note, renderedTemplate);
|
||||
|
||||
const tags = annotationItem.getTags();
|
||||
for (const tag of tags) {
|
||||
|
|
@ -98,8 +124,13 @@ async function createNoteFromAnnotation(
|
|||
}
|
||||
await note.saveTx();
|
||||
|
||||
ZoteroPane.openNoteWindow(note.id);
|
||||
await addon.api.relation.linkAnnotationToTarget({
|
||||
fromLibID: annotationItem.libraryID,
|
||||
fromKey: annotationItem.key,
|
||||
toLibID: note.libraryID,
|
||||
toKey: note.key,
|
||||
url: addon.api.convert.note2link(note, { ignore: true })!,
|
||||
});
|
||||
|
||||
annotationItem.addTag(getNoteLink(note)!);
|
||||
await annotationItem.saveTx();
|
||||
addon.hooks.onOpenNote(note.id, "builtin", {});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ export {
|
|||
getNoteLinkInboundRelation,
|
||||
getNoteLinkOutboundRelation,
|
||||
closeRelationWorker,
|
||||
linkAnnotationToTarget,
|
||||
getLinkTargetByAnnotation,
|
||||
getAnnotationByLinkTarget,
|
||||
};
|
||||
|
||||
function closeRelationWorker() {
|
||||
|
|
@ -158,3 +161,38 @@ interface LinkModel {
|
|||
toSection: string | null;
|
||||
url: string;
|
||||
}
|
||||
|
||||
async function linkAnnotationToTarget(model: AnnotationModel): Promise<void> {
|
||||
return executeRelationWorker({
|
||||
type: "linkAnnotationToTarget",
|
||||
data: model,
|
||||
});
|
||||
}
|
||||
|
||||
async function getLinkTargetByAnnotation(
|
||||
fromLibID: number,
|
||||
fromKey: string,
|
||||
): Promise<AnnotationModel> {
|
||||
return executeRelationWorker({
|
||||
type: "getLinkTargetByAnnotation",
|
||||
data: { fromLibID, fromKey },
|
||||
});
|
||||
}
|
||||
|
||||
async function getAnnotationByLinkTarget(
|
||||
toLibID: number,
|
||||
toKey: string,
|
||||
): Promise<AnnotationModel> {
|
||||
return executeRelationWorker({
|
||||
type: "getAnnotationByLinkTarget",
|
||||
data: { toLibID, toKey },
|
||||
});
|
||||
}
|
||||
|
||||
interface AnnotationModel {
|
||||
fromLibID: number;
|
||||
fromKey: string;
|
||||
toLibID: number;
|
||||
toKey: string;
|
||||
url: string;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue