Source: managers/PageTranslatorManager.js

import Cookies from 'js-cookie';

import HT from '../HT';
import { INFO_TEXT } from '../components/Actions';
import { isChildren, getMainLinkElement } from '../utils';

/** Canal de comunicação entre o TextManager e o Hugo */
class PageTranslatorManager {

  ht = null;
  firstOpen = false;
  _hugoTranslating = false;
  _currentHoverElem = null;

  _activated = false;
  get activated() { return this._activated; }
  set activated(value) {
    this._activated = value;
    this.ht.drawer.open = value;

    if (value) {
      // Verifica se o Hugo está carregado, caso contrario aguarda o loading
      // Para ativar o TextManager, isso evitar que o cursor apareça indevidamente
      if (this.ht.hugoLoaded) this.ht.textManager.activated = true;
      else this.ht.on('hugoLoaded', () => { this.ht.textManager.activated = true; });

      this.ht.logger.debug('PageTranslatorManager ativado');
      this.ht.hugo.then((hugo) => {

        hugo._mainMixer.timeScale = 1;

        // Exibe a mensagem de boas vindas caso seja a primeira abertura
        if (this.firstOpen) {
          this.ht.drawer.signWithHelperText(INFO_TEXT);
          Cookies.set(FIRST_OPEN_COOKIE_NAME, false, { expires: 7 });
          this.firstOpen = false;
        }
      });
    } else {
      // Remove o hover mobile e limpa a fila de tradução
      if (this._currentHoverElem) this._currentHoverElem.classList.remove('ht-mobile-hover');
      this.ht.hugo.then((hugo) => { hugo.stop(); });
      this.ht.textManager.activated = false;
    }

    // Define o cookie para abrir o tradutor automaticamente
    Cookies.set(AUTO_OPEN, value, { expires: 1 / 48 });

    // Pausa e desativa o hugo caso tenha algum vídeo em execução
    if (value && this.ht.videoManager) this.ht.videoManager.disableCurrentAcessibleVideo();
  }

  constructor(ht) {
    this.ht = ht;

    this.firstOpen = Cookies.get(FIRST_OPEN_COOKIE_NAME) !== 'false';

    // Abre o Hugo automaticamente (restaura a antiga sessão) 
    if (Cookies.get(AUTO_OPEN) === 'true') this.activated = true;

    // Ouve os cliques
    this.ht.textManager.on('validElementClicked', this.onValidElementClicked);
    // Ouve o hover
    this.ht.textManager.on('validElementOver', this.onValidElementOver);
    // Ouve o mouse out
    this.ht.textManager.on('validElementOut', this.onValidElementOut);
  }

  /** 
   * Quando um elemento com o texto compativel for clicado
   * @param event - Evento
   * @param text - Texto tratado (plainText)
   */
  onValidElementClicked = (e, text) => {

    const elem = e.target;

    // Só exibe o prompt link caso o elemento seja filho de um
    if (e.view == window && isChildren(elem, 'a')) {
      const element = getMainLinkElement(elem);
      if (element) this.ht.drawer.showPromptLinkAt(element, e);
    } else this.ht.drawer.hidePromptLink();


    if (HT.deviceInfo.isMobile) {
      // A função stop() do Hugo limpa a fila e pausa a animação, mas não cancela a requisição que ja foi feita,
      // por isso verificamos manualmente se o Hugo esta traduzindo uma frase 
      // antes de permitir que o usuário traduza outro texto.
      if (this._hugoTranslating) return false;
      if (this._currentHoverElem) this._currentHoverElem.classList.remove('ht-mobile-hover');
      this._currentHoverElem = elem;
      elem.classList.add('ht-mobile-hover');
    }

    this.sign(text);
  }

  /**
   * Quando o mouse/touch foca em um elemento com texto compativel
   * @param elem - Elemento que recebeu foco
   */
  onValidElementOver = (elem) => {
    if (!HT.deviceInfo.isMobile) elem.classList.add('ht-signlanguage-hover');
  }

  /**
   * Quando o mouse/touch sai de em um elemento com texto compativel
   * @param elem - Elemento que perdeu foco
   */
  onValidElementOut = (elem) => {
    if (elem.classList) elem.classList.remove('ht-signlanguage-hover');
  }

  /**
   * Envia um texto para o hugo sinalizar
   * @param text - Texto para o hugo
   */
  sign = (text) => {
    this.ht.hugo.then((hugo) => {

      // Quando o Hugo Terminar a tradução definimos _hugoTranslating como false para esconder o hover mobile
      hugo.on('translated', () => { this._hugoTranslating = false; });

      // Só traduz caso não exista nenhuma requisição sendo baixada
      if (HT.deviceInfo.isMobile && this._hugoTranslating) return false;

      this._hugoTranslating = true;
      const elem = this._currentHoverElem;

      hugo.stop().then(() => {
        this.ht.emit('translate', text);
        hugo.sign(text, {
          translationURL: TRANSLATE_SERVER_URL,
          doNotTrack: this.ht.config.doNotTrack || false,
        }).finally(() => {
          this.ht.emit('signalized');
          if (HT.deviceInfo.isMobile) elem.classList.remove('ht-mobile-hover');
        });
      });
    });
  }
}

export default PageTranslatorManager;