133 lines
5.8 KiB
HTML
133 lines
5.8 KiB
HTML
{{define "content"}}
|
||
<h2>События Twitch</h2>
|
||
<p>Настройте действия, которые будут выполняться при наступлении событий (подписка, рейд, награда и т.д.)</p>
|
||
|
||
<div class="card">
|
||
<label for="event-select">Выберите событие:</label>
|
||
<select id="event-select">
|
||
<option value="follow">Подписка на канал (follow)</option>
|
||
<option value="subscribe">Подписка (subscribe)</option>
|
||
<option value="gift_sub">Подарочная подписка (gift_sub)</option>
|
||
<option value="raid">Рейд (raid)</option>
|
||
<option value="reward_redemption">Награда за баллы (reward_redemption)</option>
|
||
</select>
|
||
<button id="load-actions">Загрузить действия</button>
|
||
</div>
|
||
|
||
<div class="card" id="actions-editor" style="display: none;">
|
||
<h3>Цепочка действий</h3>
|
||
<div id="actions-list"></div>
|
||
<button id="add-action">➕ Добавить действие</button>
|
||
<button id="save-actions">💾 Сохранить</button>
|
||
</div>
|
||
|
||
<script>
|
||
let currentPlatform = "twitch";
|
||
let currentEvent = "";
|
||
let actions = [];
|
||
|
||
const eventSelect = document.getElementById('event-select');
|
||
const loadBtn = document.getElementById('load-actions');
|
||
const actionsDiv = document.getElementById('actions-list');
|
||
const editorDiv = document.getElementById('actions-editor');
|
||
const addBtn = document.getElementById('add-action');
|
||
const saveBtn = document.getElementById('save-actions');
|
||
|
||
async function loadEventActions() {
|
||
currentEvent = eventSelect.value;
|
||
const res = await fetch(`/api/events?platform=${currentPlatform}&event=${currentEvent}`);
|
||
actions = await res.json();
|
||
renderActions();
|
||
editorDiv.style.display = 'block';
|
||
}
|
||
|
||
function renderActions() {
|
||
actionsDiv.innerHTML = '';
|
||
actions.forEach((act, idx) => {
|
||
const div = document.createElement('div');
|
||
div.className = 'action-item';
|
||
div.innerHTML = `
|
||
<select class="action-type" data-idx="${idx}">
|
||
<option value="send_message" ${act.type === 'send_message' ? 'selected' : ''}>Отправить сообщение</option>
|
||
<option value="play_sound" ${act.type === 'play_sound' ? 'selected' : ''}>Проиграть звук</option>
|
||
<option value="press_hotkey" ${act.type === 'press_hotkey' ? 'selected' : ''}>Нажать горячую клавишу</option>
|
||
<option value="http_request" ${act.type === 'http_request' ? 'selected' : ''}>HTTP запрос</option>
|
||
</select>
|
||
<div class="action-fields">
|
||
${renderFields(act, idx)}
|
||
</div>
|
||
<button class="remove-action" data-idx="${idx}">Удалить</button>
|
||
`;
|
||
actionsDiv.appendChild(div);
|
||
});
|
||
|
||
document.querySelectorAll('.action-type').forEach(select => {
|
||
select.addEventListener('change', (e) => {
|
||
const idx = parseInt(e.target.dataset.idx);
|
||
actions[idx].type = e.target.value;
|
||
renderActions();
|
||
});
|
||
});
|
||
document.querySelectorAll('.remove-action').forEach(btn => {
|
||
btn.addEventListener('click', (e) => {
|
||
const idx = parseInt(btn.dataset.idx);
|
||
actions.splice(idx, 1);
|
||
renderActions();
|
||
});
|
||
});
|
||
document.querySelectorAll('.action-fields input, .action-fields textarea').forEach(input => {
|
||
input.addEventListener('change', (e) => {
|
||
const idx = parseInt(input.dataset.idx);
|
||
const field = input.dataset.field;
|
||
actions[idx][field] = input.value;
|
||
});
|
||
});
|
||
}
|
||
|
||
function renderFields(act, idx) {
|
||
switch (act.type) {
|
||
case 'send_message':
|
||
return `<label>Текст сообщения:</label><textarea data-idx="${idx}" data-field="text" rows="2">${escapeHtml(act.text || '')}</textarea>
|
||
<small>Доступные переменные: {{.username}}, {{.reward_title}}, {{.tier}} и т.д.</small>`;
|
||
case 'play_sound':
|
||
return `<label>Путь к звуковому файлу:</label><input data-idx="${idx}" data-field="sound_file" value="${escapeHtml(act.sound_file || '')}">`;
|
||
case 'press_hotkey':
|
||
return `<label>Комбинация клавиш (например, CTRL+ALT+Q):</label><input data-idx="${idx}" data-field="keys" value="${escapeHtml(act.keys || '')}">`;
|
||
case 'http_request':
|
||
return `<label>URL:</label><input data-idx="${idx}" data-field="url" value="${escapeHtml(act.url || '')}">`;
|
||
default:
|
||
return '';
|
||
}
|
||
}
|
||
|
||
addBtn.addEventListener('click', () => {
|
||
actions.push({ type: 'send_message', text: '' });
|
||
renderActions();
|
||
});
|
||
|
||
saveBtn.addEventListener('click', async () => {
|
||
const res = await fetch(`/api/events?platform=${currentPlatform}&event=${currentEvent}`, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(actions)
|
||
});
|
||
if (res.ok) {
|
||
alert('Действия сохранены!');
|
||
} else {
|
||
alert('Ошибка сохранения');
|
||
}
|
||
});
|
||
|
||
loadBtn.addEventListener('click', loadEventActions);
|
||
|
||
function escapeHtml(str) {
|
||
if (!str) return '';
|
||
return str.replace(/[&<>]/g, function(m) {
|
||
if (m === '&') return '&';
|
||
if (m === '<') return '<';
|
||
if (m === '>') return '>';
|
||
return m;
|
||
});
|
||
}
|
||
</script>
|
||
{{end}} |