Skip to content

Repository files navigation

Documentação Componente

Essa documentação aborda como customizar o componente e seus callbacks.

Ir para Customização

Ir para Navegação de vídeos e textos

Ir para Enviar momento atual


Documentação Customização

📦 Importando o ThemeManager (Obrigatório)

Para utilizar o ThemeManager, é necessário importar o módulo dentro da sua aplicação.

import { ThemeManager } from './dist/theme-manager.js';

Caso esteja utilizando via HTML com <script type="module">, o import deve ser feito assim:

<script type="module">
  import { ThemeManager } from './dist/theme-manager.js';

  ThemeManager.setDefaultTheme({
    /* ... */
  });
</script>

🖼️ Como usar SVG em ícones (closed icon, header, submit button etc.)

Além de imagens (<img>), também é possível utilizar SVG inline em qualquer ícone do tema.

✔️ Exemplo usando SVG no botão de enviar

ThemeManager.setDefaultTheme({
  submitButtons: {
    submit: {
      svg: {
        content: `
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none"
          xmlns="http://www.w3.org/2000/svg">
          <path d="M2 21L23 12L2 3V10L17 12L2 14V21Z" fill="#3B82F6"/>
        </svg>
        `
      }
    }
  }
});

✔️ Exemplo usando SVG no título

ThemeManager.setDefaultTheme({
  header: {
    icon: {
      svg: `
        <svg width="20" height="20" fill="#3B82F6" viewBox="0 0 24 24">
          <circle cx="12" cy="12" r="10" />
        </svg>
      `
    }
  }
});

✔️ Exemplo usando SVG no botão fechado

ThemeManager.setDefaultTheme({
  closed: {
    icon: `
      <svg width="24" height="24" fill="#3B82F6" viewBox="0 0 24 24">
        <path d="M3 12h18" stroke="#fff" stroke-width="2" />
      </svg>
    `
  }
});

🎨 Trabalhando com Temas (Default, Dark e Temas Customizados)

⭐ Tema padrão (Default)

ThemeManager.setDefaultTheme({
  chat: { backgroundColor: '#ffffff' }
});

🌙 Tema escuro (Dark)

ThemeManager.setDarkTheme({
  chat: { backgroundColor: '#1e1e1e' },
  header: { styles: { color: '#ffffff' }}
});

🎨 Criando seu próprio tema (Custom Theme)

ThemeManager.setLightTheme({
  chat: {
    backgroundColor: '#f5e8ff'
  },
  header: {
    styles: {
      backgroundColor: '#a855f7',
      color: '#fff'
    }
  }
});
ThemeManager.setDarkTheme({
  chat: {
    backgroundColor: '#1a1a1a'
  },
  header: {
    styles: {
      backgroundColor: '#333',
      color: '#fff'
    }
  }
});
ThemeManager.setDefaultTheme({
  chat: {
    backgroundColor: '#ffffff'
  }
});

🔄 Alternando temas em runtime

ThemeManager.setCurrentTheme('default');
ThemeManager.setCurrentTheme('dark');
ThemeManager.setCurrentTheme('light');

🖱️ Exemplo de botões para alternar temas

<button onclick="ThemeManager.setCurrentTheme('default')">Tema Padrão</button>
<button onclick="ThemeManager.setCurrentTheme('dark')">Tema Escuro</button>
<button onclick="ThemeManager.setCurrentTheme('light')">Meu Tema Customizado</button>

💡 Observação importante:
Caso deseje utilizar uma fonte diferente da padrão, é necessário adicioná-la manualmente dentro da tag <head> do HTML.

Exemplo de inclusão de fonte personalizada:

<head>
  <link href="https://fonts.cdnfonts.com/css/stencil-paper" rel="stylesheet">
</head>

Chat minimizado

Default

image

Ícone do chat minimizado

Código:

ThemeManager.setDefaultTheme({
  closed: {
    icon: `
      <img src="https://cdn-icons-png.flaticon.com/512/4712/4712009.png">
    `,
    tooltip: { text: 'Abrir documentação' },
    styles: {
      backgroundColor: '#3B82F6',
      borderRadius: '50%',
      width: '60px',
      height: '60px'
    }
  }
});

Resultado:

image

Texto do chat minimizado:

Código:

