Files
mymovies/plugin.js
T

167 lines
6.5 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, '&amp;').replace(/</g, '&lt;')
.replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}
// ---------- Компонент: список фильмов ----------
Lampa.Component.add(PLUGIN.name, {
create: function () {
var comp = this;
var content = comp.activity.render().find('.main__content');
content.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(content.find('.movies-grid'), movies);
})
.catch(function (err) {
comp.activity.loader(false);
console.error('[mymovies] catalog error', err);
content.find('.movies-grid').html('<div class="mymovies-empty">Ошибка загрузки каталога</div>');
Lampa.Noty.show('Не удалось загрузить каталог');
});
}
});
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 () {
var comp = this;
var m = selected;
if (!m) { Lampa.Activity.back(); return; }
var content = comp.activity.render().find('.main__content');
var html = '<div class="mymovies-detail">';
html += '<div class="detail-head">';
html += '<img class="detail-poster" src="' + resolve(m.poster || m.cover) + '">';
html += '<div class="detail-info"><h1>' + esc(m.title) + '</h1>';
if (m.original_title) html += '<div class="detail-orig">' + esc(m.original_title) + '</div>';
if (m.year) html += '<div class="detail-year">' + m.year + '</div>';
if (m.genre && m.genre.length) html += '<div class="detail-genre">' + m.genre.join(', ') + '</div>';
if (m.rating) html += '<div class="detail-rating">★ ' + m.rating + '</div>';
if (m.description) html += '<div class="detail-desc">' + esc(m.description) + '</div>';
html += '</div></div>';
html += '<div class="detail-actions"><div class="btn selector" data-act="play">Смотреть</div></div>';
html += '</div>';
content.html(html);
content.find('[data-act="play"]').on('hover:enter', function () { play(m); });
Lampa.Selector.update();
}
});
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
});
}
// ---------- Пункт меню ----------
// bylampa шлёт 'menu:start' при сборке меню (body = jQuery меню).
// Добавляем <li> в .menu__list. Защита от дублей — проверка по DOM.
function addMenuItem() {
var list = $('.menu__list');
if (!list.length) return;
if ($('[data-action="' + PLUGIN.name + '"]').length) return; // уже в DOM
var item = $(
'<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>'
);
item.on('hover:enter', function () {
Lampa.Activity.push({
url: '',
component: PLUGIN.name,
title: PLUGIN.title,
page: PLUGIN.title
});
});
list.append(item);
Lampa.Selector.update();
}
function start() {
// единственный вход: подписка на сборку меню
Lampa.Listener.follow('menu', function (e) {
if (e.type === 'start') {
setTimeout(addMenuItem, 50);
}
});
// если меню уже собрано до загрузки плагина — ловим ready
Lampa.Listener.follow('app', function (e) {
if (e.type === 'ready') {
setTimeout(addMenuItem, 200);
}
});
}
if (window.Lampa && Lampa.Listener && Lampa.Activity) {
start();
} else {
document.addEventListener('lampa', start);
}
})();