webapp: keep a tile's Log tail open across refreshes
Each SSE/poll refresh replaces the tiles' HTML, so the nested Log tail <details> snapped shut on every update while a wipe was running. Its open state is now remembered per tile in localStorage like the tile itself, and its scroll position is kept: following the bottom keeps following new lines, scrolled up stays put.
This commit is contained in:
@@ -200,9 +200,9 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if s.log_tail %}
|
{% if s.log_tail %}
|
||||||
<details class="mt-3">
|
<details class="mt-3 imaging-log" data-key="{{ card_key }}">
|
||||||
<summary class="eyebrow" style="cursor:pointer;">{% if is_inferred %}Evidence{% else %}Log tail{% endif %} ({{ s.log_tail | length }} line{{ 's' if s.log_tail | length != 1 }})</summary>
|
<summary class="eyebrow" style="cursor:pointer;">{% if is_inferred %}Evidence{% else %}Log tail{% endif %} ({{ s.log_tail | length }} line{{ 's' if s.log_tail | length != 1 }})</summary>
|
||||||
<pre class="mono p-2 mt-2 mb-0" style="max-height: 12rem; overflow-y: auto; background:var(--bg); border:1px solid var(--border); border-radius:0.25rem; font-size:0.78rem;">{% for line in s.log_tail %}{{ line }}
|
<pre class="mono p-2 mt-2 mb-0 imaging-log-pre" style="max-height: 12rem; overflow-y: auto; background:var(--bg); border:1px solid var(--border); border-radius:0.25rem; font-size:0.78rem;">{% for line in s.log_tail %}{{ line }}
|
||||||
{% endfor %}</pre>
|
{% endfor %}</pre>
|
||||||
</details>
|
</details>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -321,14 +321,18 @@ document.addEventListener('keydown', function(e) {
|
|||||||
// it replaces the innerHTML of #imaging-tiles.
|
// it replaces the innerHTML of #imaging-tiles.
|
||||||
(function() {
|
(function() {
|
||||||
var EXPANDED_KEY = 'imaging-expanded';
|
var EXPANDED_KEY = 'imaging-expanded';
|
||||||
function loadExpandedSet() {
|
var LOG_EXPANDED_KEY = 'imaging-log-expanded';
|
||||||
try { return new Set(JSON.parse(localStorage.getItem(EXPANDED_KEY) || '[]')); }
|
function loadExpandedSet(key) {
|
||||||
|
try { return new Set(JSON.parse(localStorage.getItem(key || EXPANDED_KEY) || '[]')); }
|
||||||
catch (e) { return new Set(); }
|
catch (e) { return new Set(); }
|
||||||
}
|
}
|
||||||
function saveExpandedSet(set) {
|
function saveExpandedSet(set, key) {
|
||||||
try { localStorage.setItem(EXPANDED_KEY, JSON.stringify(Array.from(set))); }
|
try { localStorage.setItem(key || EXPANDED_KEY, JSON.stringify(Array.from(set))); }
|
||||||
catch (e) {}
|
catch (e) {}
|
||||||
}
|
}
|
||||||
|
// Log-tail scroll per tile, in memory only. A tile followed at the
|
||||||
|
// bottom keeps following new lines; one scrolled up stays put.
|
||||||
|
var logScroll = {};
|
||||||
|
|
||||||
function restoreExpandedState() {
|
function restoreExpandedState() {
|
||||||
var expanded = loadExpandedSet();
|
var expanded = loadExpandedSet();
|
||||||
@@ -344,6 +348,32 @@ document.addEventListener('keydown', function(e) {
|
|||||||
card._toggleBound = true;
|
card._toggleBound = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// The nested "Log tail" <details> is re-rendered closed on every
|
||||||
|
// refresh; keep it open (and its scroll) the same way as the tile.
|
||||||
|
var logExpanded = loadExpandedSet(LOG_EXPANDED_KEY);
|
||||||
|
document.querySelectorAll('.imaging-log').forEach(function(log) {
|
||||||
|
var key = log.getAttribute('data-key');
|
||||||
|
if (!key) return;
|
||||||
|
if (logExpanded.has(key)) log.open = true;
|
||||||
|
var pre = log.querySelector('.imaging-log-pre');
|
||||||
|
if (pre) {
|
||||||
|
var saved = logScroll[key];
|
||||||
|
if (!saved || saved.atBottom) pre.scrollTop = pre.scrollHeight;
|
||||||
|
else pre.scrollTop = saved.top;
|
||||||
|
pre.addEventListener('scroll', function() {
|
||||||
|
logScroll[key] = {
|
||||||
|
top: pre.scrollTop,
|
||||||
|
atBottom: pre.scrollTop + pre.clientHeight >= pre.scrollHeight - 4
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
log.addEventListener('toggle', function() {
|
||||||
|
var s = loadExpandedSet(LOG_EXPANDED_KEY);
|
||||||
|
if (log.open) s.add(key); else s.delete(key);
|
||||||
|
saveExpandedSet(s, LOG_EXPANDED_KEY);
|
||||||
|
if (log.open && pre) pre.scrollTop = pre.scrollHeight;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function autoRenderLapsQRs() {
|
function autoRenderLapsQRs() {
|
||||||
|
|||||||
Reference in New Issue
Block a user