fix: single menu item (dom-guard), proper component ready() lifecycle, console debug
This commit is contained in:
1 parent
9cf5e8055a
commit
edb03b3bdd
1 file changed
+60
-54
@@ -14,25 +14,36 @@
|
||||
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, '"');
|
||||
}
|
||||
|
||||
// ---- Компонент: список фильмов ----
|
||||
// ---------- Компонент: список фильмов ----------
|
||||
Lampa.Component.add(PLUGIN.name, {
|
||||
create: function () {
|
||||
var comp = this;
|
||||
comp.activity.loader(true);
|
||||
var content = comp.activity.render().find('.main__content');
|
||||
content.html('<div class="mymovies"><div class="movies-grid"></div></div>');
|
||||
this.activity.render();
|
||||
this.activity.ready(function () {
|
||||
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) { return r.json(); })
|
||||
.then(function (data) {
|
||||
comp.activity.loader(false);
|
||||
renderMovies(content.find('.movies-grid'), data.movies || []);
|
||||
})
|
||||
.catch(function () {
|
||||
comp.activity.loader(false);
|
||||
Lampa.Noty.show('Не удалось загрузить каталог');
|
||||
});
|
||||
fetch(base() + 'movies/catalog.json')
|
||||
.then(function (r) { 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 load error', err);
|
||||
Lampa.Noty.show('Не удалось загрузить каталог');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -40,12 +51,13 @@
|
||||
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="' + m.id + '">');
|
||||
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));
|
||||
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);
|
||||
@@ -53,29 +65,33 @@
|
||||
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 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>';
|
||||
this.activity.render();
|
||||
this.activity.ready(function () {
|
||||
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>';
|
||||
|
||||
var content = this.activity.render().find('.main__content');
|
||||
content.html(html);
|
||||
content.find('[data-act="play"]').on('hover:enter', function () { play(m); });
|
||||
Lampa.Selector.update();
|
||||
var content = comp.activity.render().find('.main__content');
|
||||
content.html(html);
|
||||
content.find('[data-act="play"]').on('hover:enter', function () { play(m); });
|
||||
Lampa.Selector.update();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -100,23 +116,13 @@
|
||||
});
|
||||
}
|
||||
|
||||
function esc(s) {
|
||||
return String(s == null ? '' : s)
|
||||
.replace(/&/g, '&').replace(/</g, '<')
|
||||
.replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
// ---- Пункт меню ----
|
||||
// bylampa строит главное меню из menu_items и ПЕРЕД отрисовкой шлёт
|
||||
// событие 'menu:start' с body = jQuery-объект меню (.menu__list внутри).
|
||||
// Добавляем <li class="menu__item"> в .menu__list. Защита от дублей по data-action.
|
||||
var added = false;
|
||||
// ---------- Пункт меню ----------
|
||||
// bylampa шлёт 'menu:start' при сборке меню (body = jQuery меню).
|
||||
// Добавляем <li> в .menu__list. Защита от дублей — проверка по DOM.
|
||||
function addMenuItem() {
|
||||
var list = $('.menu__list');
|
||||
if (!list.length) return;
|
||||
if (list.find('[data-action="' + PLUGIN.name + '"]').length) return; // уже есть в этом меню
|
||||
if (added) return; // уже добавляли когда-либо
|
||||
added = true;
|
||||
if ($('[data-action="' + PLUGIN.name + '"]').length) return; // уже в DOM
|
||||
|
||||
var item = $(
|
||||
'<li class="menu__item selector" data-action="' + PLUGIN.name + '">' +
|
||||
@@ -139,22 +145,22 @@
|
||||
}
|
||||
|
||||
function start() {
|
||||
// подписываемся на сборку меню (при каждом открытии меню)
|
||||
// единственный вход: подписка на сборку меню
|
||||
Lampa.Listener.follow('menu', function (e) {
|
||||
if (e.type === 'start') {
|
||||
setTimeout(addMenuItem, 50);
|
||||
}
|
||||
});
|
||||
// если меню уже отрисовано — добавляем сразу (один раз)
|
||||
addMenuItem();
|
||||
// если меню уже собрано до загрузки плагина — ловим ready
|
||||
Lampa.Listener.follow('app', function (e) {
|
||||
if (e.type === 'ready') {
|
||||
setTimeout(addMenuItem, 200);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Стартуем когда Lampa готова (или сразу, если уже готова)
|
||||
if (window.Lampa && Lampa.Listener && Lampa.Activity) {
|
||||
start();
|
||||
Lampa.Listener.follow('app', function (e) {
|
||||
if (e.type === 'ready') start();
|
||||
});
|
||||
} else {
|
||||
document.addEventListener('lampa', start);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user