feat(1.0.14): тематики searchable, фикс лага confirm-диалога
- Confirm dialog: предзагрузка WebContentsView при старте приложения. Раньше каждое нажатие "Закрыть" создавало новый view с холодной загрузкой HTML+React → ~2с лаг и дубликаты от повторных кликов. Теперь view кэшируется, текст обновляется через IPC, повторные клики игнорируются пока диалог открыт. - Темы: 14 → 71 (Война, Холодная война, Вьетнам, Призраки, Драконы, Шахматы, Самолёты, Поезда, Сёрфинг, Япония, ...). Все ID провалидированы probe-скриптом (≥50 фильмов на тематику). - Chip-row заменён на SearchableSelect с поиском по подстроке — длинный список не помещается в чипы, а dropdown с фильтром гораздо удобнее. Заодно ушёл фиолетовый цвет чипа, плохо сочетавшийся с темой сайта.
This commit is contained in:
58
main.js
58
main.js
@@ -453,6 +453,10 @@ async function createWindow() {
|
||||
} else {
|
||||
mainWindow.loadFile(path.join(__dirname, 'dist', 'index.html'));
|
||||
}
|
||||
|
||||
// Прогрев confirm-диалога: создаём WebContentsView один раз, чтобы убрать ~2с лаг
|
||||
// при первом нажатии кнопки закрытия (и кнопки навигации с подтверждением).
|
||||
preloadConfirmView();
|
||||
}
|
||||
|
||||
// --- View helpers ---
|
||||
@@ -544,22 +548,56 @@ function removeError() {
|
||||
dialogFadeOut(view, () => { try { removeChild(view); view.webContents.destroy(); } catch (_) {} });
|
||||
}
|
||||
|
||||
function setConfirm(text, actionOnYes) {
|
||||
const view = makeDialogView();
|
||||
confirmViews.push({ view, actionOnYes });
|
||||
const query = new URLSearchParams({ text: text || '' }).toString();
|
||||
view.webContents.once('did-finish-load', () => { addChild(view); });
|
||||
// Confirm dialog: один кэшированный WebContentsView, переиспользуем для всех confirm'ов.
|
||||
// Холодный старт WebContentsView с React-загрузкой занимает ~1-2с, отсюда был лаг
|
||||
// при нажатии на кнопку закрытия. Теперь view создаётся при старте приложения и хранится готовым.
|
||||
let confirmCachedView = null;
|
||||
let confirmReady = false;
|
||||
let activeConfirm = null; // { actionOnYes } если диалог открыт, иначе null
|
||||
let pendingConfirm = null; // если showConfirm вызвали до того как view загрузился
|
||||
|
||||
function preloadConfirmView() {
|
||||
if (confirmCachedView) return;
|
||||
confirmCachedView = makeDialogView();
|
||||
confirmCachedView.webContents.once('did-finish-load', () => {
|
||||
confirmReady = true;
|
||||
if (pendingConfirm) {
|
||||
const p = pendingConfirm;
|
||||
pendingConfirm = null;
|
||||
setConfirm(p.text, p.actionOnYes);
|
||||
}
|
||||
});
|
||||
if (isDev) {
|
||||
view.webContents.loadURL(`${RENDERER_URL}/dialog-confirm.html?${query}`);
|
||||
confirmCachedView.webContents.loadURL(`${RENDERER_URL}/dialog-confirm.html`);
|
||||
} else {
|
||||
view.webContents.loadFile(path.join(__dirname, 'dist', 'dialog-confirm.html'), { query: { text: text || '' } });
|
||||
confirmCachedView.webContents.loadFile(path.join(__dirname, 'dist', 'dialog-confirm.html'));
|
||||
}
|
||||
}
|
||||
|
||||
function setConfirm(text, actionOnYes) {
|
||||
// Гард: если уже открыт диалог — игнорируем повторные клики (никаких дубликатов).
|
||||
if (activeConfirm) return;
|
||||
if (!confirmReady) {
|
||||
pendingConfirm = { text, actionOnYes };
|
||||
return;
|
||||
}
|
||||
activeConfirm = { actionOnYes };
|
||||
// confirmViews — для backwards compat с обработчиком action; держим в синхроне.
|
||||
confirmViews.push({ view: confirmCachedView, actionOnYes });
|
||||
confirmCachedView.webContents.send('dialog-confirm-set', { text, visible: true });
|
||||
addChild(confirmCachedView);
|
||||
}
|
||||
|
||||
function removeConfirm() {
|
||||
if (!confirmViews.length) return;
|
||||
const { view } = confirmViews.pop();
|
||||
dialogFadeOut(view, () => { try { removeChild(view); view.webContents.destroy(); } catch (_) {} });
|
||||
if (!activeConfirm) return;
|
||||
activeConfirm = null;
|
||||
confirmViews.pop();
|
||||
confirmCachedView.webContents.send('dialog-confirm-set', { visible: false });
|
||||
// Жду fade-out (≈220ms по dialogs.css), потом снимаю с DOM. View остаётся живой для следующего раза.
|
||||
setTimeout(() => {
|
||||
if (activeConfirm) return; // если за это время открыли новый — оставить
|
||||
try { removeChild(confirmCachedView); } catch (_) {}
|
||||
}, 250);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user