taggart

Simple golang tagging filesystem webapp
Log | Files | Refs

file.html (4692B)


      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/{{$k}}/{{$v}}/delete" style="display:inline;"><button class="text-button" type="submit">x</button></form>
     17 		  <a href="/tag/{{$k}}/{{$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 		  Category: <input type="text" name="category" list="categories"><br>
     30 		  <datalist id="categories">
     31 			{{range .Data.Categories}}
     32 			  <option value="{{.}}">
     33 			{{end}}
     34 		  </datalist>
     35 		  Value: <input type="text" name="value"><br>
     36 		  <button class="text-button" type="submit">Add Tag</button>
     37 		</form>
     38 	</details>
     39 
     40     <details>
     41     <summary>Raw URL</summary>
     42 		<input id="raw-url" value="http://{{.IP}}:{{.Port}}/uploads/{{.Data.EscapedFilename}}"><br>
     43 		<button class="text-button" id="copy-btn" style="margin-top: 5px;">Copy</button>
     44 		<span id="copy-status" style="margin-left: 10px;"></span>
     45 		<script src="/static/copy-link.js" defer></script>
     46 	</details>
     47 
     48     <details>
     49     <summary>File Actions</summary>
     50 
     51 		<script src="/static/rename-file.js" defer></script>
     52 		<form id="renameForm-{{.Data.File.ID}}" method="post" action="/file/{{.Data.File.ID}}/rename" style="display:inline;">
     53 		  <input type="hidden" name="newfilename" value="{{.Data.File.Filename}}">
     54 		  <button type="button" class="text-button rename-button" data-file-id="{{.Data.File.ID}}" data-current-name="{{.Data.File.Filename}}">Rename File</button>
     55 		</form>
     56 		<br />
     57 		<form method="post" action="/file/{{.Data.File.ID}}/delete" style="display:inline;">
     58 		  <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>
     59 		</form>
     60 	</details>
     61 </div>
     62 
     63 <div class="file-content">
     64 
     65 	{{if hasAnySuffix .Data.File.Filename ".jpg" ".jpeg" ".png" ".gif" ".webp"}}
     66 	  <a href="/uploads/{{.Data.EscapedFilename}}" target="_blank"><img src="/uploads/{{.Data.EscapedFilename}}" style="max-width:400px"></a><br>
     67 	{{else if hasAnySuffix .Data.File.Filename ".mp4" ".webm" ".mov" ".m4v"}}
     68 	  <video id="videoPlayer" controls loop muted width="600">
     69 		<source src="/uploads/{{.Data.EscapedFilename}}">
     70 	  </video><br>
     71 	  <script src="/static/timestamps.js" defer></script>
     72 	{{else if hasAnySuffix .Data.File.Filename ".txt" ".md"}}
     73 	  <div id="text-viewer-container" style="max-width:800px; margin:1em 0;">
     74 		<div style="display:flex; justify-content:space-between; margin-bottom:5px;">
     75 		  <button onclick="toggleLineNumbers()" class="text-button">Line Numbers</button>
     76 		  <button onclick="toggleFullscreen()" class="text-button">Fullscreen</button>
     77 		</div>
     78 		<pre id="text-viewer" data-filename="{{.Data.EscapedFilename}}" style="white-space:pre-wrap; overflow:auto; background:#111; color:#eee; padding:10px; border-radius:8px; max-height:500px;">Loading...</pre>
     79 	  </div>
     80 	  <script src="/static/text-viewer.js"></script>
     81 	{{else}}
     82 	  <a href="/uploads/{{.Data.EscapedFilename}}">Download file</a><br>
     83 	{{end}}
     84 
     85 	<div class="description-section">
     86 		<h3>Description</h3>
     87 
     88 		<!-- Display Mode -->
     89 		<div id="description-display" data-original-description="{{.Data.File.Description}}">
     90 			{{if .Data.File.Description}}
     91 				<div id="current-description" >{{.Data.File.Description}}</div>
     92 			{{else}}
     93 				<div id="no-description">No description set</div>
     94 			{{end}}
     95 			<button class="text-button" id="edit-description-btn" onclick="toggleDescriptionEdit()">
     96 				{{if .Data.File.Description}}Edit Description{{else}}Add Description{{end}}
     97 			</button>
     98 		</div>
     99 
    100 		<!-- Edit Mode (initially hidden) -->
    101 		<div id="description-edit" style="display: none;">
    102 			<form method="post">
    103 				<input type="hidden" name="action" value="update_description">
    104 				<div>
    105 					<textarea
    106 						id="description-textarea"
    107 						name="description"
    108 						rows="6"
    109 						maxlength="2048"
    110 						placeholder="Enter description..."
    111 					>{{.Data.File.Description}}</textarea>
    112 				</div>
    113 				<div style="margin-top: 8px; display: flex; align-items: center; gap: 10px;">
    114 					<button class="text-button" type="submit">Save Description</button>
    115 					<button class="text-button" type="button" onclick="cancelDescriptionEdit()">Cancel</button>
    116 				</div>
    117 			</form>
    118 		</div>
    119 	</div>
    120 
    121 	<script src="/static/description.js" defer></script>
    122 
    123 </div>
    124 
    125 {{template "_footer"}}