/*
* Universal Memos sidebar.
*
* Memos persist immediately via /api/memos and Potato navigation is a
* full page reload, so correctness just requires (re)loading memos for
* the displayed instance on init. A window.MemoPanel.reload() hook is
* exposed so that if navigation ever becomes AJAX, the panel can be
* refreshed from the instance lifecycle without stale state.
*/
(function () {
"use strict";
var API = "/api/memos";
var state = { instanceId: null, memos: [], editingId: null, enabled: false };
function el(id) { return document.getElementById(id); }
function currentInstanceId() {
var input = el("instance_id");
return input ? input.value : null;
}
function esc(s) {
var d = document.createElement("div");
d.textContent = s == null ? "" : String(s);
return d.innerHTML;
}
function selectionInText() {
// Returns {start,end,field,quote} if there is a non-empty selection
// inside the instance text, else null.
var sel = window.getSelection();
if (!sel || sel.isCollapsed || sel.rangeCount === 0) return null;
var container = document.getElementById("text-content");
if (!container) return null;
var range = sel.getRangeAt(0);
if (!container.contains(range.startContainer) ||
!container.contains(range.endContainer)) return null;
var pre = range.cloneRange();
pre.selectNodeContents(container);
pre.setEnd(range.startContainer, range.startOffset);
var start = pre.toString().length;
var quote = sel.toString();
if (!quote.trim()) return null;
return { start: start, end: start + quote.length, field: "text", quote: quote };
}
function api(method, path, body) {
return fetch(API + path, {
method: method,
headers: { "Content-Type": "application/json" },
body: body ? JSON.stringify(body) : undefined,
});
}
function render() {
var list = el("memo-list");
if (!list) return;
if (!state.memos.length) {
list.innerHTML = '
No notes on this instance yet.
';
return;
}
var me = (window.config && window.config.username) || null;
list.innerHTML = state.memos.map(function (m) {
var own = m.created_by === me;
var vis = m.visibility === "shared" ? "shared" : "private";
var anchorBadge = m.anchor
? 'quote'
: "";
var actions = own
? ''
+ ''
+ ''
+ ""
: "";
return '