Banner persistente + som em loop + OS notification + title flash + vibração mobile quando conversa transiciona pra 'open' vindo de pending/snoozed/resolved. Exige interação pra dismissar — atendente não perde evento de reabertura. - AggressiveConversationBanner.vue: banner full-width no topo, dismissable, mostra nome do contato + inbox + status anterior - aggressiveAlert.js: manager do som (loop infinito), title flash (intervalo 1s), Notification API (requireInteraction: true), navigator.vibrate (padrão 500-200-500-200-500) - actionCable.onStatusChange: detecta transição pra 'open' e dispara trigger via BUS_EVENTS (só se status anterior ≠ open, pra não alertar conversa nova criada já em open) - i18n pt_BR + en: chaves de notificação (title/body/dismiss) - busEvents: AGGRESSIVE_ALERT_TRIGGER + AGGRESSIVE_ALERT_DISMISS Camada 1 da feature. Camada 2 (escalation SMS/WhatsApp se não dismissar em X segundos) fica pra outro PR. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
19 lines
804 B
JavaScript
19 lines
804 B
JavaScript
export const BUS_EVENTS = {
|
|
SHOW_ALERT: 'SHOW_ALERT',
|
|
START_NEW_CONVERSATION: 'START_NEW_CONVERSATION',
|
|
FOCUS_CUSTOM_ATTRIBUTE: 'FOCUS_CUSTOM_ATTRIBUTE',
|
|
SCROLL_TO_MESSAGE: 'SCROLL_TO_MESSAGE',
|
|
MESSAGE_SENT: 'MESSAGE_SENT',
|
|
ON_MESSAGE_LIST_SCROLL: 'ON_MESSAGE_LIST_SCROLL',
|
|
WEBSOCKET_DISCONNECT: 'WEBSOCKET_DISCONNECT',
|
|
WEBSOCKET_RECONNECT: 'WEBSOCKET_RECONNECT',
|
|
WEBSOCKET_RECONNECT_COMPLETED: 'WEBSOCKET_RECONNECT_COMPLETED',
|
|
TOGGLE_REPLY_TO_MESSAGE: 'TOGGLE_REPLY_TO_MESSAGE',
|
|
SHOW_TOAST: 'newToastMessage',
|
|
NEW_CONVERSATION_MODAL: 'newConversationModal',
|
|
INSERT_INTO_RICH_EDITOR: 'insertIntoRichEditor',
|
|
INSERT_INTO_NORMAL_EDITOR: 'insertIntoNormalEditor',
|
|
AGGRESSIVE_ALERT_TRIGGER: 'AGGRESSIVE_ALERT_TRIGGER',
|
|
AGGRESSIVE_ALERT_DISMISS: 'AGGRESSIVE_ALERT_DISMISS',
|
|
};
|