Files
ESH-Media/src/entries/dialog-confirm.tsx
eshmeshek 747b0f4c18 feat(1.0.14): тематики searchable, фикс лага confirm-диалога
- Confirm dialog: предзагрузка WebContentsView при старте приложения.
  Раньше каждое нажатие "Закрыть" создавало новый view с холодной
  загрузкой HTML+React → ~2с лаг и дубликаты от повторных кликов.
  Теперь view кэшируется, текст обновляется через IPC, повторные
  клики игнорируются пока диалог открыт.
- Темы: 14 → 71 (Война, Холодная война, Вьетнам, Призраки, Драконы,
  Шахматы, Самолёты, Поезда, Сёрфинг, Япония, ...). Все ID
  провалидированы probe-скриптом (≥50 фильмов на тематику).
- Chip-row заменён на SearchableSelect с поиском по подстроке —
  длинный список не помещается в чипы, а dropdown с фильтром
  гораздо удобнее. Заодно ушёл фиолетовый цвет чипа, плохо
  сочетавшийся с темой сайта.
2026-05-17 11:29:39 +03:00

61 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect, useState } from 'react'
import ReactDOM from 'react-dom/client'
import '../styles/dialogs.css'
declare global {
interface Window {
electron?: {
handleAction: (action: string) => void
on: (channel: string, fn: (...args: any[]) => void) => () => void
}
__dialogData?: { text?: string }
}
}
const ConfirmDialog = () => {
// Cached view re-uses этот компонент: текст и видимость приходят по IPC.
// initialText из URL — backwards compat (если кто-то откроет dialog-confirm.html напрямую).
const initialText = new URLSearchParams(window.location.search).get('text') || ''
const [text, setText] = useState(initialText)
const [visible, setVisible] = useState(false)
useEffect(() => {
if (initialText) {
requestAnimationFrame(() => requestAnimationFrame(() => setVisible(true)))
}
return window.electron?.on('dialog-confirm-set', (data: { text?: string; visible?: boolean }) => {
if (typeof data.text === 'string') setText(data.text)
if (typeof data.visible === 'boolean') {
if (data.visible) requestAnimationFrame(() => requestAnimationFrame(() => setVisible(true)))
else setVisible(false)
}
})
}, [])
useEffect(() => {
if (visible) {
document.body.classList.remove('hiding')
document.body.classList.add('visible')
} else {
document.body.classList.remove('visible')
document.body.classList.add('hiding')
}
}, [visible])
return (
<div className="card">
{text && <div className="msg">{text}</div>}
<div className="btns">
<button className="btn-yes" onClick={() => window.electron?.handleAction('confirmYes')}>
Да
</button>
<button className="btn-no" onClick={() => window.electron?.handleAction('confirmNo')}>
Нет
</button>
</div>
</div>
)
}
ReactDOM.createRoot(document.getElementById('root')!).render(<ConfirmDialog />)