Initial commit

This commit is contained in:
2025-09-23 00:29:33 +02:00
commit 4f120b68f5
14 changed files with 394 additions and 0 deletions

126
background.js Normal file
View File

@@ -0,0 +1,126 @@
function saveRevision(source) {
console.log('Syncing started from: ' + source);
chrome.bookmarks.getTree(async (tree) => {
const apiUrl = await chrome.storage.sync.get('apiUrl');
const syncToken = await chrome.storage.sync.get("syncToken");
if (!apiUrl || !syncToken)
return;
const savedRev = await chrome.storage.sync.get('revId');
const url = apiUrl.apiUrl + '/saveRevision';
const options = {
headers: {
'content-type': 'application/json',
'syncToken': syncToken.syncToken
},
method: 'POST',
body: JSON.stringify({
'revId': savedRev.revId,
'bookmarks': tree
})
};
try {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json(); // Convert to JSON
chrome.storage.sync.set({ revId: data.revId });
} catch (e) {
// TODO GD: Indicate error
}
});
}
async function getRevision() {
const apiUrl = await chrome.storage.sync.get('apiUrl');
const syncToken = await chrome.storage.sync.get("syncToken");
if (!apiUrl || !syncToken)
return;
const url = apiUrl.apiUrl + '/getRevision';
const options = {
headers: {
'content-type': 'application/json',
'syncToken': syncToken.syncToken
},
method: 'GET'
};
try {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json(); // Convert to JSON
const savedRev = await chrome.storage.sync.get('revId');
if (data.revId === savedRev.revId)
return;
chrome.storage.sync.set({ revId: data.revId });
removeAllChildren("1", () => createBookmarkTree(data.bookmarks, "1"));
removeAllChildren("2", () => createBookmarkTree(data.bookmarks, "2"));
} catch (e) {
// TODO GD: Indicate error
}
}
// Recursively delete all children
function removeAllChildren(parentId, callback) {
chrome.bookmarks.getChildren(parentId, (children) => {
if (!children || children.length === 0) return callback?.();
let count = children.length;
children.forEach((child) => {
if (child.url) {
chrome.bookmarks.remove(child.id, () => {
if (--count === 0) callback?.();
});
} else {
removeAllChildren(child.id, () => {
chrome.bookmarks.remove(child.id, () => {
if (--count === 0) callback?.();
});
});
}
});
});
}
// Sync events
chrome.bookmarks.onCreated.addListener((id, bookmark) => {
saveRevision('onCreated');
});
chrome.bookmarks.onRemoved.addListener((id, removeInfo) => {
saveRevision('onRemoved');
});
chrome.bookmarks.onChanged.addListener((id, changeInfo) => {
saveRevision('onChanged');
});
chrome.bookmarks.onMoved.addListener((id, moveInfo) => {
saveRevision('onMoved');
});
chrome.bookmarks.onChildrenReordered.addListener((id, reorderInfo) => {
saveRevision('onChildrenReordered');
});
chrome.bookmarks.onImportEnded.addListener(() => {
saveRevision('onImportEnded');
});
getRevision();
setInterval(getRevision, 5000);