ThemeManager.setDefaultTheme({  
  closed: {  
    icon: `  
      <img src="https://cdn-icons-png.flaticon.com/512/4712/4712009.png">  
    `,  
    tooltip: { text: 'Texto Chat Minimizado' },  
    styles: {  
      backgroundColor: '#3B82F6',  
      borderRadius: '50%',  
      width: '60px',  
      height: '60px'  
    }  
  }  
});

Resultado:

image

Fonte do texto do chat minimizado

Código:

ThemeManager.setDefaultTheme({  
  closed: {  
    icon: `  
      <img src="https://cdn-icons-png.flaticon.com/512/4712/4712009.png">  
    `,  
    tooltip: {  
      text: 'Exemplo font minimizada',  
      styles: {  
        fontFamily: '"Stencil Paper", sans-serif',  
        fontSize: '14px',  
        color: '#3B82F6',  
        backgroundColor: '#f0f4ff',  
        border: '1px solid #3B82F6',  
        padding: '6px 10px',  
        borderRadius: '6px'  
      }  
    }  
  }  
});

Resultado:

image

Cor de fundo do texto do chat minimizado

Código:

ThemeManager.setDefaultTheme({  
  closed: {  
    icon: `  
      <img src="https://cdn-icons-png.flaticon.com/512/4712/4712009.png">  
    `,  
    tooltip: {  
      text: 'Exemplo font minimizada',  
      styles: {  
        fontFamily: '"Stencil Paper", sans-serif',  
        fontSize: '14px',  
        color: '#3B82F6',  
        backgroundColor: '#f0f4ff',  
        border: '1px solid #3B82F6',  
        padding: '6px 10px',  
        borderRadius: '6px'  
      }  
    },  
    styles: {  
      backgroundColor: '#3B82F6'  
    }  
  }  
});

Resultado:

image

Cor do texto do chat minimizado

Código:

ThemeManager.setDefaultTheme({  
  closed: {  
    icon: `  
      <img src="https://cdn-icons-png.flaticon.com/512/4712/4712009.png">  
    `,  
    tooltip: {  
      text: 'Abrir documentação',  
      styles: {  
        fontFamily: '"Stencil Paper", sans-serif',  
        fontSize: '14px',  
        color: 'red',  
        backgroundColor: '#f0f4ff',  
        border: '1px solid #3B82F6',  
        padding: '6px 10px',  
        borderRadius: '6px'  
      }  
    }  
  }  
});

Resultado:

image

Avatares

Default

image

Avatar do bot

Código:

ThemeManager.setDefaultTheme({  
  avatars: {  
    ai: {  
      src: 'https://cdn-icons-png.flaticon.com/512/4712/4712027.png'  
    }  
  }  
});

Resultado:

image

Avatar do usuário

Código:

ThemeManager.setDefaultTheme({  
  avatars: {  
    ai: {  
      src: 'https://cdn-icons-png.flaticon.com/512/4712/4712027.png'  
    },  
    user: {  
      src: 'https://cdn-icons-png.flaticon.com/512/147/147144.png'  
    }  
  }  
});

Resultado:

image

Mensagem do chat

Default

image

Cor de fundo da mensagem do bot

Código:  
ThemeManager.setDefaultTheme({  
  messages: {  
    default: {  
      ai: {  
        bubble: {  
          backgroundColor: 'red',  
          color: 'white'  
        }  
      }  
    }  
  }  
});

Resultado:

image

Cor de fundo da mensagem do usuário

Código:

ThemeManager.setDefaultTheme({  
  messages: {  
    default: {  
      ai: {  
        bubble: {  
          backgroundColor: 'red',  
          color: 'white'  
        }  
      },  
      user: {  
        bubble: {  
          backgroundColor: 'yellow',  
          color: 'black'  
        }  
      }  
    }  
  }  
});

Resultado:

image

Cor do texto da mensagem do bot

Código:

ThemeManager.setDefaultTheme({  
  messages: {  
    default: {  
      ai: {  
        bubble: {  
          backgroundColor: 'red',  
          color: 'white'  
        }  
      }  
    }  
  }  
});

Resultado:

image

Cor do texto da mensagem do usuário

Código:

ThemeManager.setDefaultTheme({  
  messages: {  
    default: {  
      ai: {  
        bubble: {  
          backgroundColor: 'red',  
          color: 'white'  
        }  
      },  
      user: {  
        bubble: {  
          backgroundColor: 'yellow',  
          color: 'black'  
        }  
      }  
    }  
  }  
});

