use Lampa.Reguest (TV-safe) instead of fetch; EN-only comments
This commit is contained in:
1 parent
b387a1763d
commit
8db23ae058
1 file changed
+50
-37
@@ -1,28 +1,48 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var PLUGIN = { name: 'mymovies', title: 'Мои фильмы' };
|
||||
var PLUGIN = { name: 'mymovies', title: 'My Movies', menu_action: 'mymovies' };
|
||||
var DEFAULT_BASE = 'https://movies-lmp-18.dynv6.net/';
|
||||
|
||||
function base() {
|
||||
var b = Lampa.Storage.get(PLUGIN.name + '_base', DEFAULT_BASE);
|
||||
return b.replace(/\/+$/, '') + '/';
|
||||
}
|
||||
|
||||
function resolve(p) {
|
||||
if (!p) return '';
|
||||
if (/^https?:\/\//.test(p)) return p;
|
||||
if (/^magnet:/.test(p)) return p;
|
||||
return base() + p.replace(/^\/+/, '');
|
||||
}
|
||||
|
||||
function esc(s) {
|
||||
return String(s == null ? '' : s)
|
||||
.replace(/&/g, '&').replace(/</g, '<')
|
||||
.replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
// ---------- Компонент: список фильмов ----------
|
||||
// Регистрируется как функция-конструктор (как iptv), иначе Lampa падает:
|
||||
// "component is not a constructor"
|
||||
function loadCatalog(cb) {
|
||||
var url = base() + 'movies/catalog.json';
|
||||
// Use Lampa native network layer (works on TV where fetch fails)
|
||||
if (Lampa.Reguest && Lampa.Reguest.get) {
|
||||
Lampa.Reguest.get(url, function (html) {
|
||||
try {
|
||||
cb(null, JSON.parse(html));
|
||||
} catch (e) {
|
||||
cb(e, null);
|
||||
}
|
||||
}, function (err) {
|
||||
cb(err || new Error('request failed'), null);
|
||||
});
|
||||
} else {
|
||||
fetch(url).then(function (r) { return r.json(); })
|
||||
.then(function (d) { cb(null, d); })
|
||||
.catch(function (e) { cb(e, null); });
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Component: movie list ----------
|
||||
function MyMovies() {
|
||||
var comp = this;
|
||||
this.render = function () {
|
||||
@@ -34,26 +54,21 @@
|
||||
|
||||
if (comp.activity) comp.activity.loader(true);
|
||||
|
||||
fetch(base() + 'movies/catalog.json')
|
||||
.then(function (r) {
|
||||
if (!r.ok) throw new Error('HTTP ' + r.status);
|
||||
return r.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
if (comp.activity) comp.activity.loader(false);
|
||||
var movies = (data && data.movies) || [];
|
||||
console.log('[mymovies] loaded', movies.length, 'films');
|
||||
renderMovies($(grid), movies);
|
||||
Lampa.Layer.update(html);
|
||||
Lampa.Layer.visible(html);
|
||||
})
|
||||
.catch(function (err) {
|
||||
if (comp.activity) comp.activity.loader(false);
|
||||
loadCatalog(function (err, data) {
|
||||
if (comp.activity) comp.activity.loader(false);
|
||||
if (err) {
|
||||
console.error('[mymovies] catalog error', err);
|
||||
grid.innerHTML = '<div class="mymovies-empty">Ошибка загрузки каталога</div>';
|
||||
grid.innerHTML = '<div class="mymovies-empty">Catalog load error</div>';
|
||||
Lampa.Layer.update(html);
|
||||
Lampa.Layer.visible(html);
|
||||
});
|
||||
return;
|
||||
}
|
||||
var movies = (data && data.movies) || [];
|
||||
console.log('[mymovies] loaded', movies.length, 'films');
|
||||
renderMovies($(grid), movies);
|
||||
Lampa.Layer.update(html);
|
||||
Lampa.Layer.visible(html);
|
||||
});
|
||||
|
||||
return html;
|
||||
};
|
||||
@@ -63,7 +78,7 @@
|
||||
function renderMovies(grid, movies) {
|
||||
grid.empty();
|
||||
if (!movies.length) {
|
||||
grid.append('<div class="mymovies-empty">Каталог пуст</div>');
|
||||
grid.append('<div class="mymovies-empty">Catalog is empty</div>');
|
||||
if (Lampa.Selector) Lampa.Selector.update();
|
||||
return;
|
||||
}
|
||||
@@ -78,13 +93,13 @@
|
||||
if (Lampa.Selector) Lampa.Selector.update();
|
||||
}
|
||||
|
||||
// ---------- Компонент: детали фильма ----------
|
||||
// ---------- Component: movie detail ----------
|
||||
var selected = null;
|
||||
function MyMoviesDetail() {
|
||||
var comp = this;
|
||||
this.render = function () {
|
||||
var m = selected;
|
||||
if (!m) { Lampa.Activity.back(); return $('<div></div>'); }
|
||||
if (!m) { Lampa.Activity.back(); return document.createElement('div'); }
|
||||
|
||||
var html = document.createElement('div');
|
||||
html.className = 'mymovies-detail';
|
||||
@@ -99,11 +114,11 @@
|
||||
var h1 = document.createElement('h1');
|
||||
h1.textContent = m.title;
|
||||
info.appendChild(h1);
|
||||
if (m.original_title) { var d = document.createElement('div'); d.className='detail-orig'; d.textContent=m.original_title; info.appendChild(d); }
|
||||
if (m.year) { var d = document.createElement('div'); d.className='detail-year'; d.textContent=m.year; info.appendChild(d); }
|
||||
if (m.genre && m.genre.length) { var d = document.createElement('div'); d.className='detail-genre'; d.textContent=m.genre.join(', '); info.appendChild(d); }
|
||||
if (m.rating) { var d = document.createElement('div'); d.className='detail-rating'; d.textContent='★ ' + m.rating; info.appendChild(d); }
|
||||
if (m.description) { var d = document.createElement('div'); d.className='detail-desc'; d.textContent=m.description; info.appendChild(d); }
|
||||
if (m.original_title) { var d = document.createElement('div'); d.className = 'detail-orig'; d.textContent = m.original_title; info.appendChild(d); }
|
||||
if (m.year) { var d = document.createElement('div'); d.className = 'detail-year'; d.textContent = m.year; info.appendChild(d); }
|
||||
if (m.genre && m.genre.length) { var d = document.createElement('div'); d.className = 'detail-genre'; d.textContent = m.genre.join(', '); info.appendChild(d); }
|
||||
if (m.rating) { var d = document.createElement('div'); d.className = 'detail-rating'; d.textContent = '★ ' + m.rating; info.appendChild(d); }
|
||||
if (m.description) { var d = document.createElement('div'); d.className = 'detail-desc'; d.textContent = m.description; info.appendChild(d); }
|
||||
head.appendChild(info);
|
||||
html.appendChild(head);
|
||||
var actions = document.createElement('div');
|
||||
@@ -111,7 +126,7 @@
|
||||
var btn = document.createElement('div');
|
||||
btn.className = 'btn selector';
|
||||
btn.setAttribute('data-act', 'play');
|
||||
btn.textContent = 'Смотреть';
|
||||
btn.textContent = 'Watch';
|
||||
actions.appendChild(btn);
|
||||
html.appendChild(actions);
|
||||
|
||||
@@ -144,13 +159,12 @@
|
||||
});
|
||||
}
|
||||
|
||||
// ---------- Пункт меню ----------
|
||||
// Официальный паттерн Lampa: меню собирается при событии 'menu:start',
|
||||
// в e.body приходит jQuery-корень меню. Удаляем ВСЕ старые копии из DOM
|
||||
// (на случай нескольких пересборок/подписок) и добавляем ровно одну.
|
||||
// ---------- Menu item ----------
|
||||
// Lampa builds the main menu on the 'menu:start' event, e.body is the jQuery menu root.
|
||||
// Remove ALL old copies from the DOM first, then add exactly one button.
|
||||
function makeButton() {
|
||||
var button = $(
|
||||
'<li class="menu__item selector" data-action="' + PLUGIN.name + '">' +
|
||||
'<li class="menu__item selector" data-action="' + PLUGIN.menu_action + '">' +
|
||||
'<div class="menu__ico">' +
|
||||
'<svg class="sprite-folder"><use xlink:href="#sprite-folder"></use></svg>' +
|
||||
'</div>' +
|
||||
@@ -176,8 +190,7 @@
|
||||
if (e.type === 'start' && e.body) {
|
||||
var list = e.body.find('.menu__list');
|
||||
if (!list.length) return;
|
||||
// удаляем все старые копии (из текущего и любого другого меню в DOM)
|
||||
$('[data-action="' + PLUGIN.name + '"]').remove();
|
||||
$('[data-action="' + PLUGIN.menu_action + '"]').remove();
|
||||
list.append(makeButton());
|
||||
if (Lampa.Selector) Lampa.Selector.update();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user