thunderbird-patch-review
Easy-to-use patch review interface for Thunderbird
Contribute: ~marcc/thunderbird-review-plugin@lists.sr.ht
git clone git://mccd.space/thunderbird-patch-review
| Log | Files | Refs | README | LICENSE |
review-store.js (1513B)
1 // Draft review comments, persisted in storage.local so they survive closing
2 // the review tab. Keyed by the patch's Message-ID header (stable across
3 // folders and Thunderbird restarts, unlike numeric message ids).
4
5 const key = (headerMessageId) => `comments:${headerMessageId}`;
6
7 // A locator addresses a diff line: `${fileIndex}:${hunkIndex}:${lineIndex}`,
8 // or the string "general" for a whole-patch comment.
9 export const GENERAL = "general";
10
11 export function locator(fileIndex, hunkIndex, lineIndex) {
12 return `${fileIndex}:${hunkIndex}:${lineIndex}`;
13 }
14
15 export function parseLocator(loc) {
16 if (loc === GENERAL) {
17 return { general: true };
18 }
19 const [fileIndex, hunkIndex, lineIndex] = loc.split(":").map(Number);
20 return { general: false, fileIndex, hunkIndex, lineIndex };
21 }
22
23 /** @returns {Promise<Record<string, {text: string, updatedAt: number}>>} */
24 export async function loadComments(headerMessageId) {
25 const k = key(headerMessageId);
26 const found = await messenger.storage.local.get(k);
27 return found[k] || {};
28 }
29
30 export async function saveComment(headerMessageId, loc, text) {
31 const comments = await loadComments(headerMessageId);
32 if (text && text.trim()) {
33 comments[loc] = { text: text.trim(), updatedAt: Date.now() };
34 } else {
35 delete comments[loc];
36 }
37 await messenger.storage.local.set({ [key(headerMessageId)]: comments });
38 return comments;
39 }
40
41 export async function clearComments(headerMessageId) {
42 await messenger.storage.local.remove(key(headerMessageId));
43 }