diff --git a/plugin.js b/plugin.js index f935537..f5b9bb7 100644 --- a/plugin.js +++ b/plugin.js @@ -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'); },