A vibe coded tangled fork which supports pijul.
at 86d0b4060de074759eff40666b90be86c244ab23 89 lines 3.6 kB view raw
1{{ define "strings/fragments/form" }} 2 <form 3 {{ if eq .Action "new" }} 4 hx-post="/strings/new" 5 {{ else }} 6 hx-post="/strings/{{ .String.Did }}/{{ .String.Rkey }}/edit" 7 {{ end }} 8 hx-indicator="#new-button" 9 class="p-6 pb-4 dark:text-white flex flex-col gap-2 bg-white dark:bg-gray-800 drop-shadow-sm rounded" 10 hx-swap="none"> 11 <div class="flex flex-col md:flex-row md:items-center gap-2"> 12 <input 13 type="text" 14 id="filename" 15 name="filename" 16 placeholder="Filename with extension" 17 required 18 value="{{ .String.Filename }}" 19 class="md:max-w-64 dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400 px-3 py-2 border rounded" /> 20 <input 21 type="text" 22 id="description" 23 name="description" 24 value="{{ .String.Description }}" 25 placeholder="Description ..." 26 class="flex-1 dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400 px-3 py-2 border rounded" /> 27 </div> 28 <textarea 29 name="content" 30 id="content-textarea" 31 wrap="off" 32 class="w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:placeholder-gray-400" 33 rows="20" 34 placeholder="Paste your string here!" 35 required> 36{{ .String.Contents }}</textarea 37 > 38 <div class="flex justify-between items-center"> 39 <div id="content-stats" class="text-sm text-gray-500 dark:text-gray-400"> 40 <span id="line-count">0 lines</span> 41 <span class="select-none px-1 [&:before]:content-['·']"></span> 42 <span id="byte-count">0 bytes</span> 43 </div> 44 <div id="actions" class="flex gap-2 items-center"> 45 {{ if eq .Action "edit" }} 46 <a 47 class="btn flex items-center gap-2 no-underline hover:no-underline p-2 group text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 " 48 href="/strings/{{ .String.Did }}/{{ .String.Rkey }}"> 49 {{ i "x" "size-4" }} 50 <span class="hidden md:inline">cancel</span> 51 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 52 </a> 53 {{ end }} 54 <button 55 type="submit" 56 id="new-button" 57 class="w-fit btn-create rounded flex items-center py-0 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 group"> 58 <span class="inline-flex items-center gap-2"> 59 {{ i "arrow-up" "w-4 h-4" }} 60 publish 61 </span> 62 <span class="pl-2 hidden group-[.htmx-request]:inline"> 63 {{ i "loader-circle" "w-4 h-4 animate-spin" }} 64 </span> 65 </button> 66 </div> 67 </div> 68 <script> 69 (function () { 70 const textarea = document.getElementById("content-textarea"); 71 const lineCount = document.getElementById("line-count"); 72 const byteCount = document.getElementById("byte-count"); 73 function updateStats() { 74 const content = textarea.value; 75 const lines = content === "" ? 0 : content.split("\n").length; 76 const bytes = new TextEncoder().encode(content).length; 77 lineCount.textContent = `${lines} line${lines !== 1 ? "s" : ""}`; 78 byteCount.textContent = `${bytes} byte${bytes !== 1 ? "s" : ""}`; 79 } 80 textarea.addEventListener("input", updateStats); 81 textarea.addEventListener("paste", () => { 82 setTimeout(updateStats, 0); 83 }); 84 updateStats(); 85 })(); 86 </script> 87 <div id="error" class="error dark:text-red-400"></div> 88 </form> 89{{ end }}