diff --git a/app/main/windows/createWindows.editorClose.test.ts b/app/main/windows/createWindows.editorClose.test.ts index 03f4820..d8e6098 100644 --- a/app/main/windows/createWindows.editorClose.test.ts +++ b/app/main/windows/createWindows.editorClose.test.ts @@ -112,10 +112,11 @@ void test('createWindows: окно НПС закрывается с multi-window assert.ok(src.includes('will-attach-webview')); }); -void test('createWindows: закрытие пульта закрывает сессионные окна и презентацию', () => { +void test('createWindows: закрытие пульта и презентации спрашивает confirm', () => { const src = readCreateWindows(); - assert.match(src, /kind === 'control'/); - assert.match(src, /closePlaySessionAuxiliaryWindows[\s\S]*closePresentationWindow/); + assert.match(src, /kind === 'control'[\s\S]*?e\.preventDefault\(\)[\s\S]*?requestCloseMultiWindowConfirm/); + assert.match(src, /kind === 'presentation'[\s\S]*?e\.preventDefault\(\)[\s\S]*?requestCloseMultiWindowConfirm/); + assert.match(src, /export function closeMultiWindow[\s\S]*closePlaySessionAuxiliaryWindows/); }); void test('createWindows: production — loadFile для HTML (не только file://)', () => { diff --git a/app/main/windows/createWindows.ts b/app/main/windows/createWindows.ts index 5ae4982..39a7826 100644 --- a/app/main/windows/createWindows.ts +++ b/app/main/windows/createWindows.ts @@ -220,20 +220,6 @@ function closePlaySessionAuxiliaryWindows(): void { closeNpcsWindow(); } -function closePresentationWindow(): void { - const pres = windows.get('presentation'); - if (pres && !pres.isDestroyed()) { - pres.close(); - } -} - -function closeControlWindow(): void { - const ctrl = windows.get('control'); - if (ctrl && !ctrl.isDestroyed()) { - ctrl.close(); - } -} - function quitAppFromEditorClose(): void { markAppQuitting(); app.quit(); @@ -535,20 +521,18 @@ function createWindow(kind: WindowKind, opts?: CreateWindowOpts): BrowserWindow }); } if (kind === 'control') { - win.on('close', () => { + win.on('close', (e) => { if (appQuitting || closingPlaySession) return; - closingPlaySession = true; - closePlaySessionAuxiliaryWindows(); - closePresentationWindow(); + e.preventDefault(); + requestCloseMultiWindowConfirm(); }); } if (kind === 'presentation') { bindPresentationContentSizeTracking(win); - win.on('close', () => { + win.on('close', (e) => { if (appQuitting || closingPlaySession) return; - closingPlaySession = true; - closePlaySessionAuxiliaryWindows(); - closeControlWindow(); + e.preventDefault(); + requestCloseMultiWindowConfirm(); }); } win.on('closed', () => windows.delete(kind)); @@ -684,10 +668,13 @@ export function closeMultiWindow(): void { } } -/** Фокус пульта + событие: Escape с презентации спрашивает подтверждение там. */ +/** Фокус пульта + событие: выход из показа спрашивает подтверждение на пульте. */ export function requestCloseMultiWindowConfirm(): void { const ctrl = windows.get('control'); - if (!ctrl || ctrl.isDestroyed()) return; + if (!ctrl || ctrl.isDestroyed()) { + closeMultiWindow(); + return; + } if (ctrl.isMinimized()) ctrl.restore(); ctrl.show(); ctrl.focus(); diff --git a/app/renderer/control/ControlApp.tsx b/app/renderer/control/ControlApp.tsx index aa72219..3c691f5 100644 --- a/app/renderer/control/ControlApp.tsx +++ b/app/renderer/control/ControlApp.tsx @@ -1958,6 +1958,22 @@ export function ControlApp() { +
<> @@ -2498,9 +2514,7 @@ export function ControlApp() { : t('control.showPlayers')} ) : null} - +
@@ -2508,7 +2522,7 @@ export function ControlApp() {
void api.invoke(ipcChannels.windows.closeMultiWindow, {})} + onClick={() => setStopConfirmOpen(true)} > - {t('control.endPresentation')} + {t('control.stopPresentation')}
) : null} diff --git a/app/renderer/control/controlApp.effectsPanel.test.ts b/app/renderer/control/controlApp.effectsPanel.test.ts index 9d0c484..cbdc747 100644 --- a/app/renderer/control/controlApp.effectsPanel.test.ts +++ b/app/renderer/control/controlApp.effectsPanel.test.ts @@ -323,6 +323,10 @@ void test('ControlApp: Escape → своя модалка подтвержден assert.ok(src.includes('stopConfirmOpen')); assert.ok(src.includes('control.stopConfirm.title')); assert.ok(src.includes('data-testid="stop-confirm-modal"')); + assert.ok(src.includes('data-testid="control-help-tool"')); + assert.match(src, /data-testid="control-help-tool"[\s\S]{0,180}iconOnly|iconOnly[\s\S]{0,180}data-testid="control-help-tool"/); + assert.ok(src.includes("section: 'controlPanel'")); + assert.equal((src.match(/windows\.closeMultiWindow,/g) ?? []).length, 1); assert.ok(!src.includes('showMessageBox')); assert.ok(!src.includes('window.confirm')); }); diff --git a/app/renderer/editor/EditorApp.module.css b/app/renderer/editor/EditorApp.module.css index 34bc02e..a3617e1 100644 --- a/app/renderer/editor/EditorApp.module.css +++ b/app/renderer/editor/EditorApp.module.css @@ -53,6 +53,12 @@ user-select: none; } +.helpMark { + font-size: 18px; + font-weight: 400; + line-height: 1; +} + .headerActions { display: flex; align-items: center; diff --git a/app/renderer/editor/EditorApp.tsx b/app/renderer/editor/EditorApp.tsx index ab6f6e5..baa7344 100644 --- a/app/renderer/editor/EditorApp.tsx +++ b/app/renderer/editor/EditorApp.tsx @@ -130,7 +130,6 @@ export function EditorApp() { const [projectMenuOpen, setProjectMenuOpen] = useState(false); const [settingsMenuOpen, setSettingsMenuOpen] = useState(false); const [settingsLangSubOpen, setSettingsLangSubOpen] = useState(false); - const [aboutMenuOpen, setAboutMenuOpen] = useState(false); const [appAboutOpen, setAppAboutOpen] = useState(false); const [renameOpen, setRenameOpen] = useState(false); const [exportModalOpen, setExportModalOpen] = useState(false); @@ -279,11 +278,9 @@ export function EditorApp() { const fileMenuBtnRef = useRef(null); const projectMenuBtnRef = useRef(null); const settingsMenuBtnRef = useRef(null); - const aboutMenuBtnRef = useRef(null); const [fileMenuPos, setFileMenuPos] = useState<{ left: number; top: number } | null>(null); const [projectMenuPos, setProjectMenuPos] = useState<{ left: number; top: number } | null>(null); const [settingsMenuPos, setSettingsMenuPos] = useState<{ left: number; top: number } | null>(null); - const [aboutMenuPos, setAboutMenuPos] = useState<{ left: number; top: number } | null>(null); const [selectedGraphNodeId, setSelectedGraphNodeId] = useState(null); const [sceneListDrop, setSceneListDrop] = useState<{ targetId: SceneId; @@ -489,26 +486,6 @@ export function EditorApp() { if (!settingsMenuOpen) setSettingsLangSubOpen(false); }, [settingsMenuOpen]); - useEffect(() => { - if (!aboutMenuOpen) return; - const r = aboutMenuBtnRef.current?.getBoundingClientRect() ?? null; - queueMicrotask(() => { - if (r) { - setAboutMenuPos({ left: r.left, top: r.bottom + 10 }); - } else { - setAboutMenuPos(null); - } - }); - const onDown = (e: MouseEvent) => { - const t = e.target as HTMLElement | null; - if (!t) return; - if (t.closest('[data-aboutmenu-root="1"]')) return; - setAboutMenuOpen(false); - }; - window.addEventListener('mousedown', onDown); - return () => window.removeEventListener('mousedown', onDown); - }, [aboutMenuOpen]); - useEffect(() => { if (!runMenuOpen) return; const r = runSplitRef.current?.getBoundingClientRect() ?? null; @@ -818,7 +795,6 @@ export function EditorApp() { onClick={() => { setFileMenuOpen(false); setProjectMenuOpen(false); - setAboutMenuOpen(false); setSettingsMenuOpen((v) => { const next = !v; if (next) setSettingsLangSubOpen(false); @@ -829,16 +805,14 @@ export function EditorApp() { {t('top.settings')}
) : null} +
{state.project ? ( <> @@ -1477,40 +1460,6 @@ export function EditorApp() { snapshot={licenseSnap} /> setAppAboutOpen(false)} appVersion={appVersionText} /> - {aboutMenuOpen && aboutMenuPos - ? createPortal( -
- - -
, - document.body, - ) - : null} {projectMenuOpen && projectMenuPos ? createPortal(
- Редактор сцены + {t('sceneEditor.open')} ) : null} diff --git a/app/renderer/editor/i18n/editorMessages.ts b/app/renderer/editor/i18n/editorMessages.ts index debb3dd..3eadb0b 100644 --- a/app/renderer/editor/i18n/editorMessages.ts +++ b/app/renderer/editor/i18n/editorMessages.ts @@ -101,7 +101,7 @@ export const EDITOR_MESSAGES: Record> = { 'presentation.overlay': 'Презентация запущена', 'presentation.title': 'Презентация запущена', 'presentation.body': - 'Редактор заблокирован. Закройте окна «Презентация» и «Панель управления», чтобы продолжить.', + 'Редактор заблокирован. На пульте нажмите «Завершить» и подтвердите, чтобы продолжить.', 'zip.progress': 'Прогресс операции', 'zip.importTitle': 'Импорт проекта', @@ -191,7 +191,7 @@ export const EDITOR_MESSAGES: Record> = { 'help.section.sceneProps.title': 'Свойства сцены', 'help.section.sceneProps.body': - 'Выберите сцену в списке слева — справа откроются её свойства.\n\n«Название сцены» — для мастера. «Описание» — заметки мастера с форматированием: рядом с подписью нажмите карандаш, откроется редактор (жирный, курсив, заголовки, списки, ссылки). Под подписью видно фрагмент текста или «описание отсутствует», если поле пустое. Во время сессии описание открывается с пульта в отдельном окне (см. «Пульт управления»), а не в блоке «Сюжетная линия».\n\nЕсли у сцены на карте есть карточка с синей меткой «ПОБОЧНАЯ», появится поле «Название побочной линии».\n\nКартинка или видео для игроков:\n\n1) В «Превью сцены» нажмите «Загрузить» или «Изменить».\n\n2) Выберите файл (PNG, JPG, WebP, GIF, видео и др.).\n\n3) Для картинки и видео можно «Повернуть» (шаг 90°). «Очистить» — убрать превью.\n\n4) Для картинки и видео можно включить «Затемнить сцену»: при показе игроки сначала увидят кадр в полной темноте, а вы снимете её с пульта «Кистью Открытия» (см. «Эффекты»).\n\n5) Кнопка «Редактор сцены» доступна и для картинки, и для видео — сетка, ловушки, неигровые токены и токены НПС поверх превью (см. «Редактор сцены», «Генератор сетки», «Ловушки», «Неигровые токены», «НПС»).\n\nДля видео включите «Автостарт», если ролик должен сам начаться на экране игроков, и при необходимости «Цикл».\n\n«Аудио сцены» — музыка и звуки этого эпизода. «Загрузить» добавляет файлы. У каждого трека: «Авто» (играть при входе в сцену) и «Цикл». Корзина удаляет трек.\n\nСвязи между сценами задаются на карте, а не здесь — см. «Граф сцен».', + 'Выберите сцену в списке слева — справа откроются её свойства.\n\n«Название сцены» — для мастера. «Описание» — заметки мастера с форматированием: рядом с подписью нажмите карандаш, откроется редактор (жирный, курсив, заголовки, списки, ссылки). Под подписью видно фрагмент текста или «описание отсутствует», если поле пустое. Во время сессии описание открывается с пульта в отдельном окне (см. «Пульт управления»), а не в блоке «История».\n\nЕсли у сцены на карте есть карточка с синей меткой «ПОБОЧНАЯ», появится поле «Название побочной линии».\n\nКартинка или видео для игроков:\n\n1) В «Превью сцены» нажмите «Загрузить» или «Изменить».\n\n2) Выберите файл (PNG, JPG, WebP, GIF, видео и др.).\n\n3) Для картинки и видео можно «Повернуть» (шаг 90°). «Очистить» — убрать превью.\n\n4) Для картинки и видео можно включить «Затемнить сцену»: при показе игроки сначала увидят кадр в полной темноте, а вы снимете её с пульта «Кистью Открытия» (см. «Эффекты»).\n\n5) Кнопка «Редактор сцены» доступна и для картинки, и для видео — сетка, ловушки, неигровые токены и токены НПС поверх превью (см. «Редактор сцены», «Генератор сетки», «Ловушки», «Неигровые токены», «НПС»).\n\nДля видео включите «Автостарт», если ролик должен сам начаться на экране игроков, и при необходимости «Цикл».\n\n«Аудио сцены» — музыка и звуки этого эпизода. «Загрузить» добавляет файлы. У каждого трека: «Авто» (играть при входе в сцену) и «Цикл». Корзина удаляет трек.\n\nСвязи между сценами задаются на карте, а не здесь — см. «Граф сцен».', 'help.section.sceneEditor.title': 'Редактор сцены', 'help.section.sceneEditor.body': @@ -201,6 +201,56 @@ export const EDITOR_MESSAGES: Record> = { 'help.section.grid.body': 'Генератор сетки накладывает на превью сцены (картинку или видео) боевую сетку — квадратную или гексагональную. Сетка помогает ориентироваться по клеткам во время боя и видна и вам на пульте, и игрокам на презентации.\n\nНастроить:\n\n1) Откройте «Редактор сцены» (см. «Редактор сцены»).\n\n2) Раскройте аккордеон «Сетка» слева.\n\n3) Включите «Наложить сетку» — линии появятся поверх карты.\n\n4) «Тип» — «Квадратная» или «Гексогональная».\n\n5) «Цвет» — оттенок линий (удобно подобрать контраст к карте).\n\n6) «Размер» — ползунок ячейки: чем больше значение, тем крупнее клетки.\n\nПока сетка выключена, тип, цвет и размер недоступны для изменения, но запомненные значения сохраняются и вернутся при повторном включении.\n\nШаблоны сетки кампании:\n\n1) Настройте сетку на сцене.\n\n2) Нажмите «Сохранить как шаблон» и задайте имя — стиль (тип, цвет, размер) запишется в файл проекта. Автоматически на другие сцены он не подставляется.\n\n3) На любой сцене в списке шаблонов нажмите «Применить» — на сцену запишутся параметры шаблона и сетка включится.\n\n4) Шаблон можно переименовать или удалить. В кампании можно хранить несколько шаблонов (до 20).\n\nНастройки сетки каждой сцены и список шаблонов хранятся в проекте. Сетка рисуется под маркерами ловушек и токенов и не мешает их расставлять.\n\nВо время сессии на пульте можно включить «Привязка токенов к сетке»: при перетаскивании неигровые токены, токены НПС и игроков «прилипают» к клеткам (квадрат или гекс — по типу сетки). Если сетка выключена, галочка не действует.', + 'sceneEditor.open': 'Редактор сцены', + 'sceneEditor.grid': 'Сетка', + 'sceneEditor.enableGrid': 'Наложить сетку', + 'sceneEditor.gridType': 'Тип', + 'sceneEditor.gridTypeAria': 'Тип сетки', + 'sceneEditor.gridSquare': 'Квадратная', + 'sceneEditor.gridHex': 'Гексогональная', + 'sceneEditor.gridColor': 'Цвет', + 'sceneEditor.gridColorAria': 'Цвет сетки', + 'sceneEditor.gridSize': 'Размер', + 'sceneEditor.npcs': 'НПС', + 'sceneEditor.npcSearch': 'Поиск НПС…', + 'sceneEditor.noNpcs': 'Нет НПС', + 'sceneEditor.tokens': 'Неигровые токены', + 'sceneEditor.add': 'Добавить', + 'sceneEditor.tokenSearch': 'Поиск…', + 'sceneEditor.noTokens': 'Нет токенов', + 'sceneEditor.traps': 'Ловушки', + 'sceneEditor.dragToMap': 'Перетащите на карту', + 'sceneEditor.clearScene': 'Очистить сцену', + 'sceneEditor.needMedia': 'Нужно изображение или видео сцены', + 'sceneEditor.mapHint': 'Колесо — зум. СКМ / Space+ЛКМ — пан. Delete — удалить выбранное.', + 'sceneEditor.untitledScene': 'Сцена', + 'sceneEditor.deleteTokenTitle': 'Удалить токен', + 'sceneEditor.deleteTokenBody': 'Удалить токен «{name}» из пула? Он также будет убран с текущей сцены.', + 'sceneEditor.setPath': 'Указать движение', + 'sceneEditor.resetPath': 'Сбросить на старт пути', + 'sceneEditor.trap.mimic': 'Мимик', + 'sceneEditor.trap.explosion': 'Взрыв', + 'sceneEditor.trap.poison': 'Яд', + 'sceneEditor.trap.pit': 'Пропасть', + 'sceneEditor.trap.arrow': 'Стрела', + 'sceneEditor.trap.laser': 'Лазер', + 'sceneEditor.trap.freeform': 'Метка', + 'sceneEditor.editToken': 'Изменить токен', + 'sceneEditor.addToken': 'Добавить токен', + 'sceneEditor.tokenName': 'Название', + 'sceneEditor.tokenNamePlaceholder': 'Название токена', + 'sceneEditor.tokenNameRequired': 'Укажите название', + 'sceneEditor.tokenNameDuplicate': 'Такое название уже есть', + 'sceneEditor.image': 'Изображение', + 'sceneEditor.dropImage': 'Отпустите, чтобы загрузить изображение', + 'sceneEditor.dropOrPick': 'Перетащите изображение или выберите файл', + 'sceneEditor.chooseImage': 'Выбрать изображение', + 'sceneEditor.imageRequired': 'Нужно изображение', + 'sceneEditor.saveFailed': 'Не удалось сохранить', + 'sceneEditor.dragDelete': 'Перетащите · ПКМ — удалить', + 'sceneEditor.rotate': 'Повернуть', + 'sceneEditor.actions': 'Действия', + 'sceneEditor.edit': 'Изменить', 'sceneGrid.templates': 'Шаблоны кампании', 'sceneGrid.saveTemplate': 'Сохранить как шаблон', 'sceneGrid.applyTemplate': 'Применить', @@ -236,15 +286,15 @@ export const EDITOR_MESSAGES: Record> = { 'help.section.session.title': 'Запуск сессии', 'help.section.session.body': - 'Когда кампания готова, можно начать игру.\n\nОбычный запуск:\n\n1) На карте связей щёлкните правой кнопкой по карточке старта → «Начальная сцена».\n\n2) Нажмите «Запустить» в шапке редактора (левая часть кнопки).\n\nЗапуск с игроками: стрелка справа на кнопке «Запустить» → «Запустить с игроками» — выберите игроков и/или команды. Выбор сохранится на время сессии; на пульте появится «Показать игроков» / «Скрыть игроков». При смене сцены токены игроков скрываются.\n\nБыстрый запуск с любой карточки: правый клик по нужной карточке на карте → «Запустить с этой сцены». Презентация и пульт откроются сразу с выбранного места.\n\nОткроются «Презентация» (для игроков) и «Пульт управления» (для вас). Редактор на время показа затемняется — так и должно быть.\n\nЭкран для игроков можно заранее выбрать в «Настройки» → «Экран презентации»: монитор и полноэкранный режим. При «Запустить» окно презентации откроется на выбранном экране автоматически.\n\nВернуться к подготовке:\n\n1) На пульте нажмите «Выключить» или «Завершить показ» (если дальше некуда переходить).\n\n2) Дождитесь закрытия обоих окон.', + 'Когда кампания готова, можно начать игру.\n\nОбычный запуск:\n\n1) На карте связей щёлкните правой кнопкой по карточке старта → «Начальная сцена».\n\n2) Нажмите «Запустить» в шапке редактора (левая часть кнопки).\n\nЗапуск с игроками: стрелка справа на кнопке «Запустить» → «Запустить с игроками» — выберите игроков и/или команды. Выбор сохранится на время сессии; на пульте появится «Показать игроков» / «Скрыть игроков». При смене сцены токены игроков скрываются.\n\nБыстрый запуск с любой карточки: правый клик по нужной карточке на карте → «Запустить с этой сцены». Презентация и пульт откроются сразу с выбранного места.\n\nОткроются «Презентация» (для игроков) и «Пульт управления» (для вас). Редактор на время показа затемняется — так и должно быть.\n\nЭкран для игроков можно заранее выбрать в «Настройки» → «Экран презентации»: монитор и полноэкранный режим. При «Запустить» окно презентации откроется на выбранном экране автоматически.\n\nВернуться к подготовке:\n\n1) На пульте нажмите «Завершить» (у предпросмотра или в блоке ветвления, если переходов нет). Тот же вопрос задают Escape и закрытие окна презентации или пульта.\n\n2) В окне «Завершить показ?» нажмите «Завершить» и дождитесь закрытия обоих окон.', 'help.section.controlPanel.title': 'Пульт управления', 'help.section.controlPanel.body': - 'Пульт — ваш стол во время игры. Игроки смотрят на презентацию, вы управляете всем отсюда.\n\nСлева сверху — «Инструменты», затем эффекты и ход сюжета; справа — мини-копия экрана игроков, варианты переходов и музыка.\n\nВ «Инструменты» кнопка с книгой открывает отдельное окно с оформленным описанием текущей сцены. Если описания нет, кнопка неактивна — при наведении подсказка «Описание отсутствует». Кнопка материалов (иконка карты) открывает окно со списком материалов кампании — подробнее в разделе «Материалы». Кнопка ⏱ открывает таймер сессии (обратный отсчёт): «Показать игрокам» выводит виджет на предпросмотр и презентацию — его можно двигать, масштабировать и вращать на превью пульта. Кнопка НПС (цветная иконка человека) открывает окно персонажей: карточки описания, чекбокс «Показать» для аватара поверх сцены и постановка токена на карту на время сессии — см. раздел «НПС».\n\n«Предпросмотр экрана» показывает то же, что видят игроки. Здесь же рисуют эффекты — они сразу появляются на большом экране (и на картинке, и на видео). Если на сцене расставлены ловушки, они видны на предпросмотре: правый клик по маркеру — проявить, активировать или обезвредить (см. «Ловушки»). Неигровые токены, токены НПС и игроков тоже видны на предпросмотре: их можно двигать и менять размер за жёлтый уголок до конца сессии. Линии путей движения видны вам всегда; игрокам — только после «Показать путь» в меню токена. На превью можно перетащить плитку из окна НПС — появится сессионный токен. ПКМ по неигровому токену — показать / скрыть путь, остановить / продолжить движение, сброс на старт. ПКМ по токену НПС — активировать / открыть информацию / сменить тип / сделать неактивным / убрать с карты / путь (см. «НПС» и «Неигровые токены»). Аватары с чекбокса «Показать» лежат поверх сцены отдельно от токенов на карте: их двигают, масштабируют лупами из окна НПС и закрывают «Закрыть всех». На видео-сценах внизу превью остаются кнопки воспроизведения и полоса перемотки.\n\nНад превью:\n• «Привязка токенов к сетке» — если на сцене включена сетка, перетаскиваемые токены (неигровые, НПС, игроки) встают по клеткам;\n• «Размеры игр. токенов» — общий масштаб круглых токенов игроков и НПС на предпросмотре и презентации;\n• «Показать игроков» / «Скрыть игроков» — после запуска с игроками.\n\n«Сюжетная линия» — цепочка пройденных эпизодов. Текущая сцена помечена «ТЕКУЩАЯ СЦЕНА». Клик по прошлому шагу переносит партию к тому месту на карте и добавляет новый шаг в историю.\n\n«Выключить демонстрацию» — закончить показ и вернуться в редактор.', + 'Пульт — ваш стол во время игры. Игроки смотрят на презентацию, вы управляете всем отсюда.\n\nСлева сверху — «Инструменты», затем эффекты, «История» и «Сцены»; справа — мини-копия экрана игроков, варианты переходов и музыка.\n\nВ «Инструменты»: маркер (рисунок на карте), книга (описание текущей сцены; если описания нет, кнопка неактивна и подсказка «Описание отсутствует»), материалы (см. «Материалы»), плейлисты, таймер (обратный отсчёт: «Показать игрокам» выводит виджет на предпросмотр и презентацию), инициатива (очередь хода), кубики, НПС (карточки, чекбокс «Показать» для аватара и постановка токена на карту — см. «НПС») и «?» («Справка»: открывает этот раздел, не закрывая показ).\n\n«Предпросмотр экрана» показывает то же, что видят игроки. Здесь же рисуют эффекты — они сразу появляются на большом экране (и на картинке, и на видео). Если на сцене расставлены ловушки, они видны на предпросмотре: правый клик по маркеру — проявить, активировать или обезвредить (см. «Ловушки»). Неигровые токены, токены НПС и игроков тоже видны на предпросмотре: их можно двигать и менять размер за жёлтый уголок до конца сессии. Линии путей движения видны вам всегда; игрокам — только после «Показать путь» в меню токена. На превью можно перетащить плитку из окна НПС — появится сессионный токен. ПКМ по неигровому токену — показать / скрыть путь, остановить / продолжить движение, сброс на старт. ПКМ по токену НПС — активировать / открыть информацию / сменить тип / сделать неактивным / убрать с карты / путь (см. «НПС» и «Неигровые токены»). Аватары с чекбокса «Показать» лежат поверх сцены отдельно от токенов на карте: их двигают, масштабируют лупами из окна НПС и закрывают «Закрыть всех». На видео-сценах внизу превью остаются кнопки воспроизведения и полоса перемотки.\n\nНад превью:\n• «Привязка токенов к сетке» — если на сцене включена сетка, перетаскиваемые токены (неигровые, НПС, игроки) встают по клеткам;\n• «Размер токенов игроков» — общий масштаб круглых токенов игроков и НПС на предпросмотре и презентации;\n• «Показать игроков» / «Скрыть игроков» — после запуска с игроками.\n\n«История» — цепочка пройденных эпизодов. Текущая сцена помечена «ТЕКУЩАЯ СЦЕНА». Клик по прошлому шагу переносит партию к тому месту на карте и добавляет новый шаг в историю. «Сцены» — сцены текущей линии, чтобы перейти к любой из них.\n\n«Завершить» у предпросмотра и в конце ветки (когда переходов нет) спрашивает подтверждение и после него закрывает показ. Escape на пульте и на презентации, а также закрытие этих окон, задают тот же вопрос.', 'help.section.transitions.title': 'Переходы между сценами', 'help.section.transitions.body': - 'Куда можно пойти дальше — видно на пульте в «Варианты ветвления». Это исходящие стрелки с текущей карточки на карте.\n\n1) Посмотрите карточки «ОПЦИЯ 1», «ОПЦИЯ 2» — там названия целевых сцен.\n\n2) Нажмите «Переключить» у нужного варианта.\n\n3) На презентации сменятся картинка и музыка, в сюжетной линии появится новый шаг.\n\nЕсли вариантов нет (конец ветки) — «Нет вариантов перехода». Нажмите «Завершить показ», чтобы закрыть окна.\n\nВарианты появляются только там, где вы провели стрелки на карте в редакторе.', + 'Куда можно пойти дальше — видно на пульте в «Варианты ветвления». Это исходящие стрелки с текущей карточки на карте.\n\n1) Посмотрите карточки «ОПЦИЯ 1», «ОПЦИЯ 2» — там названия целевых сцен.\n\n2) Нажмите «Переключить» у нужного варианта.\n\n3) На презентации сменятся картинка и музыка, в сюжетной линии появится новый шаг.\n\nЕсли вариантов нет (конец ветки) — «Нет вариантов перехода». Нажмите «Завершить», чтобы закрыть окна.\n\nВарианты появляются только там, где вы провели стрелки на карте в редакторе.', 'help.section.music.title': 'Музыка на пульте', 'help.section.music.body': @@ -264,7 +314,7 @@ export const EDITOR_MESSAGES: Record> = { 'help.section.settings.title': 'Настройки, язык и обновления', 'help.section.settings.body': - '«Настройки» → «Указать ключ» — ввести или сменить лицензию. «О лицензии» — проверить статус и срок.\n\n«Экран презентации» — выбрать монитор для окна игроков и включить или выключить полноэкранный режим. Настройки сохраняются и применяются при каждом «Запустить».\n\n«Проверить обновления» (в установленной версии при активной лицензии) — если есть новая версия, можно скачать и перезапустить программу.\n\n«Язык» → «Русский» или «English» — меняет язык интерфейса. Выбор сохраняется между запусками.\n\nНомер версии — в шапке справа от меню. «О приложении» → «О программе» — о продукте и контактах поддержки.', + '«Настройки» → «Указать ключ» — ввести или сменить лицензию. «О лицензии» — проверить статус и срок.\n\n«Экран презентации» — выбрать монитор для окна игроков и включить или выключить полноэкранный режим. Настройки сохраняются и применяются при каждом «Запустить».\n\n«Проверить обновления» (в установленной версии при активной лицензии) — если есть новая версия, можно скачать и перезапустить программу.\n\n«Язык» → «Русский» или «English» — меняет язык интерфейса. Выбор сохраняется между запусками.\n\nНомер версии — в шапке справа от меню, сразу за ним иконка «?» («Справка»). «О приложении» открывает окно «О программе» — о продукте и контактах поддержки.', 'settings.presentation.title': 'Экран презентации', 'settings.presentation.hint': @@ -665,6 +715,8 @@ export const EDITOR_MESSAGES: Record> = { 'control.remoteTitle': 'ПУЛЬТ УПРАВЛЕНИЯ', 'control.instruments': 'ИНСТРУМЕНТЫ', + 'control.helpTool': 'Справка', + 'control.previewPanHint': 'Колесо — зум; перетаскивание СКМ/ПКМ или Space+ЛКМ — пан', 'control.descriptionTool': 'Описание', 'control.markerTool': 'Маркер', 'control.markerColor': 'Цвет маркера', @@ -757,11 +809,11 @@ export const EDITOR_MESSAGES: Record> = { 'control.passed': 'Пройдено', 'control.noActiveScene': 'Нет активной сцены.', 'control.screenPreview': 'Предпросмотр экрана', - 'control.npcTokenScale': 'Размеры игр. токенов', + 'control.npcTokenScale': 'Размер токенов игроков', 'control.resizeToken': 'Изменить размер', 'control.snapTokensToGrid': 'Привязка токенов к сетке', 'control.snapTokensToGridNoGrid': 'Сетка на текущей сцене выключена — привязка не применяется', - 'control.stopPresentation': 'Выключить', + 'control.stopPresentation': 'Завершить', 'control.stopConfirm.title': 'Завершить показ?', 'control.stopConfirm.body': 'Закрыть пульт и презентацию и вернуться в редактор?', 'control.stopConfirm.confirm': 'Завершить', @@ -776,7 +828,7 @@ export const EDITOR_MESSAGES: Record> = { 'control.unnamed': 'Без названия', 'control.switchScene': 'Переключить', 'control.noBranches': 'Нет вариантов перехода.', - 'control.endPresentation': 'Завершить показ', + 'control.endPresentation': 'Завершить', 'control.music': 'Музыка', 'control.sceneMusic': 'МУЗЫКА СЦЕНЫ', 'control.gameMusic': 'МУЗЫКА ИГРЫ', @@ -859,7 +911,7 @@ export const EDITOR_MESSAGES: Record> = { 'presentation.overlay': 'Presentation running', 'presentation.title': 'Presentation running', - 'presentation.body': 'The editor is locked. Close the Presentation and Control windows to continue.', + 'presentation.body': 'The editor is locked. On the control panel click End and confirm to continue.', 'zip.progress': 'Operation progress', 'zip.importTitle': 'Import project', @@ -925,7 +977,7 @@ export const EDITOR_MESSAGES: Record> = { 'help.section.overview.title': 'App overview', 'help.section.overview.body': - 'When you launch the app, you land in the Editor — where you prepare your campaign: scenes, images, music, and how episodes connect. When it is time to play, click Run. That opens Presentation for your players and the Control panel for you.\n\nIn the editor, the left column lists scenes, the center shows the story map, and the right column holds game and scene settings. Game properties include NPCs, materials, and campaign audio; the header has Players.\n\nWhile a session is running, the editor is temporarily locked — that is normal. Close presentation and the control panel to edit again.\n\nInternet is only needed for license activation and update checks. All projects and files stay on your computer.', + 'When you launch the app, you land in the Editor — where you prepare your campaign: scenes, images, music, and how episodes connect. When it is time to play, click Run. That opens Presentation for your players and the Control panel for you.\n\nIn the editor, the left column lists scenes, the center shows the story map, and the right column holds game and scene settings. Game properties include NPCs, materials, and campaign audio; the header has Players.\n\nWhile a session is running, the editor is temporarily locked — that is normal. On the control panel click End and confirm to edit again.\n\nInternet is only needed for license activation and update checks. All projects and files stay on your computer.', 'help.section.license.title': 'License and first launch', 'help.section.license.body': @@ -949,7 +1001,7 @@ export const EDITOR_MESSAGES: Record> = { 'help.section.sceneProps.title': 'Scene properties', 'help.section.sceneProps.body': - 'Select a scene in the left list — its properties open on the right.\n\nScene title is for the GM. Description is GM notes with formatting: click the pencil next to the label to open the editor (bold, italic, headings, lists, links). Below the label you see a text preview, or “no description” when empty. During a session, open the description from the control panel in a separate window (see Control panel) — it is not shown inside the Storyline list.\n\nIf the scene has a graph card with a blue SIDE badge, a Side storyline title field appears.\n\nImage or video for players:\n\n1) Under Scene preview, click Upload or Change.\n\n2) Pick a file (PNG, JPG, WebP, GIF, video, etc.).\n\n3) For images and video, use Rotate (90° steps). Clear removes the preview.\n\n4) For images and video, enable Darken scene so players start in full darkness and you reveal the frame with the Opening brush on the control panel (see Effects).\n\n5) Scene editor works for both images and video — battle grid, traps, non-player tokens, and NPC tokens over the preview (see Scene editor, Grid generator, Traps, Non-player tokens, and NPCs).\n\nFor video, enable Autostart if the clip should start on its own on the player screen, and Loop if needed.\n\nScene audio — music and sounds for this episode. Upload adds files. Per track: Auto (play when entering the scene) and Loop. The trash icon removes a track.\n\nLinks between scenes are drawn on the map, not here — see Scene graph.', + 'Select a scene in the left list — its properties open on the right.\n\nScene title is for the GM. Description is GM notes with formatting: click the pencil next to the label to open the editor (bold, italic, headings, lists, links). Below the label you see a text preview, or “no description” when empty. During a session, open the description from the control panel in a separate window (see Control panel) — it is not shown inside the History list.\n\nIf the scene has a graph card with a blue SIDE badge, a Side storyline title field appears.\n\nImage or video for players:\n\n1) Under Scene preview, click Upload or Change.\n\n2) Pick a file (PNG, JPG, WebP, GIF, video, etc.).\n\n3) For images and video, use Rotate (90° steps). Clear removes the preview.\n\n4) For images and video, enable Darken scene so players start in full darkness and you reveal the frame with the Opening brush on the control panel (see Effects).\n\n5) Scene editor works for both images and video — battle grid, traps, non-player tokens, and NPC tokens over the preview (see Scene editor, Grid generator, Traps, Non-player tokens, and NPCs).\n\nFor video, enable Autostart if the clip should start on its own on the player screen, and Loop if needed.\n\nScene audio — music and sounds for this episode. Upload adds files. Per track: Auto (play when entering the scene) and Loop. The trash icon removes a track.\n\nLinks between scenes are drawn on the map, not here — see Scene graph.', 'help.section.sceneEditor.title': 'Scene editor', 'help.section.sceneEditor.body': @@ -959,6 +1011,56 @@ export const EDITOR_MESSAGES: Record> = { 'help.section.grid.body': 'The grid generator overlays a battle grid on the scene preview (image or video) — square or hexagonal. It helps track cells in combat and is visible both on your control panel and on the players’ presentation.\n\nSet it up:\n\n1) Open Scene editor (see Scene editor).\n\n2) Expand the Grid accordion on the left.\n\n3) Enable Overlay grid — lines appear over the map.\n\n4) Type — Square or Hexagonal.\n\n5) Color — line tint (pick contrast that suits the map).\n\n6) Size — cell size slider: higher values mean larger cells.\n\nWhile the grid is off, type, color, and size stay disabled, but the saved values return when you turn it back on.\n\nCampaign grid templates:\n\n1) Configure the grid on a scene.\n\n2) Click Save as template and name it — type, color, and size are stored in the project file. Nothing is applied to other scenes automatically.\n\n3) On any scene, click Apply on a template — that scene gets the template style and the grid turns on.\n\n4) Rename or delete templates anytime. A campaign can keep several templates (up to 20).\n\nPer-scene grid settings and the template list live in the project. The grid draws under trap and token markers and does not block placing them.\n\nDuring a session you can enable Snap tokens to grid on the control panel: dragging non-player tokens, NPC tokens, and player tokens snaps them to cells (square or hex, matching the grid type). If the grid is off, the checkbox has no effect.', + 'sceneEditor.open': 'Scene editor', + 'sceneEditor.grid': 'Grid', + 'sceneEditor.enableGrid': 'Show grid', + 'sceneEditor.gridType': 'Type', + 'sceneEditor.gridTypeAria': 'Grid type', + 'sceneEditor.gridSquare': 'Square', + 'sceneEditor.gridHex': 'Hexagonal', + 'sceneEditor.gridColor': 'Color', + 'sceneEditor.gridColorAria': 'Grid color', + 'sceneEditor.gridSize': 'Size', + 'sceneEditor.npcs': 'NPCs', + 'sceneEditor.npcSearch': 'Search NPCs…', + 'sceneEditor.noNpcs': 'No NPCs', + 'sceneEditor.tokens': 'Non-player tokens', + 'sceneEditor.add': 'Add', + 'sceneEditor.tokenSearch': 'Search…', + 'sceneEditor.noTokens': 'No tokens', + 'sceneEditor.traps': 'Traps', + 'sceneEditor.dragToMap': 'Drag onto the map', + 'sceneEditor.clearScene': 'Clear scene', + 'sceneEditor.needMedia': 'The scene needs an image or video', + 'sceneEditor.mapHint': 'Wheel — zoom. Middle button / Space+left — pan. Delete — remove the selection.', + 'sceneEditor.untitledScene': 'Scene', + 'sceneEditor.deleteTokenTitle': 'Delete token', + 'sceneEditor.deleteTokenBody': 'Delete token “{name}” from the library? It will also be removed from the current scene.', + 'sceneEditor.setPath': 'Set movement', + 'sceneEditor.resetPath': 'Reset to path start', + 'sceneEditor.trap.mimic': 'Mimic', + 'sceneEditor.trap.explosion': 'Explosion', + 'sceneEditor.trap.poison': 'Poison', + 'sceneEditor.trap.pit': 'Pit', + 'sceneEditor.trap.arrow': 'Arrow', + 'sceneEditor.trap.laser': 'Laser', + 'sceneEditor.trap.freeform': 'Marker', + 'sceneEditor.editToken': 'Edit token', + 'sceneEditor.addToken': 'Add token', + 'sceneEditor.tokenName': 'Name', + 'sceneEditor.tokenNamePlaceholder': 'Token name', + 'sceneEditor.tokenNameRequired': 'Enter a name', + 'sceneEditor.tokenNameDuplicate': 'That name is already used', + 'sceneEditor.image': 'Image', + 'sceneEditor.dropImage': 'Drop to upload the image', + 'sceneEditor.dropOrPick': 'Drop an image or choose a file', + 'sceneEditor.chooseImage': 'Choose image', + 'sceneEditor.imageRequired': 'An image is required', + 'sceneEditor.saveFailed': 'Could not save', + 'sceneEditor.dragDelete': 'Drag · right-click to delete', + 'sceneEditor.rotate': 'Rotate', + 'sceneEditor.actions': 'Actions', + 'sceneEditor.edit': 'Edit', 'sceneGrid.templates': 'Campaign templates', 'sceneGrid.saveTemplate': 'Save as template', 'sceneGrid.applyTemplate': 'Apply', @@ -994,15 +1096,15 @@ export const EDITOR_MESSAGES: Record> = { 'help.section.session.title': 'Starting a session', 'help.section.session.body': - 'When your campaign is ready, you can start playing.\n\nStandard start:\n\n1) On the story map, right-click the starting card → Start scene.\n\n2) Click Run in the editor header (left part of the button).\n\nRun with players: use the chevron on the right of Run → Run with players — pick players and/or teams. The selection lasts for the session; the control panel shows Show players / Hide players. Changing scenes hides player tokens.\n\nQuick start from any card: right-click the card on the map → Start from this scene. Presentation and the control panel open at that spot right away.\n\nPresentation (for players) and the Control panel (for you) open. The editor dims while the show runs — that is expected.\n\nChoose the player screen ahead of time in Settings → Presentation display: pick a monitor and fullscreen mode. When you click Run, the presentation window opens on that display automatically.\n\nReturn to prep:\n\n1) On the control panel, click Turn off or End presentation (when there is nowhere left to go).\n\n2) Wait until both windows close.', + 'When your campaign is ready, you can start playing.\n\nStandard start:\n\n1) On the story map, right-click the starting card → Start scene.\n\n2) Click Run in the editor header (left part of the button).\n\nRun with players: use the chevron on the right of Run → Run with players — pick players and/or teams. The selection lasts for the session; the control panel shows Show players / Hide players. Changing scenes hides player tokens.\n\nQuick start from any card: right-click the card on the map → Start from this scene. Presentation and the control panel open at that spot right away.\n\nPresentation (for players) and the Control panel (for you) open. The editor dims while the show runs — that is expected.\n\nChoose the player screen ahead of time in Settings → Presentation display: pick a monitor and fullscreen mode. When you click Run, the presentation window opens on that display automatically.\n\nReturn to prep:\n\n1) On the control panel click End (by the preview, or in the branch block when there is nowhere left to go). Escape and closing the presentation or control window ask the same question.\n\n2) In the End presentation? dialog click End and wait until both windows close.', 'help.section.controlPanel.title': 'Control panel', 'help.section.controlPanel.body': - 'The control panel is your desk during play. Players watch presentation; you run everything from here.\n\nTop-left: Tools, then effects and storyline. On the right: a mini copy of the player screen, branch options, and music.\n\nUnder Tools, the book button opens a separate window with the current scene’s formatted description. If there is no description, the button is disabled — the tooltip reads “No description”. The materials button (map icon) opens a window with the campaign materials list — see the Materials section for details. The timer button (⏱) opens the session countdown: Show to players places the widget on the control preview and presentation — drag, resize, and rotate it on the control preview. The NPCs button (colored person icon) opens the characters window: description cards, the Show checkbox for an avatar over the scene, and placing a token on the map for this session — see NPCs.\n\nScreen preview shows what players see. Paint effects here — they appear on the big screen right away for both image and video scenes. If the scene has traps, they appear on the preview: right-click a marker to reveal, activate, or disarm (see Traps). Non-player, NPC, and player tokens are also visible on the preview: you can move them and resize them from the yellow corner until the session ends. Path lines are always visible to you; players see a line only after Show path in the token menu. You can drag a tile from the NPCs window onto the preview to spawn a session token. Right-click a non-player token to show / hide path, stop / resume movement, or reset to start. Right-click an NPC token to activate / open information / change type / make inactive / remove from map / set a path (see NPCs and Non-player tokens). Avatars from the Show checkbox sit over the scene separately from map tokens: drag them, zoom with the NPCs window magnifiers, and clear them with Close all. On video scenes, transport controls and the scrub bar stay at the bottom of the preview.\n\nAbove the preview:\n• Snap tokens to grid — when the scene grid is on, dragged tokens (non-player, NPC, players) snap to cells;\n• Play token size — shared scale for circular player and NPC tokens on the preview and presentation;\n• Show players / Hide players — after Run with players.\n\nStoryline lists episodes you have visited. The current scene is marked CURRENT SCENE. Click an earlier step to move the party back to that spot and add a new history entry.\n\nStop presentation ends the show and unlocks the editor.', + 'The control panel is your desk during play. Players watch presentation; you run everything from here.\n\nTop-left: Tools, then effects, History, and Scenes. On the right: a mini copy of the player screen, branch options, and music.\n\nUnder Tools: marker (draw on the map), book (current scene description; if there is none the button is disabled and the tooltip reads “No description”), materials (see Materials), playlists, timer (countdown: Show to players places the widget on the preview and presentation), initiative (turn order), dice, NPCs (cards, the Show checkbox for an avatar, and placing a token on the map — see NPCs), and “?” (Help: opens this section without ending the show).\n\nScreen preview shows what players see. Paint effects here — they appear on the big screen right away for both image and video scenes. If the scene has traps, they appear on the preview: right-click a marker to reveal, activate, or disarm (see Traps). Non-player, NPC, and player tokens are also visible on the preview: you can move them and resize them from the yellow corner until the session ends. Path lines are always visible to you; players see a line only after Show path in the token menu. You can drag a tile from the NPCs window onto the preview to spawn a session token. Right-click a non-player token to show / hide path, stop / resume movement, or reset to start. Right-click an NPC token to activate / open information / change type / make inactive / remove from map / set a path (see NPCs and Non-player tokens). Avatars from the Show checkbox sit over the scene separately from map tokens: drag them, zoom with the NPCs window magnifiers, and clear them with Close all. On video scenes, transport controls and the scrub bar stay at the bottom of the preview.\n\nAbove the preview:\n• Snap tokens to grid — when the scene grid is on, dragged tokens (non-player, NPC, players) snap to cells;\n• Player token size — shared scale for circular player and NPC tokens on the preview and presentation;\n• Show players / Hide players — after Run with players.\n\nHistory lists episodes you have visited. The current scene is marked CURRENT SCENE. Click an earlier step to move the party back to that spot and add a new history entry. Scenes lists scenes on the current line so you can jump to any of them.\n\nEnd by the preview and at the end of a branch (when there is nowhere left to go) asks for confirmation and then closes the show. Escape on the control panel and on presentation, and closing those windows, ask the same question.', 'help.section.transitions.title': 'Scene transitions', 'help.section.transitions.body': - 'Where you can go next appears under Branch options on the control panel. These are outgoing arrows from the current card on the map.\n\n1) Read the OPTION 1, OPTION 2 cards — they show target scene names.\n\n2) Click Switch on the choice you want.\n\n3) Presentation updates image and music; storyline adds a new step.\n\nIf there are no options (end of a branch), you will see No transitions available. Click End presentation to close the show windows.\n\nOptions only exist where you drew arrows on the map in the editor.', + 'Where you can go next appears under Branch options on the control panel. These are outgoing arrows from the current card on the map.\n\n1) Read the OPTION 1, OPTION 2 cards — they show target scene names.\n\n2) Click Switch on the choice you want.\n\n3) Presentation updates image and music; storyline adds a new step.\n\nIf there are no options (end of a branch), you will see No transitions available. Click End to close the show windows.\n\nOptions only exist where you drew arrows on the map in the editor.', 'help.section.music.title': 'Music on the control panel', 'help.section.music.body': @@ -1022,7 +1124,7 @@ export const EDITOR_MESSAGES: Record> = { 'help.section.settings.title': 'Settings, language and updates', 'help.section.settings.body': - 'Settings → Enter license key — add or change your license. About license — check status and expiry.\n\nPresentation display — choose the monitor for the player window and turn fullscreen on or off. Settings are saved and applied every time you click Run.\n\nCheck for updates (installed app with active license) — if a new version exists, you can download and restart.\n\nLanguage → Русский or English changes the interface. Your choice is saved between launches.\n\nThe version number is in the header, right of the menus. About → About opens product info and support contacts.', + 'Settings → Enter license key — add or change your license. About license — check status and expiry.\n\nPresentation display — choose the monitor for the player window and turn fullscreen on or off. Settings are saved and applied every time you click Run.\n\nCheck for updates (installed app with active license) — if a new version exists, you can download and restart.\n\nLanguage → Русский or English changes the interface. Your choice is saved between launches.\n\nThe version number is in the header, right of the menus, with a “?” (Help) button immediately after it. About opens the product and support window.', 'settings.presentation.title': 'Presentation display', 'settings.presentation.hint': @@ -1425,6 +1527,8 @@ export const EDITOR_MESSAGES: Record> = { 'control.remoteTitle': 'CONTROL PANEL', 'control.instruments': 'TOOLS', + 'control.helpTool': 'Help', + 'control.previewPanHint': 'Wheel — zoom; middle/right drag or Space+left drag — pan', 'control.descriptionTool': 'Description', 'control.markerTool': 'Marker', 'control.markerColor': 'Marker color', @@ -1517,11 +1621,11 @@ export const EDITOR_MESSAGES: Record> = { 'control.passed': 'Visited', 'control.noActiveScene': 'No active scene.', 'control.screenPreview': 'Screen preview', - 'control.npcTokenScale': 'Play token size', + 'control.npcTokenScale': 'Player token size', 'control.resizeToken': 'Resize', 'control.snapTokensToGrid': 'Snap tokens to grid', 'control.snapTokensToGridNoGrid': 'Grid is off on this scene — snap has no effect', - 'control.stopPresentation': 'Turn off', + 'control.stopPresentation': 'End', 'control.stopConfirm.title': 'End presentation?', 'control.stopConfirm.body': 'Close the control panel and presentation and return to the editor?', 'control.stopConfirm.confirm': 'End', @@ -1536,7 +1640,7 @@ export const EDITOR_MESSAGES: Record> = { 'control.unnamed': 'Untitled', 'control.switchScene': 'Switch', 'control.noBranches': 'No transitions available.', - 'control.endPresentation': 'End presentation', + 'control.endPresentation': 'End', 'control.music': 'Music', 'control.sceneMusic': 'SCENE MUSIC', 'control.gameMusic': 'GAME MUSIC', diff --git a/app/renderer/sceneEditor/SceneEditorApp.tsx b/app/renderer/sceneEditor/SceneEditorApp.tsx index d1e3144..4fb0dfa 100644 --- a/app/renderer/sceneEditor/SceneEditorApp.tsx +++ b/app/renderer/sceneEditor/SceneEditorApp.tsx @@ -38,13 +38,11 @@ import { SCENE_GRID_SIZE_MAX, SCENE_GRID_SIZE_MIN, sceneGridTokenFitFactor, - sceneGridTypeLabelRu, } from '../../shared/types/sceneGrid'; import { asSceneTrapId, DEFAULT_SCENE_TRAP_SIZE_N, SCENE_TRAP_TYPES, - trapTypeLabelRu, } from '../../shared/types/sceneTraps'; import { sceneViewPanBy, sceneViewZoomAt } from '../../shared/types/sceneView'; import { USERS_BRANCH_FEATURES_ENABLED } from '../../shared/features/usersBranchFeatures'; @@ -638,17 +636,17 @@ export function SceneEditorApp() {