Resultado:

image

Fonte da mensagem do bot

Código:

  ThemeManager.setDefaultTheme({  
    messages: {  
      default: {  
        ai: {  
          bubble: {  
            backgroundColor: 'red',  
            fontFamily: '"Stencil Paper", sans-serif',  
            fontSize: '14px',  
            color: '#000000'  
          }  
        },  
        user: {  
          bubble: {  
            backgroundColor: 'yellow',  
            color: 'black'  
          }  
        }  
      }  
    }  
  });

Resultado:

image

Fonte do texto do usuário

Código

ThemeManager.setDefaultTheme({  
  messages: {  
    default: {  
      ai: {  
        bubble: {  
          backgroundColor: 'red',  
          fontFamily: '"Stencil Paper", sans-serif',  
          fontSize: '14px',  
          color: '#000000'  
        }  
      },  
      user: {  
        bubble: {  
          backgroundColor: 'yellow',  
          fontFamily: '"Stencil Paper", sans-serif',  
          fontSize: '14px',  
          color: '#000000'  
        }  
      }  
    }  
  }  
});

Resultado:

image

Janela do chat

Default

image

Cor da caixa de texto de nova mensagem ("Como posso te ajudar?")

Código:

ThemeManager.setDefaultTheme({  
  textInput: {  
    styles: {  
      container: {  
        backgroundColor: 'lightblue'  
      }  
    }  
  }  
});

Resultado:

image

Fonte do texto de nova mensagem

Código:

ThemeManager.setDefaultTheme({  
  textInput: {  
    styles: {  
      container: {  
        fontFamily: '"Stencil Paper", sans-serif',  
        fontSize: '14px',  
        color: '#000000'  
      }  
    }  
  }  
});

Resultado:

image

Texto do placeholder de nova mensagem

Código:

ThemeManager.setDefaultTheme({  
  textInput: {  
    styles: {  
      container: {  
        fontFamily: '"Stencil Paper", sans-serif',  
        fontSize: '14px',  
        color: '#000000'  
      }  
    }  
  }  
});

Resultado:

image

Ícone do enviar nova mensagem

Código:

  ThemeManager.setDefaultTheme({
    submitButtons: {
      submit: {
        svg: {
          content: `
          <svg width="24" height="24" viewBox="0 0 24 24" fill="none"
            xmlns="http://www.w3.org/2000/svg">
            <path d="M2 21L23 12L2 3V10L17 12L2 14V21Z" fill="#3B82F6"/>
          </svg>
        `}
      }
    }
  });

Resultado:

image

Cor de fundo da janela chat

Código:

ThemeManager.setDefaultTheme({  
  chat: {  
    backgroundColor: 'lightblue'  
  }  
});

Resultado:

image

Balões do Chat

Default

image

Cor dos balões de sugestão

Código:

ThemeManager.setDefaultTheme({
      messageSuggestions: {
        default: {
          color: 'yellow',
        }       
      }
    });

Resultado:

image

Cor da fonte dos balões de sugestão

  ThemeManager.setDefaultTheme({
      messageSuggestions: {
        default: {
          color: 'darkblue',
        }
      }
    });

Resultado:

image

Cor do hover (mouse em cima) dos balões de sugestão

ThemeManager.setDefaultTheme({
      messageSuggestions: {
        default: {
          color: 'yellow',
        },
        hover: {
          backgroundColor: '#0078d4'
        }
      }
    });

Resultado:

image

Fonte dos balões de sugestão

Código:  
  ThemeManager.setDefaultTheme({  
    messages: {  
      default: {  
        'ai-suggestions': {  
          bubble: {  
            fontFamily: '"Stencil Paper", sans-serif',  
            fontSize: '14px'  
          }  
        }  
      }  
    }  
  });

Resultado:

image

Altura do chat (em %) em relação ao total da página quando utilizado em navegadores móveis e Permitir z-index customizado

Para alterar estilos do container externo do chat, basta definir via CSS como normalmente é feito e colocar na tag do componente. Código:

<style>
    .chat {
      position: fixed;
      bottom: 20px;
      right: 20px;
      max-height: 80vh;
      z-index: 9999;
    }
  </style>
  <tutor-chat class="chat" id="tutor-chat"></tutor-chat>

Notificação/Alertas

(Estou aprendendo novos conteúdos sobre o produto ...)

