_page_file.html (5962B)
1 {% from "_icons.html" import icon %} 2 {% from "_skeleton.html" import file_skeleton %} 3 {#- Everything here is built from values the server already has (path, extension, size), so the page costs 4 nothing extra to render. Previews load straight from the raw domain; text is fetched by app.js. -#} 5 {% set raw_url = raw_base_url ~ '/' ~ (path | urlencode) %} 6 {% set page_url = cdn_base_url ~ '/' ~ (path | urlencode) %} 7 {% set dl_url = cdn_base_url ~ '/api/get/' ~ (path | urlencode) %} 8 {% set ext = file_ext or '' %} 9 10 {% set kind = namespace(v='') %} 11 {% set kinds = { 12 'image': ['png', 'jpg', 'jpeg', 'gif', 'webp', 'avif', 'bmp', 'ico', 'svg'], 13 'video': ['mp4', 'webm', 'mov', 'm4v', 'ogv'], 14 'audio': ['mp3', 'wav', 'ogg', 'oga', 'flac', 'm4a', 'aac', 'opus'], 15 'pdf': ['pdf'], 16 'text': ['txt', 'md', 'markdown', 'rst', 'json', 'jsonc', 'js', 'mjs', 'cjs', 'ts', 'tsx', 'jsx', 'css', 'scss', 'sass', 'less', 17 'html', 'htm', 'xml', 'yml', 'yaml', 'toml', 'ini', 'cfg', 'conf', 'csv', 'tsv', 'log', 'py', 'rb', 'go', 'rs', 'c', 'h', 18 'cpp', 'hpp', 'cc', 'java', 'kt', 'swift', 'php', 'sh', 'bash', 'zsh', 'fish', 'bat', 'ps1', 'sql', 'lua', 'r', 'pl', 19 'vue', 'svelte', 'diff', 'patch', 'tex', 'srt', 'vtt', 'gitignore', 'map'], 20 } %} 21 {% for k, exts in kinds.items() %}{% if ext in exts %}{% set kind.v = k %}{% endif %}{% endfor %} 22 23 {% set pending = kind.v in ('image', 'pdf', 'text') %} 24 {% set embed = none %} 25 {% if kind.v == 'image' %}{% set embed = '<img src="' ~ raw_url ~ '" alt="">' %} 26 {% elif ext == 'css' %}{% set embed = '<link rel="stylesheet" href="' ~ raw_url ~ '">' %} 27 {% elif ext in ('js', 'mjs') %}{% set embed = '<script src="' ~ raw_url ~ '"></script>' %} 28 {% elif kind.v == 'video' %}{% set embed = '<video src="' ~ raw_url ~ '" controls></video>' %} 29 {% elif kind.v == 'audio' %}{% set embed = '<audio src="' ~ raw_url ~ '" controls></audio>' %} 30 {% endif %} 31 32 <article class="file-view{{ ' is-pending' if pending }}"{{ ' aria-busy="true"'|safe if pending }}> 33 {{ file_skeleton() }} 34 <div class="file-view__content"> 35 <header class="file-head"> 36 <div class="file-head__main"> 37 <h1 class="file-name">{{ filename }}</h1> 38 <p class="file-meta-row"> 39 {% if ext %}<span class="file-pill">{{ ext | upper }}</span>{% endif %} 40 {% if file_size_str and file_size_str != '-' %}<span class="file-pill">{{ file_size_str }}</span>{% endif %} 41 <span class="file-path">{{ path }}</span> 42 </p> 43 </div> 44 <div class="file-head__actions"> 45 <button type="button" class="btn btn-primary" data-copy="{{ raw_url }}" title="Copy the raw link (for embedding)">{{ icon('copy') }}<span>Copy link</span></button> 46 <a href="/api/get/{{ path | urlencode }}" class="btn" data-turbo="false">{{ icon('download') }}<span>Download</span></a> 47 <a href="{{ raw_url }}" class="btn" data-turbo="false" target="_blank" rel="noopener">{{ icon('external') }}<span>Open raw</span></a> 48 </div> 49 </header> 50 51 <section class="link-list" aria-labelledby="links-title"> 52 <h2 id="links-title" class="section-title">Links</h2> 53 {% macro link_row(label, value, hint='') %} 54 <div class="link-row"> 55 <span class="link-row__label">{{ label }}{% if hint %}<small>{{ hint }}</small>{% endif %}</span> 56 <code class="link-row__value" data-link="{{ label }}">{{ value }}</code> 57 <button type="button" class="btn btn-sm" data-copy="{{ value }}" aria-label="Copy {{ label }}">{{ icon('copy', 14) }}<span>Copy</span></button> 58 </div> 59 {% endmacro %} 60 {{ link_row('CDN page', page_url, 'This page') }} 61 {{ link_row('Raw link', raw_url, 'For embedding') }} 62 {{ link_row('Download link', dl_url, 'Starts a download') }} 63 {% if embed %} 64 <div class="link-row link-row--code"> 65 <span class="link-row__label">Embed<small>HTML snippet</small></span> 66 <code class="link-row__value" data-link="Embed">{{ embed }}</code> 67 <button type="button" class="btn btn-sm" data-copy="{{ embed }}" aria-label="Copy embed snippet">{{ icon('copy', 14) }}<span>Copy</span></button> 68 </div> 69 {% endif %} 70 </section> 71 72 <section class="preview preview--{{ kind.v or 'none' }}{{ ' is-loading' if kind.v in ('image', 'pdf') }}" aria-label="Preview"> 73 {% if kind.v == 'image' %} 74 <img src="{{ raw_url }}" alt="Preview of {{ filename }}" decoding="async"> 75 {% elif kind.v == 'video' %} 76 <video src="{{ raw_url }}" controls preload="metadata" playsinline></video> 77 {% elif kind.v == 'audio' %} 78 <div class="preview__audio">{{ icon('file', 28, 1.5) }}<audio src="{{ raw_url }}" controls preload="metadata"></audio></div> 79 {% elif kind.v == 'pdf' %} 80 <iframe src="{{ raw_url }}" title="PDF preview of {{ filename }}"></iframe> 81 <p class="preview__hint">Nothing showing? Your browser may not display PDFs inline — <a href="{{ raw_url }}" target="_blank" rel="noopener" data-turbo="false">open it directly</a>.</p> 82 {% elif kind.v == 'text' %} 83 <div class="preview__text is-skeleton" data-text-src="{{ raw_url }}" data-text-ext="{{ ext }}" data-state="idle" aria-busy="true"> 84 <div class="preview__bar" aria-hidden="true"><span class="sk sk-label"></span><span class="sk sk-btn"></span></div> 85 <div class="sk-lines" aria-hidden="true">{% for w in [58, 82, 40, 70, 92, 34, 66, 78, 48, 86, 30, 72] %}<span class="sk" style="width: {{ w }}%"></span>{% endfor %}</div> 86 <p class="sr-only">Loading preview…</p> 87 </div> 88 {% else %} 89 <div class="preview__none"> 90 <div class="preview__icon">{{ icon('file', 34, 1.5) }}</div> 91 <p>No preview for this file type.</p> 92 </div> 93 {% endif %} 94 </section> 95 </div> 96 </article>