feat: enhance ErrorModal and chat components with new features and improvements
- Refactored ErrorModal to utilize a dialog element for better accessibility and user experience, including a close button with an icon. - Updated chat components to improve participant display and message read status, enhancing user engagement and clarity. - Introduced loading indicators for user and conversation data in SalaReuniaoManager to improve responsiveness during data fetching. - Enhanced message handling in MessageList to indicate whether messages have been read, providing users with better feedback on message status. - Improved overall structure and styling across various components for consistency and maintainability.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
const mensagens = useQuery(api.chat.obterMensagens, { conversaId, limit: 50 });
|
||||
const digitando = useQuery(api.chat.obterDigitando, { conversaId });
|
||||
const isAdmin = useQuery(api.chat.verificarSeEhAdmin, { conversaId });
|
||||
const conversas = useQuery(api.chat.listarConversas, {});
|
||||
|
||||
let messagesContainer: HTMLDivElement;
|
||||
let shouldScrollToBottom = true;
|
||||
@@ -236,6 +237,7 @@
|
||||
editadaEm?: number;
|
||||
deletada?: boolean;
|
||||
agendadaPara?: number;
|
||||
minutosPara?: number;
|
||||
respostaPara?: Id<"mensagens">;
|
||||
mensagemOriginal?: {
|
||||
_id: Id<"mensagens">;
|
||||
@@ -260,6 +262,7 @@
|
||||
imagem?: string;
|
||||
site?: string;
|
||||
} | null;
|
||||
lidaPor?: Id<"usuarios">[]; // IDs dos usuários que leram a mensagem
|
||||
}
|
||||
|
||||
function agruparMensagensPorDia(msgs: Mensagem[]): Record<string, Mensagem[]> {
|
||||
@@ -369,6 +372,48 @@
|
||||
});
|
||||
window.dispatchEvent(event);
|
||||
}
|
||||
|
||||
// Obter informações da conversa atual
|
||||
const conversaAtual = $derived(() => {
|
||||
if (!conversas?.data) return null;
|
||||
return (conversas.data as any[]).find((c) => c._id === conversaId) || null;
|
||||
});
|
||||
|
||||
// Função para determinar se uma mensagem foi lida
|
||||
function mensagemFoiLida(mensagem: Mensagem): boolean {
|
||||
if (!mensagem.lidaPor || mensagem.lidaPor.length === 0) return false;
|
||||
if (!conversaAtual() || !usuarioAtualId) return false;
|
||||
|
||||
const conversa = conversaAtual();
|
||||
if (!conversa) return false;
|
||||
|
||||
// Converter lidaPor para strings para comparação
|
||||
const lidaPorStr = mensagem.lidaPor.map((id) => String(id));
|
||||
|
||||
// Para conversas individuais: verificar se o outro participante leu
|
||||
if (conversa.tipo === "individual") {
|
||||
const outroParticipante = conversa.participantes?.find(
|
||||
(p: any) => String(p) !== usuarioAtualId
|
||||
);
|
||||
if (outroParticipante) {
|
||||
return lidaPorStr.includes(String(outroParticipante));
|
||||
}
|
||||
}
|
||||
|
||||
// Para grupos/salas: verificar se pelo menos um outro participante leu
|
||||
if (conversa.tipo === "grupo" || conversa.tipo === "sala_reuniao") {
|
||||
const outrosParticipantes = conversa.participantes?.filter(
|
||||
(p: any) => String(p) !== usuarioAtualId && String(p) !== String(mensagem.remetenteId)
|
||||
) || [];
|
||||
if (outrosParticipantes.length === 0) return false;
|
||||
// Verificar se pelo menos um outro participante leu
|
||||
return outrosParticipantes.some((p: any) =>
|
||||
lidaPorStr.includes(String(p))
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
@@ -584,6 +629,53 @@
|
||||
<p class="text-xs text-base-content/50">
|
||||
{formatarDataMensagem(mensagem.enviadaEm)}
|
||||
</p>
|
||||
{#if isMinha && !mensagem.deletada && !mensagem.agendadaPara}
|
||||
<!-- Indicadores de status de envio e leitura -->
|
||||
<div class="flex items-center gap-0.5 ml-1">
|
||||
{#if mensagemFoiLida(mensagem)}
|
||||
<!-- Dois checks azuis para mensagem lida -->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="w-3.5 h-3.5 text-blue-500"
|
||||
style="margin-left: -2px;"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M19.916 4.626a.75.75 0 0 1 .208 1.04l-9 13.5a.75.75 0 0 1-1.154.114l-6-6a.75.75 0 0 1 1.06-1.06l5.353 5.353 8.493-12.74a.75.75 0 0 1 1.04-.207Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="w-3.5 h-3.5 text-blue-500"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M19.916 4.626a.75.75 0 0 1 .208 1.04l-9 13.5a.75.75 0 0 1-1.154.114l-6-6a.75.75 0 0 1 1.06-1.06l5.353 5.353 8.493-12.74a.75.75 0 0 1 1.04-.207Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
{:else}
|
||||
<!-- Um check verde para mensagem enviada -->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
class="w-3.5 h-3.5 text-green-500"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M19.916 4.626a.75.75 0 0 1 .208 1.04l-9 13.5a.75.75 0 0 1-1.154.114l-6-6a.75.75 0 0 1 1.06-1.06l5.353 5.353 8.493-12.74a.75.75 0 0 1 1.04-.207Z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{#if !mensagem.deletada && !mensagem.agendadaPara}
|
||||
<div class="flex gap-1">
|
||||
{#if isMinha}
|
||||
|
||||
Reference in New Issue
Block a user