Default

image

Cor de fundo da notificação

Código:

ThemeManager.setDefaultTheme({  
  notificationArea: {  
    styles: {  
      backgroundColor: 'yellow'  
    }  
  }  
});

Resultado:

image

Fonte da notificação

Código:

ThemeManager.setDefaultTheme({  
  notificationArea: {  
    styles: {  
      fontFamily: '"Stencil Paper", sans-serif',  
      fontSize: '14px',  
      color: '#92400E'  
    }  
  }  
});

Resultado:

image

Cor do texto da notificação

Código:

ThemeManager.setDefaultTheme({  
  notificationArea: {  
    styles: {  
      color: '#1E3A8A'  
    }  
  }  
});

Resultado:

image

Feedback

Default

image image image image

Ícone do feedback positivo (imagem de 24x24px)

Código:

ThemeManager.setDefaultTheme({  
  feedback: {  
    positiveAction: {  
      svg: `<img src="https://cdn-icons-png.flaticon.com/512/1828/1828640.png" width="24" height="24">`  
    }  
  }  
});

Resultado:

image

Cor do botão de feedback positivo

Código:

ThemeManager.setDefaultTheme({  
  feedback: {  
    positiveAction: {  
      styles: {  
        backgroundColor: '#22C55E',  
        borderRadius: '6px',  
        padding: '6px'  
      }  
    }  
  }  
});

Resultado:

image

Ícone do feedback negativo (imagem de 24x24px)

Código:

ThemeManager.setDefaultTheme({  
  feedback: {  
    negativeAction: {  
      svg: `<img src="https://cdn-icons-png.flaticon.com/512/1828/1828665.png" width="24" height="24">`  
    }  
  }  
});

Resultado:

image

Cor do botão de feedback negativo

Código:

ThemeManager.setDefaultTheme({  
  feedback: {  
    negativeAction: {  
      styles: {  
        backgroundColor: '#EF4444',  
        borderRadius: '6px',  
        padding: '6px'  
      }  
    }  
  }  
});

Resultado:

image

Fonte "Obrigado pelo feedback"

Código:

ThemeManager.setDefaultTheme({  
  feedback: {  
    positiveAction: {  
      label: {  
        styles: {  
          fontFamily: '"Stencil Paper", sans-serif',  
          fontSize: '14px',  
          color: '#16A34A'  
        }  
      }  
    }  
  }  
});

Resultado:

image

Cor "Obrigado pelo feedback"

Código:

ThemeManager.setDefaultTheme({  
  feedback: {  
    positiveAction: {  
      label: {  
        styles: {  
          fontFamily: '"Stencil Paper", sans-serif',  
          fontSize: '14px',  
          color: '#16A34A'  
        }  
      }  
    }  
  }  
});

Resultado:

image

Cor de fundo balão de sugestão ("Resposta incorreta", "Resposta muito longa", "Resposta fora do tema", "Outro")

Código:

    ThemeManager.setDefaultTheme({
      feedback: {
        negativeForm: {
          reasonButtons: {
            hoverBackgroundColor: '#FF0000',
            styles: {
              color: '#BB0000',
              backgroundColor: 'yellow'
            }
          }
        }
      }
    });

Resultado:

image

Cor do texto balão de sugestão

Código:

    ThemeManager.setDefaultTheme({
      messageSuggestions: {
        default: {
          color: '#fff',
          backgroundColor: '#000'
        },
        hover: {
          backgroundColor: '#0078d4'
        }
      }
    });

Resultado:

image

Texto "Que pena que a resposta não ajudou. Por favor, nos ajude a melhorar"

Código:

ThemeManager.setDefaultTheme({  
  feedback: {  
    negativeAction: {  
      label: {  
        text: 'Que pena que a resposta não ajudou. Esse é um TESTE!'  
      }  
    }  
  }  
});

Resultado:

image

Cor botão "Enviar"

Código:

ThemeManager.setDefaultTheme({  
  feedback: {  
    submitButton: {  
      backgroundColor: 'red'  
    }  
  }  
});

Resultado:

image

Título

Default

image

Cor do texto do título

Código:

  ThemeManager.setDefaultTheme({
    header: {
      title: {
        styles: {
          color: '#ff0000'
        },
      }
    }
  });

Resultado:

image

Fonte do texto do título

