|
@@ -34,16 +34,26 @@ function autorLabel(m) {
|
|
|
return "Desconhecido";
|
|
return "Desconhecido";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function midiaLink(m) {
|
|
|
|
|
- return m.Midia && /^https?:\/\//i.test(m.Midia) ? m.Midia : null;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
const tiposAudio = new Set(["mpga", "oga", "mp3", "audio", "ptt"]);
|
|
const tiposAudio = new Set(["mpga", "oga", "mp3", "audio", "ptt"]);
|
|
|
|
|
+const tiposImagem = new Set(["jpg", "jpeg", "png", "webp", "gif", "image", "sticker"]);
|
|
|
|
|
|
|
|
function ehAudio(m) {
|
|
function ehAudio(m) {
|
|
|
return Boolean(m.Transcricao) || tiposAudio.has(m.Tipodemidia);
|
|
return Boolean(m.Transcricao) || tiposAudio.has(m.Tipodemidia);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// arquivos de áudio às vezes vêm em /data/img com Tipodemidia "mp3", então o tipo
|
|
|
|
|
+// declarado decide primeiro; a extensão da URL é só fallback
|
|
|
|
|
+function ehImagem(m) {
|
|
|
|
|
+ if (ehAudio(m)) return false;
|
|
|
|
|
+ if (tiposImagem.has(m.Tipodemidia)) return true;
|
|
|
|
|
+ return /\.(jpe?g|png|webp|gif)$/i.test(m.MidiaUrl ?? "");
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// link genérico "Abrir mídia" só para tipos sem renderização própria (pdf, vídeo, ...)
|
|
|
|
|
+function midiaLink(m) {
|
|
|
|
|
+ return m.MidiaUrl && !ehImagem(m) && !ehAudio(m) ? m.MidiaUrl : null;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// path de armazenamento do arquivo (ex.: /data/aud/xxx.mp3); em áudios antigos sem
|
|
// path de armazenamento do arquivo (ex.: /data/aud/xxx.mp3); em áudios antigos sem
|
|
|
// Midia o próprio Body/Texto é o path
|
|
// Midia o próprio Body/Texto é o path
|
|
|
function caminhoMidia(m) {
|
|
function caminhoMidia(m) {
|
|
@@ -190,13 +200,24 @@ onMounted(async () => {
|
|
|
{{ m.Transcricao }}
|
|
{{ m.Transcricao }}
|
|
|
</p>
|
|
</p>
|
|
|
<p v-else class="mt-1 text-sm italic text-gray-400 dark:text-gray-500">Sem transcrição disponível</p>
|
|
<p v-else class="mt-1 text-sm italic text-gray-400 dark:text-gray-500">Sem transcrição disponível</p>
|
|
|
|
|
+ <audio v-if="m.MidiaUrl" controls preload="none" :src="m.MidiaUrl" class="mt-1.5 h-9 w-64 max-w-full"></audio>
|
|
|
<div
|
|
<div
|
|
|
- v-if="caminhoMidia(m)"
|
|
|
|
|
|
|
+ v-else-if="caminhoMidia(m)"
|
|
|
class="mt-1.5 break-all rounded bg-black/[0.04] px-2 py-1 font-mono text-[11px] text-gray-500 dark:bg-white/[0.06] dark:text-gray-400"
|
|
class="mt-1.5 break-all rounded bg-black/[0.04] px-2 py-1 font-mono text-[11px] text-gray-500 dark:bg-white/[0.06] dark:text-gray-400"
|
|
|
>
|
|
>
|
|
|
{{ caminhoMidia(m) }}
|
|
{{ caminhoMidia(m) }}
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
+ <template v-else-if="ehImagem(m) && m.MidiaUrl">
|
|
|
|
|
+ <a :href="m.MidiaUrl" target="_blank" rel="noopener noreferrer" title="Abrir imagem em tamanho original">
|
|
|
|
|
+ <img
|
|
|
|
|
+ :src="m.MidiaUrl"
|
|
|
|
|
+ alt="Imagem enviada na conversa"
|
|
|
|
|
+ loading="lazy"
|
|
|
|
|
+ class="mt-1.5 max-h-80 max-w-full rounded-lg object-contain"
|
|
|
|
|
+ />
|
|
|
|
|
+ </a>
|
|
|
|
|
+ </template>
|
|
|
<p v-else class="mt-0.5 whitespace-pre-wrap break-words text-sm text-gray-800 dark:text-gray-200">{{ m.Texto }}</p>
|
|
<p v-else class="mt-0.5 whitespace-pre-wrap break-words text-sm text-gray-800 dark:text-gray-200">{{ m.Texto }}</p>
|
|
|
<a
|
|
<a
|
|
|
v-if="midiaLink(m)"
|
|
v-if="midiaLink(m)"
|