[2026-09-25] eagle: personal/plans/lampac-watchlist-plugin.md personal/tech/lampac-deployment.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-25 23:16:44 +06:00
1 parent e89869b6c1
commit bbfe0329e2
2 files changed
+147 -1

No files matched your search

+103 -1
View File
@@ -8,7 +8,7 @@ related:
- '[[family/projects/watchlist-automation]]'
- '[[family/documents/movies-watchlist]]'
- '[[personal/plans/lampac-watched-to-watchlist]]'
status: third-fix-2026-09-25-component-filter+wlPrefetch-deployed-awaiting-verdict
status: fourth-fix-2026-09-25-activity-hook-deployed-awaiting-verdict
tags:
- lampac
- lampa
@@ -27,6 +27,8 @@ tags:
- partnext
- latency
- wlonmain
- wlprefetch
- activity-hook
title: Watchlist в UI Lampa — каталог из списка
type: plan
updated: '2026-09-25'
@@ -589,6 +591,106 @@ node --check plugin-cub.js → SYNTAX OK
---
## 🔴 ЧЕТВЁРТЫЙ ФИКС 2026-09-25: хук на `activity` (решение найдено замером)
**Симптомы Alex после третьего фикса:**
> «Так, хорошо, Сейчас при загрузке приложения сработало, коммить.
> Но когда я с главной ушел в раздел фильмы там снова были watchlist разделы
> А когда вернулся на главную опять разделы watchlist не сверху»
При холодном старте — правильно; навигация ломала обе части.
### Замер (CDP, живая Lampa): трейс `partNext` + значения полей
Скрипт `/tmp/wl_nav.py`: оборачивает `Lampa.Api.partNext` своим трейсом, затем
`Lampa.Router.call('category_full',{url:'movie',...})`, снапшот `Activity.active()`,
возврат, чтение трейса.
```
ЩАС(главная?) | component=main url= title=Главная - CUB
-> category_full {url:'movie'}
ПОСЛЕ Фильмов | component=category_full url=movie title=Фильмы
ПОСЛЕ возврата| component=category_full url=movie
ТРЕЙС: [] ← partNext НЕ ВЫЗЫВАЛСЯ НИ РАЗУ
```
| Экран | `component` | `url` |
|---|---|---|
| Главная | **`main`** | `` (пусто) |
| Фильмы | **`category_full`** | `movie` |
🔴 **Фильтр по `component` РАБОТАЕТ** — `main` пропускает, `category_full` режет.
Симптом «в Фильмах снова секции» **не от от фильтра**: переход
`main → category_full → main` даёт **ПУСТОЙ трейс `partNext`** — на этих переходах он
не вызывается вообще, Lampa **переиспользует уже отрисованный пул**.
Отсюда оба симптома одним объяснением:
1. **В «Фильмах» видны секции** — это те же отрисованные элементы; Lampa не
перерисовала страницу при переходе.
2. **При возврате они не сверху** — повторного `wlInject` не было, `partNext` не звался.
🔴 **Вывод: опираться на `partNext` как на ЕДИНСТВЕННУЮ точку входа НЕЛЬЗЯ.**
🔴 **Питфолл метода:** `Lampa.Router.call('main')` как «вернуться на главную» **не
работает** (`ERR: Cannot read property 'url' of undefined`). Навигацию по экранам
проверяет Alex пультом, программно её не воспроизвести.
### Фикс — `wlWatchActivity()`
Хук на `Lampa.Listener.follow('activity')`. На старте activity с `component='main'`
сбрасывается `window.__wl_done = false` — следующий `partNext` вставляет секции заново
(в голову, через `unshift`):
```js
function wlWatchActivity() {
if (window.__wl_activity_hook) return;
window.__wl_activity_hook = true;
Lampa.Listener.follow('activity', function (e) {
if (e.type !== 'start') return;
if (wlComp({component: e.component}) === 'main') {
window.__wl_done = false; // ← снять флаг вставки
if (!window.__wl_menu || !Object.keys(window.__wl_menu).length) wlPrefetch();
}
});
}
```
Плюс **`wlPrefetch()` перестал быть одноразовым** — убран гейт `__wl_prefetched`,
меню обновляется при возврате на главную. Вызов в `startPlugin()`:
`wlPatchPartNext();wlPrefetch();wlWatchActivity();`.
### Сборка и деплой (выполнено)
```
python3 build_plugin.py → 17/17 инвариантов, 19773 байт
node --check plugin-cub.js → SYNTAX OK
docker exec lampac grep -c wlWatchActivity /lampac/module/Catalog/plugin.js → 3
бэкап: catalog/plugin.js.bak-before-activityhook-<ts>
рестарт Lampa на ТВ: --- закрываю --- --- запускаю --- --- готово ---
```
**Инварианты (17 всего).** Добавлены `wlWatchActivity def=1`,
`wlWatchActivity call` — считается по строке `wlPrefetch();wlWatchActivity();`,
🔴 **НЕ по `wlWatchActivity()`** (иначе определение ловится как вызов, счётчик врёт:
первый прогон дал 3 вместо 1 → инвариант упал), `activity hook сбрасывает флаг`.
### Приёмка (ждёт Alex) — полный цикл, а не только первый экран
1. главная → 4 секции Watchlist сверху
2. Фильмы → документальные → секций Watchlist нет
3. **назад на главную → секции СНОВА сверху** ← пункт, который ломался
⚠️ **Коммит четвёртого фикса НЕ сделан** — ждёт приёмки. Файлы в
`/Users/admin/lampac-tmp/`; после приёмки скопировать в
`~/Developer/lampac-scripts/scripts/` и закоммитить порядком `5e55a47`.
🔴 **Правило процесса:** Alex не принимает статус-репорты и вопросы вместо результата
(«Ты заебал. Ты блядь задачу решаешь или мозг мне ебешь?!», «Ты делаешь блядь или
опять залип», «Ты все починил? Проверять?») — **доделать и доложить один раз**.
Замер — часть работы, а не отдельная задача на согласование.
---
## 🔴 2026-09-24 (вечер): ПЕРЕПИСЫВАНИЕ — один sync-скрипт вместо отдельного генератора
**Требование Alex:** «перепиши по нормальному чтобы не отдельный скрипт на лампу был
+44
View File
@@ -85,6 +85,50 @@ git commit -m "..." && git push origin main
рестарт приложения на ТВ через `luna-send`. И **не спать** в ожидании: Alex на паузу
`sleep 20` отреагировал резко («Чё нахуй за слип 20?!») — вместо сна опрашивать состояние.
### 🔴 Форма `Lampa.Activity.active()` — ИЗМЕРЕНО (CDP, 2026-09-25)
```
Lampa.Activity.active() → {url, title, component, source, page, params, activity}
Lampa.Activity.active().activity → {component, object, slide, body, is_stopped, is_started}
```
🔴 **`url` лежит НА ВЕРХНЕМ уровне.** Поле `activity.activity` — это СЛАЙД (DOM-обёртка),
`url` там НЕТ вообще. Чтение `active().activity.url` даёт вечные `undefined`.
**Значения по экранам (замерено):**
| Экран | `component` | `url` | `title` |
|---|---|---|---|
| **Главная** | **`main`** | **`` (ПУСТОЙ!)** | `Главная - CUB` |
| **Фильмы / категория** | **`category_full`** | `movie` | `Фильмы` |
🔴🔴 **На главной `url` ПУСТОЙ, а не `'main'`.** Поэтому:
- проверка `url === 'main'` **не работает вообще** — никогда не срабатывает;
- **определять экран надо по `component`**, оно стабильно на обоих экранах.
### 🔴 Трейс вызовов `partNext` — как узнать, вызывается ли он на переходах
Обернуть `partNext` своим трейсом, подёргать навигацию, прочитать массив:
```js
var orig = Lampa.Api.partNext;
Lampa.Api.partNext = function(parts, limit, ok, empty){
var a = Lampa.Activity.active();
window.__wl_trace.push(String(a.component||'')+'|url='+String(a.url||'')+'|n='+(parts?parts.length:'?'));
return orig.apply(this, arguments);
};
```
**Результат на переходе `main → category_full → main`: трейс ПУСТОЙ.** То есть
`partNext` на этих переходах **не вызывается вообще** — Lampa переиспользует уже
отрисованный пул. Любая логика, висящая ТОЛЬКО на `partNext`, на навигации не сработает;
нужен отдельный хук `Lampa.Listener.follow('activity')`.
🔴 **Питфолл метода:** `Lampa.Router.call('main')` как «вернуться на главную» **не
работает** — падает с `Cannot read property 'url' of undefined`. Программно
эмулируется только уход В категорию (`Router.call('category_full',{url:'movie',...})`);
возврат на главную воспроизводит только Alex пультом.
🔴 **Правило диагностики:** не читать `curl -w %{size_download}` как «размер фида» —
это размер ПОСЛЕ распаковки gzip. Брать `ls -la` или `Accept-Encoding: identity`.
Пример: `watchlist-films.json` = 88 КБ несжатых при 347 позициях, а `cards.json` = 548 КБ.