229 lines
12 KiB
HTML
229 lines
12 KiB
HTML
{{template "base.html" .}}
|
|
|
|
{{define "title"}}{{.Share.Title}} — Visor de app_compartir{{end}}
|
|
|
|
{{define "content"}}
|
|
<div class="max-w-4xl mx-auto space-y-6">
|
|
<!-- Header Card -->
|
|
<div class="bg-slate-900 border border-slate-800 rounded-3xl p-5 sm:p-6 shadow-xl flex flex-col md:flex-row md:items-center justify-between gap-4">
|
|
<div class="space-y-1.5 min-w-0">
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
<h1 class="text-xl sm:text-2xl font-bold text-white truncate max-w-lg" title="{{.Share.Title}}">
|
|
{{.Share.Title}}
|
|
</h1>
|
|
{{if .Share.IsGuest}}
|
|
<span class="px-2.5 py-0.5 rounded-full text-xs font-semibold bg-amber-500/10 border border-amber-500/20 text-amber-400">
|
|
<i class="fa-regular fa-clock mr-1"></i> Caduca en 24h
|
|
</span>
|
|
{{else}}
|
|
<span class="px-2.5 py-0.5 rounded-full text-xs font-semibold bg-emerald-500/10 border border-emerald-500/20 text-emerald-400">
|
|
<i class="fa-solid fa-shield mr-1"></i> Permanente
|
|
</span>
|
|
{{end}}
|
|
</div>
|
|
|
|
<div class="flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-slate-400">
|
|
<span><i class="fa-solid fa-user text-slate-500 mr-1"></i> {{.Share.UserDisplay}}</span>
|
|
{{if ne .Share.Type "text"}}
|
|
<span><i class="fa-solid fa-hard-drive text-slate-500 mr-1"></i> {{.Share.FormattedSize}}</span>
|
|
{{end}}
|
|
<span><i class="fa-solid fa-eye text-slate-500 mr-1"></i> {{.Share.ViewsCount}} visitas</span>
|
|
<span><i class="fa-solid fa-calendar-day text-slate-500 mr-1"></i> {{.FormattedDate}}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Action buttons -->
|
|
<div class="flex items-center gap-2 shrink-0">
|
|
{{if ne .Share.Type "text"}}
|
|
<a href="/d/{{.Share.ID}}" class="px-4 py-2 rounded-xl bg-brand-600 hover:bg-brand-500 text-slate-950 font-bold text-sm transition flex items-center gap-1.5 shadow-lg shadow-brand-500/20">
|
|
<i class="fa-solid fa-download"></i>
|
|
<span>Descargar</span>
|
|
</a>
|
|
<a href="/raw/{{.Share.ID}}" target="_blank" class="p-2.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-slate-300 border border-slate-700 transition" title="Ver archivo original / raw">
|
|
<i class="fa-solid fa-arrow-up-right-from-square"></i>
|
|
</a>
|
|
{{else}}
|
|
<button onclick="copyTextContent()" id="copyTextBtn" class="px-4 py-2 rounded-xl bg-brand-600 hover:bg-brand-500 text-slate-950 font-bold text-sm transition flex items-center gap-1.5 shadow-lg shadow-brand-500/20">
|
|
<i class="fa-regular fa-copy"></i>
|
|
<span id="copyTextBtnLabel">Copiar texto</span>
|
|
</button>
|
|
{{end}}
|
|
|
|
<button onclick="toggleQRModal()" class="p-2.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-slate-300 border border-slate-700 transition" title="Ver código QR para móvil">
|
|
<i class="fa-solid fa-qrcode"></i>
|
|
</button>
|
|
|
|
<button onclick="copyCurrentURL()" class="p-2.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-slate-300 border border-slate-700 transition" title="Copiar enlace">
|
|
<i class="fa-solid fa-link"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Viewer Body -->
|
|
<div class="bg-slate-900 border border-slate-800 rounded-3xl p-4 sm:p-6 shadow-2xl overflow-hidden">
|
|
{{if .IsImage}}
|
|
<!-- Image Viewer -->
|
|
<div class="flex flex-col items-center justify-center space-y-3">
|
|
<div class="relative group max-h-[80vh] flex items-center justify-center rounded-2xl overflow-hidden bg-slate-950/60 p-2 border border-slate-800/80">
|
|
<img id="viewerImage" src="/raw/{{.Share.ID}}" alt="{{.Share.Title}}" class="max-h-[75vh] w-auto max-w-full object-contain rounded-xl shadow-lg transition-transform duration-200">
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<button onclick="toggleImageZoom()" class="px-3 py-1.5 rounded-lg bg-slate-800 hover:bg-slate-700 text-xs text-slate-300 border border-slate-700 transition flex items-center gap-1.5">
|
|
<i class="fa-solid fa-magnifying-glass-plus text-brand-400"></i>
|
|
<span id="zoomBtnLabel">Zoom 100%</span>
|
|
</button>
|
|
<a href="/raw/{{.Share.ID}}" target="_blank" class="px-3 py-1.5 rounded-lg bg-slate-800 hover:bg-slate-700 text-xs text-slate-300 border border-slate-700 transition flex items-center gap-1.5">
|
|
<i class="fa-solid fa-expand text-brand-400"></i>
|
|
<span>Pantalla Completa</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
{{else if .IsVideo}}
|
|
<!-- Video Viewer -->
|
|
<div class="rounded-2xl overflow-hidden bg-black border border-slate-800 flex items-center justify-center">
|
|
<video controls autoplay playsinline class="w-full max-h-[75vh] rounded-2xl">
|
|
<source src="/raw/{{.Share.ID}}" type="{{.Share.MimeType}}">
|
|
Tu navegador no soporta la reproducción de video HTML5.
|
|
</video>
|
|
</div>
|
|
|
|
{{else if .IsAudio}}
|
|
<!-- Audio Viewer -->
|
|
<div class="p-8 sm:p-12 flex flex-col items-center justify-center space-y-6 bg-slate-950/60 rounded-2xl border border-slate-800/80">
|
|
<div class="w-20 h-20 rounded-3xl bg-brand-500/10 border border-brand-500/20 text-brand-400 flex items-center justify-center text-3xl shadow-xl shadow-brand-500/10 animate-pulse">
|
|
<i class="fa-solid fa-music"></i>
|
|
</div>
|
|
<div class="text-center space-y-1">
|
|
<h3 class="text-lg font-bold text-white">{{.Share.Title}}</h3>
|
|
<p class="text-xs text-slate-400">{{.Share.FormattedSize}} • {{.Share.MimeType}}</p>
|
|
</div>
|
|
<div class="w-full max-w-md">
|
|
<audio controls autoplay class="w-full">
|
|
<source src="/raw/{{.Share.ID}}" type="{{.Share.MimeType}}">
|
|
Tu navegador no soporta audio HTML5.
|
|
</audio>
|
|
</div>
|
|
</div>
|
|
|
|
{{else if .IsPDF}}
|
|
<!-- PDF Viewer -->
|
|
<div class="space-y-3">
|
|
<div class="w-full h-[80vh] rounded-2xl overflow-hidden border border-slate-800 bg-slate-950">
|
|
<iframe src="/raw/{{.Share.ID}}" class="w-full h-full border-none">
|
|
Tu navegador no soporta iframe para PDFs. <a href="/raw/{{.Share.ID}}" class="text-brand-400 underline">Haz clic para descargarlo</a>.
|
|
</iframe>
|
|
</div>
|
|
</div>
|
|
|
|
{{else if or (eq .Share.Type "text") .IsText}}
|
|
<!-- Text / Code Viewer -->
|
|
<div class="relative space-y-2">
|
|
<div class="flex items-center justify-between text-xs text-slate-400 px-1">
|
|
<span><i class="fa-solid fa-file-lines mr-1 text-slate-500"></i> Formato de texto</span>
|
|
<span>{{len .Share.TextContent}} caracteres</span>
|
|
</div>
|
|
<div class="relative group">
|
|
<pre id="rawTextContent" class="p-5 rounded-2xl bg-slate-950 border border-slate-800 font-mono text-xs sm:text-sm text-slate-100 overflow-x-auto whitespace-pre-wrap leading-relaxed custom-scrollbar selection:bg-brand-500 selection:text-black">{{.Share.TextContent}}</pre>
|
|
</div>
|
|
</div>
|
|
|
|
{{else}}
|
|
<!-- Generic File Download Card -->
|
|
<div class="p-10 sm:p-14 flex flex-col items-center justify-center space-y-6 text-center bg-slate-950/60 rounded-2xl border border-slate-800/80">
|
|
<div class="w-20 h-20 rounded-3xl bg-slate-800 border border-slate-700 text-slate-300 flex items-center justify-center text-3xl shadow-xl">
|
|
<i class="fa-solid fa-file-zipper"></i>
|
|
</div>
|
|
<div class="space-y-1">
|
|
<h3 class="text-lg font-bold text-white max-w-md break-all">{{.Share.Title}}</h3>
|
|
<p class="text-xs text-slate-400">{{.Share.FormattedSize}} • {{.Share.MimeType}}</p>
|
|
</div>
|
|
<a href="/d/{{.Share.ID}}" class="px-6 py-3 rounded-xl bg-brand-600 hover:bg-brand-500 text-slate-950 font-bold text-sm transition flex items-center gap-2 shadow-lg shadow-brand-500/20">
|
|
<i class="fa-solid fa-download"></i>
|
|
<span>Descargar archivo ahora</span>
|
|
</a>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
|
|
<!-- Quick Share QR Drawer for Mobile -->
|
|
<div class="bg-slate-900 border border-slate-800 rounded-3xl p-5 flex flex-col sm:flex-row items-center justify-between gap-4">
|
|
<div class="flex items-center gap-3 text-center sm:text-left">
|
|
<div class="w-10 h-10 rounded-xl bg-brand-500/10 border border-brand-500/20 text-brand-400 flex items-center justify-center text-lg shrink-0">
|
|
<i class="fa-solid fa-mobile-screen"></i>
|
|
</div>
|
|
<div>
|
|
<p class="text-sm font-semibold text-white">¿Quieres abrir esto en tu teléfono?</p>
|
|
<p class="text-xs text-slate-400">Escanea el código QR sin enviar mensajes por WhatsApp</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center gap-3">
|
|
<img src="/qr/{{.Share.ID}}" alt="QR Code" class="w-16 h-16 rounded-lg bg-white p-1 shadow">
|
|
<button onclick="toggleQRModal()" class="px-3.5 py-2 rounded-xl bg-slate-800 hover:bg-slate-700 text-xs font-semibold text-slate-200 border border-slate-700 transition">
|
|
Ver QR en grande
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- QR Modal -->
|
|
<div id="qrModal" class="hidden fixed inset-0 z-50 bg-slate-950/80 backdrop-blur-sm flex items-center justify-center p-4">
|
|
<div class="bg-slate-900 border border-slate-800 rounded-3xl p-6 max-w-sm w-full space-y-4 text-center shadow-2xl animate-fade-in">
|
|
<div class="flex items-center justify-between">
|
|
<h3 class="text-base font-bold text-white">Escanea con tu teléfono</h3>
|
|
<button onclick="toggleQRModal()" class="text-slate-400 hover:text-white p-1"><i class="fa-solid fa-xmark"></i></button>
|
|
</div>
|
|
<div class="p-3 bg-white rounded-2xl shadow-inner inline-block">
|
|
<img src="/qr/{{.Share.ID}}" alt="Código QR grande" class="w-56 h-56 object-contain">
|
|
</div>
|
|
<p class="text-xs text-slate-400">Apunta la cámara de tu móvil para abrir este visor directamente.</p>
|
|
<button onclick="toggleQRModal()" class="w-full py-2.5 rounded-xl bg-slate-800 hover:bg-slate-700 text-sm font-semibold text-white transition">
|
|
Cerrar
|
|
</button>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
{{define "scripts"}}
|
|
<script>
|
|
let isZoomed = false;
|
|
function toggleImageZoom() {
|
|
const img = document.getElementById('viewerImage');
|
|
const label = document.getElementById('zoomBtnLabel');
|
|
if (!img) return;
|
|
isZoomed = !isZoomed;
|
|
if (isZoomed) {
|
|
img.classList.remove('max-h-[75vh]');
|
|
img.classList.add('max-h-none', 'scale-110');
|
|
label.innerText = 'Restablecer';
|
|
} else {
|
|
img.classList.add('max-h-[75vh]');
|
|
img.classList.remove('max-h-none', 'scale-110');
|
|
label.innerText = 'Zoom 100%';
|
|
}
|
|
}
|
|
|
|
function toggleQRModal() {
|
|
const modal = document.getElementById('qrModal');
|
|
modal.classList.toggle('hidden');
|
|
}
|
|
|
|
function copyCurrentURL() {
|
|
navigator.clipboard.writeText(window.location.href).then(() => {
|
|
alert('¡Enlace copiado al portapapeles!');
|
|
});
|
|
}
|
|
|
|
function copyTextContent() {
|
|
const text = document.getElementById('rawTextContent').innerText;
|
|
navigator.clipboard.writeText(text).then(() => {
|
|
const btn = document.getElementById('copyTextBtnLabel');
|
|
btn.innerText = '¡Copiado!';
|
|
setTimeout(() => {
|
|
btn.innerText = 'Copiar texto';
|
|
}, 2000);
|
|
});
|
|
}
|
|
</script>
|
|
{{end}}
|