Skip to content

Реакции и фидбэк

SDK позволяет участникам отправлять реакции во время звонка (например, эмодзи).

Включение реакций

Реакции включаются через опции звонка:

javascript
import { ConversationOption } from '@vkontakte/calls-sdk';

// Включить реакции
await SDK.changeConversationOptions({
    [ConversationOption.FEEDBACK]: true
});

// Выключить реакции
await SDK.changeConversationOptions({
    [ConversationOption.FEEDBACK]: false
});

Отправка реакции

javascript
// Отправить реакцию
await SDK.feedback('👍');
await SDK.feedback('🎉');
await SDK.feedback('❤️');

В качестве key можно передать любое значение — это может быть эмодзи, текст или любой идентификатор реакции.

Ограничение

Реакции можно отправлять не чаще 1 раза в секунду с одного клиента. Рекомендуется реализовать cooldown на стороне UI.

Пример с cooldown:

javascript
let isOnCooldown = false;
const COOLDOWN_MS = 1000;

async function sendReaction(reactionKey) {
    if (isOnCooldown) {
        return;  // Игнорируем, если на кулдауне
    }
    
    isOnCooldown = true;
    setTimeout(() => {
        isOnCooldown = false;
    }, COOLDOWN_MS);
    
    await SDK.feedback(reactionKey);
}

Получение реакций

Реакции от других участников приходят в коллбэке onFeedback:

javascript
await SDK.init({
    // ...
    onFeedback: (feedback, roomId) => {
        // feedback - массив реакций
        // roomId - ID комнаты (null для основного зала)
        
        feedback.forEach(item => {
            console.log('Реакция:', item.key);
            // item.key содержит значение, переданное в SDK.feedback()
        });
        
        // Показать реакцию в UI
        showReaction(feedback[0].key);
    }
});

Полный пример

javascript
import * as SDK from '@vkontakte/calls-sdk';
import { ConversationOption } from '@vkontakte/calls-sdk';

// Доступные реакции
const reactions = ['😁', '😍', '👍', '🎉', '👏', '🔥', '💙', '🤔', '😢'];

let isOnCooldown = false;

await SDK.init({
    // ...
    onFeedback: (feedback, roomId) => {
        feedback.forEach(item => {
            // Показать анимацию реакции
            animateReaction(item.key);
        });
    },
    
    onOptionsChanged: (options) => {
        // Проверить, включены ли реакции
        const reactionsEnabled = options.includes(ConversationOption.FEEDBACK);
        toggleReactionsUI(reactionsEnabled);
    }
});

// Включить реакции
async function enableReactions() {
    await SDK.changeConversationOptions({
        [ConversationOption.FEEDBACK]: true
    });
}

// Отправить реакцию с проверкой cooldown
async function sendReaction(emoji) {
    if (isOnCooldown) {
        console.log('Подождите перед отправкой следующей реакции');
        return;
    }
    
    isOnCooldown = true;
    setTimeout(() => {
        isOnCooldown = false;
    }, 1000);
    
    try {
        await SDK.feedback(emoji);
    } catch (error) {
        console.error('Ошибка отправки реакции:', error);
    }
}

// Анимация реакции
function animateReaction(emoji) {
    const element = document.createElement('div');
    element.className = 'reaction-animation';
    element.textContent = emoji;
    document.body.appendChild(element);
    
    // Удалить после анимации
    setTimeout(() => element.remove(), 2000);
}

Отслеживание состояния опции

javascript
await SDK.init({
    // ...
    onOptionsChanged: (options) => {
        const reactionsEnabled = options.includes(ConversationOption.FEEDBACK);
        
        if (reactionsEnabled) {
            showReactionsButton();
        } else {
            hideReactionsButton();
        }
    }
});