// Webview для выбора шаблона и переменных import * as vscode from 'vscode'; import * as fs from 'fs'; import * as path from 'path'; import { getAllTemplateVariables } from '../core/templateUtils'; import { I18N_DICTIONARIES } from '../core/i18n'; import { writeConfig, readConfig } from '../core/config'; export async function showTemplateAndVarsWebview( context: vscode.ExtensionContext, templatesDir: string, targetPath: string, initialLanguage: string ): Promise<{ template: string, vars: Record } | undefined> { let language = initialLanguage; function getDict() { return I18N_DICTIONARIES[language] || I18N_DICTIONARIES['ru']; } const templates = fs.readdirSync(templatesDir).filter(f => fs.statSync(path.join(templatesDir, f)).isDirectory()); const stylePath = vscode.Uri.joinPath(context.extensionUri, 'src', 'webview', 'styles.css'); return new Promise((resolve) => { const panel = vscode.window.createWebviewPanel( 'templateVars', getDict().create, vscode.ViewColumn.Active, { enableScripts: true } ); const styleUri = panel.webview.asWebviewUri(stylePath); let currentVars: string[] = []; let currentTemplate = templates[0] || ''; let disposed = false; function getVarsHtml(vars: string[], values: Record = {}) { const dict = getDict(); if (!vars.length) return ''; return `

${dict.enterVariables}

${dict.varInputHint}
${vars.map(v => `

`).join('')}
`; } function getTemplatesRadioHtml(templates: string[], selected: string) { const dict = getDict(); return `

${dict.chooseTemplate}:

${templates.map(t => ` `).join('')}
`; } function getLanguageSelectorHtml(selected: string) { return ``; } function setHtml(templatesHtml: string, varsHtml: string) { const dict = getDict(); panel.webview.html = ` ${dict.create}

${dict.create}

${getLanguageSelectorHtml(language)}
${templatesHtml}
${varsHtml}
`; // После перерисовки HTML вызываем initHandlers setTimeout(() => { panel.webview.postMessage({ type: 'callInitHandlers' }); }, 0); } // Инициализация: сразу выбран первый шаблон и форма переменных let initialVars: string[] = []; if (currentTemplate) { const templateDir = path.join(templatesDir, currentTemplate); const allVars = getAllTemplateVariables(templateDir); initialVars = Array.from(allVars); currentVars = initialVars; } setHtml(getTemplatesRadioHtml(templates, currentTemplate), getVarsHtml(initialVars)); // Обработка сообщений panel.webview.onDidReceiveMessage( async message => { if (message.type === 'selectTemplate') { currentTemplate = message.template; if (message.language) language = message.language; if (!currentTemplate) { setHtml(getTemplatesRadioHtml(templates, ''), ''); return; } // Получаем переменные для выбранного шаблона const templateDir = path.join(templatesDir, currentTemplate); const allVars = getAllTemplateVariables(templateDir); currentVars = Array.from(allVars); setHtml(getTemplatesRadioHtml(templates, currentTemplate), getVarsHtml(currentVars)); } else if (message.type === 'setLanguage') { if (message.language) language = message.language; // Сохраняем язык в конфиг const oldConfig = readConfig(); writeConfig({ ...oldConfig, language }); currentTemplate = message.template || templates[0] || ''; // Получаем переменные для выбранного шаблона let baseVars: string[] = []; if (currentTemplate) { const templateDir = path.join(templatesDir, currentTemplate); const allVars = getAllTemplateVariables(templateDir); baseVars = Array.from(allVars); currentVars = baseVars; } setHtml(getTemplatesRadioHtml(templates, currentTemplate), getVarsHtml(currentVars)); } else if (message.type === 'changeLanguage') { // legacy, не нужен } else if (message.type === 'submit') { if (message.language) language = message.language; if (!disposed) { disposed = true; panel.dispose(); resolve({ template: message.template, vars: message.data }); } } else if (message.type === 'callInitHandlers') { // Ничего не делаем, скрипт внутри webview вызовет window.initHandlers } }, undefined, context.subscriptions ); panel.onDidDispose(() => { if (!disposed) { disposed = true; resolve(undefined); } }, null, context.subscriptions); }); }