1diff --git a/pkg/list/list.go b/pkg/list/list.go
2index 3aa9d65676a9bffc0007249d53373ac2dfc209df..b6b6b89135839693af2eb32d797c76492381af2c 100644
3--- a/pkg/list/list.go
4+++ b/pkg/list/list.go
5@@ -13,15 +13,15 @@ Left T
6 Right U
7 }
8
9-func Chunck[T any](slice []T, size int) [][]T {
10+func Distribuite[T any](slice []T, size int) [][]T {
11 chuncks := make([][]T, size)
12
13 for i := 0; i < len(slice); i += size {
14 for x := 0; x < size; x++ {
15 end := i + x
16
17- if end > len(slice) {
18- break
19+ if end >= len(slice) {
20+ return chuncks
21 }
22
23 chuncks[x] = append(chuncks[x], slice[end])
24diff --git a/pkg/view/media.go b/pkg/view/media.go
25index 3124119f901e683cddd810c4694584937b5c859f..d5aace24688b861992e6f6147889e9b5a25eb5ac 100644
26--- a/pkg/view/media.go
27+++ b/pkg/view/media.go
28@@ -44,7 +44,8 @@ page = p
29 }
30
31 if albumIDStr == "" {
32- page = 0
33+ id := uint(0)
34+ albumID = &id
35 } else if p, err := strconv.Atoi(albumIDStr); err == nil {
36 id := uint(p)
37 albumID = &id
38@@ -132,9 +133,9 @@ return nil
39 }
40
41 func (self *MediaView) SetMyselfIn(r *ext.Router) {
42- r.GET("/media/", self.Index)
43- r.POST("/media/", self.Index)
44+ r.GET("/media", self.Index)
45+ r.POST("/media", self.Index)
46
47- r.GET("/media/image/", self.GetImage)
48- r.GET("/media/thumbnail/", self.GetThumbnail)
49+ r.GET("/media/image", self.GetImage)
50+ r.GET("/media/thumbnail", self.GetThumbnail)
51 }
52diff --git a/templates/album.qtpl b/templates/album.qtpl
53index 328c6d444892cad0792ba27695045a93199e0b0f..1f25bf6a6e2aa62127718cc5c94e62d908a57568 100644
54--- a/templates/album.qtpl
55+++ b/templates/album.qtpl
56@@ -1,5 +1,4 @@
57 {% import "git.sr.ht/~gabrielgio/img/pkg/database/repository" %}
58-{% import "git.sr.ht/~gabrielgio/img/pkg/list" %}
59
60 {% code
61 type AlbumPage struct {
62@@ -28,26 +27,10 @@ <a href="/album/?albumId={%s FromUInttoString(&a.ID) %}" class="tag text-size-2">{%s a.Name %}</a>
63 {% endfor %}
64 </div>
65 <div class="columns">
66-{% for _, c := range list.Chunck(p.Medias, 4) %}
67- <div class="column is-3">
68- {% for _, media := range c %}
69- <div class="card-image">
70- {% if media.IsVideo() %}
71- <video class="image is-fit" controls muted="true" poster="/media/thumbnail/?path_hash={%s media.PathHash %}" preload="{%s p.PreloadAttr() %}">
72- <source src="/media/image/?path_hash={%s media.PathHash %}" type="{%s media.MIMEType %}">
73- </video>
74- {% else %}
75- <figure class="image is-fit">
76- <img src="/media/thumbnail/?path_hash={%s media.PathHash %}">
77- </figure>
78- {% endif %}
79- </div>
80- {% endfor %}
81- </div>
82-{% endfor %}
83+{%= Mosaic(p.Medias, p.PreloadAttr()) %}
84 </div>
85 <div>
86- <a href="/media/?page={%d p.Next.Page %}" class="button is-pulled-right">next</a>
87+ <a href="/media?page={%d p.Next.Page %}" class="button is-pulled-right">next</a>
88 </div>
89 {% endfunc %}
90
91diff --git a/templates/media.qtpl b/templates/media.qtpl
92index 7dcdf54a8c8e329be1b29912260e59d5e22b1ba5..737d03d63a2ae301fc37dd3a9926e216a6fe325a 100644
93--- a/templates/media.qtpl
94+++ b/templates/media.qtpl
95@@ -1,5 +1,4 @@
96 {% import "git.sr.ht/~gabrielgio/img/pkg/database/repository" %}
97-{% import "git.sr.ht/~gabrielgio/img/pkg/list" %}
98
99 {% code
100 type MediaPage struct {
101@@ -20,26 +19,10 @@ {% func (p *MediaPage) Title() %}Media{% endfunc %}
102
103 {% func (p *MediaPage) Content() %}
104 <div class="columns">
105-{% for _, c := range list.Chunck(p.Medias, 4) %}
106- <div class="column is-3">
107- {% for _, media := range c %}
108- <div class="card-image">
109- {% if media.IsVideo() %}
110- <video class="image is-fit" controls muted="true" poster="/media/thumbnail/?path_hash={%s media.PathHash %}" preload="{%s p.PreloadAttr() %}">
111- <source src="/media/image/?path_hash={%s media.PathHash %}" type="{%s media.MIMEType %}">
112- </video>
113- {% else %}
114- <figure class="image is-fit">
115- <img src="/media/thumbnail/?path_hash={%s media.PathHash %}">
116- </figure>
117- {% endif %}
118- </div>
119- {% endfor %}
120- </div>
121-{% endfor %}
122+{%= Mosaic(p.Medias, p.PreloadAttr()) %}
123 </div>
124 <div>
125- <a href="/media/?page={%d p.Next.Page %}" class="button is-pulled-right">next</a>
126+ <a href="/media?page={%d p.Next.Page %}" class="button is-pulled-right">next</a>
127 </div>
128 {% endfunc %}
129
130diff --git a/templates/mosaic.qtpl b/templates/mosaic.qtpl
131new file mode 100644
132index 0000000000000000000000000000000000000000..18dbcba489fef78faa1326522e834762f3efadba
133--- /dev/null
134+++ b/templates/mosaic.qtpl
135@@ -0,0 +1,24 @@
136+{% import "git.sr.ht/~gabrielgio/img/pkg/database/repository" %}
137+{% import "git.sr.ht/~gabrielgio/img/pkg/list" %}
138+
139+{% func Mosaic(medias []*repository.Media, preloadAttr string) %}
140+<div class="columns">
141+{% for _, c := range list.Distribuite(medias, 6) %}
142+ <div class="column is-2">
143+ {% for _, media := range c %}
144+ <div class="card-image">
145+ {% if media.IsVideo() %}
146+ <video class="image is-fit" controls muted="true" poster="/media/thumbnail?path_hash={%s media.PathHash %}" preload="{%s preloadAttr %}">
147+ <source src="/media/image?path_hash={%s media.PathHash %}" type="{%s media.MIMEType %}">
148+ </video>
149+ {% else %}
150+ <figure class="image is-fit">
151+ <img src="/media/thumbnail?path_hash={%s media.PathHash %}">
152+ </figure>
153+ {% endif %}
154+ </div>
155+ {% endfor %}
156+ </div>
157+{% endfor %}
158+</div>
159+{% endfunc %}