Código:

  ThemeManager.setDefaultTheme({  
    header: {  
      styles: {  
        fontFamily: '"Stencil Paper", sans-serif',  
        fontSize: '18px'  
      }  
    }  
  });

Resultado:

image

Ícone do título a esquerda do texto (imagem de 24x24px)

Código:

  ThemeManager.setDefaultTheme({
      header: {
        icon: {
          svg: "<img src='https://cdn-icons-png.flaticon.com/512/4712/4712027.png' />"
        }
      },
    });

Resultado:

image

Cor da barra de título

Código:

ThemeManager.setDefaultTheme({  
  header: {  
    styles: {  
      backgroundColor: '#1E3A8A'  
    }  
  }  
});

Resultado:

image

Título customizado para janela, se não enviado usar o nome do curso

Código:

ThemeManager.setDefaultTheme({  
  header: {  
    title: {  
      text: 'Assistente do Curso de C# Performance'  
    }  
  }  
});

Resultado:

image

Cor do Título

Código:

  ThemeManager.setDefaultTheme({
    header: {
      title: {
        styles: {
          color: '#ff0000'
        }
      }
    }
  });

Resultado:
image

Opções

Iniciar com o chat minimizado ou aberto (boolean)

Fechado Código

    tutorChat.options = {  
      organizationId: "4f0983fc-055c-44be-bafe-0f2d9e937f0b",  
      productId: "9206CEBB-17F0-5CFE-84A3-0C9B212FE1C8",  
      isExternalProductId: false,  
      getToken: getConsumerToken,  
      getCurrentContent: getCurrentContent,        
      baseAddress: 'https://localhost:7209',  
      startOpened: false,  
      showSuggestions: true  
    };

Resultado:

image

Aberto código:

    tutorChat.options = {  
      organizationId: "4f0983fc-055c-44be-bafe-0f2d9e937f0b",  
      productId: "9206CEBB-17F0-5CFE-84A3-0C9B212FE1C8",  
      isExternalProductId: false,  
      getToken: getConsumerToken,  
      getCurrentContent: getCurrentContent,        
      baseAddress: 'https://localhost:7209',  
      startOpened: true,  
      showSuggestions: true  
    };

Resultado:

image

Exibir/não exibir balões de sugestão (boolean)

Código mostrar:

    tutorChat.options = {  
      organizationId: "4f0983fc-055c-44be-bafe-0f2d9e937f0b",  
      productId: "9206CEBB-17F0-5CFE-84A3-0C9B212FE1C8",  
      isExternalProductId: false,  
      getToken: getConsumerToken,  
      getCurrentContent: getCurrentContent,        
      baseAddress: 'https://localhost:7209',  
      startOpened: true,  
      showSuggestions: true  
    };

Resultado:

image

Código não mostrar:

    tutorChat.options = {  
      organizationId: "4f0983fc-055c-44be-bafe-0f2d9e937f0b",  
      productId: "9206CEBB-17F0-5CFE-84A3-0C9B212FE1C8",  
      isExternalProductId: false,  
      getToken: getConsumerToken,  
      getCurrentContent: getCurrentContent,        
      baseAddress: 'https://localhost:7209',  
      startOpened: true,  
      showSuggestions: false  
    };

Resultado:

image

Botão de Speech to Text (Microfone)

Estados do Microfone

1. Estado Padrão (Default)

Botão sem interação do usuário.

image

2. Estado Hover

Botão quando o cursor do mouse está sobre o componente.

image

3. Estado Ativo (Recording)

Botão enquanto o microfone está capturando áudio.

image

Mic customizado

Código:

ThemeManager.setDefaultTheme({
    speechToText: {
        button: {
            default: {
                container: {
                    default: {
                        width: '24px',
                        height: '24px',
                        background: 'transparent',
                        borderRadius: '50%',
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'center',
                        transition: 'background .15s ease'
                    },
                    hover: {
                        backgroundColor: '#7fbded69'
                    },
                    click: {
                        backgroundColor: '#4babf669'
                    }
                },
                svg: {
                    styles: {
                        default: {
                            filter: 'none',
                            fill: '#359468'
                        }
                    }
                }
            },
            active: {
                container: {
                    default: {
                        backgroundColor: '#ffd07c70'
                    },
                    hover: {
                        backgroundColor: '#7fbded69'
                    },
                    click: {
                        backgroundColor: '#4babf669'
                    }
                },
                svg: {
                    styles: {
                        default: {
                            filter: 'none',
                            fill: '#c77930'
                        }
                    }
                }
            }
        }
    }
});

