library.html
⎇
Raw
1{{define "library"}}
2<div class="page-header">
3 <h2>Library</h2>
4 <div class="actions">
5 <form method="post" action="/library/scan" class="inline">
6 <button type="submit">Scan Library</button>
7 </form>
8 <form method="get" action="/library" class="inline filter-form">
9 <input type="hidden" name="path" value="{{.Data.Path}}">
10 <input type="text" name="filter" placeholder="Search..." value="{{.Data.Filter}}">
11 <select name="sort">
12 <option value="date" {{if eq .Data.SortBy "date"}}selected{{end}}>Date</option>
13 <option value="title" {{if eq .Data.SortBy "title"}}selected{{end}}>Title</option>
14 <option value="duration" {{if eq .Data.SortBy "duration"}}selected{{end}}>Duration</option>
15 </select>
16 <button type="submit">Filter</button>
17 </form>
18 </div>
19</div>
20
21{{if .Data.Path}}
22<nav class="breadcrumbs">
23 <a href="/library">Home</a>
24 {{$parts := splitPath .Data.Path}}
25 {{$last := sub (len $parts) 1}}
26 {{$currentPath := ""}}
27 {{range $i, $part := $parts}}
28 {{$currentPath = printf "%s/%s" $currentPath $part}}
29 <span>/</span>
30 {{if eq $i $last}}
31 <a href="/library?path={{urlEncodePath $currentPath}}" aria-current="page" class="current">{{$part}}</a>
32 {{else}}
33 <a href="/library?path={{urlEncodePath $currentPath}}">{{$part}}</a>
34 {{end}}
35 {{end}}
36</nav>
37{{end}}
38
39{{$parentPath := .Data.Path}}
40<div class="library-grid">
41 {{range .Data.Folders}}
42 <a href="/library?path={{urlEncodePath (printf "%s/%s" $parentPath .)}}" class="folder-item">
43 <div class="folder-icon">📁</div>
44 <div class="folder-name">{{baseName .}}</div>
45 </a>
46 {{end}}
47
48 {{range .Data.Media}}
49 <a href="/library/{{.ID}}" class="media-item {{if .IsAudio}}audio{{else}}video{{end}}">
50 <div class="media-thumbnail">
51 {{if .IsAudio}}
52 <img src="/static/icons/audio-icon.svg" alt="">
53 {{else}}
54 <img src="/media/{{.ID}}/thumbnail" alt="" loading="lazy">
55 {{end}}
56 {{if .Duration}}
57 <span class="media-duration">{{formatDuration .Duration}}</span>
58 {{end}}
59 </div>
60 <div class="media-info">
61 <div class="media-title">{{.Title}}</div>
62 <div class="media-path">{{.RelativePath}}</div>
63 </div>
64 </a>
65 {{end}}
66</div>
67
68{{if and (eq (len .Data.Folders) 0) (eq (len .Data.Media) 0)}}
69<div class="empty-state">
70 <p>No media found. <a href="/download">Start a download</a> or scan for existing files.</p>
71</div>
72{{end}}
73{{end}}
74