scroll: JS-tween smooth scroll (fix); add always-on remote logger to :8899 with device identification
This commit is contained in:
1 parent
210b4e2295
commit
eace6c2eeb
1 file changed
+61
-10
@@ -4,6 +4,45 @@
|
||||
var PLUGIN = { name: 'mymovies', title: 'mymovies_title', menu_action: 'mymovies' };
|
||||
var DEFAULT_BASE = 'https://movies-lmp-18.dynv6.net/';
|
||||
|
||||
// ---------- Remote logger (always on) ----------
|
||||
// Forwards console.* from the device to the server so logs are visible centrally.
|
||||
// Device is identified by userAgent + Lampa device/platform + server-seen IP.
|
||||
(function () {
|
||||
try {
|
||||
var LOG_URL = 'https://movies-lmp-18.dynv6.net:8899/mymovies-log';
|
||||
function deviceInfo() {
|
||||
var ua = navigator.userAgent || 'unknown';
|
||||
var dev = '';
|
||||
try { dev = (Lampa.Device && (Lampa.Device.name || Lampa.Device.platform)) || ''; } catch (e) {}
|
||||
if (!dev) { try { dev = (window.Platform && window.Platform.name && window.Platform.name()) || ''; } catch (e) {} }
|
||||
return ua + (dev ? ' [' + dev + ']' : '');
|
||||
}
|
||||
function send(level, args) {
|
||||
var msg = [].map.call(args, function (a) {
|
||||
try { return (typeof a === 'object') ? JSON.stringify(a) : String(a); }
|
||||
catch (e) { return String(a); }
|
||||
}).join(' ');
|
||||
var payload = 'level=' + encodeURIComponent(level) +
|
||||
'&dev=' + encodeURIComponent(deviceInfo()) +
|
||||
'&msg=' + encodeURIComponent(msg);
|
||||
// fire-and-forget; ignore failures (e.g. offline)
|
||||
var img = new Image();
|
||||
img.src = LOG_URL + '?' + payload + '&_=' + Date.now();
|
||||
}
|
||||
var orig = {
|
||||
log: console.log.bind(console),
|
||||
warn: console.warn.bind(console),
|
||||
error: console.error.bind(console),
|
||||
info: console.info.bind(console)
|
||||
};
|
||||
console.log = function () { send('log', arguments); orig.log.apply(console, arguments); };
|
||||
console.warn = function () { send('warn', arguments); orig.warn.apply(console, arguments); };
|
||||
console.error = function () { send('error', arguments); orig.error.apply(console, arguments); };
|
||||
console.info = function () { send('info', arguments); orig.info.apply(console, arguments); };
|
||||
window.onerror = function (m, s, l, c, e) { send('error', ['[onerror]', m, s + ':' + l]); };
|
||||
} catch (e) {}
|
||||
})();
|
||||
|
||||
// Localized strings. Register once, then use Lampa.Lang.translate(KEY).
|
||||
var STRINGS = {
|
||||
mymovies_title: { ru: 'Мои фильмы', en: 'My Movies' }
|
||||
@@ -70,10 +109,7 @@
|
||||
// styles (.card / .full-start-new / .full-descr / .full-start__button).
|
||||
var css =
|
||||
'.mymovies{padding:2.2em 3.4em;overflow-y:auto;height:100%;box-sizing:border-box}' +
|
||||
// Native Lampa scroll animation: smooth transition on scrollTop.
|
||||
// Class "notransition" disables it for instant jumps (mimics Lampa.Scroll).
|
||||
'.mymovies{transition:scroll-top .25s ease-out;-webkit-transition:scroll-top .25s ease-out}' +
|
||||
'.mymovies.notransition{transition:none !important;-webkit-transition:none !important}' +
|
||||
// Smooth scroll is done in JS (tween of scrollTop), no CSS transition needed.
|
||||
'.movies-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:1.4em}' +
|
||||
'.mymovies-detail{padding:2em 3em;box-sizing:border-box}' +
|
||||
'.mymovies-detail .full-start-new__img{opacity:1 !important}' +
|
||||
@@ -103,15 +139,31 @@
|
||||
if (el) comp._selectedId = el.getAttribute('data-id');
|
||||
if (cont) comp._scrollTop = cont.scrollTop;
|
||||
}
|
||||
// Smooth scroll (native Lampa feel) via JS tween of scrollTop.
|
||||
// Works on every platform (CSS transition of scrollTop is unreliable).
|
||||
function smoothScrollTo(cont, target) {
|
||||
target = Math.max(0, Math.min(target, cont.scrollHeight - cont.clientHeight));
|
||||
var start = cont.scrollTop;
|
||||
var dist = target - start;
|
||||
if (!dist) return;
|
||||
var dur = 220, t0 = performance.now();
|
||||
if (cont.__scroll_raf) cancelAnimationFrame(cont.__scroll_raf);
|
||||
function step(now) {
|
||||
var p = Math.min(1, (now - t0) / dur);
|
||||
// ease-out cubic
|
||||
var e = 1 - Math.pow(1 - p, 3);
|
||||
cont.scrollTop = start + dist * e;
|
||||
if (p < 1) cont.__scroll_raf = requestAnimationFrame(step);
|
||||
}
|
||||
cont.__scroll_raf = requestAnimationFrame(step);
|
||||
}
|
||||
|
||||
function scrollFocused() {
|
||||
var cont = document.querySelector('.mymovies');
|
||||
var el = document.querySelector('.mymovies .card.selector.focus');
|
||||
if (cont && el) {
|
||||
// Smooth scroll (native Lampa animation). Remove notransition so the
|
||||
// CSS transition on scrollTop runs.
|
||||
cont.classList.remove('notransition');
|
||||
var delta = el.getBoundingClientRect().top - cont.getBoundingClientRect().top;
|
||||
cont.scrollTop += delta - 100;
|
||||
smoothScrollTo(cont, cont.scrollTop + delta - 100);
|
||||
comp._selectedId = el.getAttribute('data-id');
|
||||
comp._scrollTop = cont.scrollTop;
|
||||
}
|
||||
@@ -195,8 +247,7 @@
|
||||
Lampa.Controller.collectionFocus(target, wrap);
|
||||
if (comp._scrollTop) {
|
||||
var cont = wrap[0];
|
||||
cont.classList.remove('notransition');
|
||||
requestAnimationFrame(function () { cont.scrollTop = comp._scrollTop; });
|
||||
smoothScrollTo(cont, comp._scrollTop);
|
||||
}
|
||||
},
|
||||
left: function () { if (Navigator.canmove('left')) Navigator.move('left'); else Lampa.Controller.toggle('menu'); },
|
||||
|
||||
Reference in new issue
Block a user