Resultado:

Estados do Microfone

1. Estado Padrão (Default)

Botão sem interação do usuário.

image

2. Estado Hover

Botão quando o cursor do mouse está sobre o componente.

image

3. Estado Ativo (Recording)

Botão enquanto o microfone está capturando áudio.

image

Documentação — Navegação de Vídeo e Texto (videoNavigation / textNavigation)

Quando a IA identifica um conteúdo relevante dentro de um vídeo ou documento PDF, ela pode retornar o ponto exato onde aquele conteúdo aparece.
Para isso, você deve implementar dois callbacks: onVideoDocumentNavigation e onTextDocumentNavigation.

Essas funções recebem um objeto contendo informações sobre o conteúdo indexado e devem redirecionar o usuário para o material correspondente no player do produtor.

Callbacks disponíveis

onVideoDocumentNavigation

Chamado quando o usuário clica em um link de conteúdo de vídeo retornado pela IA.

onTextDocumentNavigation

Chamado quando o usuário clica em um link de conteúdo textual (PDF) retornado pela IA. Essas funções recebem um objeto com metadados do conteúdo indexado (id, nome, URL amigável, tempo ou página) e devem executar a navegação no player ou visualizador do produto. Flags de habilitação Além dos callbacks, o componente exige flags explícitas para habilitar a navegação:

enableVideoDocumentsNavigation

enableTextDocumentsNavigation

Essas flags controlam se os links serão exibidos na interface.


      tutorChat.options = {
        organizationId: "",
        productId: "",
        isExternalProductId: true,
        getToken: getConsumerToken,
        getCurrentContent: getCurrentContent,
        startOpened: true,
        onVideoDocumentNavigation: (v) => this.videoNavigation(v),
        onTextDocumentNavigation: (t) => this.textNavigation(t),
        enableVideoDocumentsNavigation: true,
        enableTextDocumentsNavigation: true
      };

Regra de funcionamento (IMPORTANTE)

A navegação só é ativada quando DUAS condições são atendidas ao mesmo tempo:

Para vídeos

enableTextDocumentsNavigation === true
E
onTextDocumentNavigation foi implementado

Para documentos

enableVideoDocumentsNavigation === true
E
onVideoDocumentNavigation foi implementado

Navegação em Vídeos (videoNavigation)

Quando a IA entende que a resposta do usuário está relacionada a um trecho específico de um vídeo (ex.: “O conceito SOLID é explicado no minuto 2 do vídeo X”), ela dispara o callback:

onVideoDocumentNavigation: (currentVideo) => this.videoNavigation(currentVideo)

O método recebe:

{
  id: string,
  name?: string,
  friendlyUrl?: string,
  startTime: number // em milissegundos
}

O que o implementador do componente deve fazer?

videoNavigation(currentVideo) {
    const productId = this.tutorChat?.options?.productId;

    const url = new URL(window.location.href);
    url.hash = '';
    url.pathname = `/products/${productId}/members`;
    url.search = '';

    url.searchParams.set('documentId', currentVideo.id);
    url.searchParams.set('position', Math.round(currentVideo.startTime ?? 0));

    //invocar a chamada aqui;
}

Explicação

  1. Constrói uma URL para o player da plataforma
    • /products/{productId}/members
  2. Adiciona o ID do vídeo
    • documentId = currentVideo.id
  3. Marca o tempo do vídeo onde o conteúdo aparece
    • position = startTime
  4. Chama o Blazor para executar a navegação real:
    • NavigateTo(url, true)

Resultado

Quando o usuário clica no link sugerido pela IA, ele é redirecionado para o vídeo exatamente no segundo certo que contém o conteúdo mencionado.


Navegação em Documentos (PDF) — textNavigation

Quando o conteúdo relevante está em um material de texto (apostila, PDF, página 8, por exemplo), o callback é:

onTextDocumentNavigation: (currentText) => this.textNavigation(currentText)

O objeto recebido:

{
  id: string,
  name?: string,
  friendlyUrl?: string,
  page: number
}

O que o implementador do componente deve fazer?

