file.html (5513B)
1 {{template "_header" .}} 2 <h2>File: {{.Data.File.Filename}}</h2> 3 4 <div class="file-container"> 5 6 <div class="file-sidebar"> 7 8 <details open> 9 <summary>Tags</summary> 10 <ul> 11 {{range $k, $vs := .Data.File.Tags}} 12 <li> 13 <span class="file-tag-category">{{$k}}:</span><br> 14 {{range $i, $v := $vs}} 15 {{if $i}}<br> {{end}} 16 <form method="post" action="/file/{{$.Data.File.ID}}/tag/delete"><input type="hidden" name="category" value="{{$k}}"><input type="hidden" name="value" value="{{$v}}"><button class="text-button" type="submit">x</button></form> 17 <a href="/tag/{{pathEscape $k}}/{{pathEscape $v}}">{{$v}}</a> 18 {{end}} 19 </li> 20 {{else}} 21 <li>No tags yet</li> 22 {{end}} 23 </ul> 24 </details> 25 26 <details> 27 <summary>Add Tags</summary> 28 <form method="post"> 29 <input type="text" name="category" list="categories" placeholder="Category"><br> 30 <datalist id="categories">{{range .Data.Categories}}<option value="{{.}}">{{end}}</datalist> 31 <input type="text" name="value" placeholder="Value"><br> 32 <button class="text-button" type="submit">Add Tag</button> 33 </form> 34 </details> 35 36 <details> 37 <summary>Properties</summary> 38 {{if .Data.Properties}} 39 <ul> 40 {{range $k, $v := .Data.Properties}} 41 <li> 42 <span class="file-tag-category">{{$k}}:</span> 43 <a href="/property/{{$k}}/{{$v}}" {{if eq $k "filetype"}}style="text-transform:lowercase"{{end}}>{{$v}}</a> 44 </li> 45 {{end}} 46 </ul> 47 {{else}} 48 <p>No properties computed yet.</p> 49 {{end}} 50 </details> 51 52 <details> 53 <summary>Raw URL</summary> 54 <input id="raw-url" value="http://{{.IP}}:{{.Port}}/uploads/{{.Data.EscapedFilename}}"><br> 55 <button class="text-button" id="copy-btn">Copy</button><br> 56 <span id="copy-status"></span> 57 <script src="/static/copy-link.js" defer></script> 58 </details> 59 60 <details> 61 <summary>File Actions</summary> 62 63 <script src="/static/rename-file.js" defer></script> 64 <form id="renameForm-{{.Data.File.ID}}" method="post" action="/file/{{.Data.File.ID}}/rename"> 65 <input type="hidden" name="newfilename" value="{{.Data.File.Filename}}"> 66 <button type="button" class="text-button rename-button" data-file-id="{{.Data.File.ID}}" data-current-name="{{.Data.File.Filename}}">Rename File</button> 67 </form> 68 <br /> 69 <form method="post" action="/file/{{.Data.File.ID}}/delete"> 70 <button type="submit" onclick="return confirm('Are you sure you want to delete this file? This cannot be undone!')" class="text-button">Delete File</button> 71 </form> 72 </details> 73 </div> 74 75 <div class="file-content"> 76 77 {{if hasAnySuffix .Data.File.Filename ".jpg" ".jpeg" ".png" ".gif" ".webp"}} 78 <div id="imageContainer" class="media-container"> 79 <a href="/uploads/{{.Data.EscapedFilename}}" target="_blank"><img src="/uploads/{{.Data.EscapedFilename}}" id="imageViewer" class="file-content-image"></a><br> 80 </div> 81 <script src="/static/timestamps.js" defer></script> 82 {{else if hasAnySuffix .Data.File.Filename ".cbz"}} 83 <div class="cbz-preview"> 84 <a href="/cbz/{{.Data.File.ID}}"> 85 <img src="/uploads/thumbnails/{{.Data.File.Filename}}.jpg" class="file-content-image" alt="CBZ Preview"> 86 </a> 87 <div class="cbz-open-button"> 88 <a href="/cbz/{{.Data.File.ID}}" class="text-button" style="display: inline-block; padding: 10px 20px; margin-top: 10px;">📖 Open CBZ Viewer</a> 89 </div> 90 </div> 91 {{else if hasAnySuffix .Data.File.Filename ".mp4" ".webm" ".mov" ".m4v"}} 92 <div id="videoContainer" class="media-container"> 93 <video id="videoPlayer" controls loop muted width="600"> 94 <source src="/uploads/{{.Data.EscapedFilename}}"> 95 </video><br> 96 </div> 97 <script src="/static/timestamps.js" defer></script> 98 {{else if hasAnySuffix .Data.File.Filename ".txt" ".md"}} 99 <div id="text-viewer-container"> 100 <div> 101 <button onclick="toggleLineNumbers()" class="text-button">Line Numbers</button> 102 <button onclick="toggleFullscreen()" class="text-button">Fullscreen</button> 103 </div> 104 <pre id="text-viewer" data-filename="{{.Data.EscapedFilename}}">Loading...</pre> 105 </div> 106 <script src="/static/text-viewer.js"></script> 107 <script src="/static/common.js"></script> 108 {{else}} 109 <a href="/uploads/{{.Data.EscapedFilename}}">Download file</a><br> 110 {{end}} 111 112 <div class="description-section"> 113 <h3>Description</h3> 114 115 <!-- Display Mode --> 116 <div id="description-display" data-original-description="{{.Data.File.Description}}"> 117 {{if .Data.File.Description}} 118 <div id="current-description" >{{.Data.File.Description}}</div> 119 {{else}} 120 <div id="no-description">No description set</div> 121 {{end}} 122 <button class="text-button" id="edit-description-btn" onclick="toggleDescriptionEdit()"> 123 {{if .Data.File.Description}}Edit Description{{else}}Add Description{{end}} 124 </button> 125 </div> 126 127 <!-- Edit Mode (initially hidden) --> 128 <div id="description-edit" style="display: none;"> 129 <form method="post"> 130 <input type="hidden" name="action" value="update_description"> 131 <div> 132 <textarea 133 id="description-textarea" 134 name="description" 135 rows="6" 136 maxlength="2048" 137 placeholder="Enter description..." 138 >{{.Data.File.Description}}</textarea> 139 </div> 140 <div style="margin-top: 8px; display: flex; align-items: center; gap: 10px;"> 141 <button class="text-button" type="submit">Save Description</button> 142 <button class="text-button" type="button" onclick="cancelDescriptionEdit()">Cancel</button> 143 </div> 144 </form> 145 </div> 146 </div> 147 148 <script src="/static/description.js" defer></script> 149 150 </div> 151 152 {{template "_footer"}}