- Confirm dialog: предзагрузка WebContentsView при старте приложения. Раньше каждое нажатие "Закрыть" создавало новый view с холодной загрузкой HTML+React → ~2с лаг и дубликаты от повторных кликов. Теперь view кэшируется, текст обновляется через IPC, повторные клики игнорируются пока диалог открыт. - Темы: 14 → 71 (Война, Холодная война, Вьетнам, Призраки, Драконы, Шахматы, Самолёты, Поезда, Сёрфинг, Япония, ...). Все ID провалидированы probe-скриптом (≥50 фильмов на тематику). - Chip-row заменён на SearchableSelect с поиском по подстроке — длинный список не помещается в чипы, а dropdown с фильтром гораздо удобнее. Заодно ушёл фиолетовый цвет чипа, плохо сочетавшийся с темой сайта.
61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
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 />)
|