textNavigation(currentText) {
    const productId = this.tutorChat?.options?.productId;

    const url = new URL(window.location.href);
    url.hash = '';
    url.pathname = `/products/${productId}/members`;
    url.search = '';

    url.searchParams.set('documentId', currentText.id);
    url.searchParams.set('position', currentText.page ?? 0);

    //invocar a chamada aqui;
}

Explicação

  1. Constrói a URL do player
  2. Usa o ID do documento PDF
  3. Define a página onde o tema aparece
  4. Aciona o Blazor para navegar

Resultado

O usuário é direcionado para exatamente a página do documento mencionada pela IA.


Como o clique dispara a navegação

Dentro do componente, quando o usuário clica em um item sugerido pela IA, este método é chamado:

private async videoDocumentClick(event) {
  if (!this.options.onVideoDocumentNavigation) return;

  const target = event.currentTarget;
  if (!target) return;

  const dataset = target.dataset;

  await this.options.onVideoDocumentNavigation({
    name: dataset.name,
    friendlyUrl: dataset.friendlyUrl,
    id: dataset.id,
    startTime: dataset.startTime
  });
}

O mesmo ocorre para PDF (textNavigation).

Resumo

  • A IA monitora o conteúdo do curso (vídeos + PDFs)
  • Quando identifica uma parte relevante:
    • Fornece um link para o trecho do vídeo exato
    • Ou para a página correta do PDF
  • O Tutor dispara onVideoDocumentNavigation ou onTextDocumentNavigation
  • Você redireciona seu usuário usando o método exibido acima

Isso permite que o aluno vá diretamente ao ponto que contém a explicação necessária — aumentando retenção e experiência.


Como funciona o getCurrentContent

O componente <tutor-chat> precisa saber onde o aluno está atualmente no curso para enviar essa informação ao backend da IA.
Com isso, a IA consegue responder de forma contextualizada (ex.: "você está na página 3", "você está no minuto 12 do vídeo").

Para isso existe a função callback:

getCurrentContent: () => Promise<CurrentContentResponse>

O que o chat espera receber?

O componente sempre chamará getCurrentContent() antes de enviar uma mensagem para a IA.

O retorno deve seguir a interface:

export type CurrentContentResponse = {
  documentId: string,
  type: number,
  position: number,
  isExternalId: boolean
}

Significado dos campos

Campo Descrição
documentId Identificador do conteúdo atual (vídeo, PDF, ...). Pode ser um Id Externo, nesse caso o isExternalId deve ser true.
type 0 para vídeo 1 para texto
position Posição atual dentro do conteúdo.
Para vídeos, é o tempo em milissegundos.
Para textos, é o número da página atual.
isExternalId Indica se o documentId é um Id Externo

Exemplo real de retorno

async function getCurrentContent() {
  if (current?.DocumentFileType === "Text") {
    return {
      documentId: current?.ExternalId != null ? current.ExternalId : String(current?.Id),
      type: 1,
      position: currentPage,
      isExternalId: true
    };
  } else {
    const currentVideoTime = await getCurrentTimeAsync();

    return {
      documentId: current?.ExternalId != null ? current.ExternalId : String(current?.Id),
      type: 0,
      position: currentVideoTime,
      isExternalId: current?.ExternalId != null
    };
  }
}

Como o cliente deve implementar o getCurrentContent

✔ Exemplo para vídeo

getCurrentContent: async () => {
  return {
    documentId: "video-aula-12",
    type: 0,
    position: player.currentTime * 1000,
    isExternalId: true
  };
}

Exemplo para PDF/texto

getCurrentContent: async () => {
  return {
    documentId: "pdf-capitulo-3",
    type: 1,
    position: pdfViewer.currentPage,
    isExternalId: true
  };
}

Funções

Open

Função para abrir o chat, pode ser utilizada para abrir a janela do chat a partir de outro local, por exemplo um botão customizado.

export function openChat() {
  const tutorChat = document.getElementById('tutor-chat');
  tutorChat.open();
}

Importante: a função somente será executada caso o componente tenha sido configurado corretamente.

Close

Função para fechar o chat

export function closeChat() {
  const tutorChat = document.getElementById('tutor-chat');
  tutorChat.close();
}

Muitas vezes é desejável esconder o botão original caso o fluxo de abrir e fechar seja feito por botões customizados, nesse caso é possível utilizar a classe .chat-ative em um estilo css:

.chat:not(.chat-active) {
  display: none;
}

About

Documentação de Customização do Componente do Tutor

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages