Here is a snippet to find those (empty) top-level rem. Paste it in the DevTools (F12) console. And click a button that appeared on the bottom of a page.
function getRemText(remId, remStore, exploredRem=[]) {
let rem = remStore[remId];
if (!rem) return;
const richTextElementsText = rem.key.map((richTextElement)=>{
// If the element is a string, juts return it
if (typeof richTextElement == 'string') {
return richTextElement;
// If the element is a Rem Reference (i == "q"), then recursively get that Rem Reference's text.
} else if (richTextElement.i == 'q' && !exploredRem.includes(richTextElement._id)) {
return getRemText(richTextElement._id, remStore, exploredRem.concat([richTextElement._id]));
} else {
// If the Rem is some other rich text element, just take its .text property.
return richTextElement.text;
}
}
);
return richTextElementsText.join('');
}
(function() {
let test = true;
let targetContainerId = 'ReferenceLinks';
let buttonId = 'list-reference-button';
let listId = 'reference-list';
let linksContainer = document.getElementById(targetContainerId);
if (!test && document.getElementById(buttonId))
return;
function compareChildren(map) {
return (aId, bId) => {
const a = map[aId];
const b = map[bId];
return a.numChildren > b.numChildren ? -1 : 1;
}
}
function compareText(map) {
return (aId, bId) => {
if (aId == bId) return 0;
const ta = map[aId].text;
const tb = map[bId].text;
if (ta === tb) {
return compareChildren(map)(aId, bId);
}
if (ta === undefined) return 1;
if (tb === undefined) return -1;
return ta.toLowerCase() < tb.toLowerCase() ? -1 : 1;
}
}
let button = document.createElement('input');
button.type = 'button';
button.value = "List top-level Rem by most children";
button.onclick = () => listRem(compareChildren);
linksContainer.appendChild(button);
let button2 = document.createElement('input');
button2.type = 'button';
button2.value = "List top-level Rem alphabetically";
button2.onclick = () => listRem(compareText);
linksContainer.appendChild(button2);
function listRem(compare) {
if (!test && document.getElementById(listId))
return;
query((rems)=>{
let remStore = Object.fromEntries(rems.map(rem => [rem._id, rem]));
let topLevel = [];
for (let rem of rems) {
if (!rem.parent) {
topLevel.push(rem);
}
}
let topLevelMap = [...topLevel].reduce((map, rem) => {
map[rem._id] = { id: rem._id, text: getRemText(rem._id, remStore), numChildren: rem.children.length };
return map
}, {});
console.warn(topLevelMap)
let list = document.getElementById(listId) || document.createElement('ul');
list.id = listId;
list.innerHTML = '';
for (let rem of Object.keys(topLevelMap).sort(compare(topLevelMap))) {
let link = document.createElement('a');
link.href = `https://www.remnote.io/document/${rem}`;
link.appendChild(document.createTextNode(`${topLevelMap[rem].text} (${topLevelMap[rem].numChildren})`));
let li = document.createElement('li');
li.appendChild(link);
list.appendChild(li);
}
linksContainer.appendChild(list);
}
);
}
function query(handler) {
let openRequest = indexedDB.open('lnotes', 24)
openRequest.onsuccess = ()=>{
console.info('Connected to database.')
let db = openRequest.result;
let t = db.transaction('quanta');
let quanta = t.objectStore('quanta');
let request = quanta.getAll();
request.onsuccess = ()=>{
console.info('Loaded Rems');
handler(request.result);
}
}
openRequest.onerror = ()=>{
console.warn('There was an error:', openRequest.error);
}
openRequest.onupgradeneeded = ()=>{
console.warn('The database version has got an upgrade. Update this script!');
}
}
}
)();