175 lines
6.9 KiB
JavaScript
175 lines
6.9 KiB
JavaScript
(function () {
|
|
'use strict';
|
|
|
|
var PLUGIN = { name: 'mymovies', title: 'Мои фильмы' };
|
|
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:
|
|
// create() возвращает this.render(); render() строит html и выводит через Lampa.Layer.
|
|
Lampa.Component.add(PLUGIN.name, {
|
|
create: function () {
|
|
return this.render();
|
|
},
|
|
render: function () {
|
|
var comp = this;
|
|
var html = $('<div class="mymovies"><div class="movies-grid"></div></div>');
|
|
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) {
|
|
comp.activity.loader(false);
|
|
var movies = (data && data.movies) || [];
|
|
console.log('[mymovies] loaded', movies.length, 'films');
|
|
renderMovies(html.find('.movies-grid'), movies);
|
|
Lampa.Layer.update(html);
|
|
Lampa.Layer.visible(html);
|
|
})
|
|
.catch(function (err) {
|
|
comp.activity.loader(false);
|
|
console.error('[mymovies] catalog error', err);
|
|
html.find('.movies-grid').html('<div class="mymovies-empty">Ошибка загрузки каталога</div>');
|
|
Lampa.Layer.update(html);
|
|
Lampa.Layer.visible(html);
|
|
});
|
|
|
|
return html;
|
|
}
|
|
});
|
|
|
|
function renderMovies(grid, movies) {
|
|
grid.empty();
|
|
if (!movies.length) {
|
|
grid.append('<div class="mymovies-empty">Каталог пуст</div>');
|
|
Lampa.Selector.update();
|
|
return;
|
|
}
|
|
movies.forEach(function (m) {
|
|
var card = $('<div class="card selector" data-id="' + esc(m.id) + '">');
|
|
card.append($('<img class="card__img">').attr('src', resolve(m.poster || m.cover)).attr('loading', 'lazy'));
|
|
card.append($('<div class="card__title">').text(m.title || m.id));
|
|
if (m.year) card.append($('<div class="card__subtitle">').text(m.year));
|
|
card.on('hover:enter', function () { openMovie(m); });
|
|
grid.append(card);
|
|
});
|
|
Lampa.Selector.update();
|
|
}
|
|
|
|
// ---------- Компонент: детали фильма ----------
|
|
var selected = null;
|
|
Lampa.Component.add(PLUGIN.name + '_detail', {
|
|
create: function () {
|
|
return this.render();
|
|
},
|
|
render: function () {
|
|
var comp = this;
|
|
var m = selected;
|
|
if (!m) { Lampa.Activity.back(); return $('<div></div>'); }
|
|
|
|
var html = $('<div class="mymovies-detail">');
|
|
html.append('<div class="detail-head">');
|
|
html.append('<img class="detail-poster" src="' + resolve(m.poster || m.cover) + '">');
|
|
var info = $('<div class="detail-info">').append($('<h1>').text(m.title));
|
|
if (m.original_title) info.append($('<div class="detail-orig">').text(m.original_title));
|
|
if (m.year) info.append($('<div class="detail-year">').text(m.year));
|
|
if (m.genre && m.genre.length) info.append($('<div class="detail-genre">').text(m.genre.join(', ')));
|
|
if (m.rating) info.append($('<div class="detail-rating">').text('★ ' + m.rating));
|
|
if (m.description) info.append($('<div class="detail-desc">').text(m.description));
|
|
html.append(info);
|
|
html.append('</div>');
|
|
html.append($('<div class="detail-actions">').append(
|
|
$('<div class="btn selector" data-act="play">').text('Смотреть')
|
|
));
|
|
|
|
html.find('[data-act="play"]').on('hover:enter', function () { play(m); });
|
|
Lampa.Layer.update(html);
|
|
Lampa.Layer.visible(html);
|
|
return html;
|
|
}
|
|
});
|
|
|
|
function openMovie(m) {
|
|
selected = m;
|
|
Lampa.Activity.push({
|
|
url: '',
|
|
component: PLUGIN.name + '_detail',
|
|
title: m.title,
|
|
page: m.title
|
|
});
|
|
}
|
|
|
|
function play(m) {
|
|
var url = m.magnet ? m.magnet : resolve(m.torrent);
|
|
Lampa.Player.play({
|
|
url: url,
|
|
title: m.title,
|
|
img: resolve(m.poster || m.cover),
|
|
season: 0,
|
|
episode: 0
|
|
});
|
|
}
|
|
|
|
// ---------- Пункт меню ----------
|
|
// Официальный паттерн Lampa: меню собирается при событии 'menu:start',
|
|
// в e.body приходит jQuery-корень меню. Добавляем <li> в .menu__list внутри e.body.
|
|
// Меню пересобирается при каждом открытии, поэтому старый пункт удаляется,
|
|
// и мы добавляем ровно один (проверка по data-action внутри текущего списка).
|
|
function makeButton() {
|
|
var button = $(
|
|
'<li class="menu__item selector" data-action="' + PLUGIN.name + '">' +
|
|
'<div class="menu__ico">' +
|
|
'<svg class="sprite-folder"><use xlink:href="#sprite-folder"></use></svg>' +
|
|
'</div>' +
|
|
'<div class="menu__text">' + PLUGIN.title + '</div>' +
|
|
'</li>'
|
|
);
|
|
button.on('hover:enter', function () {
|
|
Lampa.Activity.push({
|
|
url: '',
|
|
component: PLUGIN.name,
|
|
title: PLUGIN.title,
|
|
page: PLUGIN.title
|
|
});
|
|
});
|
|
return button;
|
|
}
|
|
|
|
function start() {
|
|
Lampa.Listener.follow('menu', function (e) {
|
|
if (e.type === 'start' && e.body) {
|
|
var list = e.body.find('.menu__list');
|
|
if (list.length && !list.find('[data-action="' + PLUGIN.name + '"]').length) {
|
|
list.append(makeButton());
|
|
Lampa.Selector.update();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
if (window.Lampa && Lampa.Listener && Lampa.Activity) {
|
|
start();
|
|
} else {
|
|
document.addEventListener('lampa', start);
|
|
}
|
|
})();
|