update chat
Deploy / Deploy (push) Successful in 14s
Details
Deploy / Deploy (push) Successful in 14s
Details
This commit is contained in:
parent
756d2a98b2
commit
a00dcc4e70
|
@ -76,17 +76,33 @@
|
||||||
console.log("Usuário da live:", streamUser);
|
console.log("Usuário da live:", streamUser);
|
||||||
const videoElement = document.querySelector('video');
|
const videoElement = document.querySelector('video');
|
||||||
const playerOffElement = document.querySelector('.player-off');
|
const playerOffElement = document.querySelector('.player-off');
|
||||||
|
const chatContainer = document.querySelector('.chat-container');
|
||||||
|
const chatForm = document.querySelector('.chat-input-form');
|
||||||
|
const usernameInput = document.querySelector('#username-input');
|
||||||
|
const chatInputField = document.querySelector('.chat-enter');
|
||||||
|
|
||||||
const url = `https://class.alice.ufsj.edu.br/dash/${streamUser}.mpd`;
|
const url = `https://class.alice.ufsj.edu.br/dash/${streamUser}.mpd`;
|
||||||
videoElement.src = url;
|
videoElement.src = url;
|
||||||
|
|
||||||
|
let chatAtivo = false;
|
||||||
|
|
||||||
fetch(url)
|
fetch(url)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
console.log("Arquivo existe.");
|
console.log("Arquivo existe.");
|
||||||
playerOffElement.style.display = "none";
|
playerOffElement.style.display = "none";
|
||||||
|
iniciarChat();
|
||||||
} else {
|
} else {
|
||||||
console.log("Arquivo não encontrado.");
|
console.log("Arquivo não encontrado.");
|
||||||
videoElement.style.opacity = "0";
|
videoElement.style.opacity = "0";
|
||||||
|
|
||||||
|
if (chatContainer) {
|
||||||
|
chatContainer.style.opacity = "0.3";
|
||||||
|
chatContainer.style.pointerEvents = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usernameInput) usernameInput.disabled = true;
|
||||||
|
if (chatInputField) chatInputField.disabled = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -94,58 +110,70 @@
|
||||||
// Chat ao vivo
|
// Chat ao vivo
|
||||||
// =====================
|
// =====================
|
||||||
|
|
||||||
const nomesAlice = [
|
function iniciarChat() {
|
||||||
'Alice', 'Chapeleiro Maluco', 'Coelho Branco', 'Rainha de Copas',
|
chatAtivo = true;
|
||||||
'Gato de Cheshire', 'Lebre de Março', 'Lagarta', 'Dodo',
|
|
||||||
'Tweedledee', 'Tweedledum', 'Rainha Vermelha', 'Rei de Copas'
|
|
||||||
];
|
|
||||||
|
|
||||||
function nomeAleatorio() {
|
const nomesAlice = [
|
||||||
return nomesAlice[Math.floor(Math.random() * nomesAlice.length)];
|
'Alice', 'Chapeleiro Maluco', 'Coelho Branco', 'Rainha de Copas',
|
||||||
}
|
'Gato de Cheshire', 'Lebre de Março', 'Lagarta', 'Dodo',
|
||||||
|
'Tweedledee', 'Tweedledum', 'Rainha Vermelha', 'Rei de Copas'
|
||||||
|
];
|
||||||
|
|
||||||
let username = nomeAleatorio();
|
function nomeAleatorio() {
|
||||||
|
return nomesAlice[Math.floor(Math.random() * nomesAlice.length)];
|
||||||
|
}
|
||||||
|
|
||||||
function setCustomUsername() {
|
let username = nomeAleatorio();
|
||||||
const customUsername = document.querySelector('#username-input').value.trim();
|
|
||||||
username = customUsername || nomeAleatorio();
|
|
||||||
}
|
|
||||||
|
|
||||||
const source = new EventSource(`php/chat/relay.php?user=${encodeURIComponent(streamUser)}`);
|
function setCustomUsername() {
|
||||||
|
const customUsername = usernameInput.value.trim();
|
||||||
|
username = customUsername || nomeAleatorio();
|
||||||
|
}
|
||||||
|
|
||||||
source.onmessage = function (event) {
|
const source = new EventSource(`php/chat/relay.php?user=${encodeURIComponent(streamUser)}`);
|
||||||
const msg = JSON.parse(event.data);
|
|
||||||
addMessage(msg);
|
|
||||||
};
|
|
||||||
|
|
||||||
function sendMessage(event) {
|
let ultimaMensagem = "";
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const message = document.querySelector('.chat-enter').value;
|
source.onmessage = function (event) {
|
||||||
const msgData = {
|
if (event.data !== ultimaMensagem) {
|
||||||
nome: username,
|
ultimaMensagem = event.data;
|
||||||
mensagem: message
|
const msg = JSON.parse(event.data);
|
||||||
|
addMessage(msg);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch(`php/chat/send.php?user=${encodeURIComponent(streamUser)}`, {
|
function sendMessage(event) {
|
||||||
method: 'POST',
|
event.preventDefault();
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
body: 'mensagem=' + encodeURIComponent(JSON.stringify(msgData))
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelector('.chat-enter').value = '';
|
const message = document.querySelector('.chat-enter').value;
|
||||||
|
if (!message.trim()) return;
|
||||||
|
|
||||||
|
const msgData = {
|
||||||
|
nome: username,
|
||||||
|
mensagem: message.trim()
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch(`php/chat/send.php?user=${encodeURIComponent(streamUser)}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||||
|
body: 'mensagem=' + encodeURIComponent(JSON.stringify(msgData))
|
||||||
|
})
|
||||||
|
.catch(err => console.error("Erro ao enviar mensagem:", err));
|
||||||
|
|
||||||
|
document.querySelector('.chat-enter').value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function addMessage(msg) {
|
||||||
|
const chatLines = document.querySelector('.chat-lines');
|
||||||
|
const newMessage = document.createElement('div');
|
||||||
|
newMessage.classList.add('chat-line');
|
||||||
|
newMessage.innerHTML = `<p><span class=\"username\">${msg.nome}:</span> ${msg.mensagem}</p>`;
|
||||||
|
|
||||||
|
chatLines.appendChild(newMessage);
|
||||||
|
chatLines.scrollTop = chatLines.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
chatForm.addEventListener('submit', sendMessage);
|
||||||
|
usernameInput.addEventListener('change', setCustomUsername);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addMessage(msg) {
|
|
||||||
const chatLines = document.querySelector('.chat-lines');
|
|
||||||
const newMessage = document.createElement('div');
|
|
||||||
newMessage.classList.add('chat-line');
|
|
||||||
newMessage.innerHTML = `<p><span class=\"username\">${msg.nome}:</span> ${msg.mensagem}</p>`;
|
|
||||||
|
|
||||||
chatLines.appendChild(newMessage);
|
|
||||||
chatLines.scrollTop = chatLines.scrollHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.querySelector('.chat-input-form').addEventListener('submit', sendMessage);
|
|
||||||
document.querySelector('#username-input').addEventListener('change', setCustomUsername);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -578,7 +578,6 @@ h1, h2, h3, h4, h5, h6 {
|
||||||
|
|
||||||
.player-off{
|
.player-off{
|
||||||
height: 80vh;
|
height: 80vh;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -590,10 +589,9 @@ h1, h2, h3, h4, h5, h6 {
|
||||||
|
|
||||||
.player-container {
|
.player-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
/* width: 100%;
|
|
||||||
height: 100%; */
|
|
||||||
|
|
||||||
flex-grow: 10;
|
flex-grow: 10;
|
||||||
|
/* Em telas grandes, pode ser interessante adicionar margem para separar do chat */
|
||||||
|
/* margin: 15px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.player {
|
.player {
|
||||||
|
@ -608,14 +606,13 @@ h1, h2, h3, h4, h5, h6 {
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: rgba(0, 0, 0, 0.6); /* Cor de fundo semitransparente */
|
background-color: rgba(0, 0, 0, 0.6); /* Fundo semitransparente */
|
||||||
color: #fff;
|
color: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
z-index: 10; /* Garante que a mensagem "Offline" apareça em cima do vídeo */
|
z-index: 10; /* Garante que a mensagem "Offline" fique acima do player */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.player-info {
|
.player-info {
|
||||||
|
@ -623,7 +620,7 @@ h1, h2, h3, h4, h5, h6 {
|
||||||
background-color: #0b1a33;
|
background-color: #0b1a33;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Estilos específicos para o player, se necessário */
|
/* Estilos específicos para o player */
|
||||||
video::-webkit-media-controls {
|
video::-webkit-media-controls {
|
||||||
background-color: hsl(0, 0%, 14%);
|
background-color: hsl(0, 0%, 14%);
|
||||||
}
|
}
|
||||||
|
@ -632,22 +629,24 @@ video::-webkit-media-controls-play-button {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Container que engloba o player e o chat */
|
||||||
.live-container{
|
.live-container{
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: column; /* Padrão: empilha o player e o chat (telas pequenas) */
|
||||||
|
|
||||||
height: 70vh;
|
height: 70vh;
|
||||||
|
padding: 15px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Estilos do chat */
|
||||||
.chat {
|
.chat {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
margin: 15px;
|
margin: 15px;
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-container {
|
.chat-container {
|
||||||
|
@ -682,6 +681,7 @@ color: #fff;
|
||||||
.chat-line p {
|
.chat-line p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.username {
|
.username {
|
||||||
|
@ -714,6 +714,45 @@ color: #fff;
|
||||||
background-color: #243b65;
|
background-color: #243b65;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===== Regras responsivas ===== */
|
||||||
|
|
||||||
|
/* Para telas grandes: layout em linha com chat à direita */
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.live-container {
|
||||||
|
flex-direction: row; /* Player e chat lado a lado */
|
||||||
|
align-items: stretch; /* Garante que ambos tenham a mesma altura */
|
||||||
|
}
|
||||||
|
|
||||||
|
.player-container {
|
||||||
|
flex-grow: 1;
|
||||||
|
margin: 15px; /* Opcional: ajuste de espaçamento */
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat {
|
||||||
|
width: 400px; /* Largura fixa, semelhante à do chat da Twitch */
|
||||||
|
height: 95%; /* Alinha a altura do chat à do contêiner (e do player) */
|
||||||
|
margin: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Para telas pequenas: layout em coluna com chat abaixo do player */
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.live-container {
|
||||||
|
flex-direction: column;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player-container, .chat {
|
||||||
|
width: 100%;
|
||||||
|
margin: 15px 0; /* Espaçamento vertical */
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat {
|
||||||
|
height: 500px; /* Altura ajustada para um tamanho adequado */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.page-aula{
|
.page-aula{
|
||||||
font-family: var(--font-family);
|
font-family: var(--font-family);
|
||||||
}
|
}
|
||||||
|
@ -780,4 +819,4 @@ color: #fff;
|
||||||
}
|
}
|
||||||
.content-aula a:hover {
|
.content-aula a:hover {
|
||||||
border-bottom-color: #007bff; /* Mostra a borda inferior ao passar o mouse */
|
border-bottom-color: #007bff; /* Mostra a borda inferior ao passar o mouse */
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,31 +5,38 @@ if (!isset($_GET['user'])) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = preg_replace('/[^a-zA-Z0-9_-]/', '', $_GET['user']);
|
$user = preg_replace('/[^a-zA-Z0-9_-]/', '', $_GET['user']);
|
||||||
|
|
||||||
|
// Verifica se a live está online (arquivo .mpd existe)
|
||||||
|
$mpdPath = "/var/www/html/stream/{$user}.mpd";
|
||||||
|
if (!file_exists($mpdPath)) {
|
||||||
|
http_response_code(404);
|
||||||
|
exit("Live offline");
|
||||||
|
}
|
||||||
|
|
||||||
header("Content-Type: text/event-stream");
|
header("Content-Type: text/event-stream");
|
||||||
header("Cache-Control: no-cache");
|
header("Cache-Control: no-cache");
|
||||||
header("Connection: keep-alive");
|
header("Connection: keep-alive");
|
||||||
|
|
||||||
$tmp_file = sys_get_temp_dir() . "/relay_chat_{$user}.txt";
|
$tmp_file = sys_get_temp_dir() . "/relay_chat_{$user}.txt";
|
||||||
|
|
||||||
|
// Cria o arquivo se ainda não existir
|
||||||
if (!file_exists($tmp_file)) {
|
if (!file_exists($tmp_file)) {
|
||||||
file_put_contents($tmp_file, '');
|
file_put_contents($tmp_file, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
$last_modif = 0;
|
$lastMessage = '';
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
$current_modif = filemtime($tmp_file);
|
$currentMessage = trim(file_get_contents($tmp_file));
|
||||||
|
|
||||||
if ($current_modif > $last_modif) {
|
if ($currentMessage !== '' && $currentMessage !== $lastMessage) {
|
||||||
$last_modif = $current_modif;
|
echo "data: " . $currentMessage . "\n\n";
|
||||||
$data = file_get_contents($tmp_file);
|
|
||||||
echo "data: " . trim($data) . "\n\n";
|
|
||||||
ob_flush();
|
ob_flush();
|
||||||
flush();
|
flush();
|
||||||
|
$lastMessage = $currentMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
if (isset($_POST['mensagem']) && isset($_GET['user'])) {
|
if (isset($_POST['mensagem']) && isset($_GET['user'])) {
|
||||||
$mensagem = trim($_POST['mensagem']);
|
$mensagem = trim($_POST['mensagem']);
|
||||||
$user = preg_replace('/[^a-zA-Z0-9_-]/', '', $_GET['user']); // sanitiza o nome do usuário
|
$user = preg_replace('/[^a-zA-Z0-9_-]/', '', $_GET['user']);
|
||||||
|
|
||||||
if ($mensagem !== '') {
|
if ($mensagem !== '') {
|
||||||
$tmp_file = sys_get_temp_dir() . "/relay_chat_{$user}.txt";
|
$tmp_file = sys_get_temp_dir() . "/relay_chat_{$user}.txt";
|
||||||
file_put_contents($tmp_file, $mensagem);
|
file_put_contents($tmp_file, $mensagem); // sobrescreve, não acumula
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
Loading…
Reference in New Issue