60 lines
2.5 KiB
HTML
60 lines
2.5 KiB
HTML
<section id="id_applet_billboard_scroll" class="applet-billboard-scroll">
|
|
<h2>{{ room.name }}</h2>
|
|
{% include "core/_partials/_scroll.html" %}
|
|
</section>
|
|
<script>
|
|
(function() {
|
|
var scroll = document.getElementById('id_drama_scroll');
|
|
if (!scroll) return;
|
|
|
|
// Defer dimension-dependent work until after flex layout resolves.
|
|
// Inline scripts can run before nested flex heights are computed, producing
|
|
// wrong scrollHeight/clientHeight values (symptom: incorrect marginTop on mobile).
|
|
requestAnimationFrame(function() {
|
|
// Push buffer so its top aligns with the bottom of the aperture when all
|
|
// events fit within the viewport (no natural scrolling).
|
|
var buffer = scroll.querySelector('.scroll-buffer');
|
|
if (buffer) {
|
|
var eventsHeight = scroll.scrollHeight - buffer.offsetHeight;
|
|
var gap = scroll.clientHeight - eventsHeight;
|
|
if (gap > 0) {
|
|
buffer.style.marginTop = gap + 'px';
|
|
}
|
|
}
|
|
|
|
// Restore: position stored is bottom-of-viewport; subtract clientHeight to align it
|
|
scroll.scrollTop = Math.max(0, {{ scroll_position }} - scroll.clientHeight);
|
|
});
|
|
|
|
// Animate "What happens next. . . ?" buffer dots — 4th span shows '?'
|
|
var dotsWrap = scroll.querySelector('.scroll-buffer-dots');
|
|
if (dotsWrap) {
|
|
var dots = dotsWrap.querySelectorAll('span');
|
|
var n = 0;
|
|
setInterval(function() {
|
|
dots.forEach(function(d, i) { d.textContent = i < n ? (i === 3 ? '?' : '.') : ''; });
|
|
n = (n + 1) % 5;
|
|
}, 400);
|
|
}
|
|
|
|
// Debounced save on scroll — store bottom-of-viewport so the last-read line is restored
|
|
var saveTimer;
|
|
scroll.addEventListener('scroll', function() {
|
|
clearTimeout(saveTimer);
|
|
saveTimer = setTimeout(function() {
|
|
var csrfToken = document.querySelector('[name=csrfmiddlewaretoken]');
|
|
var token = csrfToken ? csrfToken.value : '';
|
|
var remPx = parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
fetch("{% url 'billboard:save_scroll_position' room.id %}", {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'X-CSRFToken': token,
|
|
},
|
|
body: 'position=' + Math.round(scroll.scrollTop + scroll.clientHeight + remPx * 2.5),
|
|
});
|
|
}, 800);
|
|
});
|
|
})();
|
|
</script>
|